From 40c9f4291784eaea1d9823bc006373a18cda0661 Mon Sep 17 00:00:00 2001 From: nlohmann Date: Wed, 28 Oct 2026 20:27:06 +0000 Subject: [PATCH] deploy: 54f6b3ef06c6f600897aa26bb44490d570e975be --- api/basic_json/at.md | 3 +- api/basic_json/at/index.html | 4 +- api/basic_json/at/index.md | 2 +- api/basic_json/diff.md | 7 +- api/basic_json/diff/index.html | 4 +- api/basic_json/diff/index.md | 2 +- api/basic_json/operator%5B%5D.md | 22 +- api/basic_json/operator[]/index.html | 4 +- api/basic_json/operator[]/index.md | 10 +- api/basic_json/patch_inplace.md | 15 + api/basic_json/patch_inplace/index.html | 4 +- api/basic_json/patch_inplace/index.md | 9 + api/basic_json_view/materialize.md | 24 +- api/basic_json_view/materialize/index.html | 4 +- api/basic_json_view/materialize/index.md | 12 +- api/json_pointer/operator_slasheq.md | 6 +- api/json_pointer/operator_slasheq/index.html | 4 +- api/json_pointer/operator_slasheq/index.md | 4 +- api/macros/json_diagnostic_positions.md | 1 + .../json_diagnostic_positions/index.html | 2 +- api/macros/json_diagnostic_positions/index.md | 1 + features/json_patch.md | 5 +- features/json_patch/index.html | 4 +- features/json_patch/index.md | 2 +- features/json_view.md | 8 +- features/json_view/index.html | 4 +- features/json_view/index.md | 2 +- features/parsing/untrusted_input.md | 13 + features/parsing/untrusted_input/index.html | 2 +- features/parsing/untrusted_input/index.md | 5 + home/architecture.md | 10 +- home/architecture/index.html | 6 +- home/architecture/index.md | 5 +- home/releases/unreleased/index.html | 2 +- home/releases/unreleased/index.md | 2 + search/search_index.json | 2 +- sitemap.xml | 806 +++++++++--------- sitemap.xml.gz | Bin 2657 -> 2657 bytes 38 files changed, 564 insertions(+), 458 deletions(-) diff --git a/api/basic_json/at.md b/api/basic_json/at.md index 45ec2b27d..58d9ceb28 100644 --- a/api/basic_json/at.md +++ b/api/basic_json/at.md @@ -90,7 +90,8 @@ Strong exception safety: if an exception occurs, the original value stays intact 1. Constant. 2. Logarithmic in the size of the container. 3. Logarithmic in the size of the container. -4. Logarithmic in the size of the container. +4. Linear in the number of reference tokens of `ptr`; for each of them, logarithmic in the size of the object, or + constant for an array. ## Notes diff --git a/api/basic_json/at/index.html b/api/basic_json/at/index.html index cfd19383e..ec0bd176b 100644 --- a/api/basic_json/at/index.html +++ b/api/basic_json/at/index.html @@ -15,7 +15,7 @@ // (4) reference at(const json_pointer& ptr); const_reference at(const json_pointer& ptr) const; -
  1. Returns a reference to the array element at specified location idx, with bounds checking.
  2. Returns a reference to the object element with specified key key, with bounds checking.
  3. See 2. This overload is only available if KeyType is comparable with typename object_t::key_type and typename object_comparator_t::is_transparent denotes a type.
  4. Returns a reference to the element at specified JSON pointer ptr, with bounds checking.

Template parameters

KeyType
A type for an object key other than json_pointer that is comparable with string_t using object_comparator_t. This can also be a string view (C++17).

Parameters

idx (in)
index of the element to access
key (in)
object key of the elements to access
ptr (in)
JSON pointer to the desired element

Return value

  1. reference to the element at index idx
  2. reference to the element at key key
  3. reference to the element at key key
  4. reference to the element pointed to by ptr

Exception safety

Strong exception safety: if an exception occurs, the original value stays intact.

Exceptions

  1. The function can throw the following exceptions:
    • Throws type_error.304 if the JSON value is not an array; in this case, calling at with an index makes no sense. See the example below.
    • Throws out_of_range.401 if the index idx is out of range of the array; that is, idx >= size(). See the example below.
  2. The function can throw the following exceptions:
    • Throws type_error.304 if the JSON value is not an object; in this case, calling at with a key makes no sense. See the example below.
    • Throws out_of_range.403 if the key key is not stored in the object; that is, find(key) == end(). See the example below.
  3. See 2.
  4. The function can throw the following exceptions:
    • Throws parse_error.106 if an array index in the passed JSON pointer ptr begins with '0'. See the example below.
    • Throws parse_error.109 if an array index in the passed JSON pointer ptr is not a number. See the example below.
    • Throws out_of_range.401 if an array index in the passed JSON pointer ptr is out of range. See the example below.
    • Throws out_of_range.402 if the array index '-' is used in the passed JSON pointer ptr. As at provides checked access (and no elements are implicitly inserted), the index '-' is always invalid. See the example below.
    • Throws out_of_range.403 if the JSON pointer describes a key of an object which cannot be found. See the example below.
    • Throws out_of_range.404 if the JSON pointer ptr can not be resolved. See the example below.
    • Throws out_of_range.410 if an array index in the passed JSON pointer ptr exceeds the range of size_type (e.g., on 32-bit platforms).

Complexity

  1. Constant.
  2. Logarithmic in the size of the container.
  3. Logarithmic in the size of the container.
  4. Logarithmic in the size of the container.

Notes

Deprecation

Overload (4) also accepts a json_pointer 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 for how to update existing code.

Examples

Example: (1) access specified array element with bounds checking

The example below shows how array elements can be read and written using at(). It also demonstrates the different exceptions that can be thrown.

#include <iostream>
+
  1. Returns a reference to the array element at specified location idx, with bounds checking.
  2. Returns a reference to the object element with specified key key, with bounds checking.
  3. See 2. This overload is only available if KeyType is comparable with typename object_t::key_type and typename object_comparator_t::is_transparent denotes a type.
  4. Returns a reference to the element at specified JSON pointer ptr, with bounds checking.

Template parameters

KeyType
A type for an object key other than json_pointer that is comparable with string_t using object_comparator_t. This can also be a string view (C++17).

Parameters

idx (in)
index of the element to access
key (in)
object key of the elements to access
ptr (in)
JSON pointer to the desired element

Return value

  1. reference to the element at index idx
  2. reference to the element at key key
  3. reference to the element at key key
  4. reference to the element pointed to by ptr

Exception safety

Strong exception safety: if an exception occurs, the original value stays intact.

Exceptions

  1. The function can throw the following exceptions:
    • Throws type_error.304 if the JSON value is not an array; in this case, calling at with an index makes no sense. See the example below.
    • Throws out_of_range.401 if the index idx is out of range of the array; that is, idx >= size(). See the example below.
  2. The function can throw the following exceptions:
    • Throws type_error.304 if the JSON value is not an object; in this case, calling at with a key makes no sense. See the example below.
    • Throws out_of_range.403 if the key key is not stored in the object; that is, find(key) == end(). See the example below.
  3. See 2.
  4. The function can throw the following exceptions:
    • Throws parse_error.106 if an array index in the passed JSON pointer ptr begins with '0'. See the example below.
    • Throws parse_error.109 if an array index in the passed JSON pointer ptr is not a number. See the example below.
    • Throws out_of_range.401 if an array index in the passed JSON pointer ptr is out of range. See the example below.
    • Throws out_of_range.402 if the array index '-' is used in the passed JSON pointer ptr. As at provides checked access (and no elements are implicitly inserted), the index '-' is always invalid. See the example below.
    • Throws out_of_range.403 if the JSON pointer describes a key of an object which cannot be found. See the example below.
    • Throws out_of_range.404 if the JSON pointer ptr can not be resolved. See the example below.
    • Throws out_of_range.410 if an array index in the passed JSON pointer ptr exceeds the range of size_type (e.g., on 32-bit platforms).

Complexity

  1. Constant.
  2. Logarithmic in the size of the container.
  3. Logarithmic in the size of the container.
  4. Linear in the number of reference tokens of ptr; for each of them, logarithmic in the size of the object, or constant for an array.

Notes

Deprecation

Overload (4) also accepts a json_pointer 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 for how to update existing code.

Examples

Example: (1) access specified array element with bounds checking

The example below shows how array elements can be read and written using at(). It also demonstrates the different exceptions that can be thrown.

#include <iostream>
 #include <nlohmann/json.hpp>
 
 using nlohmann::json;
@@ -498,4 +498,4 @@
 [json.exception.out_of_range.402] array index '-' (2) is out of range
 [json.exception.out_of_range.403] key 'foo' not found
 [json.exception.out_of_range.404] unresolved reference token 'foo'
-

See also

Version history

  1. Added in version 1.0.0.
  2. Added in version 1.0.0.
  3. Added in version 3.11.0. Support for keys convertible to std::string_view added in version 3.13.0 unreleased, consistently across the lookup functions.
  4. Added in version 2.0.0. Throws parse_error.109 instead of out_of_range.404 for a one-character array index that is not a digit (e.g., /x) in version 3.13.0 unreleased, as it already did for longer ones.
\ No newline at end of file +

See also

Version history

  1. Added in version 1.0.0.
  2. Added in version 1.0.0.
  3. Added in version 3.11.0. Support for keys convertible to std::string_view added in version 3.13.0 unreleased, consistently across the lookup functions.
  4. Added in version 2.0.0. Throws parse_error.109 instead of out_of_range.404 for a one-character array index that is not a digit (e.g., /x) in version 3.13.0 unreleased, as it already did for longer ones.
\ No newline at end of file diff --git a/api/basic_json/at/index.md b/api/basic_json/at/index.md index 6cacba185..3b14e98e9 100644 --- a/api/basic_json/at/index.md +++ b/api/basic_json/at/index.md @@ -71,7 +71,7 @@ Strong exception safety: if an exception occurs, the original value stays intact 1. Constant. 1. Logarithmic in the size of the container. 1. Logarithmic in the size of the container. -1. Logarithmic in the size of the container. +1. Linear in the number of reference tokens of `ptr`; for each of them, logarithmic in the size of the object, or constant for an array. ## Notes diff --git a/api/basic_json/diff.md b/api/basic_json/diff.md index c38ab251f..5188bd29d 100644 --- a/api/basic_json/diff.md +++ b/api/basic_json/diff.md @@ -19,9 +19,10 @@ The equality holds up to [`operator==`](operator_eq.md), so it has the following - A value that is not equal to itself cannot round-trip. This applies to `NaN` (also nested in an array or object) and to [discarded](is_discarded.md) values: `diff` emits a `replace` operation for them. A `NaN` in the patch is serialized as `#!json null`, so a patch that was dumped and parsed again would set `#!json null`. -- Numbers that compare equal produce no operation, even if their types or signs differ: `diff(1, 1.0)`, - `diff(1u, 1)` (unsigned and signed integer) and `diff(0.0, -0.0)` all return `#!json []`. The patched value is then - the `source` and keeps its number type. +- Numbers that compare equal produce no operation, even if their types differ or if one is zero and the other is + negative zero: `diff(1, 1.0)` (integer and floating-point), `diff(1u, 1)` (unsigned and signed integer) and + `diff(0.0, -0.0)` (positive and negative zero) all return `#!json []`. The patched value is then the `source` and + keeps its number type and sign. ## Parameters diff --git a/api/basic_json/diff/index.html b/api/basic_json/diff/index.html index 1e4abf492..005e89992 100644 --- a/api/basic_json/diff/index.html +++ b/api/basic_json/diff/index.html @@ -2,7 +2,7 @@ const basic_json& target, const string_t& path = "");

Creates a JSON Patch so that value source can be changed into the value target by calling patch function.

For two JSON values source and target, the following code yields true:

source.patch(diff(source, target)) == target;
-

The equality holds up to operator==, so it has the following exceptions:

Parameters

source (in)
JSON value to compare from
target (in)
JSON value to compare against
path (in)
a prefix that is put verbatim in front of the path member of every operation (default: "", which addresses the root of the value). The prefix is neither escaped nor validated: diff(1, 2, "abc") yields an operation with the path abc, which is not a valid JSON Pointer. Use it with a valid JSON Pointer such as /root and escape ~ and / in its reference tokens (see JSON Pointer).

Return value

a JSON patch to convert the source to target

Exception safety

Strong guarantee: source and target are never modified.

Complexity

Linear in the total number of values (including nested ones) in source and target, times the cost of a key-based object operation (looking up a key in an object): logarithmic for json, and linear for ordered_json (see ordered_map complexity). For ordered_json, diffing two objects with n and m members therefore takes O((n+m)²) when their keys do not line up (e.g., a key was added or the keys are in a different order). The size of the patch is proportional to the number of operations times the length of their paths, so a small change deep inside a value yields a long path.

Notes

Examples

Example

The following code shows how a JSON patch is created as a diff for two JSON values.

#include <iostream>
+

The equality holds up to operator==, so it has the following exceptions:

Parameters

source (in)
JSON value to compare from
target (in)
JSON value to compare against
path (in)
a prefix that is put verbatim in front of the path member of every operation (default: "", which addresses the root of the value). The prefix is neither escaped nor validated: diff(1, 2, "abc") yields an operation with the path abc, which is not a valid JSON Pointer. Use it with a valid JSON Pointer such as /root and escape ~ and / in its reference tokens (see JSON Pointer).

Return value

a JSON patch to convert the source to target

Exception safety

Strong guarantee: source and target are never modified.

Complexity

Linear in the total number of values (including nested ones) in source and target, times the cost of a key-based object operation (looking up a key in an object): logarithmic for json, and linear for ordered_json (see ordered_map complexity). For ordered_json, diffing two objects with n and m members therefore takes O((n+m)²) when their keys do not line up (e.g., a key was added or the keys are in a different order). The size of the patch is proportional to the number of operations times the length of their paths, so a small change deep inside a value yields a long path.

Notes

Examples

Example

The following code shows how a JSON patch is created as a diff for two JSON values.

#include <iostream>
 #include <iomanip>
 #include <nlohmann/json.hpp>
 
@@ -64,4 +64,4 @@
         "world"
     ]
 }
-

See also

Version history

\ No newline at end of file +

See also

Version history

\ No newline at end of file diff --git a/api/basic_json/diff/index.md b/api/basic_json/diff/index.md index 499c3e808..380658da5 100644 --- a/api/basic_json/diff/index.md +++ b/api/basic_json/diff/index.md @@ -17,7 +17,7 @@ source.patch(diff(source, target)) == target; The equality holds up to [`operator==`](https://json.nlohmann.me/api/basic_json/operator_eq/index.md), so it has the following exceptions: - A value that is not equal to itself cannot round-trip. This applies to `NaN` (also nested in an array or object) and to [discarded](https://json.nlohmann.me/api/basic_json/is_discarded/index.md) values: `diff` emits a `replace` operation for them. A `NaN` in the patch is serialized as `null`, so a patch that was dumped and parsed again would set `null`. -- Numbers that compare equal produce no operation, even if their types or signs differ: `diff(1, 1.0)`, `diff(1u, 1)` (unsigned and signed integer) and `diff(0.0, -0.0)` all return `[]`. The patched value is then the `source` and keeps its number type. +- Numbers that compare equal produce no operation, even if their types differ or if one is zero and the other is negative zero: `diff(1, 1.0)` (integer and floating-point), `diff(1u, 1)` (unsigned and signed integer) and `diff(0.0, -0.0)` (positive and negative zero) all return `[]`. The patched value is then the `source` and keeps its number type and sign. ## Parameters diff --git a/api/basic_json/operator%5B%5D.md b/api/basic_json/operator%5B%5D.md index aa39b9c07..3abb37350 100644 --- a/api/basic_json/operator%5B%5D.md +++ b/api/basic_json/operator%5B%5D.md @@ -92,12 +92,20 @@ Strong exception safety: if an exception occurs, the original value stays intact For the **const** version, an object key or array index in `ptr` that does not exist is not reported by an exception, but is undefined behavior (see the notes below). Use [`at`](at.md) for checked access. + If the **non-const** version throws, the value is left unchanged: values it created for earlier reference tokens + of `ptr` are removed again. This also holds for exceptions such as `#!cpp std::bad_alloc` or + `#!cpp std::length_error` thrown while padding an array up to a very large index. With custom + [template parameters](../../features/types/template_parameters.md), this requires that `erase()` of the object and + array types and the move operations of the custom base class do not throw. + ## Complexity 1. Constant if `idx` is in the range of the array. Otherwise, linear in `idx - size()`. 2. Logarithmic in the size of the container. 3. Logarithmic in the size of the container. -4. Logarithmic in the size of the container. +4. Linear in the number of reference tokens of `ptr`; for each of them, logarithmic in the size of the object, or + constant for an array. When the non-const version pads an array with `#!json null` values, it is additionally + linear in `idx - size()` for that array. ## Notes @@ -145,6 +153,14 @@ Strong exception safety: if an exception occurs, the original value stays intact specified by the JSON Pointer RFC; it is this library's own, intentional disambiguation rule. See also [JSON Pointer](../../features/json_pointer.md). + !!! warning "Large array indices" + + As the array is filled up with `#!json null` values to the given index, the memory used grows with the index + and not with the size of the pointer: on a 64-bit platform, the index `10000000` allocates about 160 MB. + The library does not limit the index, so check the array indices of a JSON pointer from untrusted input + before using it with the non-const version. See + [Parsing untrusted input](../../features/parsing/untrusted_input.md#json-pointers-and-flattened-keys). + !!! warning "Deprecation" Overload (4) also accepts a [`json_pointer`](../json_pointer/index.md) whose template argument is a `basic_json` @@ -564,4 +580,6 @@ Strong exception safety: if an exception occurs, the original value stays intact 4. Added in version 2.0.0. A missing array index in the const version is guarded by a runtime assertion since version 3.13.0. Throws [`parse_error.109`](../../home/exceptions.md#jsonexceptionparse_error109) instead of [`out_of_range.404`](../../home/exceptions.md#jsonexceptionout_of_range404) for a one-character array index that is not -a digit (e.g., `/x`) in version 3.13.0, as it already did for longer ones. +a digit (e.g., `/x`) in version 3.13.0, as it already did for longer ones. Fixed in version 3.13.0 to leave the value +unchanged if the non-const version throws (strong exception safety, as documented); before, values created for earlier +reference tokens of `ptr` were kept. diff --git a/api/basic_json/operator[]/index.html b/api/basic_json/operator[]/index.html index ce859769f..452605317 100644 --- a/api/basic_json/operator[]/index.html +++ b/api/basic_json/operator[]/index.html @@ -15,7 +15,7 @@ // (4) reference operator[](const json_pointer& ptr); const_reference operator[](const json_pointer& ptr) const; -
  1. Returns a reference to the array element at specified location idx.
  2. Returns a reference to the object element with specified key key. The non-const qualified overload takes the key by value.
  3. See 2. This overload is only available if KeyType is comparable with typename object_t::key_type and typename object_comparator_t::is_transparent denotes a type.
  4. Returns a reference to the element with specified JSON pointer ptr.

Template parameters

KeyType
A type for an object key other than json_pointer that is comparable with string_t using object_comparator_t. This can also be a string view (C++17).

Iterator invalidation

For the non-const versions 1. and 4., when passing an array index that does not exist, it is created and filled with a null value before a reference to it is returned. For this, a reallocation can happen, in which case all iterators (including the end() iterator) and all references to the elements are invalidated.

For ordered_json, also passing an object key to the non-const versions 2., 3., and 4., a reallocation can happen which again invalidates all iterators and all references.

Parameters

idx (in)
index of the element to access
key (in)
object key of the element to access
ptr (in)
JSON pointer to the desired element

Return value

  1. (const) reference to the element at index idx
  2. (const) reference to the element at key key
  3. (const) reference to the element at key key
  4. (const) reference to the element pointed to by ptr

Exception safety

Strong exception safety: if an exception occurs, the original value stays intact.

Exceptions

  1. The function can throw the following exceptions:
    • Throws type_error.305 if the JSON value is not an array or null; in that case, using the [] operator with an index makes no sense.
    • Throws 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 throws.)
  2. The function can throw the following exceptions:
    • Throws type_error.305 if the JSON value is not an object or null; in that case, using the [] operator with a key makes no sense.
  3. See 2.
  4. The function can throw the following exceptions:

    • Throws parse_error.106 if an array index in the passed JSON pointer ptr begins with '0'.
    • Throws parse_error.109 if an array index in the passed JSON pointer ptr is not a number.
    • Throws out_of_range.402 if the array index '-' is used in the passed JSON pointer ptr for the const version.
    • Throws out_of_range.404 if the JSON pointer ptr can not be resolved.
    • Throws out_of_range.410 if an array index in the passed JSON pointer ptr exceeds the range of size_type (e.g., on 32-bit platforms).

    For the const version, an object key or array index in ptr that does not exist is not reported by an exception, but is undefined behavior (see the notes below). Use at for checked access.

Complexity

  1. Constant if idx is in the range of the array. Otherwise, linear in idx - size().
  2. Logarithmic in the size of the container.
  3. Logarithmic in the size of the container.
  4. Logarithmic in the size of the container.

Notes

Undefined behavior and runtime assertions

The following cases apply to the const overloads; the non-const overloads instead insert the missing element (see the notes below).

  1. If the element at index idx does not exist, the behavior is undefined and is guarded by a runtime assertion!
  2. If the element with key key does not exist, the behavior is undefined and is guarded by a runtime assertion!
  3. If the JSON pointer ptr refers to an object key or an array index that does not exist, the behavior is undefined and is guarded by a runtime assertion!
  1. The non-const version may add values: If idx is beyond the range of the array (i.e., idx >= size()), then the array is silently filled up with null values to make idx a valid reference to the last stored element. In case the value was null before, it is converted to an array.

  2. If key is not found in the object, then it is silently added to the object and filled with a null value to make key a valid reference. In case the value was null before, it is converted to an object.

  3. See 2.

  4. null values are created in arrays and objects if necessary.

    In particular:

    • If the JSON pointer points to an object key that does not exist, it is created and filled with a null value before a reference to it is returned.
    • If the JSON pointer points to an array index that does not exist, it is created and filled with a null value before a reference to it is returned. All indices between the current maximum and the given index are also filled with null.
    • The special value - is treated as a synonym for the index past the end.

    Creating intermediate levels that don't exist yet

    When the JSON pointer traverses intermediate levels that don't exist at all yet (not just a missing leaf), each missing level is created as an array or an object depending on whether the corresponding pointer token is a valid array index: the token 0, a sequence of digits that does not begin with 0, or the token - creates an array, and every other token creates an object. For example, on an initially null value, /foo/0/0/0 creates nested arrays, while /foo/one/one/one creates nested objects. Tokens such as 01 or the empty token cannot be array indices (cf. RFC 6901, Sect. 4) and therefore create objects, just as they would if the level already existed as an object. This is not specified by the JSON Pointer RFC; it is this library's own, intentional disambiguation rule. See also JSON Pointer.

Deprecation

Overload (4) also accepts a json_pointer 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 for how to update existing code.

Examples

Example: (1) access specified array element

The example below shows how array elements can be read and written using [] operator. Note the addition of null values.

#include <iostream>
+
  1. Returns a reference to the array element at specified location idx.
  2. Returns a reference to the object element with specified key key. The non-const qualified overload takes the key by value.
  3. See 2. This overload is only available if KeyType is comparable with typename object_t::key_type and typename object_comparator_t::is_transparent denotes a type.
  4. Returns a reference to the element with specified JSON pointer ptr.

Template parameters

KeyType
A type for an object key other than json_pointer that is comparable with string_t using object_comparator_t. This can also be a string view (C++17).

Iterator invalidation

For the non-const versions 1. and 4., when passing an array index that does not exist, it is created and filled with a null value before a reference to it is returned. For this, a reallocation can happen, in which case all iterators (including the end() iterator) and all references to the elements are invalidated.

For ordered_json, also passing an object key to the non-const versions 2., 3., and 4., a reallocation can happen which again invalidates all iterators and all references.

Parameters

idx (in)
index of the element to access
key (in)
object key of the element to access
ptr (in)
JSON pointer to the desired element

Return value

  1. (const) reference to the element at index idx
  2. (const) reference to the element at key key
  3. (const) reference to the element at key key
  4. (const) reference to the element pointed to by ptr

Exception safety

Strong exception safety: if an exception occurs, the original value stays intact.

Exceptions

  1. The function can throw the following exceptions:
    • Throws type_error.305 if the JSON value is not an array or null; in that case, using the [] operator with an index makes no sense.
    • Throws 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 throws.)
  2. The function can throw the following exceptions:
    • Throws type_error.305 if the JSON value is not an object or null; in that case, using the [] operator with a key makes no sense.
  3. See 2.
  4. The function can throw the following exceptions:

    • Throws parse_error.106 if an array index in the passed JSON pointer ptr begins with '0'.
    • Throws parse_error.109 if an array index in the passed JSON pointer ptr is not a number.
    • Throws out_of_range.402 if the array index '-' is used in the passed JSON pointer ptr for the const version.
    • Throws out_of_range.404 if the JSON pointer ptr can not be resolved.
    • Throws out_of_range.410 if an array index in the passed JSON pointer ptr exceeds the range of size_type (e.g., on 32-bit platforms).

    For the const version, an object key or array index in ptr that does not exist is not reported by an exception, but is undefined behavior (see the notes below). Use at for checked access.

    If the non-const version throws, the value is left unchanged: values it created for earlier reference tokens of ptr are removed again. This also holds for exceptions such as std::bad_alloc or std::length_error thrown while padding an array up to a very large index. With custom template parameters, this requires that erase() of the object and array types and the move operations of the custom base class do not throw.

Complexity

  1. Constant if idx is in the range of the array. Otherwise, linear in idx - size().
  2. Logarithmic in the size of the container.
  3. Logarithmic in the size of the container.
  4. Linear in the number of reference tokens of ptr; for each of them, logarithmic in the size of the object, or constant for an array. When the non-const version pads an array with null values, it is additionally linear in idx - size() for that array.

Notes

Undefined behavior and runtime assertions

The following cases apply to the const overloads; the non-const overloads instead insert the missing element (see the notes below).

  1. If the element at index idx does not exist, the behavior is undefined and is guarded by a runtime assertion!
  2. If the element with key key does not exist, the behavior is undefined and is guarded by a runtime assertion!
  3. If the JSON pointer ptr refers to an object key or an array index that does not exist, the behavior is undefined and is guarded by a runtime assertion!
  1. The non-const version may add values: If idx is beyond the range of the array (i.e., idx >= size()), then the array is silently filled up with null values to make idx a valid reference to the last stored element. In case the value was null before, it is converted to an array.

  2. If key is not found in the object, then it is silently added to the object and filled with a null value to make key a valid reference. In case the value was null before, it is converted to an object.

  3. See 2.

  4. null values are created in arrays and objects if necessary.

    In particular:

    • If the JSON pointer points to an object key that does not exist, it is created and filled with a null value before a reference to it is returned.
    • If the JSON pointer points to an array index that does not exist, it is created and filled with a null value before a reference to it is returned. All indices between the current maximum and the given index are also filled with null.
    • The special value - is treated as a synonym for the index past the end.

    Creating intermediate levels that don't exist yet

    When the JSON pointer traverses intermediate levels that don't exist at all yet (not just a missing leaf), each missing level is created as an array or an object depending on whether the corresponding pointer token is a valid array index: the token 0, a sequence of digits that does not begin with 0, or the token - creates an array, and every other token creates an object. For example, on an initially null value, /foo/0/0/0 creates nested arrays, while /foo/one/one/one creates nested objects. Tokens such as 01 or the empty token cannot be array indices (cf. RFC 6901, Sect. 4) and therefore create objects, just as they would if the level already existed as an object. This is not specified by the JSON Pointer RFC; it is this library's own, intentional disambiguation rule. See also JSON Pointer.

    Large array indices

    As the array is filled up with null values to the given index, the memory used grows with the index and not with the size of the pointer: on a 64-bit platform, the index 10000000 allocates about 160 MB. The library does not limit the index, so check the array indices of a JSON pointer from untrusted input before using it with the non-const version. See Parsing untrusted input.

Deprecation

Overload (4) also accepts a json_pointer 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 for how to update existing code.

Examples

Example: (1) access specified array element

The example below shows how array elements can be read and written using [] operator. Note the addition of null values.

#include <iostream>
 #include <nlohmann/json.hpp>
 
 using nlohmann::json;
@@ -283,4 +283,4 @@
 "foo"
 [1,2]
 2
-

See also

Version history

  1. Added in version 1.0.0. Fixed in version 3.13.0 unreleased to throw std::length_error instead of emptying the array and accessing it out of bounds when idx equals the maximum value of size_type. A missing index in the const version is guarded by a runtime assertion since version 3.13.0 unreleased.
  2. Added in version 1.0.0. Added overloads for T* key in version 1.1.0. The T* key overloads forward to overload 3 since version 3.11.0.
  3. Added in version 3.11.0. Support for keys convertible to std::string_view added in version 3.13.0 unreleased, consistently across the lookup functions.
  4. Added in version 2.0.0. A missing array index in the const version is guarded by a runtime assertion since version 3.13.0 unreleased. Throws parse_error.109 instead of out_of_range.404 for a one-character array index that is not a digit (e.g., /x) in version 3.13.0 unreleased, as it already did for longer ones.
\ No newline at end of file +

See also

Version history

  1. Added in version 1.0.0. Fixed in version 3.13.0 unreleased to throw std::length_error instead of emptying the array and accessing it out of bounds when idx equals the maximum value of size_type. A missing index in the const version is guarded by a runtime assertion since version 3.13.0 unreleased.
  2. Added in version 1.0.0. Added overloads for T* key in version 1.1.0. The T* key overloads forward to overload 3 since version 3.11.0.
  3. Added in version 3.11.0. Support for keys convertible to std::string_view added in version 3.13.0 unreleased, consistently across the lookup functions.
  4. Added in version 2.0.0. A missing array index in the const version is guarded by a runtime assertion since version 3.13.0 unreleased. Throws parse_error.109 instead of out_of_range.404 for a one-character array index that is not a digit (e.g., /x) in version 3.13.0 unreleased, as it already did for longer ones. Fixed in version 3.13.0 unreleased to leave the value unchanged if the non-const version throws (strong exception safety, as documented); before, values created for earlier reference tokens of ptr were kept.
\ No newline at end of file diff --git a/api/basic_json/operator[]/index.md b/api/basic_json/operator[]/index.md index d2fb3791f..a29858d19 100644 --- a/api/basic_json/operator[]/index.md +++ b/api/basic_json/operator[]/index.md @@ -77,12 +77,14 @@ Strong exception safety: if an exception occurs, the original value stays intact For the **const** version, an object key or array index in `ptr` that does not exist is not reported by an exception, but is undefined behavior (see the notes below). Use [`at`](https://json.nlohmann.me/api/basic_json/at/index.md) for checked access. + If the **non-const** version throws, the value is left unchanged: values it created for earlier reference tokens of `ptr` are removed again. This also holds for exceptions such as `std::bad_alloc` or `std::length_error` thrown while padding an array up to a very large index. With custom [template parameters](https://json.nlohmann.me/features/types/template_parameters/index.md), this requires that `erase()` of the object and array types and the move operations of the custom base class do not throw. + ## Complexity 1. Constant if `idx` is in the range of the array. Otherwise, linear in `idx - size()`. 1. Logarithmic in the size of the container. 1. Logarithmic in the size of the container. -1. Logarithmic in the size of the container. +1. Linear in the number of reference tokens of `ptr`; for each of them, logarithmic in the size of the object, or constant for an array. When the non-const version pads an array with `null` values, it is additionally linear in `idx - size()` for that array. ## Notes @@ -114,6 +116,10 @@ The following cases apply to the **const** overloads; the non-const overloads in When the JSON pointer traverses intermediate levels that don't exist at all yet (not just a missing leaf), each missing level is created as an array or an object depending on whether the corresponding pointer token is a valid array index: the token `0`, a sequence of digits that does not begin with `0`, or the token `-` creates an array, and every other token creates an object. For example, on an initially `null` value, `/foo/0/0/0` creates nested arrays, while `/foo/one/one/one` creates nested objects. Tokens such as `01` or the empty token cannot be array indices (cf. RFC 6901, Sect. 4) and therefore create objects, just as they would if the level already existed as an object. This is not specified by the JSON Pointer RFC; it is this library's own, intentional disambiguation rule. See also [JSON Pointer](https://json.nlohmann.me/features/json_pointer/index.md). + Large array indices + + As the array is filled up with `null` values to the given index, the memory used grows with the index and not with the size of the pointer: on a 64-bit platform, the index `10000000` allocates about 160 MB. The library does not limit the index, so check the array indices of a JSON pointer from untrusted input before using it with the non-const version. See [Parsing untrusted input](https://json.nlohmann.me/features/parsing/untrusted_input/#json-pointers-and-flattened-keys). + Deprecation Overload (4) also accepts a [`json_pointer`](https://json.nlohmann.me/api/json_pointer/index.md) whose template argument is a `basic_json` specialization (e.g., `nlohmann::json_pointer`) 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`) instead. @@ -503,4 +509,4 @@ Output: 1. Added in version 1.0.0. Fixed in version 3.13.0 unreleased to throw `std::length_error` instead of emptying the array and accessing it out of bounds when `idx` equals the maximum value of `size_type`. A missing index in the const version is guarded by a runtime assertion since version 3.13.0 unreleased. 1. Added in version 1.0.0. Added overloads for `T* key` in version 1.1.0. The `T* key` overloads forward to overload 3 since version 3.11.0. 1. Added in version 3.11.0. Support for keys convertible to `std::string_view` added in version 3.13.0 unreleased, consistently across the lookup functions. -1. Added in version 2.0.0. A missing array index in the const version is guarded by a runtime assertion since version 3.13.0 unreleased. Throws [`parse_error.109`](https://json.nlohmann.me/home/exceptions/#jsonexceptionparse_error109) instead of [`out_of_range.404`](https://json.nlohmann.me/home/exceptions/#jsonexceptionout_of_range404) for a one-character array index that is not a digit (e.g., `/x`) in version 3.13.0 unreleased, as it already did for longer ones. +1. Added in version 2.0.0. A missing array index in the const version is guarded by a runtime assertion since version 3.13.0 unreleased. Throws [`parse_error.109`](https://json.nlohmann.me/home/exceptions/#jsonexceptionparse_error109) instead of [`out_of_range.404`](https://json.nlohmann.me/home/exceptions/#jsonexceptionout_of_range404) for a one-character array index that is not a digit (e.g., `/x`) in version 3.13.0 unreleased, as it already did for longer ones. Fixed in version 3.13.0 unreleased to leave the value unchanged if the non-const version throws (strong exception safety, as documented); before, values created for earlier reference tokens of `ptr` were kept. diff --git a/api/basic_json/patch_inplace.md b/api/basic_json/patch_inplace.md index e56d9c262..6c444faa9 100644 --- a/api/basic_json/patch_inplace.md +++ b/api/basic_json/patch_inplace.md @@ -69,6 +69,19 @@ Duplicate member names inside an operation object are resolved by the parser bef is kept, see [`object_t`](object_t.md#behavior)), so `#!json {"op": "add", "op": "remove", "path": "/a"}` is a `remove` operation. +The JSON patch may be the JSON value itself (`#!cpp j.patch_inplace(j)`): the operations are then read from a copy of +the patch made before the first operation is applied, so the result is the same as that of +`#!cpp j = j.patch(j)`, and the exception safety is the same as above. + +If [`JSON_DIAGNOSTICS`](../macros/json_diagnostics.md) is enabled, the same holds for a JSON patch stored inside the +JSON value (e.g., `#!cpp j.patch_inplace(j["patch"])`): it is detected via the parent pointers. + +!!! danger "Undefined behavior" + + Without [`JSON_DIAGNOSTICS`](../macros/json_diagnostics.md), the JSON patch must not be a value stored inside the + JSON value (e.g., `#!cpp j.patch_inplace(j["patch"])`), as the operations may change or destroy it while it is + read. Pass a copy (`#!cpp j.patch_inplace(json(j["patch"]))`) or use [`patch`](patch.md) instead. + ## Examples ??? example "Example: apply a JSON patch in place" @@ -213,3 +226,5 @@ is kept, see [`object_t`](object_t.md#behavior)), so `#!json {"op": "add", "op": - Throws [`parse_error.109`](../../home/exceptions.md#jsonexceptionparse_error109) instead of [`out_of_range.404`](../../home/exceptions.md#jsonexceptionout_of_range404) for a one-character array index that is not a digit (e.g., `/x`) in version 3.13.0, as it already did for longer ones. +- Applying a JSON value as patch to itself (or, with `JSON_DIAGNOSTICS`, to a value stored inside it) no longer results + in undefined behavior in version 3.13.0. diff --git a/api/basic_json/patch_inplace/index.html b/api/basic_json/patch_inplace/index.html index efed95129..624d98031 100644 --- a/api/basic_json/patch_inplace/index.html +++ b/api/basic_json/patch_inplace/index.html @@ -1,5 +1,5 @@ patch_inplace - JSON for Modern C++
Skip to content

nlohmann::basic_json::patch_inplace

void patch_inplace(const basic_json& json_patch);
-

JSON Patch defines a JSON document structure for expressing a sequence of operations to apply to a JSON document. With this function, a JSON Patch is applied to the current JSON value by executing all operations from the patch. This function applies a JSON patch in place and returns void.

Parameters

json_patch (in)
JSON patch document

Exception safety

No guarantees, value may be corrupted by an unsuccessful patch operation.

Exceptions

  • Throws parse_error.104 if the JSON patch does not consist of an array of objects.
  • Throws parse_error.105 if the JSON patch is malformed (e.g., mandatory attributes are missing); example: "operation 'add' must have member 'path'".
  • Throws out_of_range.401 if an array index is out of range.
  • Throws parse_error.106 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 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 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 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 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 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 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 if JSON pointer has no parent ("remove", "move")
  • Throws out_of_range.411 if an "add" operation's target location has a parent that is neither an object nor an array.
  • Throws out_of_range.413 if a "remove" operation's target location has a parent that is neither an object nor an array.
  • Throws out_of_range.414 if a "move" operation's "from" location is a proper prefix of its "path" location.
  • Throws other_error.501 if "test" operation was unsuccessful. A "test" operation whose "path" does not exist is unsuccessful, too: the failed lookup is reported as a failed test, even if the operation has no "value" member (which would otherwise be parse_error.105). Which of the two errors is reported for this combination depends on the order in which the operands of a comparison are evaluated, so do not rely on it.

Complexity

Linear in the size of the JSON value and the length of the JSON patch. As usually the patch affects only a fraction of the JSON value, the complexity can usually be neglected.

Notes

Unlike patch, patch_inplace applies the operation "in place" and no copy of the JSON value is created. That makes it faster for large documents by avoiding the copy. However, the JSON value might be corrupted if the function throws an exception.

Duplicate member names inside an operation object are resolved by the parser before the patch is applied (the last one is kept, see object_t), so {"op": "add", "op": "remove", "path": "/a"} is a remove operation.

Examples

Example: apply a JSON patch in place

The following code shows how a JSON patch is applied to a value.

#include <iostream>
+

JSON Patch defines a JSON document structure for expressing a sequence of operations to apply to a JSON document. With this function, a JSON Patch is applied to the current JSON value by executing all operations from the patch. This function applies a JSON patch in place and returns void.

Parameters

json_patch (in)
JSON patch document

Exception safety

No guarantees, value may be corrupted by an unsuccessful patch operation.

Exceptions

  • Throws parse_error.104 if the JSON patch does not consist of an array of objects.
  • Throws parse_error.105 if the JSON patch is malformed (e.g., mandatory attributes are missing); example: "operation 'add' must have member 'path'".
  • Throws out_of_range.401 if an array index is out of range.
  • Throws parse_error.106 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 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 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 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 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 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 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 if JSON pointer has no parent ("remove", "move")
  • Throws out_of_range.411 if an "add" operation's target location has a parent that is neither an object nor an array.
  • Throws out_of_range.413 if a "remove" operation's target location has a parent that is neither an object nor an array.
  • Throws out_of_range.414 if a "move" operation's "from" location is a proper prefix of its "path" location.
  • Throws other_error.501 if "test" operation was unsuccessful. A "test" operation whose "path" does not exist is unsuccessful, too: the failed lookup is reported as a failed test, even if the operation has no "value" member (which would otherwise be parse_error.105). Which of the two errors is reported for this combination depends on the order in which the operands of a comparison are evaluated, so do not rely on it.

Complexity

Linear in the size of the JSON value and the length of the JSON patch. As usually the patch affects only a fraction of the JSON value, the complexity can usually be neglected.

Notes

Unlike patch, patch_inplace applies the operation "in place" and no copy of the JSON value is created. That makes it faster for large documents by avoiding the copy. However, the JSON value might be corrupted if the function throws an exception.

Duplicate member names inside an operation object are resolved by the parser before the patch is applied (the last one is kept, see object_t), so {"op": "add", "op": "remove", "path": "/a"} is a remove operation.

The JSON patch may be the JSON value itself (j.patch_inplace(j)): the operations are then read from a copy of the patch made before the first operation is applied, so the result is the same as that of j = j.patch(j), and the exception safety is the same as above.

If JSON_DIAGNOSTICS is enabled, the same holds for a JSON patch stored inside the JSON value (e.g., j.patch_inplace(j["patch"])): it is detected via the parent pointers.

Undefined behavior

Without JSON_DIAGNOSTICS, the JSON patch must not be a value stored inside the JSON value (e.g., j.patch_inplace(j["patch"])), as the operations may change or destroy it while it is read. Pass a copy (j.patch_inplace(json(j["patch"]))) or use patch instead.

Examples

Example: apply a JSON patch in place

The following code shows how a JSON patch is applied to a value.

#include <iostream>
 #include <iomanip>
 #include <nlohmann/json.hpp>
 
@@ -90,4 +90,4 @@
     "a": 99,
     "b": 2
 }
-

See also

Version history

  • Added in version 3.11.0.
  • Added out_of_range.411 and stopped relying on an internal assertion when an "add" operation's target location has a non-object/non-array parent in version 3.13.0 unreleased. This includes a null parent, which was previously silently converted to an object, in version 3.13.0 unreleased.
  • Added out_of_range.413 and stopped silently ignoring a "remove" operation whose target location has a non-object/non-array parent in version 3.13.0 unreleased.
  • Added out_of_range.414 and rejected a "move" operation whose "from" location is a proper prefix of its "path" location instead of silently producing a corrupted result in version 3.13.0 unreleased.
  • Throws parse_error.109 instead of out_of_range.404 for a one-character array index that is not a digit (e.g., /x) in version 3.13.0 unreleased, as it already did for longer ones.
\ No newline at end of file +

See also

Version history

  • Added in version 3.11.0.
  • Added out_of_range.411 and stopped relying on an internal assertion when an "add" operation's target location has a non-object/non-array parent in version 3.13.0 unreleased. This includes a null parent, which was previously silently converted to an object, in version 3.13.0 unreleased.
  • Added out_of_range.413 and stopped silently ignoring a "remove" operation whose target location has a non-object/non-array parent in version 3.13.0 unreleased.
  • Added out_of_range.414 and rejected a "move" operation whose "from" location is a proper prefix of its "path" location instead of silently producing a corrupted result in version 3.13.0 unreleased.
  • Throws parse_error.109 instead of out_of_range.404 for a one-character array index that is not a digit (e.g., /x) in version 3.13.0 unreleased, as it already did for longer ones.
  • Applying a JSON value as patch to itself (or, with JSON_DIAGNOSTICS, to a value stored inside it) no longer results in undefined behavior in version 3.13.0 unreleased.
\ No newline at end of file diff --git a/api/basic_json/patch_inplace/index.md b/api/basic_json/patch_inplace/index.md index 83c5b3c47..10ec64a30 100644 --- a/api/basic_json/patch_inplace/index.md +++ b/api/basic_json/patch_inplace/index.md @@ -42,6 +42,14 @@ Unlike [`patch`](https://json.nlohmann.me/api/basic_json/patch/index.md), `patch Duplicate member names inside an operation object are resolved by the parser before the patch is applied (the last one is kept, see [`object_t`](https://json.nlohmann.me/api/basic_json/object_t/#behavior)), so `{"op": "add", "op": "remove", "path": "/a"}` is a `remove` operation. +The JSON patch may be the JSON value itself (`j.patch_inplace(j)`): the operations are then read from a copy of the patch made before the first operation is applied, so the result is the same as that of `j = j.patch(j)`, and the exception safety is the same as above. + +If [`JSON_DIAGNOSTICS`](https://json.nlohmann.me/api/macros/json_diagnostics/index.md) is enabled, the same holds for a JSON patch stored inside the JSON value (e.g., `j.patch_inplace(j["patch"])`): it is detected via the parent pointers. + +Undefined behavior + +Without [`JSON_DIAGNOSTICS`](https://json.nlohmann.me/api/macros/json_diagnostics/index.md), the JSON patch must not be a value stored inside the JSON value (e.g., `j.patch_inplace(j["patch"])`), as the operations may change or destroy it while it is read. Pass a copy (`j.patch_inplace(json(j["patch"]))`) or use [`patch`](https://json.nlohmann.me/api/basic_json/patch/index.md) instead. + ## Examples Example: apply a JSON patch in place @@ -174,3 +182,4 @@ Output: - Added [`out_of_range.413`](https://json.nlohmann.me/home/exceptions/#jsonexceptionout_of_range413) and stopped silently ignoring a "remove" operation whose target location has a non-object/non-array parent in version 3.13.0 unreleased. - Added [`out_of_range.414`](https://json.nlohmann.me/home/exceptions/#jsonexceptionout_of_range414) and rejected a "move" operation whose "from" location is a proper prefix of its "path" location instead of silently producing a corrupted result in version 3.13.0 unreleased. - Throws [`parse_error.109`](https://json.nlohmann.me/home/exceptions/#jsonexceptionparse_error109) instead of [`out_of_range.404`](https://json.nlohmann.me/home/exceptions/#jsonexceptionout_of_range404) for a one-character array index that is not a digit (e.g., `/x`) in version 3.13.0 unreleased, as it already did for longer ones. +- Applying a JSON value as patch to itself (or, with `JSON_DIAGNOSTICS`, to a value stored inside it) no longer results in undefined behavior in version 3.13.0 unreleased. diff --git a/api/basic_json_view/materialize.md b/api/basic_json_view/materialize.md index c77343a07..fc9a759d0 100644 --- a/api/basic_json_view/materialize.md +++ b/api/basic_json_view/materialize.md @@ -32,9 +32,24 @@ uses, so the result matches it exactly — including, for an object, that a repe last value. The replay is iterative, so it is not limited by the call stack the way a naive recursive conversion would be; the JSON nesting depth is limited only by available memory, as for `BasicJsonType::parse()` itself. -Unlike parsing with [`JSON_DIAGNOSTIC_POSITIONS`](../macros/json_diagnostic_positions.md) enabled, the values -produced by `materialize()` do not carry source positions. The index has the start offset of every value, but not the -end of arrays, objects, and escaped strings, which the positions also need. +With [`JSON_DIAGNOSTIC_POSITIONS`](../macros/json_diagnostic_positions.md) enabled, the values get the source +positions [`BasicJsonType::parse()`](../basic_json/parse.md) would give them, also for the subtree of a view (the +positions are those in the document's whole source text), and exceptions about them name the same bytes. For values of +an [editable document](../json_editable_document.md), positions are all-or-nothing, and [`start_pos()`](../basic_json/start_pos.md) +and [`end_pos()`](../basic_json/end_pos.md) return `std::string::npos` for + +- a value written by an edit (a copy of an array or object of the document is also new; copies of its scalars keep + their positions), +- an array or object whose elements were changed (its elements keep theirs), and +- an array or object whose last element has no positions (its end is found from that element). + +This differs from a `basic_json` value, whose positions are not updated when it is changed: they stay as they were +parsed, even if they no longer match the value (see [`start_pos()`](../basic_json/start_pos.md)). + +Documents [loaded](../basic_json_document/load.md) from an image have the positions of the saved document. Its strings +with escapes have positions only if the document was parsed with `JSON_DIAGNOSTIC_POSITIONS`: the position of their +opening quote is recorded while parsing, and `save()` and `load()` keep it whether or not they are compiled with the +macro. Calling `materialize()` on the same view repeatedly builds a new, independent `BasicJsonType` value each time; it never caches the result. @@ -98,8 +113,7 @@ never caches the result. - [`root`](../basic_json_document/root.md) - the view of a document's root value - [`BasicJsonType::parse`](../basic_json/parse.md) - build a `BasicJsonType` value directly from a JSON text -- [`JSON_DIAGNOSTIC_POSITIONS`](../macros/json_diagnostic_positions.md) - source positions on parsed values (not - produced by `materialize()`) +- [`JSON_DIAGNOSTIC_POSITIONS`](../macros/json_diagnostic_positions.md) - source positions on parsed values - [Zero-copy JSON views](../../features/json_view.md#getting-values-out-without-copying) - when to build a basic_json value from a view ## Version history diff --git a/api/basic_json_view/materialize/index.html b/api/basic_json_view/materialize/index.html index c76773b2a..bc695fa9a 100644 --- a/api/basic_json_view/materialize/index.html +++ b/api/basic_json_view/materialize/index.html @@ -1,5 +1,5 @@ materialize - JSON for Modern C++
Skip to content

nlohmann::basic_json_view::materialize

BasicJsonType materialize() const;
-

Builds the BasicJsonType value of this subtree: the value BasicJsonType::parse() would have produced for the same source text, allocated for the first time by this call.

Return value

The BasicJsonType value of this subtree, or a discarded BasicJsonType value (BasicJsonType(value_t::discarded)) if the view is discarded.

Exception safety

Strong guarantee: there are no changes to the view or the document it refers to (nothing about either is mutated by this function).

Exceptions

May throw std::bad_alloc (via BasicJsonType's allocator) if constructing the result fails.

Complexity

Linear in the size of the subtree.

Notes

materialize() replays the subtree through the same SAX builder BasicJsonType::parse() uses, so the result matches it exactly — including, for an object, that a repeated key keeps only its last value. The replay is iterative, so it is not limited by the call stack the way a naive recursive conversion would be; the JSON nesting depth is limited only by available memory, as for BasicJsonType::parse() itself.

Unlike parsing with JSON_DIAGNOSTIC_POSITIONS enabled, the values produced by materialize() do not carry source positions. The index has the start offset of every value, but not the end of arrays, objects, and escaped strings, which the positions also need.

Calling materialize() on the same view repeatedly builds a new, independent BasicJsonType value each time; it never caches the result.

Examples

Example

The example below skips messages that are not useful — a discarded value, or an empty array — using only is_array() and empty(), and calls materialize() only for the messages that are actually used, so no BasicJsonType value (and none of its per-element allocations) is ever built for the skipped ones.

#include <array>
+

Builds the BasicJsonType value of this subtree: the value BasicJsonType::parse() would have produced for the same source text, allocated for the first time by this call.

Return value

The BasicJsonType value of this subtree, or a discarded BasicJsonType value (BasicJsonType(value_t::discarded)) if the view is discarded.

Exception safety

Strong guarantee: there are no changes to the view or the document it refers to (nothing about either is mutated by this function).

Exceptions

May throw std::bad_alloc (via BasicJsonType's allocator) if constructing the result fails.

Complexity

Linear in the size of the subtree.

Notes

materialize() replays the subtree through the same SAX builder BasicJsonType::parse() uses, so the result matches it exactly — including, for an object, that a repeated key keeps only its last value. The replay is iterative, so it is not limited by the call stack the way a naive recursive conversion would be; the JSON nesting depth is limited only by available memory, as for BasicJsonType::parse() itself.

With JSON_DIAGNOSTIC_POSITIONS enabled, the values get the source positions BasicJsonType::parse() would give them, also for the subtree of a view (the positions are those in the document's whole source text), and exceptions about them name the same bytes. For values of an editable document, positions are all-or-nothing, and start_pos() and end_pos() return std::string::npos for

  • a value written by an edit (a copy of an array or object of the document is also new; copies of its scalars keep their positions),
  • an array or object whose elements were changed (its elements keep theirs), and
  • an array or object whose last element has no positions (its end is found from that element).

This differs from a basic_json value, whose positions are not updated when it is changed: they stay as they were parsed, even if they no longer match the value (see start_pos()).

Documents loaded from an image have the positions of the saved document. Its strings with escapes have positions only if the document was parsed with JSON_DIAGNOSTIC_POSITIONS: the position of their opening quote is recorded while parsing, and save() and load() keep it whether or not they are compiled with the macro.

Calling materialize() on the same view repeatedly builds a new, independent BasicJsonType value each time; it never caches the result.

Examples

Example

The example below skips messages that are not useful — a discarded value, or an empty array — using only is_array() and empty(), and calls materialize() only for the messages that are actually used, so no BasicJsonType value (and none of its per-element allocations) is ever built for the skipped ones.

#include <array>
 #include <iostream>
 #include <nlohmann/json_view.hpp>
 
@@ -35,4 +35,4 @@
 

Output:

skipped
 skipped
 [{"id":1},{"id":2},{"id":3}]
-

See also

Version history

  • Added in version 3.13.0 unreleased.
\ No newline at end of file +

See also

Version history

  • Added in version 3.13.0 unreleased.
\ No newline at end of file diff --git a/api/basic_json_view/materialize/index.md b/api/basic_json_view/materialize/index.md index 05424726d..8ec337c3f 100644 --- a/api/basic_json_view/materialize/index.md +++ b/api/basic_json_view/materialize/index.md @@ -26,7 +26,15 @@ Linear in the size of the subtree. `materialize()` replays the subtree through the same SAX builder [`BasicJsonType::parse()`](https://json.nlohmann.me/api/basic_json/parse/index.md) uses, so the result matches it exactly — including, for an object, that a repeated key keeps only its last value. The replay is iterative, so it is not limited by the call stack the way a naive recursive conversion would be; the JSON nesting depth is limited only by available memory, as for `BasicJsonType::parse()` itself. -Unlike parsing with [`JSON_DIAGNOSTIC_POSITIONS`](https://json.nlohmann.me/api/macros/json_diagnostic_positions/index.md) enabled, the values produced by `materialize()` do not carry source positions. The index has the start offset of every value, but not the end of arrays, objects, and escaped strings, which the positions also need. +With [`JSON_DIAGNOSTIC_POSITIONS`](https://json.nlohmann.me/api/macros/json_diagnostic_positions/index.md) enabled, the values get the source positions [`BasicJsonType::parse()`](https://json.nlohmann.me/api/basic_json/parse/index.md) would give them, also for the subtree of a view (the positions are those in the document's whole source text), and exceptions about them name the same bytes. For values of an [editable document](https://json.nlohmann.me/api/json_editable_document/index.md), positions are all-or-nothing, and [`start_pos()`](https://json.nlohmann.me/api/basic_json/start_pos/index.md) and [`end_pos()`](https://json.nlohmann.me/api/basic_json/end_pos/index.md) return `std::string::npos` for + +- a value written by an edit (a copy of an array or object of the document is also new; copies of its scalars keep their positions), +- an array or object whose elements were changed (its elements keep theirs), and +- an array or object whose last element has no positions (its end is found from that element). + +This differs from a `basic_json` value, whose positions are not updated when it is changed: they stay as they were parsed, even if they no longer match the value (see [`start_pos()`](https://json.nlohmann.me/api/basic_json/start_pos/index.md)). + +Documents [loaded](https://json.nlohmann.me/api/basic_json_document/load/index.md) from an image have the positions of the saved document. Its strings with escapes have positions only if the document was parsed with `JSON_DIAGNOSTIC_POSITIONS`: the position of their opening quote is recorded while parsing, and `save()` and `load()` keep it whether or not they are compiled with the macro. Calling `materialize()` on the same view repeatedly builds a new, independent `BasicJsonType` value each time; it never caches the result. @@ -84,7 +92,7 @@ skipped - [`root`](https://json.nlohmann.me/api/basic_json_document/root/index.md) - the view of a document's root value - [`BasicJsonType::parse`](https://json.nlohmann.me/api/basic_json/parse/index.md) - build a `BasicJsonType` value directly from a JSON text -- [`JSON_DIAGNOSTIC_POSITIONS`](https://json.nlohmann.me/api/macros/json_diagnostic_positions/index.md) - source positions on parsed values (not produced by `materialize()`) +- [`JSON_DIAGNOSTIC_POSITIONS`](https://json.nlohmann.me/api/macros/json_diagnostic_positions/index.md) - source positions on parsed values - [Zero-copy JSON views](https://json.nlohmann.me/features/json_view/#getting-values-out-without-copying) - when to build a basic_json value from a view ## Version history diff --git a/api/json_pointer/operator_slasheq.md b/api/json_pointer/operator_slasheq.md index 019de380d..2e1613f4d 100644 --- a/api/json_pointer/operator_slasheq.md +++ b/api/json_pointer/operator_slasheq.md @@ -18,7 +18,8 @@ json_pointer& operator/=(std::size_t array_idx) ## Parameters `ptr` (in) -: JSON pointer to append +: JSON pointer to append; may be the JSON pointer itself (`#!cpp p /= p`), which then appends a copy of its + reference tokens `token` (in) : reference token to append @@ -96,6 +97,7 @@ json_pointer& operator/=(std::size_t array_idx) ## Version history -1. Added in version 3.6.0. +1. Added in version 3.6.0. Appending a JSON pointer to itself no longer results in undefined behavior in version + 3.13.0. 2. Added in version 3.6.0. Changed type of `token` to `string_t` in version 3.11.0. 3. Added in version 3.6.0. diff --git a/api/json_pointer/operator_slasheq/index.html b/api/json_pointer/operator_slasheq/index.html index d8f8d1854..9c207fe34 100644 --- a/api/json_pointer/operator_slasheq/index.html +++ b/api/json_pointer/operator_slasheq/index.html @@ -6,7 +6,7 @@ // (3) json_pointer& operator/=(std::size_t array_idx) -
  1. append another JSON pointer at the end of this JSON pointer
  2. append an unescaped reference token at the end of this JSON pointer
  3. append an array index at the end of this JSON pointer

Parameters

ptr (in)
JSON pointer to append
token (in)
reference token to append
array_idx (in)
array index to append

Return value

  1. JSON pointer with ptr appended
  2. JSON pointer with token appended without escaping token
  3. JSON pointer with array_idx appended

Exception safety

  1. Basic guarantee: if an exception is thrown (for instance, if copying a reference token fails), the JSON pointer is left in a valid state, but it may contain some of the reference tokens of ptr.
  2. Strong guarantee: if an exception is thrown, there are no changes to the JSON pointer.
  3. Strong guarantee: if an exception is thrown, there are no changes to the JSON pointer.

Complexity

  1. Linear in the length of ptr.
  2. Amortized constant.
  3. Amortized constant.

Examples

Example

The example shows the usage of operator/=.

#include <iostream>
+
  1. append another JSON pointer at the end of this JSON pointer
  2. append an unescaped reference token at the end of this JSON pointer
  3. append an array index at the end of this JSON pointer

Parameters

ptr (in)
JSON pointer to append; may be the JSON pointer itself (p /= p), which then appends a copy of its reference tokens
token (in)
reference token to append
array_idx (in)
array index to append

Return value

  1. JSON pointer with ptr appended
  2. JSON pointer with token appended without escaping token
  3. JSON pointer with array_idx appended

Exception safety

  1. Basic guarantee: if an exception is thrown (for instance, if copying a reference token fails), the JSON pointer is left in a valid state, but it may contain some of the reference tokens of ptr.
  2. Strong guarantee: if an exception is thrown, there are no changes to the JSON pointer.
  3. Strong guarantee: if an exception is thrown, there are no changes to the JSON pointer.

Complexity

  1. Linear in the length of ptr.
  2. Amortized constant.
  3. Amortized constant.

Examples

Example

The example shows the usage of operator/=.

#include <iostream>
 #include <nlohmann/json.hpp>
 
 using nlohmann::json;
@@ -33,4 +33,4 @@
 "/foo/bar/baz"
 "/foo/bar/baz/fob"
 "/foo/bar/baz/fob/42"
-

See also

  • operator/ - create JSON Pointer by appending
  • push_back - append an unescaped token at the end of the pointer
  • JSON Pointer - the article on JSON Pointer support

Version history

  1. Added in version 3.6.0.
  2. Added in version 3.6.0. Changed type of token to string_t in version 3.11.0.
  3. Added in version 3.6.0.
\ No newline at end of file +

See also

  • operator/ - create JSON Pointer by appending
  • push_back - append an unescaped token at the end of the pointer
  • JSON Pointer - the article on JSON Pointer support

Version history

  1. Added in version 3.6.0. Appending a JSON pointer to itself no longer results in undefined behavior in version 3.13.0.
  2. Added in version 3.6.0. Changed type of token to string_t in version 3.11.0.
  3. Added in version 3.6.0.
\ No newline at end of file diff --git a/api/json_pointer/operator_slasheq/index.md b/api/json_pointer/operator_slasheq/index.md index 4412003b4..4ff6010f7 100644 --- a/api/json_pointer/operator_slasheq/index.md +++ b/api/json_pointer/operator_slasheq/index.md @@ -17,7 +17,7 @@ json_pointer& operator/=(std::size_t array_idx) ## Parameters -`ptr` (in) : JSON pointer to append +`ptr` (in) : JSON pointer to append; may be the JSON pointer itself (`p /= p`), which then appends a copy of its reference tokens `token` (in) : reference token to append @@ -90,6 +90,6 @@ Output: ## Version history -1. Added in version 3.6.0. +1. Added in version 3.6.0. Appending a JSON pointer to itself no longer results in undefined behavior in version 3.13.0. 1. Added in version 3.6.0. Changed type of `token` to `string_t` in version 3.11.0. 1. Added in version 3.6.0. diff --git a/api/macros/json_diagnostic_positions.md b/api/macros/json_diagnostic_positions.md index 9e79c9a6a..936e3333f 100644 --- a/api/macros/json_diagnostic_positions.md +++ b/api/macros/json_diagnostic_positions.md @@ -277,6 +277,7 @@ When the macro is not defined, the library will define it to its default value. - [:simple-cmake: JSON_Diagnostic_Positions](../../integration/cmake.md#json_diagnostic_positions) - CMake option to control the macro - [`JSON_DIAGNOSTICS`](json_diagnostics.md) - macro to control extended diagnostics +- [`materialize()`](../basic_json_view/materialize.md) - values of a JSON view, with the same positions - [Parsing and Exceptions](../../features/parsing/parse_exceptions.md) - handling parse errors and locating them in the input ## Version history diff --git a/api/macros/json_diagnostic_positions/index.html b/api/macros/json_diagnostic_positions/index.html index 65502f177..2e6f40f5a 100644 --- a/api/macros/json_diagnostic_positions/index.html +++ b/api/macros/json_diagnostic_positions/index.html @@ -165,4 +165,4 @@ Parsed string: }

Output:

[json.exception.type_error.302] (/address/housenumber) (bytes 92-95) type must be number, but is string
 
The output shows the exception with diagnostic path info and start/end positions.
-

See also

Version history

  • Added in version 3.12.0.
\ No newline at end of file +

See also

Version history

  • Added in version 3.12.0.
\ No newline at end of file diff --git a/api/macros/json_diagnostic_positions/index.md b/api/macros/json_diagnostic_positions/index.md index 02e469c26..66d15ef49 100644 --- a/api/macros/json_diagnostic_positions/index.md +++ b/api/macros/json_diagnostic_positions/index.md @@ -256,6 +256,7 @@ The output shows the exception with diagnostic path info and start/end positions - [JSON_Diagnostic_Positions](https://json.nlohmann.me/integration/cmake/#json_diagnostic_positions) - CMake option to control the macro - [`JSON_DIAGNOSTICS`](https://json.nlohmann.me/api/macros/json_diagnostics/index.md) - macro to control extended diagnostics +- [`materialize()`](https://json.nlohmann.me/api/basic_json_view/materialize/index.md) - values of a JSON view, with the same positions - [Parsing and Exceptions](https://json.nlohmann.me/features/parsing/parse_exceptions/index.md) - handling parse errors and locating them in the input ## Version history diff --git a/features/json_patch.md b/features/json_patch.md index 2b979b85d..1e4010e0c 100644 --- a/features/json_patch.md +++ b/features/json_patch.md @@ -122,8 +122,9 @@ flowchart LR - `NaN` and [discarded](../api/basic_json/is_discarded.md) values are not equal to themselves, so the invariant cannot hold for them. `diff` emits a `replace` operation for such a value, and a `NaN` in a patch is serialized as `#!json null`. - - Numbers that compare equal produce no operation even if their types differ: `diff(1, 1.0)`, `diff(1u, 1)`, and - `diff(0.0, -0.0)` return `#!json []`, so the patched value keeps the number type of *source*. + - Numbers that compare equal produce no operation even if their types differ or if one is zero and the other is + negative zero: `diff(1, 1.0)`, `diff(1u, 1)`, and `diff(0.0, -0.0)` return `#!json []`, so the patched value + keeps the number type and sign of *source*. - A [binary value](binary_values.md) in a patch is serialized as an object (`#!json {"bytes":[...],"subtype":null}`), so a patch that was dumped and parsed again no longer holds a binary value. diff --git a/features/json_patch/index.html b/features/json_patch/index.html index 6db3e5596..5cafb5d18 100644 --- a/features/json_patch/index.html +++ b/features/json_patch/index.html @@ -46,7 +46,7 @@ S["source"] -->|"diff(source, target)"| P["patch"] S -->|"source.patch(patch)"| T["target"] P -.->|"applied to source, yields"| T

How diff and patch relate: diff(source, target) yields a patch, and applying that patch to the source yields the target.

Invariant

For two JSON values source and target, the following code yields true:

source.patch(diff(source, target)) == target;
-

The equality holds up to operator==, with these exceptions:

  • NaN and discarded values are not equal to themselves, so the invariant cannot hold for them. diff emits a replace operation for such a value, and a NaN in a patch is serialized as null.
  • Numbers that compare equal produce no operation even if their types differ: diff(1, 1.0), diff(1u, 1), and diff(0.0, -0.0) return [], so the patched value keeps the number type of source.
  • A binary value in a patch is serialized as an object ({"bytes":[...],"subtype":null}), so a patch that was dumped and parsed again no longer holds a binary value.
Example: create a JSON Patch from the difference of two values

The following code shows how a JSON patch is created as a diff for two JSON values.

#include <iostream>
+

The equality holds up to operator==, with these exceptions:

  • NaN and discarded values are not equal to themselves, so the invariant cannot hold for them. diff emits a replace operation for such a value, and a NaN in a patch is serialized as null.
  • Numbers that compare equal produce no operation even if their types differ or if one is zero and the other is negative zero: diff(1, 1.0), diff(1u, 1), and diff(0.0, -0.0) return [], so the patched value keeps the number type and sign of source.
  • A binary value in a patch is serialized as an object ({"bytes":[...],"subtype":null}), so a patch that was dumped and parsed again no longer holds a binary value.
Example: create a JSON Patch from the difference of two values

The following code shows how a JSON patch is created as a diff for two JSON values.

#include <iostream>
 #include <iomanip>
 #include <nlohmann/json.hpp>
 
@@ -108,4 +108,4 @@
         "world"
     ]
 }
-

See also

\ No newline at end of file +

See also

\ No newline at end of file diff --git a/features/json_patch/index.md b/features/json_patch/index.md index 03fcc60b0..9ba388a45 100644 --- a/features/json_patch/index.md +++ b/features/json_patch/index.md @@ -105,7 +105,7 @@ source.patch(diff(source, target)) == target; The equality holds up to [`operator==`](https://json.nlohmann.me/api/basic_json/operator_eq/index.md), with these exceptions: - `NaN` and [discarded](https://json.nlohmann.me/api/basic_json/is_discarded/index.md) values are not equal to themselves, so the invariant cannot hold for them. `diff` emits a `replace` operation for such a value, and a `NaN` in a patch is serialized as `null`. -- Numbers that compare equal produce no operation even if their types differ: `diff(1, 1.0)`, `diff(1u, 1)`, and `diff(0.0, -0.0)` return `[]`, so the patched value keeps the number type of *source*. +- Numbers that compare equal produce no operation even if their types differ or if one is zero and the other is negative zero: `diff(1, 1.0)`, `diff(1u, 1)`, and `diff(0.0, -0.0)` return `[]`, so the patched value keeps the number type and sign of *source*. - A [binary value](https://json.nlohmann.me/features/binary_values/index.md) in a patch is serialized as an object (`{"bytes":[...],"subtype":null}`), so a patch that was dumped and parsed again no longer holds a binary value. Example: create a JSON Patch from the difference of two values diff --git a/features/json_view.md b/features/json_view.md index 7eb4b4cab..724dc010d 100644 --- a/features/json_view.md +++ b/features/json_view.md @@ -447,10 +447,12 @@ document: `#!cpp auto v = json_document::parse(text).root();` does not compile. end must still fit. - **A stream is always read to its end.** There is no partial/streaming read of an `#!cpp std::istream`: the stream is read to its end into a buffer the document owns, and parsing starts after that. -- **No source positions on `materialize()`.** Even with +- **Fewer source positions after edits.** With [`JSON_DIAGNOSTIC_POSITIONS`](../api/macros/json_diagnostic_positions.md) enabled, - [`materialize()`](../api/basic_json_view/materialize.md) does not set them. The index has the start offset of every - value, but not the end of arrays, objects, and escaped strings, which the positions also need. + [`materialize()`](../api/basic_json_view/materialize.md) sets the same positions as `#!cpp basic_json::parse()`. + In an [editable document](../api/json_editable_document.md), a value written by an edit has none, and neither has + an array or object whose elements changed or whose last element has none; a `basic_json` value keeps its positions + when it is changed. See [`materialize()`](../api/basic_json_view/materialize.md#notes). - **Objects iterate in document order.** [`begin()`](../api/basic_json_view/begin.md)/ [`end()`](../api/basic_json_view/end.md) and [`items()`](../api/basic_json_view/items.md) visit an object's members in the order they appear in the source text. `basic_json`'s default `object_t` is a `std::map`, which diff --git a/features/json_view/index.html b/features/json_view/index.html index 4ffef541c..01baa81da 100644 --- a/features/json_view/index.html +++ b/features/json_view/index.html @@ -53,7 +53,7 @@ true true true -

What is the same as parse()

  • Accept/reject. accept() and parse() accept and reject exactly the same inputs as basic_json::accept()/basic_json::parse(), with the same ignore_comments and ignore_trailing_commas options.
  • Errors. A failing parse throws the same exception — the same id, message, and position — because on failure the library's own parser is run on the same bytes to produce the diagnostic. Valid input never pays for this, and the replay builds no values: it costs about a lexing pass up to the error. allow_exceptions == false skips the replay and gives a discarded document instead of throwing, just as it gives a discarded value for basic_json::parse().
  • Number classification. An integer literal that does not fit into the 64-bit integer type becomes a floating-point value, exactly as it does for basic_json::parse().
  • Macros. JSON_STRICT_NUL_HANDLING and JSON_NOEXCEPTION/JSON_THROW_USER behave the same way they do for <nlohmann/json.hpp>. These are the macros that change what the parser accepts or how it reports errors. The others either do not apply (JSON_DIAGNOSTICS needs parent pointers in basic_json values) or only affect the values materialize() produces, through BasicJsonType.

What is different

  • Only 64-bit integers. basic_json_document<BasicJsonType> requires BasicJsonType::number_integer_t and number_unsigned_t to both be 64 bits wide; this is a compile-time static_assert.
  • A 4 GiB input limit. An input of 4294967280 bytes (4 GiB minus 16 bytes) or more throws out_of_range.416, a limit basic_json::parse() does not have. It keeps an index entry at 16 bytes: offsets and counts are 32 bits wide. The limit is 16 bytes below 2^32, because the parser reads in 16-byte steps, and a position one step past the end must still fit.
  • A stream is always read to its end. There is no partial/streaming read of an std::istream: the stream is read to its end into a buffer the document owns, and parsing starts after that.
  • No source positions on materialize(). Even with JSON_DIAGNOSTIC_POSITIONS enabled, materialize() does not set them. The index has the start offset of every value, but not the end of arrays, objects, and escaped strings, which the positions also need.
  • Objects iterate in document order. begin()/ end() and items() visit an object's members in the order they appear in the source text. basic_json's default object_t is a std::map, which sorts by key, so iterating a materialize()d value can print members in a different order than iterating the view they came from.
  • Chained access is safe. operator[] with a missing key, an index out of range, or an unresolvable JSON pointer returns a discarded view, and operator[] on a discarded view returns a discarded view without throwing: v["a"]["b"][0] can be tested once at the end. Type errors on values that exist (a key on an array, an index on an object) still throw, and at throws for every missing value.
  • Duplicate keys: lookups find the first member, parse() keeps the last. See Duplicate keys below.
  • No JSON_DIAGNOSTICS path. Exceptions thrown by basic_json_view's own element access and lookup functions never carry the JSON Pointer path JSON_DIAGNOSTICS would otherwise add: the view has no basic_json value to point at, so the exception is created without one, regardless of how BasicJsonType was built.
  • Ordering comparisons are not provided by basic_json_view — there is no operator<. operator== and operator!= are provided, though: two views, or a view and a BasicJsonType value, compare equal exactly when materialize() or parse() would produce equal values for them, without ever building a tree to do it. For ordering, too, materialize() is the way to get a value you can compare.

Duplicate keys

A lookup in a view and in the parsed value can give different answers

If an object in the source text repeats a key, operator[], at, find, value, contains, and JSON pointer resolution all return the first member with that key. basic_json::parse() instead keeps the last value of a repeated key, so for {"a":1,"a":2}, view["a"] is 1 while parse(text)["a"] is 2. count counts every member with the key, so it is 2 here.

begin()/end() and items() visit every occurrence, in document order, and size() counts all of them, so view.size() can be larger than view.materialize().size().

Why the first? A lookup can stop as soon as it finds a match. Returning the last member would force every lookup to scan all members of the object, even when the key is found at the very first one: this made lookups in small objects 1.6 to 3.4 times slower. The hash index of the keys of objects with 128 members or more leads to the first member of a key as well. Other zero-copy parsers that index the source text, such as yyjson and simdjson, also return the first member. RFC 8259 only says that names within an object SHOULD be unique and that the behavior of a receiver that sees duplicates is unpredictable, so neither choice is wrong.

The same holds for get<T>() of a type whose from_json() reads the view, such as the types of the NLOHMANN_DEFINE_TYPE_* macros: their members are looked up, so get<point>() of {"x":1,"x":2} reads x == 1, while materialize().get<point>() reads 2.

What stays the same as parse()? materialize() and get<std::map<...>>() replay every member in order, so they keep the last value exactly like basic_json::parse() (at the position of the first occurrence of the key, for an ordered_json).

How do I get the value parse() would give? Either call view.materialize() and look the key up in the result, or iterate the members and keep the last match:

// the last member with the key "a", as parse() would keep it
+

What is the same as parse()

  • Accept/reject. accept() and parse() accept and reject exactly the same inputs as basic_json::accept()/basic_json::parse(), with the same ignore_comments and ignore_trailing_commas options.
  • Errors. A failing parse throws the same exception — the same id, message, and position — because on failure the library's own parser is run on the same bytes to produce the diagnostic. Valid input never pays for this, and the replay builds no values: it costs about a lexing pass up to the error. allow_exceptions == false skips the replay and gives a discarded document instead of throwing, just as it gives a discarded value for basic_json::parse().
  • Number classification. An integer literal that does not fit into the 64-bit integer type becomes a floating-point value, exactly as it does for basic_json::parse().
  • Macros. JSON_STRICT_NUL_HANDLING and JSON_NOEXCEPTION/JSON_THROW_USER behave the same way they do for <nlohmann/json.hpp>. These are the macros that change what the parser accepts or how it reports errors. The others either do not apply (JSON_DIAGNOSTICS needs parent pointers in basic_json values) or only affect the values materialize() produces, through BasicJsonType.

What is different

  • Only 64-bit integers. basic_json_document<BasicJsonType> requires BasicJsonType::number_integer_t and number_unsigned_t to both be 64 bits wide; this is a compile-time static_assert.
  • A 4 GiB input limit. An input of 4294967280 bytes (4 GiB minus 16 bytes) or more throws out_of_range.416, a limit basic_json::parse() does not have. It keeps an index entry at 16 bytes: offsets and counts are 32 bits wide. The limit is 16 bytes below 2^32, because the parser reads in 16-byte steps, and a position one step past the end must still fit.
  • A stream is always read to its end. There is no partial/streaming read of an std::istream: the stream is read to its end into a buffer the document owns, and parsing starts after that.
  • Fewer source positions after edits. With JSON_DIAGNOSTIC_POSITIONS enabled, materialize() sets the same positions as basic_json::parse(). In an editable document, a value written by an edit has none, and neither has an array or object whose elements changed or whose last element has none; a basic_json value keeps its positions when it is changed. See materialize().
  • Objects iterate in document order. begin()/ end() and items() visit an object's members in the order they appear in the source text. basic_json's default object_t is a std::map, which sorts by key, so iterating a materialize()d value can print members in a different order than iterating the view they came from.
  • Chained access is safe. operator[] with a missing key, an index out of range, or an unresolvable JSON pointer returns a discarded view, and operator[] on a discarded view returns a discarded view without throwing: v["a"]["b"][0] can be tested once at the end. Type errors on values that exist (a key on an array, an index on an object) still throw, and at throws for every missing value.
  • Duplicate keys: lookups find the first member, parse() keeps the last. See Duplicate keys below.
  • No JSON_DIAGNOSTICS path. Exceptions thrown by basic_json_view's own element access and lookup functions never carry the JSON Pointer path JSON_DIAGNOSTICS would otherwise add: the view has no basic_json value to point at, so the exception is created without one, regardless of how BasicJsonType was built.
  • Ordering comparisons are not provided by basic_json_view — there is no operator<. operator== and operator!= are provided, though: two views, or a view and a BasicJsonType value, compare equal exactly when materialize() or parse() would produce equal values for them, without ever building a tree to do it. For ordering, too, materialize() is the way to get a value you can compare.

Duplicate keys

A lookup in a view and in the parsed value can give different answers

If an object in the source text repeats a key, operator[], at, find, value, contains, and JSON pointer resolution all return the first member with that key. basic_json::parse() instead keeps the last value of a repeated key, so for {"a":1,"a":2}, view["a"] is 1 while parse(text)["a"] is 2. count counts every member with the key, so it is 2 here.

begin()/end() and items() visit every occurrence, in document order, and size() counts all of them, so view.size() can be larger than view.materialize().size().

Why the first? A lookup can stop as soon as it finds a match. Returning the last member would force every lookup to scan all members of the object, even when the key is found at the very first one: this made lookups in small objects 1.6 to 3.4 times slower. The hash index of the keys of objects with 128 members or more leads to the first member of a key as well. Other zero-copy parsers that index the source text, such as yyjson and simdjson, also return the first member. RFC 8259 only says that names within an object SHOULD be unique and that the behavior of a receiver that sees duplicates is unpredictable, so neither choice is wrong.

The same holds for get<T>() of a type whose from_json() reads the view, such as the types of the NLOHMANN_DEFINE_TYPE_* macros: their members are looked up, so get<point>() of {"x":1,"x":2} reads x == 1, while materialize().get<point>() reads 2.

What stays the same as parse()? materialize() and get<std::map<...>>() replay every member in order, so they keep the last value exactly like basic_json::parse() (at the position of the first occurrence of the key, for an ordered_json).

How do I get the value parse() would give? Either call view.materialize() and look the key up in the result, or iterate the members and keep the last match:

// the last member with the key "a", as parse() would keep it
 json_view last;
 for (const auto item : view.items())
 {
@@ -161,4 +161,4 @@
 

Output:

316
 true
 true
-

Experimental

The image format is versioned but not yet stable, and may change in an incompatible way before it is declared stable. It is little-endian only (on big-endian targets, save() and load() do not exist), and tied to the library build that wrote it — use it to cache a document or to hand one to another process running the same build, not as a long-term storage format; keep the original JSON text if a saved document needs to be readable by a future library version.

The idea of a document you can read without parsing comes from zero-copy formats such as FlatBuffers and YaFF; the check load() runs follows the idea of FlatBuffers' Verifier. No code is taken from either.

Choosing between json, ordered_json, the SAX interface, and json_view

json / ordered_json SAX interface json_document / json_view json_editable_document / json_editable_view
Ownership owns every value owns nothing; you decide what to keep, in your handler borrows or owns the text; the index is always owned by the document same as json_document; edits go to storage the document owns
Mutability freely mutable not applicable (a one-shot event stream) read-only set/push_back/insert/erase edit in place; the source text is never rewritten
What you get a full tree you can read, write, and keep as long as you like a sequence of callbacks; whatever your handler builds from them a flat index plus, on demand, materialize()d json/ordered_json values for the parts you actually use the same, plus dump() of an edited document that keeps the member order and, with number_format::source, the spelling of every untouched number
Typical use general-purpose JSON handling: config, request/response bodies you build or modify, anything you hold onto validating or projecting a text into your own data structure without ever holding the whole thing as JSON large or high-volume input where you only need part of it, or need it repeatedly, and can keep the source text (or a copy) alive for as long as the document lives a document you read, patch a few fields of, and write back — a configuration file, for instance — where the rest of it should come back exactly as it was
Caching/reload not applicable — re-parse, or roll your own serialization not applicable save()/load(): cache the parsed index as an image and reload it without parsing same, saving the document's current — possibly edited — state

Each column is one way to work with JSON in this library, and each row compares one property of them.

See also

Version history

  • Added in version 3.13.0 unreleased.
\ No newline at end of file +

Experimental

The image format is versioned but not yet stable, and may change in an incompatible way before it is declared stable. It is little-endian only (on big-endian targets, save() and load() do not exist), and tied to the library build that wrote it — use it to cache a document or to hand one to another process running the same build, not as a long-term storage format; keep the original JSON text if a saved document needs to be readable by a future library version.

The idea of a document you can read without parsing comes from zero-copy formats such as FlatBuffers and YaFF; the check load() runs follows the idea of FlatBuffers' Verifier. No code is taken from either.

Choosing between json, ordered_json, the SAX interface, and json_view

json / ordered_json SAX interface json_document / json_view json_editable_document / json_editable_view
Ownership owns every value owns nothing; you decide what to keep, in your handler borrows or owns the text; the index is always owned by the document same as json_document; edits go to storage the document owns
Mutability freely mutable not applicable (a one-shot event stream) read-only set/push_back/insert/erase edit in place; the source text is never rewritten
What you get a full tree you can read, write, and keep as long as you like a sequence of callbacks; whatever your handler builds from them a flat index plus, on demand, materialize()d json/ordered_json values for the parts you actually use the same, plus dump() of an edited document that keeps the member order and, with number_format::source, the spelling of every untouched number
Typical use general-purpose JSON handling: config, request/response bodies you build or modify, anything you hold onto validating or projecting a text into your own data structure without ever holding the whole thing as JSON large or high-volume input where you only need part of it, or need it repeatedly, and can keep the source text (or a copy) alive for as long as the document lives a document you read, patch a few fields of, and write back — a configuration file, for instance — where the rest of it should come back exactly as it was
Caching/reload not applicable — re-parse, or roll your own serialization not applicable save()/load(): cache the parsed index as an image and reload it without parsing same, saving the document's current — possibly edited — state

Each column is one way to work with JSON in this library, and each row compares one property of them.

See also

Version history

  • Added in version 3.13.0 unreleased.
\ No newline at end of file diff --git a/features/json_view/index.md b/features/json_view/index.md index a5e6a27db..c71e52ae5 100644 --- a/features/json_view/index.md +++ b/features/json_view/index.md @@ -130,7 +130,7 @@ true - **Only 64-bit integers.** `basic_json_document` requires `BasicJsonType::number_integer_t` and `number_unsigned_t` to both be 64 bits wide; this is a compile-time `static_assert`. - **A 4 GiB input limit.** An input of 4294967280 bytes (4 GiB minus 16 bytes) or more throws [`out_of_range.416`](https://json.nlohmann.me/home/exceptions/#jsonexceptionout_of_range416), a limit `basic_json::parse()` does not have. It keeps an index entry at 16 bytes: offsets and counts are 32 bits wide. The limit is 16 bytes below 2^32, because the parser reads in 16-byte steps, and a position one step past the end must still fit. - **A stream is always read to its end.** There is no partial/streaming read of an `std::istream`: the stream is read to its end into a buffer the document owns, and parsing starts after that. -- **No source positions on `materialize()`.** Even with [`JSON_DIAGNOSTIC_POSITIONS`](https://json.nlohmann.me/api/macros/json_diagnostic_positions/index.md) enabled, [`materialize()`](https://json.nlohmann.me/api/basic_json_view/materialize/index.md) does not set them. The index has the start offset of every value, but not the end of arrays, objects, and escaped strings, which the positions also need. +- **Fewer source positions after edits.** With [`JSON_DIAGNOSTIC_POSITIONS`](https://json.nlohmann.me/api/macros/json_diagnostic_positions/index.md) enabled, [`materialize()`](https://json.nlohmann.me/api/basic_json_view/materialize/index.md) sets the same positions as `basic_json::parse()`. In an [editable document](https://json.nlohmann.me/api/json_editable_document/index.md), a value written by an edit has none, and neither has an array or object whose elements changed or whose last element has none; a `basic_json` value keeps its positions when it is changed. See [`materialize()`](https://json.nlohmann.me/api/basic_json_view/materialize/#notes). - **Objects iterate in document order.** [`begin()`](https://json.nlohmann.me/api/basic_json_view/begin/index.md)/ [`end()`](https://json.nlohmann.me/api/basic_json_view/end/index.md) and [`items()`](https://json.nlohmann.me/api/basic_json_view/items/index.md) visit an object's members in the order they appear in the source text. `basic_json`'s default `object_t` is a `std::map`, which sorts by key, so iterating a [`materialize()`](https://json.nlohmann.me/api/basic_json_view/materialize/index.md)d value can print members in a different order than iterating the view they came from. - **Chained access is safe.** [`operator[]`](https://json.nlohmann.me/api/basic_json_view/operator%5B%5D/index.md) with a missing key, an index out of range, or an unresolvable JSON pointer returns a [discarded](https://json.nlohmann.me/api/basic_json_view/is_discarded/index.md) view, and `operator[]` on a discarded view returns a discarded view without throwing: `v["a"]["b"][0]` can be tested once at the end. Type errors on values that exist (a key on an array, an index on an object) still throw, and [`at`](https://json.nlohmann.me/api/basic_json_view/at/index.md) throws for every missing value. - **Duplicate keys: lookups find the first member, `parse()` keeps the last.** See [Duplicate keys](#duplicate-keys) below. diff --git a/features/parsing/untrusted_input.md b/features/parsing/untrusted_input.md index e89a7a7a3..1fe7b64aa 100644 --- a/features/parsing/untrusted_input.md +++ b/features/parsing/untrusted_input.md @@ -130,6 +130,17 @@ parameters of [`parse()`](../../api/basic_json/parse.md) or [`accept()`](../../a enable either for input whose conformance you cannot otherwise control, since interoperability with strictly conforming JSON consumers is exactly what the default rejects. +## JSON Pointers and flattened keys + +A [JSON Pointer](../json_pointer.md) can come from untrusted input as well, for instance as a path in a request or as a +key of a flattened object. The non-const [`operator[]`](../../api/basic_json/operator%5B%5D.md) with a JSON Pointer and +[`unflatten`](../../api/basic_json/unflatten.md) create missing values, and when an array index lies beyond the end of +an array, they fill the array with `#!json null` values up to that index. The memory used therefore grows with the +index, not with the size of the pointer: on a 64-bit platform, the index `10000000` allocates about 160 MB, the index +`100000000` about 1.6 GB. The library does not limit the index. For pointers from untrusted input, check the array +indices (or the pointer as a whole) before using them, or use [`at`](../../api/basic_json/at.md) or +[`contains`](../../api/basic_json/contains.md), which never add values. + ## Checklist - Wrap parsing in a `#!cpp try`/`#!cpp catch` block, or use `allow_exceptions=false`/`accept()` if your environment @@ -145,6 +156,8 @@ conforming JSON consumers is exactly what the default rejects. `JSON_STRICT_NUL_HANDLING`. - Decide whether duplicate object keys should be an error for your application, and add a callback if so. - Do not enable `ignore_comments` or `ignore_trailing_commas` for input that must be strictly conforming JSON. +- Check the array indices of untrusted JSON Pointers and flattened keys before passing them to the non-const + `operator[]` or `unflatten()`, which fill arrays with `#!json null` values up to the index. For the broader design rationale and how it is tested (fuzzing, sanitizers, static analysis), see the [assurance case](../../community/assurance_case.md) and [quality assurance](../../community/quality_assurance.md). To diff --git a/features/parsing/untrusted_input/index.html b/features/parsing/untrusted_input/index.html index 8d9892ed6..c2456a2fd 100644 --- a/features/parsing/untrusted_input/index.html +++ b/features/parsing/untrusted_input/index.html @@ -1 +1 @@ - Parsing Untrusted Input - JSON for Modern C++
Skip to content

Parsing Untrusted Input

This page is for applications that parse JSON — or one of the supported binary formats (BJData, BON8, BSON, CBOR, MessagePack, UBJSON) — from a source they do not fully control, such as a network connection, an uploaded file, or another process. It summarizes what the library already does for such input and what remains the caller's responsibility, linking to the pages that cover each aspect in detail rather than repeating them.

For the project's threat model and the countermeasures behind these behaviors, see the assurance case; to report a vulnerability, see the security policy.

Errors without exceptions

By default, parse() throws a parse_error (for instance parse_error.101 for a syntax error) when the input is not valid. If your environment cannot use exceptions for untrusted input, the library offers several alternatives; see Parsing and exceptions for the full comparison:

  • Pass false as the third argument to parse() to get a discarded value (checked with is_discarded()) instead of a thrown exception, with no diagnostic information.
  • Use accept() to only check whether the input is valid JSON, without building a value.
  • Implement the SAX interface and override parse_error() to react to an error yourself, with the byte position and the exception that would otherwise have been thrown; see the example that overrides it to print instead of throw.

If exceptions are unavailable entirely (-fno-exceptions, or JSON_NOEXCEPTION defined), every throw in the library becomes a call to std::abort(). The alternatives above do not throw, so parse() with allow_exceptions set to false (and likewise accept() and the from_* functions with allow_exceptions set to false) can still reject invalid input in that configuration; a plain parse() call aborts on invalid input. See Working without exceptions and Switch off exceptions for the details and for overriding the abort with JSON_THROW_USER.

Nesting depth

The JSON parser and the binary readers are iterative: they keep the containers they are currently inside of on a heap-allocated stack instead of calling themselves once per nesting level, so the native call stack does not grow with the nesting depth of the input. A deeply nested document is therefore bounded by available memory, not by the call stack, however deeply it is nested.

No built-in depth limit while parsing

Neither the parser nor the binary readers impose a limit on how deep the input may nest. An attacker can still exhaust memory (though not the call stack) with a sufficiently deep document. If you need to reject over-deep untrusted input outright, track the depth yourself, either with a parser callback for the JSON parser, or by counting start_object/start_array and end_object/end_array calls in a SAX handler (for the JSON parser or a binary format alike) and throwing once your limit is exceeded.

Once a value has been parsed, operations that walk it recursively — serializing it with dump, hashing it, copying it, comparing two values with ==, <, or (in C++20) <=>, merging with update, applying a merge_patch, creating a patch with diff or merge_diff, flatten, and the binary writers (to_cbor, to_msgpack, ...) — descend at most 128 levels on the call stack and continue below that with an explicit stack instead, so none of them can exhaust the stack either, however deeply the value is nested. Destroying a value (its destructor) never recurses at all, regardless of nesting depth, for the same reason.

Input size

The library does not limit the overall size of a JSON text; a value nested or wide enough will use memory proportional to the input. If you parse untrusted input of unbounded size, check the size of the file or stream yourself before — or while — handing it to parse().

For the binary formats, an announced size is never trusted outright:

  • Reading a string or binary value copies the input in bounded 4096-byte chunks and grows the result as bytes are actually consumed, rather than allocating the announced length up front — a truncated input runs out of bytes (reported as a parse error) instead of triggering an oversized allocation.
  • When an array announces its number of elements and the array container supports reserve() (as std::vector, the default, does), the library reserves storage for at most 16384 of them upfront, regardless of how large the announced count is; further elements still grow the container normally as they are read.
  • An announced array or object size that exceeds what the target container could ever hold (its max_size()) is rejected immediately as out_of_range.408, without attempting to allocate anything.

Strings

Invalid UTF-8 is rejected while parsing, not just while serializing:

  • In JSON text, an ill-formed UTF-8 byte in a string is a parse_error.101 ("invalid string: ill-formed UTF-8 byte").
  • In UTF-16 or UTF-32 input, an ill-formed sequence is a parse_error.101 as well: a lone surrogate, a high surrogate that is not followed by its low surrogate, and a code point above U+10FFFF are all rejected.
  • In a binary format, a string that is not valid UTF-8 is a parse_error.113.

A '\0' (NUL) byte inside a quoted JSON string is always rejected (it must be escaped as \u0000). A NUL byte outside of a string is different: by default it is silently treated as the end of the input, so trailing bytes after it — including further, otherwise well-formed JSON — are silently ignored rather than rejected. Since untrusted input that happens to embed a NUL is a way to make part of it disappear without a parse error, see the FAQ entry and consider defining JSON_STRICT_NUL_HANDLING to 1 to reject a NUL byte like any other unexpected byte instead.

Parsing is not the only place invalid UTF-8 matters: a string that reached a json value some other way (for example, constructed by application code, or, before JSON_STRICT_NUL_HANDLING existed, read from a binary format that does not validate strings) still has to round-trip back to JSON text. By default, dump() throws type_error.316 if the string is not valid UTF-8; passing error_handler_t::replace or error_handler_t::ignore avoids the exception instead of crashing an application that forgot to catch it. See Handling invalid UTF-8 for the options and an example.

Duplicate object keys

The JSON specification leaves the handling of repeated keys in an object up to the implementation, and this library does too: as described in object_t, it is unspecified which of the values for a repeated key ends up in the parsed object. If your application must reject duplicate keys instead of silently resolving them one way or another, see the parser callback recipe for rejecting duplicate keys.

Numbers

A number whose value cannot be represented — for instance 1E1000, which overflows double — is rejected while parsing as out_of_range.406 rather than silently becoming infinity. An integer that is syntactically valid but does not fit the 64-bit integer types is not rejected; it is instead stored as a double, which may lose precision for very large values. See number limits for the exact ranges and an example.

Comments and trailing commas

Both comments and trailing commas are rejected by default, matching the JSON specification; they must be explicitly enabled per call with the ignore_comments and ignore_trailing_commas parameters of parse() or accept(). Do not enable either for input whose conformance you cannot otherwise control, since interoperability with strictly conforming JSON consumers is exactly what the default rejects.

Checklist

  • Wrap parsing in a try/catch block, or use allow_exceptions=false/accept() if your environment cannot use exceptions; never let JSON_NOEXCEPTION's abort() be the first time you think about error handling.
  • If the input's nesting depth matters to you, enforce your own limit with a parser callback or a SAX handler; the library bounds the call stack but not memory use.
  • Bound the size of the input itself before parsing, independent of the library's own bounded allocations for binary format lengths.
  • Decide up front how you want a string with invalid UTF-8 — from any source, not only parsing — to be serialized (strict, replace, or ignore), rather than discovering it from an uncaught type_error.316.
  • If a stray NUL byte silently truncating trailing input is a problem for your input format, define JSON_STRICT_NUL_HANDLING.
  • Decide whether duplicate object keys should be an error for your application, and add a callback if so.
  • Do not enable ignore_comments or ignore_trailing_commas for input that must be strictly conforming JSON.

For the broader design rationale and how it is tested (fuzzing, sanitizers, static analysis), see the assurance case and quality assurance. To report a security issue in the library itself, follow the security policy.

See also

\ No newline at end of file + Parsing Untrusted Input - JSON for Modern C++
Skip to content

Parsing Untrusted Input

This page is for applications that parse JSON — or one of the supported binary formats (BJData, BON8, BSON, CBOR, MessagePack, UBJSON) — from a source they do not fully control, such as a network connection, an uploaded file, or another process. It summarizes what the library already does for such input and what remains the caller's responsibility, linking to the pages that cover each aspect in detail rather than repeating them.

For the project's threat model and the countermeasures behind these behaviors, see the assurance case; to report a vulnerability, see the security policy.

Errors without exceptions

By default, parse() throws a parse_error (for instance parse_error.101 for a syntax error) when the input is not valid. If your environment cannot use exceptions for untrusted input, the library offers several alternatives; see Parsing and exceptions for the full comparison:

  • Pass false as the third argument to parse() to get a discarded value (checked with is_discarded()) instead of a thrown exception, with no diagnostic information.
  • Use accept() to only check whether the input is valid JSON, without building a value.
  • Implement the SAX interface and override parse_error() to react to an error yourself, with the byte position and the exception that would otherwise have been thrown; see the example that overrides it to print instead of throw.

If exceptions are unavailable entirely (-fno-exceptions, or JSON_NOEXCEPTION defined), every throw in the library becomes a call to std::abort(). The alternatives above do not throw, so parse() with allow_exceptions set to false (and likewise accept() and the from_* functions with allow_exceptions set to false) can still reject invalid input in that configuration; a plain parse() call aborts on invalid input. See Working without exceptions and Switch off exceptions for the details and for overriding the abort with JSON_THROW_USER.

Nesting depth

The JSON parser and the binary readers are iterative: they keep the containers they are currently inside of on a heap-allocated stack instead of calling themselves once per nesting level, so the native call stack does not grow with the nesting depth of the input. A deeply nested document is therefore bounded by available memory, not by the call stack, however deeply it is nested.

No built-in depth limit while parsing

Neither the parser nor the binary readers impose a limit on how deep the input may nest. An attacker can still exhaust memory (though not the call stack) with a sufficiently deep document. If you need to reject over-deep untrusted input outright, track the depth yourself, either with a parser callback for the JSON parser, or by counting start_object/start_array and end_object/end_array calls in a SAX handler (for the JSON parser or a binary format alike) and throwing once your limit is exceeded.

Once a value has been parsed, operations that walk it recursively — serializing it with dump, hashing it, copying it, comparing two values with ==, <, or (in C++20) <=>, merging with update, applying a merge_patch, creating a patch with diff or merge_diff, flatten, and the binary writers (to_cbor, to_msgpack, ...) — descend at most 128 levels on the call stack and continue below that with an explicit stack instead, so none of them can exhaust the stack either, however deeply the value is nested. Destroying a value (its destructor) never recurses at all, regardless of nesting depth, for the same reason.

Input size

The library does not limit the overall size of a JSON text; a value nested or wide enough will use memory proportional to the input. If you parse untrusted input of unbounded size, check the size of the file or stream yourself before — or while — handing it to parse().

For the binary formats, an announced size is never trusted outright:

  • Reading a string or binary value copies the input in bounded 4096-byte chunks and grows the result as bytes are actually consumed, rather than allocating the announced length up front — a truncated input runs out of bytes (reported as a parse error) instead of triggering an oversized allocation.
  • When an array announces its number of elements and the array container supports reserve() (as std::vector, the default, does), the library reserves storage for at most 16384 of them upfront, regardless of how large the announced count is; further elements still grow the container normally as they are read.
  • An announced array or object size that exceeds what the target container could ever hold (its max_size()) is rejected immediately as out_of_range.408, without attempting to allocate anything.

Strings

Invalid UTF-8 is rejected while parsing, not just while serializing:

  • In JSON text, an ill-formed UTF-8 byte in a string is a parse_error.101 ("invalid string: ill-formed UTF-8 byte").
  • In UTF-16 or UTF-32 input, an ill-formed sequence is a parse_error.101 as well: a lone surrogate, a high surrogate that is not followed by its low surrogate, and a code point above U+10FFFF are all rejected.
  • In a binary format, a string that is not valid UTF-8 is a parse_error.113.

A '\0' (NUL) byte inside a quoted JSON string is always rejected (it must be escaped as \u0000). A NUL byte outside of a string is different: by default it is silently treated as the end of the input, so trailing bytes after it — including further, otherwise well-formed JSON — are silently ignored rather than rejected. Since untrusted input that happens to embed a NUL is a way to make part of it disappear without a parse error, see the FAQ entry and consider defining JSON_STRICT_NUL_HANDLING to 1 to reject a NUL byte like any other unexpected byte instead.

Parsing is not the only place invalid UTF-8 matters: a string that reached a json value some other way (for example, constructed by application code, or, before JSON_STRICT_NUL_HANDLING existed, read from a binary format that does not validate strings) still has to round-trip back to JSON text. By default, dump() throws type_error.316 if the string is not valid UTF-8; passing error_handler_t::replace or error_handler_t::ignore avoids the exception instead of crashing an application that forgot to catch it. See Handling invalid UTF-8 for the options and an example.

Duplicate object keys

The JSON specification leaves the handling of repeated keys in an object up to the implementation, and this library does too: as described in object_t, it is unspecified which of the values for a repeated key ends up in the parsed object. If your application must reject duplicate keys instead of silently resolving them one way or another, see the parser callback recipe for rejecting duplicate keys.

Numbers

A number whose value cannot be represented — for instance 1E1000, which overflows double — is rejected while parsing as out_of_range.406 rather than silently becoming infinity. An integer that is syntactically valid but does not fit the 64-bit integer types is not rejected; it is instead stored as a double, which may lose precision for very large values. See number limits for the exact ranges and an example.

Comments and trailing commas

Both comments and trailing commas are rejected by default, matching the JSON specification; they must be explicitly enabled per call with the ignore_comments and ignore_trailing_commas parameters of parse() or accept(). Do not enable either for input whose conformance you cannot otherwise control, since interoperability with strictly conforming JSON consumers is exactly what the default rejects.

JSON Pointers and flattened keys

A JSON Pointer can come from untrusted input as well, for instance as a path in a request or as a key of a flattened object. The non-const operator[] with a JSON Pointer and unflatten create missing values, and when an array index lies beyond the end of an array, they fill the array with null values up to that index. The memory used therefore grows with the index, not with the size of the pointer: on a 64-bit platform, the index 10000000 allocates about 160 MB, the index 100000000 about 1.6 GB. The library does not limit the index. For pointers from untrusted input, check the array indices (or the pointer as a whole) before using them, or use at or contains, which never add values.

Checklist

  • Wrap parsing in a try/catch block, or use allow_exceptions=false/accept() if your environment cannot use exceptions; never let JSON_NOEXCEPTION's abort() be the first time you think about error handling.
  • If the input's nesting depth matters to you, enforce your own limit with a parser callback or a SAX handler; the library bounds the call stack but not memory use.
  • Bound the size of the input itself before parsing, independent of the library's own bounded allocations for binary format lengths.
  • Decide up front how you want a string with invalid UTF-8 — from any source, not only parsing — to be serialized (strict, replace, or ignore), rather than discovering it from an uncaught type_error.316.
  • If a stray NUL byte silently truncating trailing input is a problem for your input format, define JSON_STRICT_NUL_HANDLING.
  • Decide whether duplicate object keys should be an error for your application, and add a callback if so.
  • Do not enable ignore_comments or ignore_trailing_commas for input that must be strictly conforming JSON.
  • Check the array indices of untrusted JSON Pointers and flattened keys before passing them to the non-const operator[] or unflatten(), which fill arrays with null values up to the index.

For the broader design rationale and how it is tested (fuzzing, sanitizers, static analysis), see the assurance case and quality assurance. To report a security issue in the library itself, follow the security policy.

See also

\ No newline at end of file diff --git a/features/parsing/untrusted_input/index.md b/features/parsing/untrusted_input/index.md index cd39b76e2..9cae0ec7e 100644 --- a/features/parsing/untrusted_input/index.md +++ b/features/parsing/untrusted_input/index.md @@ -58,6 +58,10 @@ A number whose value cannot be represented — for instance `1E1000`, which over Both [comments](https://json.nlohmann.me/features/comments/index.md) and [trailing commas](https://json.nlohmann.me/features/trailing_commas/index.md) are rejected by default, matching the JSON specification; they must be explicitly enabled per call with the `ignore_comments` and `ignore_trailing_commas` parameters of [`parse()`](https://json.nlohmann.me/api/basic_json/parse/index.md) or [`accept()`](https://json.nlohmann.me/api/basic_json/accept/index.md). Do not enable either for input whose conformance you cannot otherwise control, since interoperability with strictly conforming JSON consumers is exactly what the default rejects. +## JSON Pointers and flattened keys + +A [JSON Pointer](https://json.nlohmann.me/features/json_pointer/index.md) can come from untrusted input as well, for instance as a path in a request or as a key of a flattened object. The non-const [`operator[]`](https://json.nlohmann.me/api/basic_json/operator%5B%5D/index.md) with a JSON Pointer and [`unflatten`](https://json.nlohmann.me/api/basic_json/unflatten/index.md) create missing values, and when an array index lies beyond the end of an array, they fill the array with `null` values up to that index. The memory used therefore grows with the index, not with the size of the pointer: on a 64-bit platform, the index `10000000` allocates about 160 MB, the index `100000000` about 1.6 GB. The library does not limit the index. For pointers from untrusted input, check the array indices (or the pointer as a whole) before using them, or use [`at`](https://json.nlohmann.me/api/basic_json/at/index.md) or [`contains`](https://json.nlohmann.me/api/basic_json/contains/index.md), which never add values. + ## Checklist - Wrap parsing in a `try`/`catch` block, or use `allow_exceptions=false`/`accept()` if your environment cannot use exceptions; never let `JSON_NOEXCEPTION`'s `abort()` be the first time you think about error handling. @@ -67,6 +71,7 @@ Both [comments](https://json.nlohmann.me/features/comments/index.md) and [traili - If a stray NUL byte silently truncating trailing input is a problem for your input format, define `JSON_STRICT_NUL_HANDLING`. - Decide whether duplicate object keys should be an error for your application, and add a callback if so. - Do not enable `ignore_comments` or `ignore_trailing_commas` for input that must be strictly conforming JSON. +- Check the array indices of untrusted JSON Pointers and flattened keys before passing them to the non-const `operator[]` or `unflatten()`, which fill arrays with `null` values up to the index. For the broader design rationale and how it is tested (fuzzing, sanitizers, static analysis), see the [assurance case](https://json.nlohmann.me/community/assurance_case/index.md) and [quality assurance](https://json.nlohmann.me/community/quality_assurance/index.md). To report a security issue in the library itself, follow the [security policy](https://json.nlohmann.me/community/security_policy/index.md). diff --git a/home/architecture.md b/home/architecture.md index 82a660e3a..1b0d84dd7 100644 --- a/home/architecture.md +++ b/home/architecture.md @@ -203,7 +203,7 @@ packet-beta | 2-3 | `extra` | `uint16_t` | numbers: the number of integer digits (low byte) and fraction digits (high byte), 255 for more; objects: the number of their key hash index (1-based), or 0; otherwise 0 | | 4-7 | `off` | `uint32_t` | where the value starts: the first byte after a string's opening quote (or its position in the buffer of decoded strings), the first byte of a number or literal, the bracket of an array or object | | 8-11 | `len` | `uint32_t` | strings: the length after decoding; floats and literals: the length of the token; arrays and objects: the number of elements | -| 12-15 | `next` | `uint32_t` | arrays and objects: the number of nodes of the subtree, including the node itself | +| 12-15 | `next` | `uint32_t` | arrays and objects: the number of nodes of the subtree, including the node itself; strings with escapes: the position of the opening quote in the source plus one if the document was parsed with [`JSON_DIAGNOSTIC_POSITIONS`](../api/macros/json_diagnostic_positions.md), or 0 if it was not; all other values: 0 |

Fields of a node, by their byte offset within the 16-byte node. Integers use bytes 8-15 differently, see below.

@@ -218,6 +218,12 @@ packet-beta step from element to element this way and skip whole subtrees in constant time. - **Offsets** are 32 bits wide, so a document is limited to 4294967279 bytes, 4 GiB minus 16 bytes (a margin below 2^32 for positions one scanner step past the end of the text; `out_of_range.416`). +- **Source positions** ([`JSON_DIAGNOSTIC_POSITIONS`](../api/macros/json_diagnostic_positions.md)) are derived by + [`materialize()`](../api/basic_json_view/materialize.md) and cost almost nothing while parsing: the only work is + storing the offset of the opening quote of a string with escapes in its `next`, which is otherwise unused. A + scalar's range follows from `off` and its length, a string with escapes is scanned from its opening quote (`next`) to the closing one, + and the end of an array or object is found by scanning from the end of its last element over whitespace, comments, + and a trailing comma. `materialize()` hands these positions to the SAX builder of `parse()` in place of its lexer. - **Large objects** (128 members or more) get a hash index for their keys after parsing ([`detail/view/object_index.hpp`](https://github.com/nlohmann/json/blob/develop/include/nlohmann/detail/view/object_index.hpp)): an open-addressing table whose slots hold the distance from the object's node to a key's node, so that a lookup does @@ -277,7 +283,7 @@ Images ([`save`](../api/basic_json_document/save.md) and [`load`](../api/basic_j the nodes as they are: a 64-byte header (the magic bytes `NJVI`, a format version, the sizes, and reserved bytes that must be zero), the nodes, the text, and the decoded strings. An edited document is first written in document order, as the parser would have written it (without links), and the numbers of the hash indexes are cleared, since `load` -rebuilds the indexes. So a change of the node layout is a change of the image format: it must raise `image_version`, +rebuilds the indexes. The flag *new* is kept, as these values have no position in the text. So a change of the node layout is a change of the image format: it must raise `image_version`, and `load` then rejects images of other versions (`parse_error.116`) instead of misreading them. ## Input adapters diff --git a/home/architecture/index.html b/home/architecture/index.html index 34ce6430c..e3dbbb12f 100644 --- a/home/architecture/index.html +++ b/home/architecture/index.html @@ -65,7 +65,7 @@ 16-31: "extra" 32-63: "off" 64-95: "len" - 96-127: "next"

Layout of one 16-byte node of a JSON view index. Each row is 32 bits wide, and the numbers are the bit offsets of the fields kind, flags, extra, off, len, and next.

Bytes Field Type Contents
0 kind uint8_t the type, numbered as value_t: 0 null, 1 object, 2 array, 3 string, 4 boolean, 5 signed integer, 6 unsigned integer, 7 float; 10 for a link (see below). There is no node for a discarded value: a discarded view has none
1 flags uint8_t bits 0-1: where a string's bytes (or a number's token) are (0: the source text, 1: the buffer of decoded strings, for strings with escapes, 2: the edit buffer); bit 2: the value of a boolean; bit 3: moved, bit 4: new, bit 5: linked (see below)
2-3 extra uint16_t numbers: the number of integer digits (low byte) and fraction digits (high byte), 255 for more; objects: the number of their key hash index (1-based), or 0; otherwise 0
4-7 off uint32_t where the value starts: the first byte after a string's opening quote (or its position in the buffer of decoded strings), the first byte of a number or literal, the bracket of an array or object
8-11 len uint32_t strings: the length after decoding; floats and literals: the length of the token; arrays and objects: the number of elements
12-15 next uint32_t arrays and objects: the number of nodes of the subtree, including the node itself

Fields of a node, by their byte offset within the 16-byte node. Integers use bytes 8-15 differently, see below.

  • Integers keep their converted value in bytes 8-15 instead of len and next; the length of their token follows from the number of digits in extra (and the sign). Non-negative integers are unsigned integers, as with parse.
  • Floats keep only their token. The digit layout in extra lets the conversion read the digits without scanning the token again, and only when the value is read.
  • Object members are the node of the key (a string) followed by the nodes of the value.
  • Navigation needs no pointers: the elements of an array or object follow its node, and the node after a value's subtree is next nodes further for an array or object, and the next node otherwise (document_data::after). Views step from element to element this way and skip whole subtrees in constant time.
  • Offsets are 32 bits wide, so a document is limited to 4294967279 bytes, 4 GiB minus 16 bytes (a margin below 2^32 for positions one scanner step past the end of the text; out_of_range.416).
  • Large objects (128 members or more) get a hash index for their keys after parsing (detail/view/object_index.hpp): an open-addressing table whose slots hold the distance from the object's node to a key's node, so that a lookup does not compare every key. Of duplicate keys the table leads to the first, as a linear search does. The object's extra holds the number of its table. Only 65,535 tables fit into extra; objects beyond them are searched linearly.

For example, {"a": [1, 2.5]} becomes five nodes. Each node's elements follow it, and next leads from an array or object past its subtree:

flowchart LR
+  96-127: "next"

Layout of one 16-byte node of a JSON view index. Each row is 32 bits wide, and the numbers are the bit offsets of the fields kind, flags, extra, off, len, and next.

Bytes Field Type Contents
0 kind uint8_t the type, numbered as value_t: 0 null, 1 object, 2 array, 3 string, 4 boolean, 5 signed integer, 6 unsigned integer, 7 float; 10 for a link (see below). There is no node for a discarded value: a discarded view has none
1 flags uint8_t bits 0-1: where a string's bytes (or a number's token) are (0: the source text, 1: the buffer of decoded strings, for strings with escapes, 2: the edit buffer); bit 2: the value of a boolean; bit 3: moved, bit 4: new, bit 5: linked (see below)
2-3 extra uint16_t numbers: the number of integer digits (low byte) and fraction digits (high byte), 255 for more; objects: the number of their key hash index (1-based), or 0; otherwise 0
4-7 off uint32_t where the value starts: the first byte after a string's opening quote (or its position in the buffer of decoded strings), the first byte of a number or literal, the bracket of an array or object
8-11 len uint32_t strings: the length after decoding; floats and literals: the length of the token; arrays and objects: the number of elements
12-15 next uint32_t arrays and objects: the number of nodes of the subtree, including the node itself; strings with escapes: the position of the opening quote in the source plus one if the document was parsed with JSON_DIAGNOSTIC_POSITIONS, or 0 if it was not; all other values: 0

Fields of a node, by their byte offset within the 16-byte node. Integers use bytes 8-15 differently, see below.

  • Integers keep their converted value in bytes 8-15 instead of len and next; the length of their token follows from the number of digits in extra (and the sign). Non-negative integers are unsigned integers, as with parse.
  • Floats keep only their token. The digit layout in extra lets the conversion read the digits without scanning the token again, and only when the value is read.
  • Object members are the node of the key (a string) followed by the nodes of the value.
  • Navigation needs no pointers: the elements of an array or object follow its node, and the node after a value's subtree is next nodes further for an array or object, and the next node otherwise (document_data::after). Views step from element to element this way and skip whole subtrees in constant time.
  • Offsets are 32 bits wide, so a document is limited to 4294967279 bytes, 4 GiB minus 16 bytes (a margin below 2^32 for positions one scanner step past the end of the text; out_of_range.416).
  • Source positions (JSON_DIAGNOSTIC_POSITIONS) are derived by materialize() and cost almost nothing while parsing: the only work is storing the offset of the opening quote of a string with escapes in its next, which is otherwise unused. A scalar's range follows from off and its length, a string with escapes is scanned from its opening quote (next) to the closing one, and the end of an array or object is found by scanning from the end of its last element over whitespace, comments, and a trailing comma. materialize() hands these positions to the SAX builder of parse() in place of its lexer.
  • Large objects (128 members or more) get a hash index for their keys after parsing (detail/view/object_index.hpp): an open-addressing table whose slots hold the distance from the object's node to a key's node, so that a lookup does not compare every key. Of duplicate keys the table leads to the first, as a linear search does. The object's extra holds the number of its table. Only 65,535 tables fit into extra; objects beyond them are searched linearly.

For example, {"a": [1, 2.5]} becomes five nodes. Each node's elements follow it, and next leads from an array or object past its subtree:

flowchart LR
     n0["0: object<br>len 1, next 5"]
     n1["1: key a"]
     n2["2: array<br>len 2, next 3"]
@@ -74,7 +74,7 @@
     e(["end"])
     n0 --> n1 --> n2 --> n3 --> n4 --> e
     n0 -. next .-> e
-    n2 -. next .-> e

The five nodes of {"a": [1, 2.5]} in document order. Solid arrows lead from each node to the one after it; dotted arrows show where next leads from the object and the array, past their subtrees.

Node kind extra off len next
0 1 (object) 0 0 1 5
1 3 (string) 0 2 1 0
2 2 (array) 0 6 2 3
3 6 (unsigned integer) 0x0001 7 - -
4 7 (float) 0x0101 10 3 0

Fields of the five nodes of {"a": [1, 2.5]}. off is the byte offset in the text, and - marks the bytes 8-15 that hold the integer's value instead of len and next.

All flags are 0. The integer's bytes 8-15 hold its value, 1; its extra says it has one digit. The float's extra says it has one integer and one fraction digit, and its len is that of the token 2.5.

Editable documents (json_editable_document, detail/view/edit.hpp and detail/view/edit_storage.hpp) never write the source text and never move or resize the parsed index, so views stay valid while the document is edited:

  • A new scalar is written over its node. Its text (a string, or the token of a number as dump() writes it) goes to the edit buffer, which flags bits 0-1 then name.
  • An array or object whose elements change gets the flag moved (bit 3): its elements then live in a separate sequence (a header node, then the entries), whose number is in off. The entries are links (kind 10), whose bytes 8-15 hold the address of the value's node, so values never move.
  • A node written by an edit gets the flag new (bit 4): it has no position in the source text.
  • A value that an entry of such a sequence links to gets the flag linked (bit 5): its extent in the parsed layout (next) no longer matters, so a scalar can replace an array or object there in place.
  • Views of read-only documents compile without any of this: how views walk the index is a template parameter (navigation<Editable>).

Images (save and load, detail/view/image.hpp) store the nodes as they are: a 64-byte header (the magic bytes NJVI, a format version, the sizes, and reserved bytes that must be zero), the nodes, the text, and the decoded strings. An edited document is first written in document order, as the parser would have written it (without links), and the numbers of the hash indexes are cleared, since load rebuilds the indexes. So a change of the node layout is a change of the image format: it must raise image_version, and load then rejects images of other versions (parse_error.116) instead of misreading them.

Input adapters

Input is read via input adapters that abstract a source. Every input adapter provides this interface:

/// the type of the characters in the input
+    n2 -. next .-> e

The five nodes of {"a": [1, 2.5]} in document order. Solid arrows lead from each node to the one after it; dotted arrows show where next leads from the object and the array, past their subtrees.

Node kind extra off len next
0 1 (object) 0 0 1 5
1 3 (string) 0 2 1 0
2 2 (array) 0 6 2 3
3 6 (unsigned integer) 0x0001 7 - -
4 7 (float) 0x0101 10 3 0

Fields of the five nodes of {"a": [1, 2.5]}. off is the byte offset in the text, and - marks the bytes 8-15 that hold the integer's value instead of len and next.

All flags are 0. The integer's bytes 8-15 hold its value, 1; its extra says it has one digit. The float's extra says it has one integer and one fraction digit, and its len is that of the token 2.5.

Editable documents (json_editable_document, detail/view/edit.hpp and detail/view/edit_storage.hpp) never write the source text and never move or resize the parsed index, so views stay valid while the document is edited:

  • A new scalar is written over its node. Its text (a string, or the token of a number as dump() writes it) goes to the edit buffer, which flags bits 0-1 then name.
  • An array or object whose elements change gets the flag moved (bit 3): its elements then live in a separate sequence (a header node, then the entries), whose number is in off. The entries are links (kind 10), whose bytes 8-15 hold the address of the value's node, so values never move.
  • A node written by an edit gets the flag new (bit 4): it has no position in the source text.
  • A value that an entry of such a sequence links to gets the flag linked (bit 5): its extent in the parsed layout (next) no longer matters, so a scalar can replace an array or object there in place.
  • Views of read-only documents compile without any of this: how views walk the index is a template parameter (navigation<Editable>).

Images (save and load, detail/view/image.hpp) store the nodes as they are: a 64-byte header (the magic bytes NJVI, a format version, the sizes, and reserved bytes that must be zero), the nodes, the text, and the decoded strings. An edited document is first written in document order, as the parser would have written it (without links), and the numbers of the hash indexes are cleared, since load rebuilds the indexes. The flag new is kept, as these values have no position in the text. So a change of the node layout is a change of the image format: it must raise image_version, and load then rejects images of other versions (parse_error.116) instead of misreading them.

Input adapters

Input is read via input adapters that abstract a source. Every input adapter provides this interface:

/// the type of the characters in the input
 using char_type = ...;
 
 /// read a single character; returns std::char_traits<char_type>::eof() at the end of the input
@@ -138,4 +138,4 @@
 
 template<class T>
 void from_json(const basic_json& j, T& t);
-

found by argument-dependent lookup. The library defines them for standard types in detail/conversions; users add them for their own types, see Arbitrary Type Conversions. The serialization macros generate these functions.

Additional features

Details namespace

Namespace nlohmann::detail contains all implementation details. It is not part of the public API and may change in any release. Besides the components above, it contains:

  • type traits to detect the capabilities of user-defined types (detail/meta/type_traits.hpp),
  • backports of C++14/17 features to C++11 (detail/meta/cpp_future.hpp), and
  • helpers such as string_concat and string_escape.

See also

\ No newline at end of file +

found by argument-dependent lookup. The library defines them for standard types in detail/conversions; users add them for their own types, see Arbitrary Type Conversions. The serialization macros generate these functions.

Additional features

Details namespace

Namespace nlohmann::detail contains all implementation details. It is not part of the public API and may change in any release. Besides the components above, it contains:

  • type traits to detect the capabilities of user-defined types (detail/meta/type_traits.hpp),
  • backports of C++14/17 features to C++11 (detail/meta/cpp_future.hpp), and
  • helpers such as string_concat and string_escape.

See also

\ No newline at end of file diff --git a/home/architecture/index.md b/home/architecture/index.md index fa2aa3385..02eff36b7 100644 --- a/home/architecture/index.md +++ b/home/architecture/index.md @@ -171,7 +171,7 @@ Layout of one 16-byte node of a JSON view index. Each row is 32 bits wide, and t | 2-3 | `extra` | `uint16_t` | numbers: the number of integer digits (low byte) and fraction digits (high byte), 255 for more; objects: the number of their key hash index (1-based), or 0; otherwise 0 | | 4-7 | `off` | `uint32_t` | where the value starts: the first byte after a string's opening quote (or its position in the buffer of decoded strings), the first byte of a number or literal, the bracket of an array or object | | 8-11 | `len` | `uint32_t` | strings: the length after decoding; floats and literals: the length of the token; arrays and objects: the number of elements | -| 12-15 | `next` | `uint32_t` | arrays and objects: the number of nodes of the subtree, including the node itself | +| 12-15 | `next` | `uint32_t` | arrays and objects: the number of nodes of the subtree, including the node itself; strings with escapes: the position of the opening quote in the source plus one if the document was parsed with [`JSON_DIAGNOSTIC_POSITIONS`](https://json.nlohmann.me/api/macros/json_diagnostic_positions/index.md), or 0 if it was not; all other values: 0 | Fields of a node, by their byte offset within the 16-byte node. Integers use bytes 8-15 differently, see below. @@ -180,6 +180,7 @@ Fields of a node, by their byte offset within the 16-byte node. Integers use byt - **Object members** are the node of the key (a string) followed by the nodes of the value. - **Navigation** needs no pointers: the elements of an array or object follow its node, and the node after a value's subtree is `next` nodes further for an array or object, and the next node otherwise (`document_data::after`). Views step from element to element this way and skip whole subtrees in constant time. - **Offsets** are 32 bits wide, so a document is limited to 4294967279 bytes, 4 GiB minus 16 bytes (a margin below 2^32 for positions one scanner step past the end of the text; `out_of_range.416`). +- **Source positions** ([`JSON_DIAGNOSTIC_POSITIONS`](https://json.nlohmann.me/api/macros/json_diagnostic_positions/index.md)) are derived by [`materialize()`](https://json.nlohmann.me/api/basic_json_view/materialize/index.md) and cost almost nothing while parsing: the only work is storing the offset of the opening quote of a string with escapes in its `next`, which is otherwise unused. A scalar's range follows from `off` and its length, a string with escapes is scanned from its opening quote (`next`) to the closing one, and the end of an array or object is found by scanning from the end of its last element over whitespace, comments, and a trailing comma. `materialize()` hands these positions to the SAX builder of `parse()` in place of its lexer. - **Large objects** (128 members or more) get a hash index for their keys after parsing ([`detail/view/object_index.hpp`](https://github.com/nlohmann/json/blob/develop/include/nlohmann/detail/view/object_index.hpp)): an open-addressing table whose slots hold the distance from the object's node to a key's node, so that a lookup does not compare every key. Of duplicate keys the table leads to the first, as a linear search does. The object's `extra` holds the number of its table. Only 65,535 tables fit into `extra`; objects beyond them are searched linearly. For example, `{"a": [1, 2.5]}` becomes five nodes. Each node's elements follow it, and `next` leads from an array or object past its subtree: @@ -219,7 +220,7 @@ Editable documents ([`json_editable_document`](https://json.nlohmann.me/api/json - A value that an entry of such a sequence links to gets the flag *linked* (bit 5): its extent in the parsed layout (`next`) no longer matters, so a scalar can replace an array or object there in place. - Views of read-only documents compile without any of this: how views walk the index is a template parameter (`navigation`). -Images ([`save`](https://json.nlohmann.me/api/basic_json_document/save/index.md) and [`load`](https://json.nlohmann.me/api/basic_json_document/load/index.md), [`detail/view/image.hpp`](https://github.com/nlohmann/json/blob/develop/include/nlohmann/detail/view/image.hpp)) store the nodes as they are: a 64-byte header (the magic bytes `NJVI`, a format version, the sizes, and reserved bytes that must be zero), the nodes, the text, and the decoded strings. An edited document is first written in document order, as the parser would have written it (without links), and the numbers of the hash indexes are cleared, since `load` rebuilds the indexes. So a change of the node layout is a change of the image format: it must raise `image_version`, and `load` then rejects images of other versions (`parse_error.116`) instead of misreading them. +Images ([`save`](https://json.nlohmann.me/api/basic_json_document/save/index.md) and [`load`](https://json.nlohmann.me/api/basic_json_document/load/index.md), [`detail/view/image.hpp`](https://github.com/nlohmann/json/blob/develop/include/nlohmann/detail/view/image.hpp)) store the nodes as they are: a 64-byte header (the magic bytes `NJVI`, a format version, the sizes, and reserved bytes that must be zero), the nodes, the text, and the decoded strings. An edited document is first written in document order, as the parser would have written it (without links), and the numbers of the hash indexes are cleared, since `load` rebuilds the indexes. The flag *new* is kept, as these values have no position in the text. So a change of the node layout is a change of the image format: it must raise `image_version`, and `load` then rejects images of other versions (`parse_error.116`) instead of misreading them. ## Input adapters diff --git a/home/releases/unreleased/index.html b/home/releases/unreleased/index.html index 2af03a0bc..adc32d6cd 100644 --- a/home/releases/unreleased/index.html +++ b/home/releases/unreleased/index.html @@ -1 +1 @@ - Unreleased - JSON for Modern C++

Unreleased

These changes are part of the develop branch, but not of a release yet.

  • Converting an rvalue container to JSON (json j = std::move(vec);, json j = std::map<std::string, std::string>{...};) now moves the elements instead of copying them (e.g., std::vector<std::string> with 100,000 strings: 4.7 ms to 2.3 ms). Two consequences: the source container is left in a valid but unspecified (moved-from) state, and if an exception is thrown during the conversion, the source may be partially moved-from, so the strong exception guarantee no longer holds for the source of an rvalue conversion (the JSON value itself is unaffected). Lvalues and const objects are still copied. See basic_json.

API changes

Added (88 pages):

Changed:

  • operator>>(basic_json): Fixed a null pointer dereference for an std::istream without a stream buffer (now throws parse_error.101), and a crash (std::terminate) when i has eofbit in its exception mask, in version 3.13.0 unreleased.
  • operator>>(basic_json): Changed to the strong exception safety guarantee in version 3.13.0 unreleased: j is no longer left with a partially parsed value if parsing throws.
  • operator>>(basic_json): Scans the characters in the stream buffer of i in bulk in version 3.13.0 unreleased; the position of i after the call is unchanged (JSON_DISABLE_STREAM_BULK_SCAN restores reading one character at a time).
  • operator""_json: Added char8_t* overload in version 3.13.0 unreleased.
  • operator""_json_pointer: Added char8_t* overload in version 3.13.0 unreleased.
  • ordered_map: Changed in version 3.13.0 unreleased: growing the storage moves the mapped values instead of copying them.
  • basic_json::accept: Added ignore_trailing_commas in version 3.13.0 unreleased.
  • basic_json::accept: Extended container support (1) to include types with lvalue-only ADL begin/end (matching std::begin/std::end semantics) in version 3.13.0 unreleased.
  • basic_json::accept: Extended overload (2) to accept heterogeneous iterator+sentinel pairs (C++20 ranges support) in version 3.13.0 unreleased.
  • basic_json::accept: Parsing from an std::istream scans the characters in its stream buffer in bulk in version 3.13.0 unreleased (JSON_DISABLE_STREAM_BULK_SCAN).
  • basic_json::accept: Parsing from a FILE* locks the file once instead of once per character in version 3.13.0 unreleased (JSON_DISABLE_UNLOCKED_FILE_IO).
  • basic_json::accept: Ill-formed UTF-16 and UTF-32 input (a lone surrogate, a high surrogate that is not followed by its low surrogate, or a code point above U+10FFFF) is rejected in version 3.13.0 unreleased; before that, some such sequences were accepted or ended the input silently.
  • basic_json::array_t: Made capacity() optional, so that array types such as std::deque can be used, in version 3.13.0 unreleased.
  • basic_json::at: Overload 3: Support for keys convertible to std::string_view added in version 3.13.0 unreleased, consistently across the lookup functions.
  • basic_json::basic_json: Overload 4: Explicit for different string types if JSON_USE_IMPLICIT_CONVERSIONS is 0 since version 3.13.0 unreleased.
  • basic_json::basic_json: Overload 7: Fixed in version 3.13.0 unreleased 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.
  • basic_json::binary_t: Fixed dump, std::hash, and to_ubjson for byte types that are not integers (e.g., std::byte) in version 3.13.0 unreleased.
  • basic_json::clear: Fixed in version 3.13.0 unreleased to also clear the subtype of a binary value; before, the subtype was left unchanged.
  • basic_json::contains: Overload 2: Support for keys convertible to std::string_view added in version 3.13.0 unreleased, consistently across the lookup functions.
  • basic_json::contains: Overload 4: Deleted overloads for integral key types added in version 3.13.0 unreleased to reject such calls at compile time instead of causing undefined behavior at runtime.
  • basic_json::count: Overload 2: Support for keys convertible to std::string_view added in version 3.13.0 unreleased, consistently across the lookup functions.
  • basic_json::count: Overload 3: Deleted overload for integral key types added in version 3.13.0 unreleased to reject such calls at compile time instead of causing undefined behavior at runtime.
  • basic_json::dump: Error handler keep added in version 3.13.0 unreleased.
  • basic_json::dump: Doubles are written with the shortest digits (Żmij instead of Grisu2) since version 3.13.0 unreleased; about 0.1% of doubles are written differently, most of them with fewer digits.
  • basic_json::emplace: Fixed in version 3.13.0 unreleased: for ordered_json, the value could previously only be passed as an rvalue; it can now also be passed as an lvalue or a const lvalue, matching the behavior of json.
  • basic_json::erase: Overload 4: Support for keys convertible to std::string_view added in version 3.13.0 unreleased, consistently across the lookup functions.
  • basic_json::error_handler_t: Added keep, and made this enumeration apply to the binary readers and writers in addition to dump, in version 3.13.0 unreleased.
  • basic_json::find: Overload 2: Support for keys convertible to std::string_view added in version 3.13.0 unreleased, consistently across the lookup functions.
  • basic_json::find: Overload 3: Deleted overloads for integral key types added in version 3.13.0 unreleased to reject such calls at compile time instead of causing undefined behavior at runtime.
  • basic_json::from_bjdata: Extended container support (1) to include types with lvalue-only ADL begin/end (matching std::begin/std::end semantics) in version 3.13.0 unreleased.
  • basic_json::from_bjdata: Extended overload (2) to accept heterogeneous iterator+sentinel pairs (C++20 ranges support) in version 3.13.0 unreleased.
  • basic_json::from_bjdata: Added error_handler parameter in version 3.13.0 unreleased.
  • basic_json::from_bson: Extended container support (1) to include types with lvalue-only ADL begin/end (matching std::begin/std::end semantics) in version 3.13.0 unreleased.
  • basic_json::from_bson: Extended overload (2) to accept heterogeneous iterator+sentinel pairs (C++20 ranges support) in version 3.13.0 unreleased.
  • basic_json::from_bson: Added error_handler parameter in version 3.13.0 unreleased.
  • basic_json::from_cbor: Extended container support (1) to include types with lvalue-only ADL begin/end (matching std::begin/std::end semantics) in version 3.13.0 unreleased.
  • basic_json::from_cbor: Extended overload (2) to accept heterogeneous iterator+sentinel pairs (C++20 ranges support) in version 3.13.0 unreleased.
  • basic_json::from_cbor: Added error_handler parameter in version 3.13.0 unreleased.
  • basic_json::from_msgpack: Extended container support (1) to include types with lvalue-only ADL begin/end (matching std::begin/std::end semantics) in version 3.13.0 unreleased.
  • basic_json::from_msgpack: Extended overload (2) to accept heterogeneous iterator+sentinel pairs (C++20 ranges support) in version 3.13.0 unreleased.
  • basic_json::from_msgpack: Added error_handler parameter in version 3.13.0 unreleased.
  • basic_json::from_ubjson: Extended container support (1) to include types with lvalue-only ADL begin/end (matching std::begin/std::end semantics) in version 3.13.0 unreleased.
  • basic_json::from_ubjson: Extended overload (2) to accept heterogeneous iterator+sentinel pairs (C++20 ranges support) in version 3.13.0 unreleased.
  • basic_json::from_ubjson: Added error_handler parameter in version 3.13.0 unreleased.
  • basic_json::get_to: Added a static_assert with a clear message for const arguments in version 3.13.0 unreleased.
  • basic_json::insert: Overload 4: Fixed in version 3.13.0 unreleased 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.
  • basic_json::json_base_class_t: Made a public member type in version 3.13.0 unreleased; it was private before, so it could not be named outside the class.
  • basic_json::merge_patch: Fixed use of freed or relocated memory when apply_patch is *this or refers to a value contained in *this, in version 3.13.0 unreleased.
  • basic_json::number_unsigned_t: Can be the same type as number_integer_t since version 3.13.0 unreleased.
  • basic_json::object_comparator_t: Fixed the fallback to default_object_comparator_t, which previously failed to compile for object types without a key_compare member type, in version 3.13.0 unreleased.
  • basic_json::object_t: Allowed object types whose erase(iterator) returns void in version 3.13.0 unreleased.
  • basic_json::operator[]: Overload 1: Fixed in version 3.13.0 unreleased to throw std::length_error instead of emptying the array and accessing it out of bounds when idx equals the maximum value of size_type.
  • basic_json::operator[]: Overload 1: A missing index in the const version is guarded by a runtime assertion since version 3.13.0 unreleased.
  • basic_json::operator[]: Overload 3: Support for keys convertible to std::string_view added in version 3.13.0 unreleased, consistently across the lookup functions.
  • basic_json::operator[]: Overload 4: A missing array index in the const version is guarded by a runtime assertion since version 3.13.0 unreleased.
  • basic_json::operator==: Overload 2: Made conditionally noexcept in version 3.13.0 unreleased; before, a throwing conversion called std::terminate.
  • basic_json::operator>=: Overload 2: Made conditionally noexcept in version 3.13.0 unreleased; before, a throwing conversion called std::terminate.
  • basic_json::operator>: Overload 2: Made conditionally noexcept in version 3.13.0 unreleased; before, a throwing conversion called std::terminate.
  • basic_json::operator<=: Overload 2: Made conditionally noexcept in version 3.13.0 unreleased; before, a throwing conversion called std::terminate.
  • basic_json::operator<: Overload 2: Made conditionally noexcept in version 3.13.0 unreleased; before, a throwing conversion called std::terminate.
  • basic_json::operator!=: Overload 1: Changed in version 3.13.0 unreleased to remove special-casing for NaN and discarded values; operator!= now consistently means !(a == b).
  • basic_json::operator!=: Overload 1: Removed the C++20 member function in version 3.13.0 unreleased; since C++20, the compiler rewrites a != b using operator==.
  • basic_json::operator!=: Overload 2: Changed in version 3.13.0 unreleased to remove special-casing for NaN and discarded values; operator!= now consistently means !(a == b).
  • basic_json::operator!=: Overload 2: Made conditionally noexcept in version 3.13.0 unreleased; before, a throwing conversion called std::terminate.
  • basic_json::operator<=>: Overload 2: Made conditionally noexcept in version 3.13.0 unreleased; before, a throwing conversion called std::terminate.
  • basic_json::parse: Added ignore_trailing_commas in version 3.13.0 unreleased.
  • basic_json::parse: Extended container support (1) to include types with lvalue-only ADL begin/end (matching std::begin/std::end semantics) in version 3.13.0 unreleased.
  • basic_json::parse: Extended overload (2) to accept heterogeneous iterator+sentinel pairs (C++20 ranges support) in version 3.13.0 unreleased.
  • basic_json::parse: 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 unreleased.
  • basic_json::parse: Parsing from an std::istream scans the characters in its stream buffer in bulk in version 3.13.0 unreleased (JSON_DISABLE_STREAM_BULK_SCAN restores reading one character at a time).
  • basic_json::parse: Parsing from a FILE* locks the file once instead of once per character in version 3.13.0 unreleased (JSON_DISABLE_UNLOCKED_FILE_IO restores std::fgetc).
  • basic_json::parse: Ill-formed UTF-16 and UTF-32 input (a lone surrogate, a high surrogate that is not followed by its low surrogate, or a code point above U+10FFFF) is rejected with parse_error.101 in version 3.13.0 unreleased; before that, some such sequences were accepted or ended the input silently.
  • basic_json::parser_callback_t: Fixed in version 3.13.0 unreleased 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.
  • basic_json::parser_callback_t: Fixed in version 3.13.0 unreleased 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.
  • basic_json::patch: Added out_of_range.411 and stopped relying on an internal assertion when an "add" operation's target location has a non-object/non-array parent in version 3.13.0 unreleased.
  • basic_json::patch: This includes a null parent, which was previously silently converted to an object, in version 3.13.0 unreleased.
  • basic_json::patch: Added out_of_range.413 and stopped silently ignoring a "remove" operation whose target location has a non-object/non-array parent in version 3.13.0 unreleased.
  • basic_json::patch: Added out_of_range.414 and rejected a "move" operation whose "from" location is a proper prefix of its "path" location instead of silently producing a corrupted result in version 3.13.0 unreleased.
  • basic_json::patch: Throws parse_error.109 instead of out_of_range.404 for a one-character array index that is not a digit (e.g., /x) in version 3.13.0 unreleased, as it already did for longer ones.
  • basic_json::patch_inplace: Added out_of_range.411 and stopped relying on an internal assertion when an "add" operation's target location has a non-object/non-array parent in version 3.13.0 unreleased.
  • basic_json::patch_inplace: This includes a null parent, which was previously silently converted to an object, in version 3.13.0 unreleased.
  • basic_json::patch_inplace: Added out_of_range.413 and stopped silently ignoring a "remove" operation whose target location has a non-object/non-array parent in version 3.13.0 unreleased.
  • basic_json::patch_inplace: Added out_of_range.414 and rejected a "move" operation whose "from" location is a proper prefix of its "path" location instead of silently producing a corrupted result in version 3.13.0 unreleased.
  • basic_json::patch_inplace: Throws parse_error.109 instead of out_of_range.404 for a one-character array index that is not a digit (e.g., /x) in version 3.13.0 unreleased, as it already did for longer ones.
  • basic_json::sax_parse: Added ignore_trailing_commas in version 3.13.0 unreleased.
  • basic_json::sax_parse: Added tag_handler in version 3.13.0 unreleased.
  • basic_json::sax_parse: Extended container support (1) to include types with lvalue-only ADL begin/end (matching std::begin/std::end semantics) in version 3.13.0 unreleased.
  • basic_json::sax_parse: Extended overload (2) to accept heterogeneous iterator+sentinel pairs (C++20 ranges support) in version 3.13.0 unreleased.
  • basic_json::sax_parse: JSON_PRECISE_STREAM_POSITION added in version 3.13.0 unreleased to optionally leave a std::istream positioned right after the parsed value when strict is false.
  • basic_json::sax_parse: Parsing from an std::istream scans the characters in its stream buffer in bulk in version 3.13.0 unreleased (JSON_DISABLE_STREAM_BULK_SCAN).
  • basic_json::sax_parse: Parsing from a FILE* locks the file once instead of once per character in version 3.13.0 unreleased (JSON_DISABLE_UNLOCKED_FILE_IO).
  • basic_json::sax_parse: Ill-formed UTF-16 and UTF-32 input (a lone surrogate, a high surrogate that is not followed by its low surrogate, or a code point above U+10FFFF) is rejected with parse_error.101 in version 3.13.0 unreleased; before that, some such sequences were accepted or ended the input silently.
  • std::hash<nlohmann::basic_json>: Numbers that compare equal hash equally since version 3.13.0 unreleased; before, 0, 0U, and 0.0 had different hash values.
  • basic_json::string_t: Removed the requirement that string_t be implicitly convertible from std::string, which the BSON writer and the UBJSON reader relied on, in version 3.13.0 unreleased.
  • basic_json::swap: Overload 1: Exchanges the json_base_class_t subobject along with the value since version 3.13.0 unreleased.
  • basic_json::swap: Overload 2: Exchanges the json_base_class_t subobject along with the value since version 3.13.0 unreleased.
  • basic_json::to_bjdata: Added error_handler parameter in version 3.13.0 unreleased.
  • basic_json::to_bjdata: Throws type_error.321 for a discarded value since version 3.13.0 unreleased; previously, a discarded value nested in an array or object was silently skipped, producing invalid BJData.
  • basic_json::to_bson: Throws out_of_range.412 and out_of_range.415 since version 3.13.0 unreleased.
  • basic_json::to_bson: Linear in the size of j, and no longer limited by the call stack for deeply nested values, since version 3.13.0 unreleased.
  • basic_json::to_bson: out_of_range.415 is now detected before anything is written, like the other exceptions above, since version 3.13.0 unreleased.
  • basic_json::to_bson: Throws type_error.321 for a discarded value nested in j since version 3.13.0 unreleased; previously, it was silently skipped, producing a document whose declared size did not match what was actually written.
  • basic_json::to_bson: Added error_handler parameter in version 3.13.0 unreleased.
  • basic_json::to_bson: Throws out_of_range.407 for integers that do not fit 64 bits since version 3.13.0 unreleased; previously, integers of a number type wider than 64 bits were silently truncated.
  • basic_json::to_cbor: Added error_handler parameter in version 3.13.0 unreleased.
  • basic_json::to_cbor: Throws type_error.321 for a discarded value since version 3.13.0 unreleased; previously, a discarded value nested in an array or object was silently skipped, producing invalid CBOR.
  • basic_json::to_cbor: Throws out_of_range.407 for integers that do not fit 64 bits since version 3.13.0 unreleased; previously, integers of a number type wider than 64 bits were silently truncated.
  • basic_json::to_msgpack: Throws out_of_range.412 and out_of_range.415 since version 3.13.0 unreleased.
  • basic_json::to_msgpack: Added error_handler parameter in version 3.13.0 unreleased.
  • basic_json::to_msgpack: Fixed in version 3.13.0 unreleased 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.
  • basic_json::to_msgpack: Throws type_error.321 for a discarded value since version 3.13.0 unreleased; previously, a discarded value nested in an array or object was silently skipped, producing invalid MessagePack.
  • basic_json::to_msgpack: Throws out_of_range.407 for integers that do not fit 64 bits since version 3.13.0 unreleased; previously, integers of a number type wider than 64 bits were silently truncated.
  • basic_json::to_ubjson: Added error_handler parameter in version 3.13.0 unreleased.
  • basic_json::to_ubjson: Throws type_error.321 for a discarded value since version 3.13.0 unreleased; previously, a discarded value nested in an array or object was silently skipped, producing invalid UBJSON.
  • basic_json::type_name: Added "invalid" return value for corrupted JSON values in version 3.13.0 unreleased.
  • basic_json::unflatten: Made the array/object decision independent of the object's iteration order in version 3.13.0 unreleased.
  • basic_json::unflatten: Throws parse_error.109 instead of out_of_range.404 for a one-character array index that is not a digit (e.g., /x) in version 3.13.0 unreleased, as it already did for longer ones.
  • basic_json::update: Fixed use of freed or relocated memory when the argument is *this or refers to a value contained in *this, in version 3.13.0 unreleased.
  • basic_json::value: Overload 1: Deleted overload for integral key types added in version 3.13.0 unreleased to reject such calls at compile time instead of causing undefined behavior at runtime.
  • basic_json::value: Overload 2: Support for keys convertible to std::string_view added in version 3.13.0 unreleased, consistently across the lookup functions.
  • basic_json::value: Overload 3: Extended to work with arrays in version 3.13.0 unreleased.
  • basic_json::value: Overload 3: Throws parse_error.109 instead of returning default_value for a one-character array index that is not a digit (e.g., /x) in version 3.13.0 unreleased, as it already did for longer ones.
  • JSON_HAS_CPP_11, JSON_HAS_CPP_14, JSON_HAS_CPP_17, JSON_HAS_CPP_20, JSON_HAS_CPP_23, JSON_HAS_CPP_26: Added JSON_HAS_CPP_26 in version 3.13.0 unreleased.
  • JSON_HAS_RANGES: Added the exclusions for libstdc++ < 11, Clang < 16 with libstdc++, libc++ < 16, and nvcc (CUDA) 12.0.x and 12.1.x in version 3.13.0 unreleased.
  • JSON_USE_IMPLICIT_CONVERSIONS: Also affects the conversion between basic_json specializations with different string types since version 3.13.0 unreleased.
  • JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON: Fixed in version 3.13.0 unreleased so <= and >= also emulate the legacy behavior in C++20 when the JSON value is the right-hand operand of a scalar comparison; before, only the 3-way-comparison-rewritten candidate was found, which yielded false instead of true.
\ No newline at end of file + Unreleased - JSON for Modern C++

Unreleased

These changes are part of the develop branch, but not of a release yet.

  • Converting an rvalue container to JSON (json j = std::move(vec);, json j = std::map<std::string, std::string>{...};) now moves the elements instead of copying them (e.g., std::vector<std::string> with 100,000 strings: 4.7 ms to 2.3 ms). Two consequences: the source container is left in a valid but unspecified (moved-from) state, and if an exception is thrown during the conversion, the source may be partially moved-from, so the strong exception guarantee no longer holds for the source of an rvalue conversion (the JSON value itself is unaffected). Lvalues and const objects are still copied. See basic_json.

API changes

Added (88 pages):

Changed:

  • operator>>(basic_json): Fixed a null pointer dereference for an std::istream without a stream buffer (now throws parse_error.101), and a crash (std::terminate) when i has eofbit in its exception mask, in version 3.13.0 unreleased.
  • operator>>(basic_json): Changed to the strong exception safety guarantee in version 3.13.0 unreleased: j is no longer left with a partially parsed value if parsing throws.
  • operator>>(basic_json): Scans the characters in the stream buffer of i in bulk in version 3.13.0 unreleased; the position of i after the call is unchanged (JSON_DISABLE_STREAM_BULK_SCAN restores reading one character at a time).
  • operator""_json: Added char8_t* overload in version 3.13.0 unreleased.
  • operator""_json_pointer: Added char8_t* overload in version 3.13.0 unreleased.
  • ordered_map: Changed in version 3.13.0 unreleased: growing the storage moves the mapped values instead of copying them.
  • basic_json::accept: Added ignore_trailing_commas in version 3.13.0 unreleased.
  • basic_json::accept: Extended container support (1) to include types with lvalue-only ADL begin/end (matching std::begin/std::end semantics) in version 3.13.0 unreleased.
  • basic_json::accept: Extended overload (2) to accept heterogeneous iterator+sentinel pairs (C++20 ranges support) in version 3.13.0 unreleased.
  • basic_json::accept: Parsing from an std::istream scans the characters in its stream buffer in bulk in version 3.13.0 unreleased (JSON_DISABLE_STREAM_BULK_SCAN).
  • basic_json::accept: Parsing from a FILE* locks the file once instead of once per character in version 3.13.0 unreleased (JSON_DISABLE_UNLOCKED_FILE_IO).
  • basic_json::accept: Ill-formed UTF-16 and UTF-32 input (a lone surrogate, a high surrogate that is not followed by its low surrogate, or a code point above U+10FFFF) is rejected in version 3.13.0 unreleased; before that, some such sequences were accepted or ended the input silently.
  • basic_json::array_t: Made capacity() optional, so that array types such as std::deque can be used, in version 3.13.0 unreleased.
  • basic_json::at: Overload 3: Support for keys convertible to std::string_view added in version 3.13.0 unreleased, consistently across the lookup functions.
  • basic_json::basic_json: Overload 4: Explicit for different string types if JSON_USE_IMPLICIT_CONVERSIONS is 0 since version 3.13.0 unreleased.
  • basic_json::basic_json: Overload 7: Fixed in version 3.13.0 unreleased 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.
  • basic_json::binary_t: Fixed dump, std::hash, and to_ubjson for byte types that are not integers (e.g., std::byte) in version 3.13.0 unreleased.
  • basic_json::clear: Fixed in version 3.13.0 unreleased to also clear the subtype of a binary value; before, the subtype was left unchanged.
  • basic_json::contains: Overload 2: Support for keys convertible to std::string_view added in version 3.13.0 unreleased, consistently across the lookup functions.
  • basic_json::contains: Overload 4: Deleted overloads for integral key types added in version 3.13.0 unreleased to reject such calls at compile time instead of causing undefined behavior at runtime.
  • basic_json::count: Overload 2: Support for keys convertible to std::string_view added in version 3.13.0 unreleased, consistently across the lookup functions.
  • basic_json::count: Overload 3: Deleted overload for integral key types added in version 3.13.0 unreleased to reject such calls at compile time instead of causing undefined behavior at runtime.
  • basic_json::dump: Error handler keep added in version 3.13.0 unreleased.
  • basic_json::dump: Doubles are written with the shortest digits (Żmij instead of Grisu2) since version 3.13.0 unreleased; about 0.1% of doubles are written differently, most of them with fewer digits.
  • basic_json::emplace: Fixed in version 3.13.0 unreleased: for ordered_json, the value could previously only be passed as an rvalue; it can now also be passed as an lvalue or a const lvalue, matching the behavior of json.
  • basic_json::erase: Overload 4: Support for keys convertible to std::string_view added in version 3.13.0 unreleased, consistently across the lookup functions.
  • basic_json::error_handler_t: Added keep, and made this enumeration apply to the binary readers and writers in addition to dump, in version 3.13.0 unreleased.
  • basic_json::find: Overload 2: Support for keys convertible to std::string_view added in version 3.13.0 unreleased, consistently across the lookup functions.
  • basic_json::find: Overload 3: Deleted overloads for integral key types added in version 3.13.0 unreleased to reject such calls at compile time instead of causing undefined behavior at runtime.
  • basic_json::from_bjdata: Extended container support (1) to include types with lvalue-only ADL begin/end (matching std::begin/std::end semantics) in version 3.13.0 unreleased.
  • basic_json::from_bjdata: Extended overload (2) to accept heterogeneous iterator+sentinel pairs (C++20 ranges support) in version 3.13.0 unreleased.
  • basic_json::from_bjdata: Added error_handler parameter in version 3.13.0 unreleased.
  • basic_json::from_bson: Extended container support (1) to include types with lvalue-only ADL begin/end (matching std::begin/std::end semantics) in version 3.13.0 unreleased.
  • basic_json::from_bson: Extended overload (2) to accept heterogeneous iterator+sentinel pairs (C++20 ranges support) in version 3.13.0 unreleased.
  • basic_json::from_bson: Added error_handler parameter in version 3.13.0 unreleased.
  • basic_json::from_cbor: Extended container support (1) to include types with lvalue-only ADL begin/end (matching std::begin/std::end semantics) in version 3.13.0 unreleased.
  • basic_json::from_cbor: Extended overload (2) to accept heterogeneous iterator+sentinel pairs (C++20 ranges support) in version 3.13.0 unreleased.
  • basic_json::from_cbor: Added error_handler parameter in version 3.13.0 unreleased.
  • basic_json::from_msgpack: Extended container support (1) to include types with lvalue-only ADL begin/end (matching std::begin/std::end semantics) in version 3.13.0 unreleased.
  • basic_json::from_msgpack: Extended overload (2) to accept heterogeneous iterator+sentinel pairs (C++20 ranges support) in version 3.13.0 unreleased.
  • basic_json::from_msgpack: Added error_handler parameter in version 3.13.0 unreleased.
  • basic_json::from_ubjson: Extended container support (1) to include types with lvalue-only ADL begin/end (matching std::begin/std::end semantics) in version 3.13.0 unreleased.
  • basic_json::from_ubjson: Extended overload (2) to accept heterogeneous iterator+sentinel pairs (C++20 ranges support) in version 3.13.0 unreleased.
  • basic_json::from_ubjson: Added error_handler parameter in version 3.13.0 unreleased.
  • basic_json::get_to: Added a static_assert with a clear message for const arguments in version 3.13.0 unreleased.
  • basic_json::insert: Overload 4: Fixed in version 3.13.0 unreleased 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.
  • basic_json::json_base_class_t: Made a public member type in version 3.13.0 unreleased; it was private before, so it could not be named outside the class.
  • basic_json::merge_patch: Fixed use of freed or relocated memory when apply_patch is *this or refers to a value contained in *this, in version 3.13.0 unreleased.
  • basic_json::number_unsigned_t: Can be the same type as number_integer_t since version 3.13.0 unreleased.
  • basic_json::object_comparator_t: Fixed the fallback to default_object_comparator_t, which previously failed to compile for object types without a key_compare member type, in version 3.13.0 unreleased.
  • basic_json::object_t: Allowed object types whose erase(iterator) returns void in version 3.13.0 unreleased.
  • basic_json::operator[]: Overload 1: Fixed in version 3.13.0 unreleased to throw std::length_error instead of emptying the array and accessing it out of bounds when idx equals the maximum value of size_type.
  • basic_json::operator[]: Overload 1: A missing index in the const version is guarded by a runtime assertion since version 3.13.0 unreleased.
  • basic_json::operator[]: Overload 3: Support for keys convertible to std::string_view added in version 3.13.0 unreleased, consistently across the lookup functions.
  • basic_json::operator[]: Overload 4: A missing array index in the const version is guarded by a runtime assertion since version 3.13.0 unreleased.
  • basic_json::operator==: Overload 2: Made conditionally noexcept in version 3.13.0 unreleased; before, a throwing conversion called std::terminate.
  • basic_json::operator>=: Overload 2: Made conditionally noexcept in version 3.13.0 unreleased; before, a throwing conversion called std::terminate.
  • basic_json::operator>: Overload 2: Made conditionally noexcept in version 3.13.0 unreleased; before, a throwing conversion called std::terminate.
  • basic_json::operator<=: Overload 2: Made conditionally noexcept in version 3.13.0 unreleased; before, a throwing conversion called std::terminate.
  • basic_json::operator<: Overload 2: Made conditionally noexcept in version 3.13.0 unreleased; before, a throwing conversion called std::terminate.
  • basic_json::operator!=: Overload 1: Changed in version 3.13.0 unreleased to remove special-casing for NaN and discarded values; operator!= now consistently means !(a == b).
  • basic_json::operator!=: Overload 1: Removed the C++20 member function in version 3.13.0 unreleased; since C++20, the compiler rewrites a != b using operator==.
  • basic_json::operator!=: Overload 2: Changed in version 3.13.0 unreleased to remove special-casing for NaN and discarded values; operator!= now consistently means !(a == b).
  • basic_json::operator!=: Overload 2: Made conditionally noexcept in version 3.13.0 unreleased; before, a throwing conversion called std::terminate.
  • basic_json::operator<=>: Overload 2: Made conditionally noexcept in version 3.13.0 unreleased; before, a throwing conversion called std::terminate.
  • basic_json::parse: Added ignore_trailing_commas in version 3.13.0 unreleased.
  • basic_json::parse: Extended container support (1) to include types with lvalue-only ADL begin/end (matching std::begin/std::end semantics) in version 3.13.0 unreleased.
  • basic_json::parse: Extended overload (2) to accept heterogeneous iterator+sentinel pairs (C++20 ranges support) in version 3.13.0 unreleased.
  • basic_json::parse: 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 unreleased.
  • basic_json::parse: Parsing from an std::istream scans the characters in its stream buffer in bulk in version 3.13.0 unreleased (JSON_DISABLE_STREAM_BULK_SCAN restores reading one character at a time).
  • basic_json::parse: Parsing from a FILE* locks the file once instead of once per character in version 3.13.0 unreleased (JSON_DISABLE_UNLOCKED_FILE_IO restores std::fgetc).
  • basic_json::parse: Ill-formed UTF-16 and UTF-32 input (a lone surrogate, a high surrogate that is not followed by its low surrogate, or a code point above U+10FFFF) is rejected with parse_error.101 in version 3.13.0 unreleased; before that, some such sequences were accepted or ended the input silently.
  • basic_json::parser_callback_t: Fixed in version 3.13.0 unreleased 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.
  • basic_json::parser_callback_t: Fixed in version 3.13.0 unreleased 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.
  • basic_json::patch: Added out_of_range.411 and stopped relying on an internal assertion when an "add" operation's target location has a non-object/non-array parent in version 3.13.0 unreleased.
  • basic_json::patch: This includes a null parent, which was previously silently converted to an object, in version 3.13.0 unreleased.
  • basic_json::patch: Added out_of_range.413 and stopped silently ignoring a "remove" operation whose target location has a non-object/non-array parent in version 3.13.0 unreleased.
  • basic_json::patch: Added out_of_range.414 and rejected a "move" operation whose "from" location is a proper prefix of its "path" location instead of silently producing a corrupted result in version 3.13.0 unreleased.
  • basic_json::patch: Throws parse_error.109 instead of out_of_range.404 for a one-character array index that is not a digit (e.g., /x) in version 3.13.0 unreleased, as it already did for longer ones.
  • basic_json::patch_inplace: Added out_of_range.411 and stopped relying on an internal assertion when an "add" operation's target location has a non-object/non-array parent in version 3.13.0 unreleased.
  • basic_json::patch_inplace: This includes a null parent, which was previously silently converted to an object, in version 3.13.0 unreleased.
  • basic_json::patch_inplace: Added out_of_range.413 and stopped silently ignoring a "remove" operation whose target location has a non-object/non-array parent in version 3.13.0 unreleased.
  • basic_json::patch_inplace: Added out_of_range.414 and rejected a "move" operation whose "from" location is a proper prefix of its "path" location instead of silently producing a corrupted result in version 3.13.0 unreleased.
  • basic_json::patch_inplace: Throws parse_error.109 instead of out_of_range.404 for a one-character array index that is not a digit (e.g., /x) in version 3.13.0 unreleased, as it already did for longer ones.
  • basic_json::patch_inplace: Applying a JSON value as patch to itself (or, with JSON_DIAGNOSTICS, to a value stored inside it) no longer results in undefined behavior in version 3.13.0 unreleased.
  • basic_json::sax_parse: Added ignore_trailing_commas in version 3.13.0 unreleased.
  • basic_json::sax_parse: Added tag_handler in version 3.13.0 unreleased.
  • basic_json::sax_parse: Extended container support (1) to include types with lvalue-only ADL begin/end (matching std::begin/std::end semantics) in version 3.13.0 unreleased.
  • basic_json::sax_parse: Extended overload (2) to accept heterogeneous iterator+sentinel pairs (C++20 ranges support) in version 3.13.0 unreleased.
  • basic_json::sax_parse: JSON_PRECISE_STREAM_POSITION added in version 3.13.0 unreleased to optionally leave a std::istream positioned right after the parsed value when strict is false.
  • basic_json::sax_parse: Parsing from an std::istream scans the characters in its stream buffer in bulk in version 3.13.0 unreleased (JSON_DISABLE_STREAM_BULK_SCAN).
  • basic_json::sax_parse: Parsing from a FILE* locks the file once instead of once per character in version 3.13.0 unreleased (JSON_DISABLE_UNLOCKED_FILE_IO).
  • basic_json::sax_parse: Ill-formed UTF-16 and UTF-32 input (a lone surrogate, a high surrogate that is not followed by its low surrogate, or a code point above U+10FFFF) is rejected with parse_error.101 in version 3.13.0 unreleased; before that, some such sequences were accepted or ended the input silently.
  • std::hash<nlohmann::basic_json>: Numbers that compare equal hash equally since version 3.13.0 unreleased; before, 0, 0U, and 0.0 had different hash values.
  • basic_json::string_t: Removed the requirement that string_t be implicitly convertible from std::string, which the BSON writer and the UBJSON reader relied on, in version 3.13.0 unreleased.
  • basic_json::swap: Overload 1: Exchanges the json_base_class_t subobject along with the value since version 3.13.0 unreleased.
  • basic_json::swap: Overload 2: Exchanges the json_base_class_t subobject along with the value since version 3.13.0 unreleased.
  • basic_json::to_bjdata: Added error_handler parameter in version 3.13.0 unreleased.
  • basic_json::to_bjdata: Throws type_error.321 for a discarded value since version 3.13.0 unreleased; previously, a discarded value nested in an array or object was silently skipped, producing invalid BJData.
  • basic_json::to_bson: Throws out_of_range.412 and out_of_range.415 since version 3.13.0 unreleased.
  • basic_json::to_bson: Linear in the size of j, and no longer limited by the call stack for deeply nested values, since version 3.13.0 unreleased.
  • basic_json::to_bson: out_of_range.415 is now detected before anything is written, like the other exceptions above, since version 3.13.0 unreleased.
  • basic_json::to_bson: Throws type_error.321 for a discarded value nested in j since version 3.13.0 unreleased; previously, it was silently skipped, producing a document whose declared size did not match what was actually written.
  • basic_json::to_bson: Added error_handler parameter in version 3.13.0 unreleased.
  • basic_json::to_bson: Throws out_of_range.407 for integers that do not fit 64 bits since version 3.13.0 unreleased; previously, integers of a number type wider than 64 bits were silently truncated.
  • basic_json::to_cbor: Added error_handler parameter in version 3.13.0 unreleased.
  • basic_json::to_cbor: Throws type_error.321 for a discarded value since version 3.13.0 unreleased; previously, a discarded value nested in an array or object was silently skipped, producing invalid CBOR.
  • basic_json::to_cbor: Throws out_of_range.407 for integers that do not fit 64 bits since version 3.13.0 unreleased; previously, integers of a number type wider than 64 bits were silently truncated.
  • basic_json::to_msgpack: Throws out_of_range.412 and out_of_range.415 since version 3.13.0 unreleased.
  • basic_json::to_msgpack: Added error_handler parameter in version 3.13.0 unreleased.
  • basic_json::to_msgpack: Fixed in version 3.13.0 unreleased 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.
  • basic_json::to_msgpack: Throws type_error.321 for a discarded value since version 3.13.0 unreleased; previously, a discarded value nested in an array or object was silently skipped, producing invalid MessagePack.
  • basic_json::to_msgpack: Throws out_of_range.407 for integers that do not fit 64 bits since version 3.13.0 unreleased; previously, integers of a number type wider than 64 bits were silently truncated.
  • basic_json::to_ubjson: Added error_handler parameter in version 3.13.0 unreleased.
  • basic_json::to_ubjson: Throws type_error.321 for a discarded value since version 3.13.0 unreleased; previously, a discarded value nested in an array or object was silently skipped, producing invalid UBJSON.
  • basic_json::type_name: Added "invalid" return value for corrupted JSON values in version 3.13.0 unreleased.
  • basic_json::unflatten: Made the array/object decision independent of the object's iteration order in version 3.13.0 unreleased.
  • basic_json::unflatten: Throws parse_error.109 instead of out_of_range.404 for a one-character array index that is not a digit (e.g., /x) in version 3.13.0 unreleased, as it already did for longer ones.
  • basic_json::update: Fixed use of freed or relocated memory when the argument is *this or refers to a value contained in *this, in version 3.13.0 unreleased.
  • basic_json::value: Overload 1: Deleted overload for integral key types added in version 3.13.0 unreleased to reject such calls at compile time instead of causing undefined behavior at runtime.
  • basic_json::value: Overload 2: Support for keys convertible to std::string_view added in version 3.13.0 unreleased, consistently across the lookup functions.
  • basic_json::value: Overload 3: Extended to work with arrays in version 3.13.0 unreleased.
  • basic_json::value: Overload 3: Throws parse_error.109 instead of returning default_value for a one-character array index that is not a digit (e.g., /x) in version 3.13.0 unreleased, as it already did for longer ones.
  • json_pointer::operator/=: Overload 1: Appending a JSON pointer to itself no longer results in undefined behavior in version 3.13.0 unreleased.
  • JSON_HAS_CPP_11, JSON_HAS_CPP_14, JSON_HAS_CPP_17, JSON_HAS_CPP_20, JSON_HAS_CPP_23, JSON_HAS_CPP_26: Added JSON_HAS_CPP_26 in version 3.13.0 unreleased.
  • JSON_HAS_RANGES: Added the exclusions for libstdc++ < 11, Clang < 16 with libstdc++, libc++ < 16, and nvcc (CUDA) 12.0.x and 12.1.x in version 3.13.0 unreleased.
  • JSON_USE_IMPLICIT_CONVERSIONS: Also affects the conversion between basic_json specializations with different string types since version 3.13.0 unreleased.
  • JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON: Fixed in version 3.13.0 unreleased so <= and >= also emulate the legacy behavior in C++20 when the JSON value is the right-hand operand of a scalar comparison; before, only the 3-way-comparison-rewritten candidate was found, which yielded false instead of true.
\ No newline at end of file diff --git a/home/releases/unreleased/index.md b/home/releases/unreleased/index.md index dbfa6a436..5e658ef8a 100644 --- a/home/releases/unreleased/index.md +++ b/home/releases/unreleased/index.md @@ -100,6 +100,7 @@ These changes are part of the `develop` branch, but not of a release yet. - [`basic_json::patch_inplace`](https://json.nlohmann.me/api/basic_json/patch_inplace/index.md): Added [`out_of_range.413`](https://json.nlohmann.me/home/exceptions/#jsonexceptionout_of_range413) and stopped silently ignoring a "remove" operation whose target location has a non-object/non-array parent in version 3.13.0 unreleased. - [`basic_json::patch_inplace`](https://json.nlohmann.me/api/basic_json/patch_inplace/index.md): Added [`out_of_range.414`](https://json.nlohmann.me/home/exceptions/#jsonexceptionout_of_range414) and rejected a "move" operation whose "from" location is a proper prefix of its "path" location instead of silently producing a corrupted result in version 3.13.0 unreleased. - [`basic_json::patch_inplace`](https://json.nlohmann.me/api/basic_json/patch_inplace/index.md): Throws [`parse_error.109`](https://json.nlohmann.me/home/exceptions/#jsonexceptionparse_error109) instead of [`out_of_range.404`](https://json.nlohmann.me/home/exceptions/#jsonexceptionout_of_range404) for a one-character array index that is not a digit (e.g., `/x`) in version 3.13.0 unreleased, as it already did for longer ones. +- [`basic_json::patch_inplace`](https://json.nlohmann.me/api/basic_json/patch_inplace/index.md): Applying a JSON value as patch to itself (or, with `JSON_DIAGNOSTICS`, to a value stored inside it) no longer results in undefined behavior in version 3.13.0 unreleased. - [`basic_json::sax_parse`](https://json.nlohmann.me/api/basic_json/sax_parse/index.md): Added `ignore_trailing_commas` in version 3.13.0 unreleased. - [`basic_json::sax_parse`](https://json.nlohmann.me/api/basic_json/sax_parse/index.md): Added `tag_handler` in version 3.13.0 unreleased. - [`basic_json::sax_parse`](https://json.nlohmann.me/api/basic_json/sax_parse/index.md): Extended container support (1) to include types with lvalue-only ADL `begin`/`end` (matching `std::begin`/`std::end` semantics) in version 3.13.0 unreleased. @@ -138,6 +139,7 @@ These changes are part of the `develop` branch, but not of a release yet. - [`basic_json::value`](https://json.nlohmann.me/api/basic_json/value/index.md): Overload 2: Support for keys convertible to `std::string_view` added in version 3.13.0 unreleased, consistently across the lookup functions. - [`basic_json::value`](https://json.nlohmann.me/api/basic_json/value/index.md): Overload 3: Extended to work with arrays in version 3.13.0 unreleased. - [`basic_json::value`](https://json.nlohmann.me/api/basic_json/value/index.md): Overload 3: Throws [`parse_error.109`](https://json.nlohmann.me/home/exceptions/#jsonexceptionparse_error109) instead of returning `default_value` for a one-character array index that is not a digit (e.g., `/x`) in version 3.13.0 unreleased, as it already did for longer ones. +- [`json_pointer::operator/=`](https://json.nlohmann.me/api/json_pointer/operator_slasheq/index.md): Overload 1: Appending a JSON pointer to itself no longer results in undefined behavior in version 3.13.0 unreleased. - [`JSON_HAS_CPP_11, JSON_HAS_CPP_14, JSON_HAS_CPP_17, JSON_HAS_CPP_20, JSON_HAS_CPP_23, JSON_HAS_CPP_26`](https://json.nlohmann.me/api/macros/json_has_cpp_11/index.md): Added `JSON_HAS_CPP_26` in version 3.13.0 unreleased. - [`JSON_HAS_RANGES`](https://json.nlohmann.me/api/macros/json_has_ranges/index.md): Added the exclusions for libstdc++ < 11, Clang < 16 with libstdc++, libc++ < 16, and nvcc (CUDA) 12.0.x and 12.1.x in version 3.13.0 unreleased. - [`JSON_USE_IMPLICIT_CONVERSIONS`](https://json.nlohmann.me/api/macros/json_use_implicit_conversions/index.md): Also affects the conversion between `basic_json` specializations with different string types since version 3.13.0 unreleased. diff --git a/search/search_index.json b/search/search_index.json index 82261228d..4295769b9 100644 --- a/search/search_index.json +++ b/search/search_index.json @@ -1 +1 @@ -{"config":{"lang":["en"],"separator":"[\\s\\-\\.]","pipeline":["stopWordFilter"],"fields":{"title":{"boost":1000.0},"text":{"boost":1.0},"tags":{"boost":1000000.0}}},"docs":[{"location":"","title":"JSON for Modern C++","text":"
  • Features

    Creating, parsing, accessing, and serializing JSON values, converting your own C++ types, JSON Pointer/Patch/Merge Patch, binary formats, zero-copy views, and more.

    Features

  • Integration

    Add the library to your project via a single header, CMake, a package manager, or pkg-config.

    Integration

  • API documentation

    The complete reference for basic_json and its member functions, types, and related classes, as well as for json_document and json_view.

    API documentation

  • FAQ

    Answers to common questions and known surprises when using the library.

    FAQ

  • Releases

    What changed in each release, with links to the relevant documentation.

    Releases

  • Community

    The ecosystem, contribution guidelines, governance, and quality assurance around the project.

    Community

"},{"location":"api/is_json_view/","title":"nlohmann::is_json_view","text":"

Defined in header <nlohmann/json_view.hpp>

template<typename T>\nstruct is_json_view;\n

A type trait: is_json_view<T>::value is true if T is a basic_json_view of any BasicJsonType and any view_mode -- json_view, json_editable_view, ordered_json_view, ... -- and false otherwise, for basic_json as well.

It is meant for constraining templates that accept views, in particular a from_json() that should read views directly: get<T>() on a view calls a from_json() with the view only if that from_json() accepts views but not arbitrary types.

"},{"location":"api/is_json_view/#template-parameters","title":"Template parameters","text":"T the type to check (without cv-qualifiers or references)"},{"location":"api/is_json_view/#notes","title":"Notes","text":"

A view is recognized by its member type basic_json_type (a basic_json specialization) and its materialize() returning that type, so the trait needs no declaration of the view class.

"},{"location":"api/is_json_view/#examples","title":"Examples","text":"Example

The example below shows the trait, and a from_json() constrained to json values and views: get<T>() on a view reads the view directly.

#include <iostream>\n#include <type_traits>\n#include <nlohmann/json_view.hpp>\n\nusing nlohmann::json;\n\nnamespace ns\n{\nstruct person\n{\n    std::string name;\n    int age = 0;\n};\n\n// reads json values and views (of any document type), but nothing else\ntemplate < typename J, typename std::enable_if < nlohmann::is_json_view<J>::value || std::is_same<J, json>::value, int >::type = 0 >\nvoid from_json(const J& j, person& p)\n{\n    p.name = j.at(\"name\").template get<std::string>();\n    p.age = j.at(\"age\").template get<int>();\n}\n} // namespace ns\n\nint main()\n{\n    std::cout << std::boolalpha\n              << nlohmann::is_json_view<nlohmann::json_view>::value << ' '\n              << nlohmann::is_json_view<nlohmann::ordered_json_editable_view>::value << ' '\n              << nlohmann::is_json_view<json>::value << '\\n';\n\n    const nlohmann::json_document doc = nlohmann::json_document::parse(R\"({\"name\": \"Ada\", \"age\": 36})\");\n    const auto p = doc.root().get<ns::person>(); // reads the view, no json value is built\n    std::cout << p.name << ' ' << p.age << '\\n';\n}\n

Output:

true true false\nAda 36\n
"},{"location":"api/is_json_view/#see-also","title":"See also","text":"
  • basic_json_view - a handle to one value of a document
  • get - which conversions read the view directly
  • view_mode - read-only or editable
  • Writing generic code - functions and from_json() for views
"},{"location":"api/is_json_view/#version-history","title":"Version history","text":"

Added in version 3.13.0 unreleased.

"},{"location":"api/json/","title":"nlohmann::json","text":"
using json = basic_json<>;\n

This type is the default specialization of the basic_json class which uses the standard template types.

"},{"location":"api/json/#examples","title":"Examples","text":"Example

The example below demonstrates how to use the type nlohmann::json.

#include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create a JSON object\n    json j =\n    {\n        {\"pi\", 3.141},\n        {\"happy\", true},\n        {\"name\", \"Niels\"},\n        {\"nothing\", nullptr},\n        {\n            \"answer\", {\n                {\"everything\", 42}\n            }\n        },\n        {\"list\", {1, 0, 2}},\n        {\n            \"object\", {\n                {\"currency\", \"USD\"},\n                {\"value\", 42.99}\n            }\n        }\n    };\n\n    // add new values\n    j[\"new\"][\"key\"][\"value\"] = {\"another\", \"list\"};\n\n    // count elements\n    auto s = j.size();\n    j[\"size\"] = s;\n\n    // pretty print with indent of 4 spaces\n    std::cout << std::setw(4) << j << '\\n';\n}\n

Output:

{\n    \"answer\": {\n        \"everything\": 42\n    },\n    \"happy\": true,\n    \"list\": [\n        1,\n        0,\n        2\n    ],\n    \"name\": \"Niels\",\n    \"new\": {\n        \"key\": {\n            \"value\": [\n                \"another\",\n                \"list\"\n            ]\n        }\n    },\n    \"nothing\": null,\n    \"object\": {\n        \"currency\": \"USD\",\n        \"value\": 42.99\n    },\n    \"pi\": 3.141,\n    \"size\": 8\n}\n
"},{"location":"api/json/#see-also","title":"See also","text":"
  • basic_json - the underlying class template
  • ordered_json - specialization that preserves the insertion order of object keys
  • Types - the JSON value types and how they are stored
  • Converting values - get values out of a JSON value and put values in
  • Creating JSON values - all the ways to build a JSON value
"},{"location":"api/json/#version-history","title":"Version history","text":"

Added in version 1.0.0.

"},{"location":"api/json_document/","title":"nlohmann::json_document","text":"

Defined in header <nlohmann/json_view.hpp>

using json_document = basic_json_document<json, view_mode::read_only>;\n

This type is a basic_json_document of the default json specialization.

"},{"location":"api/json_document/#examples","title":"Examples","text":"Example

The example below demonstrates how to use the type nlohmann::json_document.

#include <iostream>\n#include <nlohmann/json_view.hpp>\n\nusing nlohmann::json_document;\n\nint main()\n{\n    std::cout << std::boolalpha;\n\n    // json_document is basic_json_document<nlohmann::json>: same value types\n    // and containers as the ordinary json specialization\n    json_document doc = json_document::parse(R\"({\"pi\": 3.14, \"numbers\": [1, 2, 3]})\");\n\n    std::cout << doc.root().is_object() << '\\n';\n    std::cout << doc.root().materialize().dump() << '\\n';\n}\n

Output:

true\n{\"numbers\":[1,2,3],\"pi\":3.14}\n
"},{"location":"api/json_document/#see-also","title":"See also","text":"
  • json_view - a view of a value of a json_document
  • ordered_json_document - the corresponding document for ordered_json
  • Zero-copy JSON views - how to parse, inspect and edit a document without building a tree
"},{"location":"api/json_document/#version-history","title":"Version history","text":"

Added in version 3.13.0 unreleased.

"},{"location":"api/json_editable_document/","title":"nlohmann::json_editable_document","text":"

Defined in header <nlohmann/json_view.hpp>

using json_editable_document = basic_json_document<json, view_mode::editable>;\n

This type is an editable basic_json_document of the default json specialization: in addition to everything json_document offers, set and push_back change values after parsing, without ever rewriting the source text \u2014 see Edits and Editing a document.

"},{"location":"api/json_editable_document/#examples","title":"Examples","text":"Example

The example below patches two fields of a small configuration document \u2014 changing one and adding another \u2014 and dumps it back out with the member order and the spelling of the untouched number preserved, something a plain json value cannot do.

#include <iostream>\n#include <nlohmann/json_view.hpp>\n\nusing nlohmann::json;\nusing nlohmann::json_editable_document;\nusing nlohmann::json_editable_view;\n\nint main()\n{\n    // a configuration file, as it might be read from disk\n    const std::string text = R\"({\"name\": \"cache\", \"host\": \"db1\", \"port\": 6379, \"price\": 19.90})\";\n    std::cout << text << \"\\n\\n\";\n\n    // patch two fields -- \"price\" is never touched\n    json_editable_document doc = json_editable_document::parse(text);\n    doc.set(doc.root(), \"host\", \"db2\");\n    doc.set(doc.root(), \"retries\", 3);\n\n    // member order (the new member at the end) and the untouched number's\n    // exact spelling survive\n    std::cout << doc.root().dump(-1, ' ', false, json_editable_view::number_format::source) << '\\n';\n\n    // the same patch on a plain json value: keys are sorted (object_t is a\n    // std::map), and \"price\" is rewritten even though the patch never\n    // touched it\n    json plain = json::parse(text);\n    plain[\"host\"] = \"db2\";\n    plain[\"retries\"] = 3;\n    std::cout << plain.dump() << '\\n';\n}\n

Output:

{\"name\": \"cache\", \"host\": \"db1\", \"port\": 6379, \"price\": 19.90}\n\n{\"name\":\"cache\",\"host\":\"db2\",\"port\":6379,\"price\":19.90,\"retries\":3}\n{\"host\":\"db2\",\"name\":\"cache\",\"port\":6379,\"price\":19.9,\"retries\":3}\n
"},{"location":"api/json_editable_document/#see-also","title":"See also","text":"
  • json_editable_view - a view of a value of a json_editable_document
  • json_document - the read-only document this type adds edits to
  • ordered_json_editable_document - the corresponding editable document for ordered_json
  • Edits - what an edit guarantees
"},{"location":"api/json_editable_document/#version-history","title":"Version history","text":"

Added in version 3.13.0 unreleased.

"},{"location":"api/json_editable_view/","title":"nlohmann::json_editable_view","text":"

Defined in header <nlohmann/json_view.hpp>

using json_editable_view = basic_json_view<json, view_mode::editable>;\n

This type is a basic_json_view of a value of a json_editable_document. It offers the same read-only interface as json_view; what is different is what it can be a view of \u2014 a value that set and push_back can change, with every view still referring to it seeing the change, see Edits.

"},{"location":"api/json_editable_view/#examples","title":"Examples","text":"Example

The example below is the same as json_editable_document's: every view read back out of the document \u2014 doc.root() and the views nested under it \u2014 sees the edits made through set.

#include <iostream>\n#include <nlohmann/json_view.hpp>\n\nusing nlohmann::json;\nusing nlohmann::json_editable_document;\nusing nlohmann::json_editable_view;\n\nint main()\n{\n    // a configuration file, as it might be read from disk\n    const std::string text = R\"({\"name\": \"cache\", \"host\": \"db1\", \"port\": 6379, \"price\": 19.90})\";\n    std::cout << text << \"\\n\\n\";\n\n    // patch two fields -- \"price\" is never touched\n    json_editable_document doc = json_editable_document::parse(text);\n    doc.set(doc.root(), \"host\", \"db2\");\n    doc.set(doc.root(), \"retries\", 3);\n\n    // member order (the new member at the end) and the untouched number's\n    // exact spelling survive\n    std::cout << doc.root().dump(-1, ' ', false, json_editable_view::number_format::source) << '\\n';\n\n    // the same patch on a plain json value: keys are sorted (object_t is a\n    // std::map), and \"price\" is rewritten even though the patch never\n    // touched it\n    json plain = json::parse(text);\n    plain[\"host\"] = \"db2\";\n    plain[\"retries\"] = 3;\n    std::cout << plain.dump() << '\\n';\n}\n

Output:

{\"name\": \"cache\", \"host\": \"db1\", \"port\": 6379, \"price\": 19.90}\n\n{\"name\":\"cache\",\"host\":\"db2\",\"port\":6379,\"price\":19.90,\"retries\":3}\n{\"host\":\"db2\",\"name\":\"cache\",\"port\":6379,\"price\":19.9,\"retries\":3}\n
"},{"location":"api/json_editable_view/#see-also","title":"See also","text":"
  • json_editable_document - the document type this view refers into
  • json_view - the corresponding read-only view
  • ordered_json_editable_view - the corresponding view for ordered_json_editable_document
  • Zero-copy JSON views - editing a document in place and writing it back
"},{"location":"api/json_editable_view/#version-history","title":"Version history","text":"

Added in version 3.13.0 unreleased.

"},{"location":"api/json_view/","title":"nlohmann::json_view","text":"

Defined in header <nlohmann/json_view.hpp>

using json_view = basic_json_view<json, view_mode::read_only>;\n

This type is a basic_json_view of a value of a json_document.

"},{"location":"api/json_view/#examples","title":"Examples","text":"Example

The example below demonstrates how to use the type nlohmann::json_view.

#include <iostream>\n#include <nlohmann/json_view.hpp>\n\nint main()\n{\n    std::cout << std::boolalpha;\n\n    // json_view is basic_json_view<nlohmann::json>: a read-only handle\n    // returned by json_document::root()\n    nlohmann::json_document doc = nlohmann::json_document::parse(\"[1, 2, 3]\");\n    nlohmann::json_view v = doc.root();\n\n    std::cout << v.is_array() << ' ' << v.size() << '\\n';\n}\n

Output:

true 3\n
"},{"location":"api/json_view/#see-also","title":"See also","text":"
  • json_document - the document type this view refers into
  • ordered_json_view - the corresponding view for ordered_json_document
  • Zero-copy JSON views - how to parse, inspect and edit a document without building a tree
"},{"location":"api/json_view/#version-history","title":"Version history","text":"

Added in version 3.13.0 unreleased.

"},{"location":"api/operator_gtgt/","title":"nlohmann::operator>>(basic_json)","text":"
std::istream& operator>>(std::istream& i, basic_json& j);\n

Deserializes an input stream to a JSON value.

"},{"location":"api/operator_gtgt/#parameters","title":"Parameters","text":"i (in, out) input stream to read a serialized JSON value from j (in, out) JSON value to write the deserialized input to"},{"location":"api/operator_gtgt/#return-value","title":"Return value","text":"

the stream i

"},{"location":"api/operator_gtgt/#exception-safety","title":"Exception safety","text":"

Strong guarantee: if an exception is thrown, there are no changes in j.

"},{"location":"api/operator_gtgt/#exceptions","title":"Exceptions","text":"
  • Throws parse_error.101 in case of an unexpected token, or if i has no stream buffer (i.rdbuf() == nullptr, for instance std::istream(nullptr)).
  • If reading from i reaches the end of the input and eofbit is part of i's exceptions() mask, the std::ios_base::failure thrown by i itself propagates instead of a parse_error, the same as it would for the standard library's own extraction operators.
"},{"location":"api/operator_gtgt/#complexity","title":"Complexity","text":"

Linear in the length of the input. The parser is a predictive LL(1) parser.

"},{"location":"api/operator_gtgt/#notes","title":"Notes","text":"

A UTF-8 byte order mark is silently ignored.

Invalid Unicode escapes and unpaired surrogates in the input are reported as parse_error.101 with a detailed message.

operator>> parses exactly one JSON value, so it can be called repeatedly to read a sequence of concatenated JSON values from the same stream:

json j1, j2;\ninput >> j1;  // parses the first value\ninput >> j2;  // parses the next value\n

A number must be followed by whitespace

A number is only terminated by the character that follows it. That character is read from the stream to detect the end of the number, and it is not put back. When a value that is a number is immediately followed by the next value, the first character of that next value is lost:

std::istringstream input(\"1true\");\njson j1, j2;\ninput >> j1;  // j1 == 1\ninput >> j2;  // throws parse_error.101: the stream now starts at \"rue\"\n

Separating the values with whitespace avoids this, because the character that is eaten is then the separator:

std::istringstream input(\"1 true\");\njson j1, j2;\ninput >> j1;  // j1 == 1\ninput >> j2;  // j2 == true\n

Only numbers are affected. Values ending in a self-delimiting character do not read past themselves, so truefalse, [1][2], {\"a\":1}{\"b\":2}, and \"a\"\"b\" can be read back to back without a separator.

Define JSON_PRECISE_STREAM_POSITION to 1 to leave the terminating character in the stream instead, so that the stream is positioned right after the value for every value type and no separator is needed. This is tracked in #5340.

Note that reading concatenated values does not work for JSON Lines (newline-delimited JSON) input \u2014 see that page for why and for the recommended alternative.

By default, a '\\0' (NUL) byte encountered while reading a value is treated as end of input, rather than as an ordinary (and, outside of a string, invalid) byte; see the FAQ entry for details and the JSON_STRICT_NUL_HANDLING macro to opt into rejecting it instead. Because operator>> only parses a single value and does not require the rest of the stream to be consumed, a NUL byte after a complete value has no effect on operator>> either way; it only matters while a value is still being read.

Deprecation

This function replaces function std::istream& operator<<(basic_json& j, std::istream& i) which has been deprecated in version 3.0.0. It will be removed in version 4.0.0. Please replace calls like j << i; with i >> j;.

See the migration guide for how to update existing code.

"},{"location":"api/operator_gtgt/#examples","title":"Examples","text":"Example

The example below shows how a JSON value is constructed by reading a serialization from a stream.

#include <iostream>\n#include <iomanip>\n#include <sstream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create stream with serialized JSON\n    std::stringstream ss;\n    ss << R\"({\n        \"number\": 23,\n        \"string\": \"Hello, world!\",\n        \"array\": [1, 2, 3, 4, 5],\n        \"boolean\": false,\n        \"null\": null\n    })\";\n\n    // create JSON value and read the serialization from the stream\n    json j;\n    ss >> j;\n\n    // serialize JSON\n    std::cout << std::setw(2) << j << '\\n';\n}\n

Output:

{\n  \"array\": [\n    1,\n    2,\n    3,\n    4,\n    5\n  ],\n  \"boolean\": false,\n  \"null\": null,\n  \"number\": 23,\n  \"string\": \"Hello, world!\"\n}\n
"},{"location":"api/operator_gtgt/#see-also","title":"See also","text":"
  • accept - check if the input is valid JSON
  • parse - deserialize from a compatible input
  • JSON_STRICT_NUL_HANDLING - opt in to rejecting a NUL byte in the input instead of treating it as end of input
  • JSON_PRECISE_STREAM_POSITION - opt in to leaving the stream positioned right after a number
  • JSON_DISABLE_STREAM_BULK_SCAN - read the stream one character at a time
  • Parsing - overview of the parsing functions
  • JSON Lines - newline-delimited JSON
  • Large, Streamed, and Partial Input - chunked, concatenated, and very large input
"},{"location":"api/operator_gtgt/#version-history","title":"Version history","text":"
  • Added in version 1.0.0.
  • JSON_STRICT_NUL_HANDLING added in version 3.13.0 unreleased 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.
  • JSON_PRECISE_STREAM_POSITION added in version 3.13.0 unreleased to optionally leave the character that terminates a number in the stream; planned to become the default in version 4.0.0.
  • Fixed a null pointer dereference for an std::istream without a stream buffer (now throws parse_error.101), and a crash (std::terminate) when i has eofbit in its exception mask, in version 3.13.0 unreleased.
  • Changed to the strong exception safety guarantee in version 3.13.0 unreleased: j is no longer left with a partially parsed value if parsing throws.
  • Scans the characters in the stream buffer of i in bulk in version 3.13.0 unreleased; the position of i after the call is unchanged (JSON_DISABLE_STREAM_BULK_SCAN restores reading one character at a time).
"},{"location":"api/operator_literal_json/","title":"nlohmann::operator\"\"_json","text":"
json operator \"\"_json(const char* s, std::size_t n);\njson operator \"\"_json(const char8_t* s, std::size_t n);  // since C++20\n

This operator implements a user-defined string literal for JSON objects. It can be used by adding _json to a string literal and returns a json object if no parse error occurred.

It is recommended to bring the operator into scope using any of the following lines:

using nlohmann::literals::operator \"\"_json;\nusing namespace nlohmann::literals;\nusing namespace nlohmann::json_literals;\nusing namespace nlohmann::literals::json_literals;\nusing namespace nlohmann;\n

This is suggested to ease migration to the next major version release of the library. See JSON_USE_GLOBAL_UDLS and the migration guide for details. The operator is declared in header <nlohmann/json_literals.hpp>, which <nlohmann/json.hpp> includes unless JSON_NO_AUTOMATIC_UDLS is defined.

"},{"location":"api/operator_literal_json/#parameters","title":"Parameters","text":"s (in) a string representation of a JSON object n (in) length of string s"},{"location":"api/operator_literal_json/#return-value","title":"Return value","text":"

json value parsed from s

"},{"location":"api/operator_literal_json/#exceptions","title":"Exceptions","text":"

The function can throw anything that parse(s, s+n) would throw.

"},{"location":"api/operator_literal_json/#complexity","title":"Complexity","text":"

Linear.

"},{"location":"api/operator_literal_json/#examples","title":"Examples","text":"Example

The following code shows how to create JSON values from string literals.

#include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\nusing namespace nlohmann::literals;\n\nint main()\n{\n    json j = R\"( {\"hello\": \"world\", \"answer\": 42} )\"_json;\n\n    std::cout << std::setw(2) << j << '\\n';\n}\n

Output:

{\n  \"answer\": 42,\n  \"hello\": \"world\"\n}\n
"},{"location":"api/operator_literal_json/#see-also","title":"See also","text":"
  • Creating JSON values - the article on creating JSON values
  • JSON_NO_AUTOMATIC_UDLS - do not include the user-defined string literals automatically
"},{"location":"api/operator_literal_json/#version-history","title":"Version history","text":"
  • Added in version 1.0.0.
  • Moved to namespace nlohmann::literals::json_literals in 3.11.0.
  • Added char8_t* overload in version 3.13.0 unreleased.
"},{"location":"api/operator_literal_json_pointer/","title":"nlohmann::operator\"\"_json_pointer","text":"
json_pointer operator \"\"_json_pointer(const char* s, std::size_t n);\njson_pointer operator \"\"_json_pointer(const char8_t* s, std::size_t n);  // since C++20\n

This operator implements a user-defined string literal for JSON Pointers. It can be used by adding _json_pointer to a string literal and returns a json_pointer object if no parse error occurred.

It is recommended to bring the operator into scope using any of the following lines:

using nlohmann::literals::operator \"\"_json_pointer;\nusing namespace nlohmann::literals;\nusing namespace nlohmann::json_literals;\nusing namespace nlohmann::literals::json_literals;\nusing namespace nlohmann;\n
This is suggested to ease migration to the next major version release of the library. See JSON_USE_GLOBAL_UDLS and the migration guide for details. The operator is declared in header <nlohmann/json_literals.hpp>, which <nlohmann/json.hpp> includes unless JSON_NO_AUTOMATIC_UDLS is defined.

"},{"location":"api/operator_literal_json_pointer/#parameters","title":"Parameters","text":"s (in) a string representation of a JSON Pointer n (in) length of string s"},{"location":"api/operator_literal_json_pointer/#return-value","title":"Return value","text":"

json_pointer value parsed from s

"},{"location":"api/operator_literal_json_pointer/#exceptions","title":"Exceptions","text":"

The function can throw anything that json_pointer::json_pointer would throw.

"},{"location":"api/operator_literal_json_pointer/#complexity","title":"Complexity","text":"

Linear.

"},{"location":"api/operator_literal_json_pointer/#examples","title":"Examples","text":"Example

The following code shows how to create JSON Pointers from string literals.

#include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\nusing namespace nlohmann::literals;\n\nint main()\n{\n    json j = R\"( {\"hello\": \"world\", \"answer\": 42} )\"_json;\n    auto val = j[\"/hello\"_json_pointer];\n\n    std::cout << std::setw(2) << val << '\\n';\n}\n

Output:

\"world\"\n
"},{"location":"api/operator_literal_json_pointer/#see-also","title":"See also","text":"
  • json_pointer - type to represent JSON Pointers
  • JSON_NO_AUTOMATIC_UDLS - do not include the user-defined string literals automatically
  • JSON Pointer - the article on JSON Pointer support
"},{"location":"api/operator_literal_json_pointer/#version-history","title":"Version history","text":"
  • Added in version 2.0.0.
  • Moved to namespace nlohmann::literals::json_literals in 3.11.0.
  • Added char8_t* overload in version 3.13.0 unreleased.
"},{"location":"api/operator_ltlt/","title":"nlohmann::operator<<(basic_json), nlohmann::operator<<(json_pointer)","text":"
std::ostream& operator<<(std::ostream& o, const basic_json& j);      // (1)\n\nstd::ostream& operator<<(std::ostream& o, const json_pointer& ptr);  // (2)\n
  1. Serialize the given JSON value j to the output stream o. The JSON value will be serialized using the dump member function.
    • The indentation of the output can be controlled with the member variable width of the output stream o. For instance, using the manipulator std::setw(4) on o sets the indentation level to 4 and the serialization result is the same as calling dump(4).
    • The indentation character can be controlled with the member variable fill of the output stream o. For instance, the manipulator std::setfill('\\\\t') sets indentation to use a tab character rather than the default space character.
  2. Write a string representation of the given JSON pointer ptr to the output stream o. The string representation is obtained using the to_string member function.
"},{"location":"api/operator_ltlt/#parameters","title":"Parameters","text":"o (in, out) stream to write to j (in) JSON value to serialize ptr (in) JSON pointer to write"},{"location":"api/operator_ltlt/#return-value","title":"Return value","text":"

the stream o

"},{"location":"api/operator_ltlt/#exceptions","title":"Exceptions","text":"
  1. Throws type_error.316 if a string stored inside the JSON value is not UTF-8 encoded. Note that unlike the dump member functions, no error_handler can be set.
  2. Throws no library exceptions. As the string representation is built with to_string, std::bad_alloc is possible.
"},{"location":"api/operator_ltlt/#complexity","title":"Complexity","text":"

Linear.

"},{"location":"api/operator_ltlt/#notes","title":"Notes","text":"

Deprecation

Function std::ostream& operator<<(std::ostream& o, const basic_json& j) replaces function std::ostream& operator>>(const basic_json& j, std::ostream& o) which has been deprecated in version 3.0.0. It will be removed in version 4.0.0. Please replace calls like j >> o; with o << j;.

See the migration guide for how to update existing code.

"},{"location":"api/operator_ltlt/#examples","title":"Examples","text":"Example: (1) serialize JSON value to stream

The example below shows the serialization with different parameters to width to adjust the indentation level.

#include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create JSON values\n    json j_object = {{\"one\", 1}, {\"two\", 2}};\n    json j_array = {1, 2, 4, 8, 16};\n\n    // serialize without indentation\n    std::cout << j_object << \"\\n\\n\";\n    std::cout << j_array << \"\\n\\n\";\n\n    // serialize with indentation\n    std::cout << std::setw(4) << j_object << \"\\n\\n\";\n    std::cout << std::setw(2) << j_array << \"\\n\\n\";\n    std::cout << std::setw(1) << std::setfill('\\t') << j_object << \"\\n\\n\";\n}\n

Output:

{\"one\":1,\"two\":2}\n\n[1,2,4,8,16]\n\n{\n    \"one\": 1,\n    \"two\": 2\n}\n\n[\n  1,\n  2,\n  4,\n  8,\n  16\n]\n\n{\n    \"one\": 1,\n    \"two\": 2\n}\n
Example: (2) write JSON pointer to stream

The example below shows how to write a JSON pointer to a stream.

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create JSON pointer\n    json::json_pointer ptr(\"/foo/bar/baz\");\n\n    // write string representation to stream\n    std::cout << ptr << '\\n';\n}\n

Output:

/foo/bar/baz\n
"},{"location":"api/operator_ltlt/#see-also","title":"See also","text":"
  • dump - serialize to a JSON-formatted string
  • basic_json_view::operator<< - the corresponding operator for basic_json_view
  • Serialization - the serialization article
  • JSON_NO_IO - remove stream and file I/O
"},{"location":"api/operator_ltlt/#version-history","title":"Version history","text":"
  1. Added in version 1.0.0. Added support for indentation character and deprecated std::ostream& operator>>(const basic_json& j, std::ostream& o) in version 3.0.0.
  2. Added in version 3.11.0.
"},{"location":"api/ordered_json/","title":"nlohmann::ordered_json","text":"
using ordered_json = basic_json<ordered_map>;\n

This type preserves the insertion order of object keys.

"},{"location":"api/ordered_json/#iterator-invalidation","title":"Iterator invalidation","text":"

The type is based on ordered_map which in turn uses a std::vector to store object elements. Therefore, adding object elements can yield a reallocation in which case all iterators (including the end() iterator) and all references to the elements are invalidated. Also, any iterator or reference after the insertion point will point to the same index, which is now a different value.

"},{"location":"api/ordered_json/#complexity","title":"Complexity","text":"

ordered_map has no lookup index: every key-based object operation is a linear scan, so building or parsing an object of n keys costs O(n\u00b2) rather than O(n log n). See ordered_map complexity for the per-operation table and for measured numbers.

"},{"location":"api/ordered_json/#examples","title":"Examples","text":"Example

The example below demonstrates how ordered_json preserves the insertion order of object keys.

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::ordered_json;\n\nint main()\n{\n    ordered_json j;\n    j[\"one\"] = 1;\n    j[\"two\"] = 2;\n    j[\"three\"] = 3;\n\n    std::cout << j.dump(2) << '\\n';\n}\n

Output:

{\n  \"one\": 1,\n  \"two\": 2,\n  \"three\": 3\n}\n
"},{"location":"api/ordered_json/#see-also","title":"See also","text":"
  • ordered_map - ordered map type used by ordered_json
  • Object Order - preserving the insertion order of object keys
"},{"location":"api/ordered_json/#version-history","title":"Version history","text":"

Added in version 3.9.0.

"},{"location":"api/ordered_json_document/","title":"nlohmann::ordered_json_document","text":"

Defined in header <nlohmann/json_view.hpp>

using ordered_json_document = basic_json_document<ordered_json, view_mode::read_only>;\n

This type is a basic_json_document of the ordered_json specialization: materialize() on one of its views preserves the insertion order of object keys, instead of sorting them like json_document does.

"},{"location":"api/ordered_json_document/#examples","title":"Examples","text":"Example

The example below demonstrates how ordered_json_document preserves the insertion order of object keys when materializing.

#include <iostream>\n#include <nlohmann/json_view.hpp>\n\nusing nlohmann::ordered_json_document;\n\nint main()\n{\n    // ordered_json_document is basic_json_document<nlohmann::ordered_json>:\n    // materialize() preserves the insertion (source) order of object keys,\n    // instead of sorting them like json_document does\n    ordered_json_document doc = ordered_json_document::parse(R\"({\"z\": 1, \"a\": 2, \"m\": 3})\");\n    std::cout << doc.root().materialize().dump() << '\\n';\n}\n

Output:

{\"z\":1,\"a\":2,\"m\":3}\n
"},{"location":"api/ordered_json_document/#see-also","title":"See also","text":"
  • ordered_json_view - a view of a value of an ordered_json_document
  • json_document - the corresponding document for the default json specialization
  • Object Order - preserving the insertion order of object keys
  • Zero-copy JSON views - how to parse, inspect and edit a document without building a tree
"},{"location":"api/ordered_json_document/#version-history","title":"Version history","text":"

Added in version 3.13.0 unreleased.

"},{"location":"api/ordered_json_editable_document/","title":"nlohmann::ordered_json_editable_document","text":"

Defined in header <nlohmann/json_view.hpp>

using ordered_json_editable_document = basic_json_document<ordered_json, view_mode::editable>;\n

This type is an editable basic_json_document of the ordered_json specialization: set and push_back change values after parsing, as for json_editable_document, and materialize() preserves the document order of object members \u2014 including members set added \u2014 instead of sorting them like json_editable_document does.

"},{"location":"api/ordered_json_editable_document/#examples","title":"Examples","text":"Example

The example below edits a document with set, then shows that materialize() keeps the member order of the source text (with the new member at the end) for ordered_json_editable_document, where it would sort the members alphabetically for json_editable_document.

#include <iostream>\n#include <nlohmann/json_view.hpp>\n\nusing nlohmann::ordered_json_editable_document;\n\nint main()\n{\n    // ordered_json_editable_document is basic_json_document<nlohmann::ordered_json, nlohmann::view_mode::editable>\n    ordered_json_editable_document doc = ordered_json_editable_document::parse(R\"({\"z\": 1, \"a\": 2, \"m\": 3})\");\n    doc.set(doc.root(), \"b\", 4); // set() always appends a new member at the end\n\n    // materialize() preserves the document order (with \"b\" at the end),\n    // instead of sorting the keys the way json_editable_document does\n    std::cout << doc.root().materialize().dump() << '\\n';\n}\n

Output:

{\"z\":1,\"a\":2,\"m\":3,\"b\":4}\n
"},{"location":"api/ordered_json_editable_document/#see-also","title":"See also","text":"
  • ordered_json_editable_view - a view of a value of an ordered_json_editable_document
  • ordered_json_document - the read-only document this type adds edits to
  • json_editable_document - the corresponding editable document for the default json specialization
  • Object Order - preserving the insertion order of object keys
  • Edits - what an edit guarantees
  • Zero-copy JSON views - editing a document in place and writing it back
"},{"location":"api/ordered_json_editable_document/#version-history","title":"Version history","text":"

Added in version 3.13.0 unreleased.

"},{"location":"api/ordered_json_editable_view/","title":"nlohmann::ordered_json_editable_view","text":"

Defined in header <nlohmann/json_view.hpp>

using ordered_json_editable_view = basic_json_view<ordered_json, view_mode::editable>;\n

This type is a basic_json_view of a value of an ordered_json_editable_document, the corresponding view for ordered_json_view the way json_editable_view is for json_view.

"},{"location":"api/ordered_json_editable_view/#examples","title":"Examples","text":"Example

The example below is the same as ordered_json_editable_document's: the views set returns see the document's member order preserved on materialize(), unlike for a json_editable_document.

#include <iostream>\n#include <nlohmann/json_view.hpp>\n\nusing nlohmann::ordered_json_editable_document;\n\nint main()\n{\n    // ordered_json_editable_document is basic_json_document<nlohmann::ordered_json, nlohmann::view_mode::editable>\n    ordered_json_editable_document doc = ordered_json_editable_document::parse(R\"({\"z\": 1, \"a\": 2, \"m\": 3})\");\n    doc.set(doc.root(), \"b\", 4); // set() always appends a new member at the end\n\n    // materialize() preserves the document order (with \"b\" at the end),\n    // instead of sorting the keys the way json_editable_document does\n    std::cout << doc.root().materialize().dump() << '\\n';\n}\n

Output:

{\"z\":1,\"a\":2,\"m\":3,\"b\":4}\n
"},{"location":"api/ordered_json_editable_view/#see-also","title":"See also","text":"
  • ordered_json_editable_document - the document type this view refers into
  • ordered_json_view - the corresponding read-only view
  • json_editable_view - the corresponding view for json_editable_document
  • Zero-copy JSON views - editing a document in place and writing it back
"},{"location":"api/ordered_json_editable_view/#version-history","title":"Version history","text":"

Added in version 3.13.0 unreleased.

"},{"location":"api/ordered_json_view/","title":"nlohmann::ordered_json_view","text":"

Defined in header <nlohmann/json_view.hpp>

using ordered_json_view = basic_json_view<ordered_json, view_mode::read_only>;\n

This type is a basic_json_view of a value of an ordered_json_document.

"},{"location":"api/ordered_json_view/#examples","title":"Examples","text":"Example

The example below demonstrates how to use the type nlohmann::ordered_json_view.

#include <iostream>\n#include <nlohmann/json_view.hpp>\n\nint main()\n{\n    nlohmann::ordered_json_document doc = nlohmann::ordered_json_document::parse(R\"({\"z\": 1, \"a\": 2})\");\n    nlohmann::ordered_json_view v = doc.root();\n\n    std::cout << std::boolalpha << v.is_object() << ' ' << v.size() << '\\n';\n}\n

Output:

true 2\n
"},{"location":"api/ordered_json_view/#see-also","title":"See also","text":"
  • ordered_json_document - the document type this view refers into
  • json_view - the corresponding view for json_document
  • Zero-copy JSON views - how to parse, inspect and edit a document without building a tree
"},{"location":"api/ordered_json_view/#version-history","title":"Version history","text":"

Added in version 3.13.0 unreleased.

"},{"location":"api/ordered_map/","title":"nlohmann::ordered_map","text":"
template<class Key, class T, class IgnoredLess = std::less<Key>,\n         class Allocator = std::allocator<std::pair<const Key, T>>>\nstruct ordered_map : std::vector<std::pair<const Key, T>, Allocator>;\n

A minimal map-like container that preserves insertion order for use within nlohmann::ordered_json (nlohmann::basic_json<ordered_map>).

"},{"location":"api/ordered_map/#template-parameters","title":"Template parameters","text":"Key key type T mapped type IgnoredLess comparison function (ignored and only added to ensure compatibility with std::map) Allocator allocator type"},{"location":"api/ordered_map/#iterator-invalidation","title":"Iterator invalidation","text":"

The type uses a std::vector to store object elements. Therefore, adding elements can yield a reallocation in which case all iterators (including the end() iterator) and all references to the elements are invalidated.

When the storage grows, the keys are copied and the mapped values are moved to the new storage. A plain std::vector would copy the whole elements instead, because their const keys make them not nothrow move constructible; for ordered_json, this would be a deep copy of every nested value. The values are only copied if T is not default constructible or not nothrow move assignable.

"},{"location":"api/ordered_map/#member-types","title":"Member types","text":"
  • key_type - key type (Key)
  • mapped_type - mapped type (T)
  • Container - base container type (std::vector<std::pair<const Key, T>, Allocator>)
  • iterator
  • const_iterator
  • size_type
  • value_type
  • key_compare - key comparison function
    std::equal_to<Key>  // until C++14\n\nstd::equal_to<>     // since C++14\n
"},{"location":"api/ordered_map/#member-functions","title":"Member functions","text":"
  • (constructor)
  • (destructor)
  • emplace
  • operator[]
  • at
  • erase
  • count
  • find
  • insert
"},{"location":"api/ordered_map/#exception-safety","title":"Exception safety","text":"

emplace, operator[], and insert(value) have the strong exception guarantee: if an exception is thrown (for instance, because copying a key or allocating memory fails), the contents of the container are unchanged.

"},{"location":"api/ordered_map/#complexity","title":"Complexity","text":"

Because the elements are stored in a std::vector in insertion order, there is no index to look a key up by. Every key-based operation performs a linear scan over the stored elements. With n denoting the number of elements in the container:

Operation Complexity Note emplace O(n) scans for an existing key, then appends (amortized O(1)) operator[] O(n) delegates to emplace (non-const) or at (const) at O(n) throws std::out_of_range if the key is not found find O(n) count O(n) the result is always 0 or 1 erase(key) O(n) scan, then move the remaining elements one position down erase(pos), erase(first, last) O(n) moves all elements after the erased range insert(value) O(n) equivalent to emplace insert(first, last) O((n + m) * m) for m inserted elements

This differs from std::map, where the same operations are O(log n).

Quadratic cost of building large objects

Because every insertion scans all elements inserted so far, building an object of n distinct keys costs O(n\u00b2) in total. This applies to filling an ordered_json object key by key as well as to parsing one, since the parser inserts each key as it is read.

The cost is negligible for the object sizes typically found in configuration files or API payloads, but it grows steeply for machine-generated objects with many thousands of keys. Measured with -O2 -DNDEBUG for parsing a flat object of n keys, relative to nlohmann::json (which uses std::map):

n json ordered_json factor 2000 0.7 ms 3.6 ms 5\u00d7 4000 0.8 ms 14.0 ms 19\u00d7 8000 1.6 ms 67.8 ms 43\u00d7 16 000 3.3 ms 181.6 ms 54\u00d7

If key order matters for objects of that size, consider a container with a lookup index, such as nlohmann::fifo_map (integration), as the object type \u2014 see object order.

"},{"location":"api/ordered_map/#examples","title":"Examples","text":"Example

The example shows the different behavior of std::map and nlohmann::ordered_map.

#include <iostream>\n#include <nlohmann/json.hpp>\n\n// simple output function\ntemplate<typename Map>\nvoid output(const char* prefix, const Map& m)\n{\n    std::cout << prefix << \" = { \";\n    for (auto& element : m)\n    {\n        std::cout << element.first << \":\" << element.second << ' ';\n    }\n    std::cout << \"}\" << '\\n';\n}\n\nint main()\n{\n    // create and fill two maps\n    nlohmann::ordered_map<std::string, std::string> m_ordered;\n    m_ordered[\"one\"] = \"eins\";\n    m_ordered[\"two\"] = \"zwei\";\n    m_ordered[\"three\"] = \"drei\";\n\n    std::map<std::string, std::string> m_std;\n    m_std[\"one\"] = \"eins\";\n    m_std[\"two\"] = \"zwei\";\n    m_std[\"three\"] = \"drei\";\n\n    // output: m_ordered is ordered by insertion order, m_std is ordered by key\n    output(\"m_ordered\", m_ordered);\n    output(\"m_std\", m_std);\n\n    // erase and re-add \"one\" key\n    m_ordered.erase(\"one\");\n    m_ordered[\"one\"] = \"eins\";\n\n    m_std.erase(\"one\");\n    m_std[\"one\"] = \"eins\";\n\n    // output: m_ordered shows newly added key at the end; m_std is again ordered by key\n    output(\"m_ordered\", m_ordered);\n    output(\"m_std\", m_std);\n}\n

Output:

m_ordered = { one:eins two:zwei three:drei }\nm_std = { one:eins three:drei two:zwei }\nm_ordered = { two:zwei three:drei one:eins }\nm_std = { one:eins three:drei two:zwei }\n
"},{"location":"api/ordered_map/#see-also","title":"See also","text":"
  • ordered_json - JSON specialization preserving insertion order
  • Object Order - the article on object key order
"},{"location":"api/ordered_map/#version-history","title":"Version history","text":"
  • Added in version 3.9.0 to implement nlohmann::ordered_json.
  • Added key_compare member in version 3.11.0.
  • Changed in version 3.13.0 unreleased: growing the storage moves the mapped values instead of copying them.
"},{"location":"api/view_mode/","title":"nlohmann::view_mode","text":"

Defined in header <nlohmann/json_view.hpp>

enum class view_mode : std::uint8_t\n{\n    read_only,\n    editable\n};\n

The second template parameter of basic_json_document and basic_json_view: whether a document can be changed after parsing, and whether a view is of such a document.

read_only the default: the document is parsed once and then only read. It carries none of the bookkeeping edits need, and calling set, push_back, insert, or erase on it fails to compile. editable the document also offers set, push_back, insert, and erase; its views see every edit, see Edits.

The shortcuts name both modes: json_document and json_view are read-only, json_editable_document and json_editable_view are editable (and likewise for ordered_json).

"},{"location":"api/view_mode/#notes","title":"Notes","text":"

The mode is a compile-time property of the document's and the view's type, not a setting of a call. A read-only view reads a container in place, while a view of an editable document follows the links that edits leave behind. A view of a read-only document converts implicitly to a view of an editable document of the same BasicJsonType: a read-only document has no edits, so the converted view reads it like an editable document before its first edit (at the cost of one check per access). There is no conversion the other way, because a read-only view of an editable document would read wrong values after the next edit.

A function that takes a json_editable_view therefore accepts the views of both modes. A function template deduces the mode from its argument instead, without conversions, so it names the modes it accepts in its signature:

// views of editable documents only\ntemplate<typename BasicJsonType>\nvoid f(basic_json_view<BasicJsonType, view_mode::editable> v);\n\n// views of read-only documents only\ntemplate<typename BasicJsonType>\nvoid f(basic_json_view<BasicJsonType, view_mode::read_only> v);\n\n// views of either document type\ntemplate<typename BasicJsonType, view_mode Mode>\nvoid f(basic_json_view<BasicJsonType, Mode> v);\n

A function that takes a json_view accepts neither an ordered_json_view nor a json_editable_view. Views of the two modes compare with operator==.

"},{"location":"api/view_mode/#examples","title":"Examples","text":"Example

The example below shows a function template that accepts the views of both modes, one that accepts only views of editable documents, and a function taking a json_editable_view that also accepts a view of a read-only document.

#include <iostream>\n#include <nlohmann/json_view.hpp>\n\nusing nlohmann::basic_json_view;\nusing nlohmann::view_mode;\n\n// accepts the views of read-only and of editable documents, of json and of ordered_json\ntemplate<typename BasicJsonType, view_mode Mode>\nstd::size_t count_members(basic_json_view<BasicJsonType, Mode> v)\n{\n    return v.is_object() ? v.size() : 0;\n}\n\n// accepts only the views of editable documents\ntemplate<typename BasicJsonType>\nbool is_edited(basic_json_view<BasicJsonType, view_mode::editable> v)\n{\n    return v.is_string() && v.get_string() == \"edited\";\n}\n\n// a function (no template) taking a json_editable_view also accepts the view of a read-only document\nstd::size_t size_of(nlohmann::json_editable_view v)\n{\n    return v.size();\n}\n\nint main()\n{\n    const nlohmann::json_document doc = nlohmann::json_document::parse(R\"({\"a\": 1, \"b\": 2})\");\n    nlohmann::json_editable_document edoc = nlohmann::json_editable_document::parse(R\"({\"a\": 1})\");\n    edoc.set(edoc.root()[\"a\"], \"edited\");\n\n    std::cout << count_members(doc.root()) << ' ' << count_members(edoc.root()) << '\\n';\n    std::cout << std::boolalpha << is_edited(edoc.root()[\"a\"]) << '\\n';\n    std::cout << size_of(doc.root()) << ' ' << size_of(edoc.root()) << '\\n';\n}\n

Output:

2 1\ntrue\n2 1\n
"},{"location":"api/view_mode/#see-also","title":"See also","text":"
  • basic_json_document - a parsed JSON text
  • basic_json_view - a handle to one value of a document
  • json_editable_document - an editable document of json
  • (constructor) - the conversion from a read-only to an editable view
  • Writing generic code - functions that accept views
"},{"location":"api/view_mode/#version-history","title":"Version history","text":"

Added in version 3.13.0 unreleased.

"},{"location":"api/adl_serializer/","title":"nlohmann::adl_serializer","text":"
template<typename, typename>\nstruct adl_serializer;\n

Serializer that uses ADL (Argument-Dependent Lookup) to choose to_json/from_json functions from the types' namespaces.

It is implemented similarly to

template<typename ValueType>\nstruct adl_serializer {\n    template<typename BasicJsonType>\n    static void to_json(BasicJsonType& j, const T& value) {\n        // calls the \"to_json\" method in T's namespace\n    }\n\n    template<typename BasicJsonType>\n    static void from_json(const BasicJsonType& j, T& value) {\n        // same thing, but with the \"from_json\" method\n    }\n};\n
"},{"location":"api/adl_serializer/#member-functions","title":"Member functions","text":"
  • from_json - convert a JSON value to any value type
  • to_json - convert any value type to a JSON value
"},{"location":"api/adl_serializer/#see-also","title":"See also","text":"
  • Arbitrary type conversions - how to make your types convertible
  • get - / get_to - convert a JSON value to a C++ type
  • basic_json - construct a JSON value from a C++ value
  • NLOHMANN_DEFINE_TYPE_INTRUSIVE - generate the conversion functions for a type
  • Specializing enum conversion - serializing enums as JSON strings
"},{"location":"api/adl_serializer/#version-history","title":"Version history","text":"
  • Added in version 2.1.0.
"},{"location":"api/adl_serializer/from_json/","title":"nlohmann::adl_serializer::from_json","text":"
// (1)\ntemplate<typename BasicJsonType, typename TargetType = ValueType>\nstatic auto from_json(BasicJsonType && j, TargetType& val) noexcept(\n    noexcept(::nlohmann::from_json(std::forward<BasicJsonType>(j), val)))\n-> decltype(::nlohmann::from_json(std::forward<BasicJsonType>(j), val), void())\n\n// (2)\ntemplate<typename BasicJsonType, typename TargetType = ValueType>\nstatic auto from_json(BasicJsonType && j) noexcept(\nnoexcept(::nlohmann::from_json(std::forward<BasicJsonType>(j), detail::identity_tag<TargetType> {})))\n-> decltype(::nlohmann::from_json(std::forward<BasicJsonType>(j), detail::identity_tag<TargetType> {}))\n

This function is usually called by the get() function of the basic_json class (either explicitly or via the conversion operators).

  1. This function is chosen for default-constructible value types.
  2. This function is chosen for value types which are not default-constructible.
"},{"location":"api/adl_serializer/from_json/#parameters","title":"Parameters","text":"j (in) JSON value to read from val (out) value to write to"},{"location":"api/adl_serializer/from_json/#return-value","title":"Return value","text":"
  1. (none) \u2014 the converted value is written to the output parameter val.
  2. the JSON value j converted to TargetType
"},{"location":"api/adl_serializer/from_json/#examples","title":"Examples","text":"Example: (1) Default-constructible type

The example below shows how a from_json function can be implemented for a user-defined type. This function is called by the adl_serializer when get<ns::person>() is called.

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nnamespace ns\n{\n// a simple struct to model a person\nstruct person\n{\n    std::string name;\n    std::string address;\n    int age;\n};\n} // namespace ns\n\nnamespace ns\n{\nvoid from_json(const json& j, person& p)\n{\n    j.at(\"name\").get_to(p.name);\n    j.at(\"address\").get_to(p.address);\n    j.at(\"age\").get_to(p.age);\n}\n} // namespace ns\n\nint main()\n{\n    json j;\n    j[\"name\"] = \"Ned Flanders\";\n    j[\"address\"] = \"744 Evergreen Terrace\";\n    j[\"age\"] = 60;\n\n    auto p = j.get<ns::person>();\n\n    std::cout << p.name << \" (\" << p.age << \") lives in \" << p.address << '\\n';\n}\n

Output:

Ned Flanders (60) lives in 744 Evergreen Terrace\n
Example: (2) Non-default-constructible type

The example below shows how a from_json is implemented as part of a specialization of the adl_serializer to realize the conversion of a non-default-constructible type.

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nnamespace ns\n{\n// a simple struct to model a person (not default constructible)\nstruct person\n{\n    person(std::string n, std::string a, int aa)\n        : name(std::move(n)), address(std::move(a)), age(aa)\n    {}\n\n    std::string name;\n    std::string address;\n    int age;\n};\n} // namespace ns\n\nnamespace nlohmann\n{\ntemplate <>\nstruct adl_serializer<ns::person>\n{\n    static ns::person from_json(const json& j)\n    {\n        return {j.at(\"name\"), j.at(\"address\"), j.at(\"age\")};\n    }\n\n    // Here's the catch! You must provide a to_json method! Otherwise, you\n    // will not be able to convert person to json, since you fully\n    // specialized adl_serializer on that type\n    static void to_json(json& j, ns::person p)\n    {\n        j[\"name\"] = p.name;\n        j[\"address\"] = p.address;\n        j[\"age\"] = p.age;\n    }\n};\n} // namespace nlohmann\n\nint main()\n{\n    json j;\n    j[\"name\"] = \"Ned Flanders\";\n    j[\"address\"] = \"744 Evergreen Terrace\";\n    j[\"age\"] = 60;\n\n    auto p = j.get<ns::person>();\n\n    std::cout << p.name << \" (\" << p.age << \") lives in \" << p.address << '\\n';\n}\n

Output:

Ned Flanders (60) lives in 744 Evergreen Terrace\n
"},{"location":"api/adl_serializer/from_json/#see-also","title":"See also","text":"
  • to_json - convert a C++ value to JSON
  • Arbitrary Type Conversions - write your own from_json and to_json functions
  • Converting values - overview of get, get_to and implicit conversions
"},{"location":"api/adl_serializer/from_json/#version-history","title":"Version history","text":"
  • Added in version 2.1.0.
"},{"location":"api/adl_serializer/to_json/","title":"nlohmann::adl_serializer::to_json","text":"
template<typename BasicJsonType, typename TargetType = ValueType>\nstatic auto to_json(BasicJsonType& j, TargetType && val) noexcept(\n    noexcept(::nlohmann::to_json(j, std::forward<TargetType>(val))))\n-> decltype(::nlohmann::to_json(j, std::forward<TargetType>(val)), void())\n

This function is usually called by the constructors of the basic_json class.

"},{"location":"api/adl_serializer/to_json/#parameters","title":"Parameters","text":"j (out) JSON value to write to val (in) value to read from"},{"location":"api/adl_serializer/to_json/#examples","title":"Examples","text":"Example

The example below shows how a to_json function can be implemented for a user-defined type. This function is called by the adl_serializer when the constructor basic_json(ns::person) is called.

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nnamespace ns\n{\n// a simple struct to model a person\nstruct person\n{\n    std::string name;\n    std::string address;\n    int age;\n};\n} // namespace ns\n\nnamespace ns\n{\nvoid to_json(json& j, const person& p)\n{\n    j = json{ {\"name\", p.name}, {\"address\", p.address}, {\"age\", p.age} };\n}\n} // namespace ns\n\nint main()\n{\n    ns::person p = {\"Ned Flanders\", \"744 Evergreen Terrace\", 60};\n\n    json j = p;\n\n    std::cout << j << '\\n';\n}\n

Output:

{\"address\":\"744 Evergreen Terrace\",\"age\":60,\"name\":\"Ned Flanders\"}\n
"},{"location":"api/adl_serializer/to_json/#see-also","title":"See also","text":"
  • from_json - convert JSON to a C++ value
  • Arbitrary Type Conversions - write your own from_json and to_json functions
  • Converting values - overview of get, get_to and implicit conversions
"},{"location":"api/adl_serializer/to_json/#version-history","title":"Version history","text":"
  • Added in version 2.1.0.
"},{"location":"api/basic_json/","title":"nlohmann::basic_json","text":"

Defined in header <nlohmann/json.hpp>

template<\n    template<typename U, typename V, typename... Args> class ObjectType = std::map,\n    template<typename U, typename... Args> class ArrayType = std::vector,\n    class StringType = std::string,\n    class BooleanType = bool,\n    class NumberIntegerType = std::int64_t,\n    class NumberUnsignedType = std::uint64_t,\n    class NumberFloatType = double,\n    template<typename U> class AllocatorType = std::allocator,\n    template<typename T, typename SFINAE = void> class JSONSerializer = adl_serializer,\n    class BinaryType = std::vector<std::uint8_t>,\n    class CustomBaseClass = void\n>\nclass basic_json;\n
"},{"location":"api/basic_json/#template-parameters","title":"Template parameters","text":"Template parameter Description Derived type ObjectType type for JSON objects object_t ArrayType type for JSON arrays array_t StringType type for JSON strings and object keys string_t BooleanType type for JSON booleans boolean_t NumberIntegerType type for JSON integer numbers number_integer_t NumberUnsignedType type for JSON unsigned integer numbers number_unsigned_t NumberFloatType type for JSON floating-point numbers number_float_t AllocatorType type of the allocator to use JSONSerializer the serializer to resolve internal calls to to_json() and from_json() json_serializer BinaryType type for binary arrays binary_t CustomBaseClass extension point for user code json_base_class_t

The library imposes a number of requirements on these types that are not expressed as C++ concepts, such as the container operations object_t and array_t must provide, or the fact that StringType must be char-based. They are collected in Template Parameter Requirements.

"},{"location":"api/basic_json/#specializations","title":"Specializations","text":"
  • json - default specialization
  • ordered_json - a specialization that maintains the insertion order of object keys
"},{"location":"api/basic_json/#documents-and-views","title":"Documents and views","text":"

Besides basic_json, the library offers a second way to hold a parsed JSON text: a basic_json_document, which owns or borrows the text and holds a flat index of the values in it, and a basic_json_view, a read-only handle to one value of such a document. Both are defined in the header <nlohmann/json_view.hpp>; see Zero-copy JSON views for the concept and the trade-offs.

  • json_document / ordered_json_document - read-only documents of the basic_json specialization they belong to
  • json_editable_document / ordered_json_editable_document - documents that can be modified in place
  • json_view / ordered_json_view - views of a document
  • json_editable_view / ordered_json_editable_view - views of an editable document
"},{"location":"api/basic_json/#iterator-invalidation","title":"Iterator invalidation","text":"

All operations that add values to an array (push_back , operator+=, emplace_back, insert, and operator[] for a non-existing index) can yield a reallocation, in which case all iterators (including the end() iterator) and all references to the elements are invalidated.

For ordered_json, also all operations that add a value to an object (push_back, operator+=, emplace, insert, update, and operator[] for a non-existing key) can yield a reallocation, in which case all iterators (including the end() iterator) and all references to the elements are invalidated.

"},{"location":"api/basic_json/#requirements","title":"Requirements","text":"

The class satisfies the following concept requirements:

"},{"location":"api/basic_json/#basic","title":"Basic","text":"
  • DefaultConstructible: JSON values can be default-constructed. The result will be a JSON null value.
  • MoveConstructible: A JSON value can be constructed from an rvalue argument.
  • CopyConstructible: A JSON value can be copy-constructed from an lvalue expression.
  • MoveAssignable: A JSON value can be assigned from an rvalue argument.
  • CopyAssignable: A JSON value can be copy-assigned from an lvalue expression.
  • Destructible: JSON values can be destructed.
"},{"location":"api/basic_json/#layout","title":"Layout","text":"
  • StandardLayoutType: JSON values have standard layout: All non-static data members are private and standard layout types, the class has no virtual functions or (virtual) base classes.
"},{"location":"api/basic_json/#library-wide","title":"Library-wide","text":"
  • EqualityComparable: JSON values can be compared with ==, see operator==.
  • LessThanComparable: JSON values can be compared with <, see operator<.
  • Swappable: Any JSON lvalue or rvalue of can be swapped with any lvalue or rvalue of other compatible types, using unqualified function swap.
  • NullablePointer: JSON values can be compared against std::nullptr_t objects which are used to model the null value.
"},{"location":"api/basic_json/#container","title":"Container","text":"
  • Container: JSON values can be used like STL containers and provide iterator access.
  • ReversibleContainer: JSON values can be used like STL containers and provide reverse iterator access.
"},{"location":"api/basic_json/#member-types","title":"Member types","text":"
  • adl_serializer - the default serializer
  • value_t - the JSON type enumeration
  • json_pointer - JSON Pointer implementation
  • json_serializer - type of the serializer to for conversions from/to JSON
  • error_handler_t - type to choose behavior on decoding errors
  • bjdata_version_t - type to choose the BJData version to write
  • cbor_tag_handler_t - type to choose how to handle CBOR tags
  • initializer_list_t - type for initializer lists of basic_json values
  • input_format_t - type to choose the format to parse
  • json_sax_t - type for SAX events
  • with_object_t, with_array_t, with_string_t, with_boolean_t, with_integers_t, with_float_t, with_allocator_t, with_json_serializer_t, with_binary_t, with_base_class_t - types to create a basic_json type with one (or two) replaced template parameters
"},{"location":"api/basic_json/#exceptions","title":"Exceptions","text":"
  • exception - general exception of the basic_json class
    • parse_error - exception indicating a parse error
    • invalid_iterator - exception indicating errors with iterators
    • type_error - exception indicating executing a member function with a wrong type
    • out_of_range - exception indicating access out of the defined range
    • other_error - exception indicating other library errors
"},{"location":"api/basic_json/#container-types","title":"Container types","text":"Type Definition value_type basic_json reference value_type& const_reference const value_type& difference_type std::ptrdiff_t size_type std::size_t allocator_type AllocatorType<basic_json> pointer std::allocator_traits<allocator_type>::pointer const_pointer std::allocator_traits<allocator_type>::const_pointer iterator LegacyBidirectionalIterator const_iterator constant LegacyBidirectionalIterator reverse_iterator reverse iterator, derived from iterator const_reverse_iterator reverse iterator, derived from const_iterator iteration_proxy helper type for items function"},{"location":"api/basic_json/#json-value-data-types","title":"JSON value data types","text":"
  • array_t - type for arrays
  • binary_t - type for binary arrays
  • boolean_t - type for booleans
  • default_object_comparator_t - default comparator for objects
  • number_float_t - type for numbers (floating-point)
  • number_integer_t - type for numbers (integer)
  • number_unsigned_t - type for numbers (unsigned)
  • object_comparator_t - comparator for objects
  • object_t - type for objects
  • string_t - type for strings
"},{"location":"api/basic_json/#parser-callback","title":"Parser callback","text":"
  • parse_event_t - parser event types
  • parser_callback_t - per-element parser callback type
"},{"location":"api/basic_json/#member-functions","title":"Member functions","text":"
  • (constructor)
  • (destructor)
  • operator= - copy assignment
  • array (static) - explicitly create an array
  • binary (static) - explicitly create a binary array
  • object (static) - explicitly create an object
"},{"location":"api/basic_json/#object-inspection","title":"Object inspection","text":"

Functions to inspect the type of a JSON value.

  • type - return the type of the JSON value
  • operator value_t - return the type of the JSON value
  • type_name - return the type as string
  • is_primitive - return whether the type is primitive
  • is_structured - return whether the type is structured
  • is_null - return whether the value is null
  • is_boolean - return whether the value is a boolean
  • is_number - return whether the value is a number
  • is_number_integer - return whether the value is an integer number
  • is_number_unsigned - return whether the value is an unsigned integer number
  • is_number_float - return whether the value is a floating-point number
  • is_object - return whether the value is an object
  • is_array - return whether the value is an array
  • is_string - return whether the value is a string
  • is_binary - return whether the value is a binary array
  • is_discarded - return whether the value is discarded

Optional functions to access the diagnostic positions.

  • start_pos - return the start position of the value
  • end_pos - return the one past the end position of the value
"},{"location":"api/basic_json/#value-access","title":"Value access","text":"

Direct access to the stored value of a JSON value.

  • get - get a value
  • get_to - get a value and write it to a destination
  • get_ptr - get a pointer value
  • get_ref - get a reference value
  • operator ValueType - get a value
  • get_binary - get a binary value
  • as_base_class - access the custom base class
"},{"location":"api/basic_json/#element-access","title":"Element access","text":"

Access to the JSON value

  • at - access specified element with bounds checking
  • operator[] - access specified element
  • value - access specified object element with default value
  • front - access the first element
  • back - access the last element
"},{"location":"api/basic_json/#lookup","title":"Lookup","text":"
  • find - find an element in a JSON object
  • count - returns the number of occurrences of a key in a JSON object
  • contains - check the existence of an element in a JSON object
"},{"location":"api/basic_json/#iterators","title":"Iterators","text":"
  • begin - returns an iterator to the first element
  • cbegin - returns a const iterator to the first element
  • end - returns an iterator to one past the last element
  • cend - returns a const iterator to one past the last element
  • rbegin - returns an iterator to the reverse-beginning
  • rend - returns an iterator to the reverse-end
  • crbegin - returns a const iterator to the reverse-beginning
  • crend - returns a const iterator to the reverse-end
  • items - wrapper to access iterator member functions in range-based for
"},{"location":"api/basic_json/#capacity","title":"Capacity","text":"
  • empty - checks whether the container is empty
  • size - returns the number of elements
  • max_size - returns the maximum possible number of elements
"},{"location":"api/basic_json/#modifiers","title":"Modifiers","text":"
  • clear - clears the contents
  • push_back - add a value to an array/object
  • operator+= - add a value to an array/object
  • emplace_back - add a value to an array
  • emplace - add a value to an object if a key does not exist
  • erase - remove elements
  • insert - inserts elements
  • update - updates a JSON object from another object, overwriting existing keys
  • swap - exchanges the values
"},{"location":"api/basic_json/#lexicographical-comparison-operators","title":"Lexicographical comparison operators","text":"
  • operator== - comparison: equal
  • operator!= - comparison: not equal
  • operator< - comparison: less than
  • operator> - comparison: greater than
  • operator<= - comparison: less than or equal
  • operator>= - comparison: greater than or equal
  • operator<=> - comparison: 3-way
"},{"location":"api/basic_json/#serialization-dumping","title":"Serialization / Dumping","text":"
  • dump - serialization
"},{"location":"api/basic_json/#deserialization-parsing","title":"Deserialization / Parsing","text":"
  • parse (static) - deserialize from a compatible input
  • accept (static) - check if the input is valid JSON
  • sax_parse (static) - generate SAX events
"},{"location":"api/basic_json/#json-pointer-functions","title":"JSON Pointer functions","text":"
  • flatten - return flattened JSON value
  • unflatten - unflatten a previously flattened JSON value
"},{"location":"api/basic_json/#json-patch-functions","title":"JSON Patch functions","text":"
  • patch - applies a JSON patch
  • patch_inplace - applies a JSON patch in place
  • diff (static) - creates a diff as a JSON patch
"},{"location":"api/basic_json/#json-merge-patch-functions","title":"JSON Merge Patch functions","text":"
  • merge_patch - applies a JSON Merge Patch
  • merge_diff (static) - creates a diff as a JSON Merge Patch
"},{"location":"api/basic_json/#static-functions","title":"Static functions","text":"
  • meta - returns version information on the library
  • get_allocator - returns the allocator associated with the container
"},{"location":"api/basic_json/#binary-formats","title":"Binary formats","text":"
  • from_bjdata (static) - create a JSON value from an input in BJData format
  • from_bon8 (static) - create a JSON value from an input in BON8 format
  • from_bson (static) - create a JSON value from an input in BSON format
  • from_cbor (static) - create a JSON value from an input in CBOR format
  • from_msgpack (static) - create a JSON value from an input in MessagePack format
  • from_ubjson (static) - create a JSON value from an input in UBJSON format
  • to_bjdata (static) - create a BJData serialization of a given JSON value
  • to_bon8 (static) - create a BON8 serialization of a given JSON value
  • to_bson (static) - create a BSON serialization of a given JSON value
  • to_cbor (static) - create a CBOR serialization of a given JSON value
  • to_msgpack (static) - create a MessagePack serialization of a given JSON value
  • to_ubjson (static) - create a UBJSON serialization of a given JSON value
"},{"location":"api/basic_json/#non-member-functions","title":"Non-member functions","text":"
  • operator<<(std::ostream&) - serialize to stream
  • operator>>(std::istream&) - deserialize from stream
  • to_string - user-defined to_string function for JSON values
  • format_as - user-defined format_as function for JSON values (fmt support)
"},{"location":"api/basic_json/#literals","title":"Literals","text":"
  • operator\"\"_json - user-defined string literal for JSON values
"},{"location":"api/basic_json/#helper-classes","title":"Helper classes","text":"
  • std::formatter<basic_json> - make JSON values formattable with std::format
  • std::hash<basic_json> - return a hash value for a JSON object
  • std::swap<basic_json> - exchanges the values of two JSON objects
"},{"location":"api/basic_json/#examples","title":"Examples","text":"Example

The example shows how the library is used.

#include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create a JSON object\n    json j =\n    {\n        {\"pi\", 3.141},\n        {\"happy\", true},\n        {\"name\", \"Niels\"},\n        {\"nothing\", nullptr},\n        {\n            \"answer\", {\n                {\"everything\", 42}\n            }\n        },\n        {\"list\", {1, 0, 2}},\n        {\n            \"object\", {\n                {\"currency\", \"USD\"},\n                {\"value\", 42.99}\n            }\n        }\n    };\n\n    // add new values\n    j[\"new\"][\"key\"][\"value\"] = {\"another\", \"list\"};\n\n    // count elements\n    auto s = j.size();\n    j[\"size\"] = s;\n\n    // pretty print with indent of 4 spaces\n    std::cout << std::setw(4) << j << '\\n';\n}\n

Output:

{\n    \"answer\": {\n        \"everything\": 42\n    },\n    \"happy\": true,\n    \"list\": [\n        1,\n        0,\n        2\n    ],\n    \"name\": \"Niels\",\n    \"new\": {\n        \"key\": {\n            \"value\": [\n                \"another\",\n                \"list\"\n            ]\n        }\n    },\n    \"nothing\": null,\n    \"object\": {\n        \"currency\": \"USD\",\n        \"value\": 42.99\n    },\n    \"pi\": 3.141,\n    \"size\": 8\n}\n
"},{"location":"api/basic_json/#see-also","title":"See also","text":"
  • RFC 8259: The JavaScript Object Notation (JSON) Data Interchange Format - specification of the JSON data interchange format
  • basic_json_document - / basic_json_view - parse a JSON text into a flat index and read it through a view
  • Zero-copy JSON views - when to use a document and a view instead of a basic_json
  • Types - how JSON values are stored and which types exist
  • Converting values - get values out of a JSON value and put values in
  • Creating JSON values - all the ways to build a JSON value
  • Arbitrary Type Conversions - convert your own types to and from JSON
"},{"location":"api/basic_json/#version-history","title":"Version history","text":"
  • Added in version 1.0.0.
"},{"location":"api/basic_json/accept/","title":"nlohmann::basic_json::accept","text":"
// (1)\ntemplate<typename InputType>\nstatic bool accept(InputType&& i,\n                   const bool ignore_comments = false,\n                   const bool ignore_trailing_commas = false);\n\n// (2)\ntemplate<typename IteratorType, typename SentinelType = IteratorType>\nstatic bool accept(IteratorType first, SentinelType last,\n                   const bool ignore_comments = false,\n                   const bool ignore_trailing_commas = false);\n

Checks whether the input is valid JSON.

  1. Reads from a compatible input.
  2. Reads from a pair of character iterators, or an iterator and a sentinel of a different type (C++20 ranges support)

    The value_type of the iterator must be an integral type with a size of 1, 2, or 4 bytes, which will be interpreted respectively as UTF-8, UTF-16, and UTF-32. If SentinelType differs from IteratorType, it must be comparable to the iterator type with operator!=.

    Ill-formed UTF-16 and UTF-32 sequences are rejected: a lone surrogate, a high surrogate that is not followed by its low surrogate, and a code point above U+10FFFF all make this function return false.

Unlike the parse() function, this function neither throws an exception in case of invalid JSON input (i.e., a parse error) nor creates diagnostic information.

"},{"location":"api/basic_json/accept/#template-parameters","title":"Template parameters","text":"InputType

A compatible input, for instance:

  • an std::istream object
  • a FILE pointer (throws if null)
  • a C-style array of characters
  • a pointer to a null-terminated string of single byte characters (throws if null)
  • a std::string or a std::string_view (C++17)
  • a container obj for which begin(obj) and end(obj) produce a valid pair of iterators (as found via ADL or member functions, with semantics compatible to std::begin and std::end)
  • wide characters (wchar_t, char16_t, char32_t), which are converted to UTF-8: a wide string object (std::wstring, std::u16string, std::u32string) or an array (e.g. a wide string literal); a pointer to a null-terminated wide string (e.g. std::u16string::c_str()) is not supported
IteratorType

a compatible iterator type, for instance.

  • a pair of std::string::iterator or std::vector<std::uint8_t>::iterator
  • a pair of pointers such as ptr and ptr + len
SentinelType

defaults to IteratorType; may be a different type comparable to IteratorType via operator!=, for instance.

  • a custom sentinel type for C++20 ranges
  • std::default_sentinel_t, when IteratorType is std::counted_iterator
"},{"location":"api/basic_json/accept/#parameters","title":"Parameters","text":"i (in) Input to parse from. ignore_comments (in) whether comments should be ignored and treated like whitespace (true) or yield a parse error (false); (optional, false by default) ignore_trailing_commas (in) whether trailing commas in arrays or objects should be ignored and treated like whitespace (true) or yield a parse error (false); (optional, false by default) first (in) iterator to the start of the character range last (in) iterator to the end of the character range, or a sentinel value that compares equal to the end iterator with operator!="},{"location":"api/basic_json/accept/#return-value","title":"Return value","text":"

Whether the input is valid JSON.

"},{"location":"api/basic_json/accept/#exception-safety","title":"Exception safety","text":"

Strong guarantee: if an exception is thrown, there are no changes in the JSON value.

"},{"location":"api/basic_json/accept/#exceptions","title":"Exceptions","text":"

Throws parse_error.101 in case of an empty input like a null FILE* or char* pointer.

"},{"location":"api/basic_json/accept/#complexity","title":"Complexity","text":"

Linear in the length of the input. The parser is a predictive LL(1) parser.

"},{"location":"api/basic_json/accept/#notes","title":"Notes","text":"

A UTF-8 byte order mark is silently ignored.

By default, a '\\0' (NUL) byte anywhere in the input is treated as end of input, rather than as an ordinary (and, outside of a string, invalid) byte; see the FAQ entry for details and the JSON_STRICT_NUL_HANDLING macro to opt into rejecting it instead.

"},{"location":"api/basic_json/accept/#examples","title":"Examples","text":"Example: (1) reading from a string

The example below demonstrates the accept() function reading from a string.

#include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // a valid JSON text\n    const auto* valid_text = R\"(\n    {\n        \"numbers\": [1, 2, 3]\n    }\n    )\";\n\n    // an invalid JSON text\n    const auto* invalid_text = R\"(\n    {\n        \"strings\": [\"extra\", \"comma\", ]\n    }\n    )\";\n\n    std::cout << std::boolalpha\n              << json::accept(valid_text) << ' '\n              << json::accept(invalid_text) << '\\n';\n}\n

Output:

true false\n
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.

#include <iostream>\n#include <vector>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // a buffer containing a JSON text followed by more data\n    std::vector<std::uint8_t> input = {'[', '1', ',', '2', ',', '3', ']', 'o', 't', 'h', 'e', 'r'};\n\n    std::cout << std::boolalpha\n              << json::accept(input.begin(), input.begin() + 7) << ' '\n              << json::accept(input.begin(), input.end()) << '\\n';\n}\n

Output:

true false\n
Example: (3) reading from UTF-16 strings

The encoding is deduced from the character type of the input. String literals like u\"...\", U\"...\", and L\"...\" work as well.

#include <iostream>\n#include <string>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // a valid JSON text, given as UTF-16\n    const std::u16string valid_text = u\"{\\\"name\\\":\\\"\\u00e9\\\"}\";\n\n    // an invalid JSON text, given as UTF-16\n    const std::u16string invalid_text = u\"{\\\"name\\\":\\\"\\u00e9\\\",}\";\n\n    std::cout << std::boolalpha\n              << json::accept(valid_text) << ' '\n              << json::accept(invalid_text) << '\\n';\n}\n

Output:

true false\n
"},{"location":"api/basic_json/accept/#see-also","title":"See also","text":"
  • parse - deserialize from a compatible input
  • sax_parse - parse input using the SAX interface
  • operator>> - deserialize from stream
  • JSON_STRICT_NUL_HANDLING - opt in to rejecting a NUL byte in the input instead of treating it as end of input
  • JSON_DISABLE_STREAM_BULK_SCAN - read a std::istream one character at a time
  • JSON_DISABLE_UNLOCKED_FILE_IO - read a FILE* with the locking stdio functions
  • Parsing - overview of the parsing functions
  • Comments - ignore // and /* */ comments while parsing
  • Trailing Commas - accept trailing commas in arrays and objects
  • Parsing and Exceptions - handling parse errors and locating them in the input
  • Parsing Untrusted Input - limits and checks for input you do not control
"},{"location":"api/basic_json/accept/#version-history","title":"Version history","text":"
  • Added in version 3.0.0.
  • Ignoring comments via ignore_comments added in version 3.9.0.
  • Changed runtime assertion in case of FILE* null pointers to exception in version 3.12.0.
  • Added ignore_trailing_commas in version 3.13.0 unreleased.
  • Extended container support (1) to include types with lvalue-only ADL begin/end (matching std::begin/std::end semantics) in version 3.13.0 unreleased.
  • Extended overload (2) to accept heterogeneous iterator+sentinel pairs (C++20 ranges support) in version 3.13.0 unreleased.
  • JSON_STRICT_NUL_HANDLING added in version 3.13.0 unreleased 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.
  • Parsing from an std::istream scans the characters in its stream buffer in bulk in version 3.13.0 unreleased (JSON_DISABLE_STREAM_BULK_SCAN).
  • Parsing from a FILE* locks the file once instead of once per character in version 3.13.0 unreleased (JSON_DISABLE_UNLOCKED_FILE_IO).
  • Ill-formed UTF-16 and UTF-32 input (a lone surrogate, a high surrogate that is not followed by its low surrogate, or a code point above U+10FFFF) is rejected in version 3.13.0 unreleased; before that, some such sequences were accepted or ended the input silently.

Deprecation

Overload (2) replaces calls to accept 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 accept({ptr, ptr+len}, ...); with accept(ptr, ptr+len, ...);.

You should be warned by your compiler with a -Wdeprecated-declarations warning if you are using a deprecated function.

See the migration guide for how to update existing code.

"},{"location":"api/basic_json/array/","title":"nlohmann::basic_json::array","text":"
static basic_json array(initializer_list_t init = {});\n

Creates a JSON array value from a given initializer list. That is, given a list of values a, b, c, creates the JSON value [a, b, c]. If the initializer list is empty, the empty array [] is created.

"},{"location":"api/basic_json/array/#parameters","title":"Parameters","text":"init (in) initializer list with JSON values to create an array from (optional)"},{"location":"api/basic_json/array/#return-value","title":"Return value","text":"

JSON array value

"},{"location":"api/basic_json/array/#exception-safety","title":"Exception safety","text":"

Strong guarantee: if an exception is thrown, there are no changes in the JSON value.

"},{"location":"api/basic_json/array/#complexity","title":"Complexity","text":"

Linear in the size of init.

"},{"location":"api/basic_json/array/#notes","title":"Notes","text":"

This function is only needed to express two edge cases that cannot be realized with the initializer list constructor (basic_json(initializer_list_t, bool, value_t)). These cases are:

  1. creating an array whose elements are all pairs whose first element is a string \u2014 in this case, the initializer list constructor would create an object, taking the first elements as keys
  2. creating an empty array \u2014 passing the empty initializer list to the initializer list constructor yields an empty object
"},{"location":"api/basic_json/array/#examples","title":"Examples","text":"Example

The following code shows an example for the array function.

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create JSON arrays\n    json j_no_init_list = json::array();\n    json j_empty_init_list = json::array({});\n    json j_nonempty_init_list = json::array({1, 2, 3, 4});\n    json j_list_of_pairs = json::array({ {\"one\", 1}, {\"two\", 2} });\n\n    // serialize the JSON arrays\n    std::cout << j_no_init_list << '\\n';\n    std::cout << j_empty_init_list << '\\n';\n    std::cout << j_nonempty_init_list << '\\n';\n    std::cout << j_list_of_pairs << '\\n';\n}\n

Output:

[]\n[]\n[1,2,3,4]\n[[\"one\",1],[\"two\",2]]\n
"},{"location":"api/basic_json/array/#see-also","title":"See also","text":"
  • basic_json(initializer_list_t) - create a JSON value from an initializer list
  • object - create a JSON object value from an initializer list
  • Creating JSON values - the article on creating JSON values
"},{"location":"api/basic_json/array/#version-history","title":"Version history","text":"
  • Added in version 1.0.0.
"},{"location":"api/basic_json/array_t/","title":"nlohmann::basic_json::array_t","text":"
using array_t = ArrayType<basic_json, AllocatorType<basic_json>>;\n

The type used to store JSON arrays.

RFC 8259 describes JSON arrays as follows:

An array is an ordered sequence of zero or more values.

To store objects in C++, a type is defined by the template parameters explained below.

"},{"location":"api/basic_json/array_t/#template-parameters","title":"Template parameters","text":"ArrayType container type to store arrays. It must be a vector-like container: the library uses operator[], at(), and resize(), and requires random-access iterators. std::vector and std::deque qualify; std::list does not. See Template Parameter Requirements for the full list of requirements. AllocatorType the allocator to use for objects (e.g., std::allocator)"},{"location":"api/basic_json/array_t/#notes","title":"Notes","text":""},{"location":"api/basic_json/array_t/#default-type","title":"Default type","text":"

With the default values for ArrayType (std::vector) and AllocatorType (std::allocator), the default type for array_t is:

std::vector<\n  basic_json, // value_type\n  std::allocator<basic_json> // allocator_type\n>\n
"},{"location":"api/basic_json/array_t/#limits","title":"Limits","text":"

RFC 8259 specifies:

An implementation may set limits on the maximum depth of nesting.

In this class, the array's limit of nesting is not explicitly constrained. However, a maximum depth of nesting may be introduced by the compiler or runtime environment. A theoretical limit can be queried by calling the max_size function of a JSON array.

"},{"location":"api/basic_json/array_t/#storage","title":"Storage","text":"

Arrays are stored as pointers in a basic_json type. That is, for any access to array values, a pointer of type array_t* must be dereferenced.

"},{"location":"api/basic_json/array_t/#examples","title":"Examples","text":"Example

The following code shows that array_t is by default, a typedef to std::vector<nlohmann::json>.

#include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    std::cout << std::boolalpha << std::is_same<std::vector<json>, json::array_t>::value << '\\n';\n}\n

Output:

true\n
"},{"location":"api/basic_json/array_t/#see-also","title":"See also","text":"
  • object_t - the type used to store JSON objects
  • binary_t - the type used to store binary values
  • is_array - checks whether the JSON value is an array
  • max_size - returns the maximum possible number of elements
  • Types - how arrays are stored
  • Template Parameter Requirements - requirements on the ArrayType template parameter
"},{"location":"api/basic_json/array_t/#version-history","title":"Version history","text":"
  • Added in version 1.0.0.
  • Made capacity() optional, so that array types such as std::deque can be used, in version 3.13.0 unreleased.
"},{"location":"api/basic_json/as_base_class/","title":"nlohmann::basic_json::as_base_class","text":"
json_base_class_t& as_base_class() noexcept;\nconst json_base_class_t& as_base_class() const noexcept;\n

Returns a reference to this object as its custom base class json_base_class_t. No copy is made.

Since basic_json derives from json_base_class_t, a member of basic_json hides any member of the custom base class with the same name. This function makes such hidden members accessible again.

"},{"location":"api/basic_json/as_base_class/#return-value","title":"Return value","text":"

reference to this object as json_base_class_t

"},{"location":"api/basic_json/as_base_class/#exception-safety","title":"Exception safety","text":"

No-throw guarantee: this function never throws exceptions.

"},{"location":"api/basic_json/as_base_class/#complexity","title":"Complexity","text":"

Constant.

"},{"location":"api/basic_json/as_base_class/#notes","title":"Notes","text":"

The function is equivalent to static_cast<json_base_class_t&>(j) (or static_cast<const json_base_class_t&>(j)).

"},{"location":"api/basic_json/as_base_class/#examples","title":"Examples","text":"Example

The example shows how to use as_base_class to access members of the custom base class that are hidden by members of basic_json.

#include <iostream>\n#include <nlohmann/json.hpp>\n\nclass base_class_with_hidden_members\n{\n  public:\n    const char* type_name() const noexcept\n    {\n        return \"my_type_name\";\n    }\n\n    std::size_t size() const noexcept\n    {\n        return 42;\n    }\n};\n\nusing json = nlohmann::json::with_base_class_t<base_class_with_hidden_members>;\n\nint main()\n{\n    json j = {1, 2, 3};\n\n    // the members of basic_json hide the members of the base class\n    std::cout << j.type_name() << ' ' << j.size() << '\\n';\n\n    // access the hidden members of the base class\n    std::cout << j.as_base_class().type_name() << ' ' << j.as_base_class().size() << '\\n';\n}\n

Output:

array 3\nmy_type_name 42\n
"},{"location":"api/basic_json/as_base_class/#see-also","title":"See also","text":"
  • json_base_class_t - type of the custom base class
  • Template Parameter Requirements - requirements on the CustomBaseClass template parameter
"},{"location":"api/basic_json/as_base_class/#version-history","title":"Version history","text":"
  • Added in version 3.13.0 unreleased.
"},{"location":"api/basic_json/at/","title":"nlohmann::basic_json::at","text":"
// (1)\nreference at(size_type idx);\nconst_reference at(size_type idx) const;\n\n// (2)\nreference at(const typename object_t::key_type& key);\nconst_reference at(const typename object_t::key_type& key) const;\n\n// (3)\ntemplate<typename KeyType>\nreference at(KeyType&& key);\ntemplate<typename KeyType>\nconst_reference at(KeyType&& key) const;\n\n// (4)\nreference at(const json_pointer& ptr);\nconst_reference at(const json_pointer& ptr) const;\n
  1. Returns a reference to the array element at specified location idx, with bounds checking.
  2. Returns a reference to the object element with specified key key, with bounds checking.
  3. See 2. This overload is only available if KeyType is comparable with typename object_t::key_type and typename object_comparator_t::is_transparent denotes a type.
  4. Returns a reference to the element at specified JSON pointer ptr, with bounds checking.
"},{"location":"api/basic_json/at/#template-parameters","title":"Template parameters","text":"KeyType A type for an object key other than json_pointer that is comparable with string_t using object_comparator_t. This can also be a string view (C++17)."},{"location":"api/basic_json/at/#parameters","title":"Parameters","text":"idx (in) index of the element to access key (in) object key of the elements to access ptr (in) JSON pointer to the desired element"},{"location":"api/basic_json/at/#return-value","title":"Return value","text":"
  1. reference to the element at index idx
  2. reference to the element at key key
  3. reference to the element at key key
  4. reference to the element pointed to by ptr
"},{"location":"api/basic_json/at/#exception-safety","title":"Exception safety","text":"

Strong exception safety: if an exception occurs, the original value stays intact.

"},{"location":"api/basic_json/at/#exceptions","title":"Exceptions","text":"
  1. The function can throw the following exceptions:
    • Throws type_error.304 if the JSON value is not an array; in this case, calling at with an index makes no sense. See the example below.
    • Throws out_of_range.401 if the index idx is out of range of the array; that is, idx >= size(). See the example below.
  2. The function can throw the following exceptions:
    • Throws type_error.304 if the JSON value is not an object; in this case, calling at with a key makes no sense. See the example below.
    • Throws out_of_range.403 if the key key is not stored in the object; that is, find(key) == end(). See the example below.
  3. See 2.
  4. The function can throw the following exceptions:
    • Throws parse_error.106 if an array index in the passed JSON pointer ptr begins with '0'. See the example below.
    • Throws parse_error.109 if an array index in the passed JSON pointer ptr is not a number. See the example below.
    • Throws out_of_range.401 if an array index in the passed JSON pointer ptr is out of range. See the example below.
    • Throws out_of_range.402 if the array index '-' is used in the passed JSON pointer ptr. As at provides checked access (and no elements are implicitly inserted), the index '-' is always invalid. See the example below.
    • Throws out_of_range.403 if the JSON pointer describes a key of an object which cannot be found. See the example below.
    • Throws out_of_range.404 if the JSON pointer ptr can not be resolved. See the example below.
    • Throws out_of_range.410 if an array index in the passed JSON pointer ptr exceeds the range of size_type (e.g., on 32-bit platforms).
"},{"location":"api/basic_json/at/#complexity","title":"Complexity","text":"
  1. Constant.
  2. Logarithmic in the size of the container.
  3. Logarithmic in the size of the container.
  4. Logarithmic in the size of the container.
"},{"location":"api/basic_json/at/#notes","title":"Notes","text":"

Deprecation

Overload (4) also accepts a json_pointer 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 for how to update existing code.

"},{"location":"api/basic_json/at/#examples","title":"Examples","text":"Example: (1) access specified array element with bounds checking

The example below shows how array elements can be read and written using at(). It also demonstrates the different exceptions that can be thrown.

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create JSON array\n    json array = {\"first\", \"2nd\", \"third\", \"fourth\"};\n\n    // output element at index 2 (third element)\n    std::cout << array.at(2) << '\\n';\n\n    // change element at index 1 (second element) to \"second\"\n    array.at(1) = \"second\";\n\n    // output changed array\n    std::cout << array << '\\n';\n\n    // exception type_error.304\n    try\n    {\n        // use at() on a non-array type\n        json str = \"I am a string\";\n        str.at(0) = \"Another string\";\n    }\n    catch (const json::type_error& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n\n    // exception out_of_range.401\n    try\n    {\n        // try to write beyond the array limit\n        array.at(5) = \"sixth\";\n    }\n    catch (const json::out_of_range& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n}\n

Output:

\"third\"\n[\"first\",\"second\",\"third\",\"fourth\"]\n[json.exception.type_error.304] cannot use at() with string\n[json.exception.out_of_range.401] array index 5 is out of range\n
Example: (1) access specified array element with bounds checking

The example below shows how array elements can be read using at(). It also demonstrates the different exceptions that can be thrown.

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create JSON array\n    const json array = {\"first\", \"2nd\", \"third\", \"fourth\"};\n\n    // output element at index 2 (third element)\n    std::cout << array.at(2) << '\\n';\n\n    // exception type_error.304\n    try\n    {\n        // use at() on a non-array type\n        const json str = \"I am a string\";\n        std::cout << str.at(0) << '\\n';\n    }\n    catch (const json::type_error& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n\n    // exception out_of_range.401\n    try\n    {\n        // try to read beyond the array limit\n        std::cout << array.at(5) << '\\n';\n    }\n    catch (const json::out_of_range& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n}\n

Output:

\"third\"\n[json.exception.type_error.304] cannot use at() with string\n[json.exception.out_of_range.401] array index 5 is out of range\n
Example: (2) access specified object element with bounds checking

The example below shows how object elements can be read and written using at(). It also demonstrates the different exceptions that can be thrown.

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create JSON object\n    json object =\n    {\n        {\"the good\", \"il buono\"},\n        {\"the bad\", \"il cattivo\"},\n        {\"the ugly\", \"il brutto\"}\n    };\n\n    // output element with key \"the ugly\"\n    std::cout << object.at(\"the ugly\") << '\\n';\n\n    // change element with key \"the bad\"\n    object.at(\"the bad\") = \"il cattivo\";\n\n    // output changed array\n    std::cout << object << '\\n';\n\n    // exception type_error.304\n    try\n    {\n        // use at() on a non-object type\n        json str = \"I am a string\";\n        str.at(\"the good\") = \"Another string\";\n    }\n    catch (const json::type_error& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n\n    // exception out_of_range.401\n    try\n    {\n        // try to write at a nonexisting key\n        object.at(\"the fast\") = \"il rapido\";\n    }\n    catch (const json::out_of_range& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n}\n

Output:

\"il brutto\"\n{\"the bad\":\"il cattivo\",\"the good\":\"il buono\",\"the ugly\":\"il brutto\"}\n[json.exception.type_error.304] cannot use at() with string\n[json.exception.out_of_range.403] key 'the fast' not found\n
Example: (2) access specified object element with bounds checking

The example below shows how object elements can be read using at(). It also demonstrates the different exceptions that can be thrown.

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create JSON object\n    const json object =\n    {\n        {\"the good\", \"il buono\"},\n        {\"the bad\", \"il cattivo\"},\n        {\"the ugly\", \"il brutto\"}\n    };\n\n    // output element with key \"the ugly\"\n    std::cout << object.at(\"the ugly\") << '\\n';\n\n    // exception type_error.304\n    try\n    {\n        // use at() on a non-object type\n        const json str = \"I am a string\";\n        std::cout << str.at(\"the good\") << '\\n';\n    }\n    catch (const json::type_error& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n\n    // exception out_of_range.401\n    try\n    {\n        // try to read from a nonexisting key\n        std::cout << object.at(\"the fast\") << '\\n';\n    }\n    catch (const json::out_of_range)\n    {\n        std::cout << \"out of range\" << '\\n';\n    }\n}\n

Output:

\"il brutto\"\n[json.exception.type_error.304] cannot use at() with string\nout of range\n
Example: (3) access specified object element using string_view with bounds checking

The example below shows how object elements can be read and written using at(). It also demonstrates the different exceptions that can be thrown.

#include <iostream>\n#include <string_view>\n#include <nlohmann/json.hpp>\n\nusing namespace std::string_view_literals;\nusing nlohmann::json;\n\nint main()\n{\n    // create JSON object\n    json object =\n    {\n        {\"the good\", \"il buono\"},\n        {\"the bad\", \"il cattivo\"},\n        {\"the ugly\", \"il brutto\"}\n    };\n\n    // output element with key \"the ugly\" using string_view\n    std::cout << object.at(\"the ugly\"sv) << '\\n';\n\n    // change element with key \"the bad\" using string_view\n    object.at(\"the bad\"sv) = \"il cattivo\";\n\n    // output changed array\n    std::cout << object << '\\n';\n\n    // exception type_error.304\n    try\n    {\n        // use at() with string_view on a non-object type\n        json str = \"I am a string\";\n        str.at(\"the good\"sv) = \"Another string\";\n    }\n    catch (const json::type_error& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n\n    // exception out_of_range.401\n    try\n    {\n        // try to write at a nonexisting key using string_view\n        object.at(\"the fast\"sv) = \"il rapido\";\n    }\n    catch (const json::out_of_range& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n}\n

Output:

\"il brutto\"\n{\"the bad\":\"il cattivo\",\"the good\":\"il buono\",\"the ugly\":\"il brutto\"}\n[json.exception.type_error.304] cannot use at() with string\n[json.exception.out_of_range.403] key 'the fast' not found\n
Example: (3) access specified object element using string_view with bounds checking

The example below shows how object elements can be read using at(). It also demonstrates the different exceptions that can be thrown.

#include <iostream>\n#include <string_view>\n#include <nlohmann/json.hpp>\n\nusing namespace std::string_view_literals;\nusing nlohmann::json;\n\nint main()\n{\n    // create JSON object\n    const json object =\n    {\n        {\"the good\", \"il buono\"},\n        {\"the bad\", \"il cattivo\"},\n        {\"the ugly\", \"il brutto\"}\n    };\n\n    // output element with key \"the ugly\" using string_view\n    std::cout << object.at(\"the ugly\"sv) << '\\n';\n\n    // exception type_error.304\n    try\n    {\n        // use at() with string_view on a non-object type\n        const json str = \"I am a string\";\n        std::cout << str.at(\"the good\"sv) << '\\n';\n    }\n    catch (const json::type_error& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n\n    // exception out_of_range.401\n    try\n    {\n        // try to read from a nonexisting key using string_view\n        std::cout << object.at(\"the fast\"sv) << '\\n';\n    }\n    catch (const json::out_of_range& e)\n    {\n        std::cout << \"out of range\" << '\\n';\n    }\n}\n

Output:

\"il brutto\"\n[json.exception.type_error.304] cannot use at() with string\nout of range\n
Example: (4) access specified element via JSON Pointer

The example below shows how object elements can be read and written using at(). It also demonstrates the different exceptions that can be thrown.

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\nusing namespace nlohmann::literals;\n\nint main()\n{\n    // create a JSON value\n    json j =\n    {\n        {\"number\", 1}, {\"string\", \"foo\"}, {\"array\", {1, 2}}\n    };\n\n    // read-only access\n\n    // output element with JSON pointer \"/number\"\n    std::cout << j.at(\"/number\"_json_pointer) << '\\n';\n    // output element with JSON pointer \"/string\"\n    std::cout << j.at(\"/string\"_json_pointer) << '\\n';\n    // output element with JSON pointer \"/array\"\n    std::cout << j.at(\"/array\"_json_pointer) << '\\n';\n    // output element with JSON pointer \"/array/1\"\n    std::cout << j.at(\"/array/1\"_json_pointer) << '\\n';\n\n    // writing access\n\n    // change the string\n    j.at(\"/string\"_json_pointer) = \"bar\";\n    // output the changed string\n    std::cout << j[\"string\"] << '\\n';\n\n    // change an array element\n    j.at(\"/array/1\"_json_pointer) = 21;\n    // output the changed array\n    std::cout << j[\"array\"] << '\\n';\n\n    // out_of_range.106\n    try\n    {\n        // try to use an array index with leading '0'\n        json::reference ref = j.at(\"/array/01\"_json_pointer);\n    }\n    catch (const json::parse_error& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n\n    // out_of_range.109\n    try\n    {\n        // try to use an array index that is not a number\n        json::reference ref = j.at(\"/array/one\"_json_pointer);\n    }\n    catch (const json::parse_error& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n\n    // out_of_range.401\n    try\n    {\n        // try to use an invalid array index\n        json::reference ref = j.at(\"/array/4\"_json_pointer);\n    }\n    catch (const json::out_of_range& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n\n    // out_of_range.402\n    try\n    {\n        // try to use the array index '-'\n        json::reference ref = j.at(\"/array/-\"_json_pointer);\n    }\n    catch (const json::out_of_range& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n\n    // out_of_range.403\n    try\n    {\n        // try to use a JSON pointer to a nonexistent object key\n        json::const_reference ref = j.at(\"/foo\"_json_pointer);\n    }\n    catch (const json::out_of_range& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n\n    // out_of_range.404\n    try\n    {\n        // try to use a JSON pointer that cannot be resolved\n        json::reference ref = j.at(\"/number/foo\"_json_pointer);\n    }\n    catch (const json::out_of_range& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n}\n

Output:

1\n\"foo\"\n[1,2]\n2\n\"bar\"\n[1,21]\n[json.exception.parse_error.106] parse error: array index '01' must not begin with '0'\n[json.exception.parse_error.109] parse error: array index 'one' is not a number\n[json.exception.out_of_range.401] array index 4 is out of range\n[json.exception.out_of_range.402] array index '-' (2) is out of range\n[json.exception.out_of_range.403] key 'foo' not found\n[json.exception.out_of_range.404] unresolved reference token 'foo'\n
Example: (4) access specified element via JSON Pointer

The example below shows how object elements can be read using at(). It also demonstrates the different exceptions that can be thrown.

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\nusing namespace nlohmann::literals;\n\nint main()\n{\n    // create a JSON value\n    const json j =\n    {\n        {\"number\", 1}, {\"string\", \"foo\"}, {\"array\", {1, 2}}\n    };\n\n    // read-only access\n\n    // output element with JSON pointer \"/number\"\n    std::cout << j.at(\"/number\"_json_pointer) << '\\n';\n    // output element with JSON pointer \"/string\"\n    std::cout << j.at(\"/string\"_json_pointer) << '\\n';\n    // output element with JSON pointer \"/array\"\n    std::cout << j.at(\"/array\"_json_pointer) << '\\n';\n    // output element with JSON pointer \"/array/1\"\n    std::cout << j.at(\"/array/1\"_json_pointer) << '\\n';\n\n    // out_of_range.109\n    try\n    {\n        // try to use an array index that is not a number\n        json::const_reference ref = j.at(\"/array/one\"_json_pointer);\n    }\n    catch (const json::parse_error& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n\n    // out_of_range.401\n    try\n    {\n        // try to use an invalid array index\n        json::const_reference ref = j.at(\"/array/4\"_json_pointer);\n    }\n    catch (const json::out_of_range& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n\n    // out_of_range.402\n    try\n    {\n        // try to use the array index '-'\n        json::const_reference ref = j.at(\"/array/-\"_json_pointer);\n    }\n    catch (const json::out_of_range& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n\n    // out_of_range.403\n    try\n    {\n        // try to use a JSON pointer to a nonexistent object key\n        json::const_reference ref = j.at(\"/foo\"_json_pointer);\n    }\n    catch (const json::out_of_range& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n\n    // out_of_range.404\n    try\n    {\n        // try to use a JSON pointer that cannot be resolved\n        json::const_reference ref = j.at(\"/number/foo\"_json_pointer);\n    }\n    catch (const json::out_of_range& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n}\n

Output:

1\n\"foo\"\n[1,2]\n2\n[json.exception.parse_error.109] parse error: array index 'one' is not a number\n[json.exception.out_of_range.401] array index 4 is out of range\n[json.exception.out_of_range.402] array index '-' (2) is out of range\n[json.exception.out_of_range.403] key 'foo' not found\n[json.exception.out_of_range.404] unresolved reference token 'foo'\n
"},{"location":"api/basic_json/at/#see-also","title":"See also","text":"
  • Checked access - element access with range checking
  • operator[] - unchecked access by reference
  • value - access with default value
  • basic_json_view::at - the same access on a zero-copy view
  • Element Access - overview of all ways to access elements
  • JSON Pointer - access nested values with a pointer
"},{"location":"api/basic_json/at/#version-history","title":"Version history","text":"
  1. Added in version 1.0.0.
  2. Added in version 1.0.0.
  3. Added in version 3.11.0. Support for keys convertible to std::string_view added in version 3.13.0 unreleased, consistently across the lookup functions.
  4. Added in version 2.0.0. Throws parse_error.109 instead of out_of_range.404 for a one-character array index that is not a digit (e.g., /x) in version 3.13.0 unreleased, as it already did for longer ones.
"},{"location":"api/basic_json/back/","title":"nlohmann::basic_json::back","text":"
reference back();\n\nconst_reference back() const;\n

Returns a reference to the last element in the container. For a JSON container c, the expression c.back() is equivalent to

auto tmp = c.end();\n--tmp;\nreturn *tmp;\n
"},{"location":"api/basic_json/back/#return-value","title":"Return value","text":"

In the case of a structured type (array or object), a reference to the last element is returned. In the case of number, string, boolean, or binary values, a reference to the value is returned.

"},{"location":"api/basic_json/back/#exception-safety","title":"Exception safety","text":"

Strong guarantee: if an exception is thrown, there are no changes in the JSON value.

"},{"location":"api/basic_json/back/#exceptions","title":"Exceptions","text":"

If the JSON value is null, exception invalid_iterator.214 is thrown.

"},{"location":"api/basic_json/back/#complexity","title":"Complexity","text":"

Constant.

"},{"location":"api/basic_json/back/#notes","title":"Notes","text":"

Precondition

The array or object must not be empty. Calling back on an empty array or object yields undefined behavior.

"},{"location":"api/basic_json/back/#examples","title":"Examples","text":"Example

The following code shows an example for back().

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create JSON values\n    json j_boolean = true;\n    json j_number_integer = 17;\n    json j_number_float = 23.42;\n    json j_object = {{\"one\", 1}, {\"two\", 2}};\n    json j_object_empty(json::value_t::object);\n    json j_array = {1, 2, 4, 8, 16};\n    json j_array_empty(json::value_t::array);\n    json j_string = \"Hello, world\";\n\n    // call back()\n    std::cout << j_boolean.back() << '\\n';\n    std::cout << j_number_integer.back() << '\\n';\n    std::cout << j_number_float.back() << '\\n';\n    std::cout << j_object.back() << '\\n';\n    //std::cout << j_object_empty.back() << '\\n';  // undefined behavior\n    std::cout << j_array.back() << '\\n';\n    //std::cout << j_array_empty.back() << '\\n';   // undefined behavior\n    std::cout << j_string.back() << '\\n';\n\n    // back() called on a null value\n    try\n    {\n        json j_null;\n        j_null.back();\n    }\n    catch (const json::invalid_iterator& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n}\n

Output:

true\n17\n23.42\n2\n16\n\"Hello, world\"\n[json.exception.invalid_iterator.214] cannot get value\n
"},{"location":"api/basic_json/back/#see-also","title":"See also","text":"
  • front - to access the first element
  • basic_json_view::back - the same access on a zero-copy view
  • Element Access - overview of all ways to access elements
"},{"location":"api/basic_json/back/#version-history","title":"Version history","text":"
  • Added in version 1.0.0.
  • Binary values are supported since version 3.8.0.
"},{"location":"api/basic_json/basic_json/","title":"nlohmann::basic_json::basic_json","text":"
// (1)\nbasic_json(const value_t v);\n\n// (2)\nbasic_json(std::nullptr_t = nullptr) noexcept;\n\n// (3)\ntemplate<typename CompatibleType>\nbasic_json(CompatibleType&& val) noexcept(noexcept(\n           JSONSerializer<U>::to_json(std::declval<basic_json_t&>(),\n                                      std::forward<CompatibleType>(val))));\n\n// (4)\ntemplate<typename BasicJsonType>\nbasic_json(const BasicJsonType& val);\n\n// (5)\nbasic_json(initializer_list_t init,\n           bool type_deduction = true,\n           value_t manual_type = value_t::array);\n\n// (6)\nbasic_json(size_type cnt, const basic_json& val);\n\n// (7)\nbasic_json(iterator first, iterator last);\nbasic_json(const_iterator first, const_iterator last);\n\n// (8)\nbasic_json(const basic_json& other);\n\n// (9)\nbasic_json(basic_json&& other) noexcept;\n
  1. Create an empty JSON value with a given type. The value will be default initialized with an empty value which depends on the type:

    Value type initial value null null boolean false string \"\" number 0 object {} array [] binary empty array

    The postcondition of this constructor can be restored by calling clear().

  2. Create a null JSON value. It either takes a null pointer as parameter (explicitly creating null) or no parameter (implicitly creating null). The passed null pointer itself is not read \u2014 it is only used to choose the right constructor.

  3. This is a \"catch all\" constructor for all compatible JSON types; that is, types for which a to_json() method exists. The constructor forwards the parameter val to that method (to json_serializer<U>::to_json method with U = uncvref_t<CompatibleType>, to be exact).

    Template type CompatibleType includes, but is not limited to, the following types:

    • arrays: array_t and all kinds of compatible containers such as std::vector, std::deque, std::list, std::forward_list, std::array, std::valarray, std::set, std::unordered_set, std::multiset, and std::unordered_multiset with a value_type from which a basic_json value can be constructed.
    • objects: object_t and all kinds of compatible associative containers such as std::map, std::unordered_map, std::multimap, and std::unordered_multimap with a key_type compatible to string_t and a value_type from which a basic_json value can be constructed.
    • strings: string_t, string literals, and all compatible string containers can be used.

    Rvalue containers are moved from

    If val is an rvalue of a compatible array-like or object-like container other than array_t/object_t (e.g., json j = std::move(vec); or json j(std::vector<std::string>{...});), the elements are moved into the JSON value instead of copied. Afterwards, the elements of the source container are in a valid but unspecified state (moved-from). Keys of associative containers are const and therefore still copied. Lvalues and const rvalues are copied, and the source is left unchanged.

    • numbers: number_integer_t, number_unsigned_t, number_float_t, and all convertible number types such as int, size_t, int64_t, float or double can be used.
    • boolean: boolean_t / bool can be used.
    • binary: binary_t / std::vector<uint8_t> may be used; unfortunately because string literals cannot be distinguished from binary character arrays by the C++ type system, all types compatible with const char* will be directed to the string constructor instead. This is both for backwards compatibility and due to the fact that a binary type is not a standard JSON type.

    See the examples below.

  4. This is a constructor for existing basic_json types. It does not hijack copy/move constructors, since the parameter has different template arguments than the current ones.

    The constructor tries to convert the internal m_value of the parameter. Each member value (object, array, string, etc.) is serialized via the corresponding to_json() overload. For objects and strings, the conversion requires that the target basic_json type's object_t::key_type (or string_t) be directly constructible from the source type's corresponding member type via is_constructible. If this requirement is not met, the conversion does not fail to compile; instead, it silently falls back to the array-conversion path, which represents objects as arrays of [key, value] pairs and strings as arrays of character codes. This is a known limitation tracked in issue #3425.

  5. Creates a JSON value of type array or object from the passed initializer list init. In case type_deduction is true (default), the type of the JSON value to be created is deducted from the initializer list init according to the following rules:

    1. If the list is empty, an empty JSON object value {} is created.
    2. If the list consists of pairs whose first element is a string, a JSON object value is created where the first 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 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):

    flowchart TD\n    A([\"initializer_list init\"]) --> B{{\"empty, or every element is a 2-element<br/>array whose first element is a string?\"}}\n    B -->|\"yes\"| C{{\"type_deduction\"}}\n    B -->|\"no\"| D{{\"type_deduction\"}}\n    C -->|\"true\"| OBJ[\"create object\"]\n    C -->|\"false\"| E{{\"manual_type\"}}\n    E -->|\"object\"| OBJ\n    E -->|\"array\"| ARR[\"create array\"]\n    D -->|\"true\"| ARR\n    D -->|\"false\"| F{{\"manual_type\"}}\n    F -->|\"array\"| ARR\n    F -->|\"object\"| ERR[\"throw type_error.301\"]

    Decision flow for an initializer list: hexagons are checks, edge labels are their outcomes, and rectangles are the resulting value or exception.

    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 {} which is exactly an empty JSON object.
    2. C++ has no way of describing mapped types other than to list a list of pairs. As JSON requires that keys must be of type string, rule 2 is the weakest constraint one can pose on initializer lists to interpret them as an object.
    3. In all other cases, the initializer list could not be interpreted as a JSON object type, so interpreting it as a JSON array type is safe.

    With the rules described above, the following JSON values cannot be expressed by an initializer list:

    • the empty array ([]): use array(initializer_list_t) with an empty initializer list in this case
    • arrays whose elements satisfy rule 2: use array(initializer_list_t) with the same initializer list in this case

    Function array() and object() force array and object creation from initializer lists, respectively.

    Brace initialization yields arrays

    Because this constructor takes an initializer_list_t, brace-initializing a json/ordered_json from another json value wraps it in a single-element array rather than copying it:

    json j1 = \"hello\";\njson j2{j1};   // [!] j2 is [\"hello\"], NOT a copy of j1\njson j3(j1);   // j3 is \"hello\" -- parentheses copy as expected\n

    See the FAQ entry on brace initialization for the full explanation, an opt-in macro to change this behavior, and how to explicitly create a single-element array (json::array({value})) if that is what you want.

  6. Constructs a JSON array value by creating cnt copies of a passed value. In case cnt is 0, an empty array is created.

  7. Constructs the JSON value with the contents of the range [first, last). The semantics depend on the different types a JSON value can have:

    • In case of a null type, invalid_iterator.206 is thrown.
    • 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 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.
  8. Creates a copy of a given JSON value.

  9. Move constructor. Constructs a JSON value with the contents of the given value other using move semantics. It \"steals\" the resources from other and leaves it as JSON null value.

"},{"location":"api/basic_json/basic_json/#template-parameters","title":"Template parameters","text":"CompatibleType

a type such that:

  • CompatibleType is not derived from std::istream,
  • CompatibleType is not basic_json (to avoid hijacking copy/move constructors),
  • CompatibleType is not a different basic_json type (i.e. with different template arguments)
  • CompatibleType is not a basic_json nested type (e.g., json_pointer, iterator, etc.)
  • if JSON_DISABLE_TUPLE_REFERENCE_CONVERSION is defined to 1: CompatibleType is not a one-element std::tuple holding a reference to basic_json
  • json_serializer<U> (with U = uncvref_t<CompatibleType>) has a to_json(basic_json_t&, CompatibleType&&) method
BasicJsonType:

a type such that:

  • BasicJsonType is a basic_json type.
  • 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 this requirement is not met.

U: uncvref_t<CompatibleType>"},{"location":"api/basic_json/basic_json/#parameters","title":"Parameters","text":"v (in) the type of the value to create val (in) the value to be forwarded to the respective constructor init (in) initializer list with JSON values type_deduction (in) internal parameter; when set to true, the type of the JSON value is deducted from the initializer list init; when set to false, the type provided via manual_type is forced. This mode is used by the functions array(initializer_list_t) and object(initializer_list_t). manual_type (in) internal parameter; when type_deduction is set to false, the created JSON value will use the provided type (only value_t::array and value_t::object are valid); when type_deduction is set to true, this parameter has no effect cnt (in) the number of JSON copies of val to create first (in) the beginning of the range to copy from (included) last (in) the end of the range to copy from (excluded) other (in) the JSON value to copy/move"},{"location":"api/basic_json/basic_json/#exception-safety","title":"Exception safety","text":"
  1. Strong guarantee: if an exception is thrown, there are no changes to any JSON value.
  2. No-throw guarantee: this constructor never throws exceptions.
  3. Depends on the called constructor. For types directly supported by the library (i.e., all types for which no to_json() function was provided), a strong guarantee holds: if an exception is thrown, there are no changes to any JSON value. Exception: when val is an rvalue array-like or object-like container, its elements are moved one by one; if an exception is thrown in the middle of the conversion (e.g., an allocation failure), the JSON value is unchanged, but the source container may be left partially moved-from.
  4. Depends on the called constructor. For types directly supported by the library (i.e., all types for which no to_json() function was provided), a strong guarantee holds: if an exception is thrown, there are no changes to any JSON value.
  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.
  8. Strong guarantee: if an exception is thrown, there are no changes to any JSON value.
  9. No-throw guarantee: this constructor never throws exceptions.
"},{"location":"api/basic_json/basic_json/#exceptions","title":"Exceptions","text":"
  1. (none)
  2. The function does not throw exceptions.
  3. (none)
  4. (none)
  5. The function can throw the following exceptions:
    • Throws type_error.301 if type_deduction is false, manual_type is value_t::object, but init contains an element which is not a pair whose first element is a string. In this case, the constructor could not create an object. If type_deduction would have been true, an array would have been created. See object(initializer_list_t) for an example.
  6. (none)
  7. The function can throw the following exceptions:
    • Throws invalid_iterator.201 if iterators first 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 if iterators first 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 if iterators first and last belong to a null value. In this case, the range [first, last) is undefined.
  8. (none)
  9. The function does not throw exceptions.
"},{"location":"api/basic_json/basic_json/#complexity","title":"Complexity","text":"
  1. Constant.
  2. Constant.
  3. Usually linear in the size of the passed val, also depending on the implementation of the called to_json() method.
  4. Usually linear in the size of the passed val, also depending on the implementation of the called to_json() method.
  5. Linear in the size of the initializer list init.
  6. Linear in cnt.
  7. Linear in distance between first and last.
  8. Linear in the size of other.
  9. Constant.
"},{"location":"api/basic_json/basic_json/#notes","title":"Notes","text":"
  • Overload 5:

    Empty initializer list

    When used without parentheses around an empty initializer list, basic_json() is called instead of this function, yielding the JSON null value.

  • Overload 4:

    Implicit conversion

    The conversion is implicit unless JSON_USE_IMPLICIT_CONVERSIONS is defined to 0 and BasicJsonType::string_t differs from string_t. In that case, the constructor is explicit, so a JSON value with a different string type is no longer silently converted, for example when it is passed to a function taking const json&. Write json(other) or other.get<json>() instead.

  • Overload 7:

    Preconditions

    • Iterators first and last must be initialized. **This precondition is enforced with a runtime assertion.
    • Range [first, last) is valid. Usually, this precondition cannot be checked efficiently. Only certain edge cases are detected; see the description of the exceptions above. A violation of this precondition yields undefined behavior.

    Runtime assertion

    A precondition is enforced with a runtime assertion.

  • Overload 8:

    Postcondition

    *this == other

  • Overload 9:

    Postconditions

    • *thishas the same value asother` before the call.
    • other is a JSON null value
"},{"location":"api/basic_json/basic_json/#examples","title":"Examples","text":"Example: (1) create an empty value with a given type

The following code shows the constructor for different value_t values.

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create the different JSON values with default values\n    json j_null(json::value_t::null);\n    json j_boolean(json::value_t::boolean);\n    json j_number_integer(json::value_t::number_integer);\n    json j_number_float(json::value_t::number_float);\n    json j_object(json::value_t::object);\n    json j_array(json::value_t::array);\n    json j_string(json::value_t::string);\n\n    // serialize the JSON values\n    std::cout << j_null << '\\n';\n    std::cout << j_boolean << '\\n';\n    std::cout << j_number_integer << '\\n';\n    std::cout << j_number_float << '\\n';\n    std::cout << j_object << '\\n';\n    std::cout << j_array << '\\n';\n    std::cout << j_string << '\\n';\n}\n

Output:

null\nfalse\n0\n0.0\n{}\n[]\n\"\"\n
Example: (2) create a null object

The following code shows the constructor with and without a null pointer parameter.

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // implicitly create a JSON null value\n    json j1;\n\n    // explicitly create a JSON null value\n    json j2(nullptr);\n\n    // serialize the JSON null value\n    std::cout << j1 << '\\n' << j2 << '\\n';\n}\n

Output:

null\nnull\n
Example: (3) create a JSON value from compatible types

The following code shows the constructor with several compatible types.

#include <iostream>\n#include <deque>\n#include <list>\n#include <forward_list>\n#include <set>\n#include <unordered_map>\n#include <unordered_set>\n#include <valarray>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // ============\n    // object types\n    // ============\n\n    // create an object from an object_t value\n    json::object_t object_value = { {\"one\", 1}, {\"two\", 2} };\n    json j_object_t(object_value);\n\n    // create an object from std::map\n    std::map<std::string, int> c_map\n    {\n        {\"one\", 1}, {\"two\", 2}, {\"three\", 3}\n    };\n    json j_map(c_map);\n\n    // create an object from std::unordered_map\n    std::unordered_map<const char*, double> c_umap\n    {\n        {\"one\", 1.2}, {\"two\", 2.3}, {\"three\", 3.4}\n    };\n    json j_umap(c_umap);\n\n    // create an object from std::multimap\n    std::multimap<std::string, bool> c_mmap\n    {\n        {\"one\", true}, {\"two\", true}, {\"three\", false}, {\"three\", true}\n    };\n    json j_mmap(c_mmap); // only one entry for key \"three\" is used\n\n    // create an object from std::unordered_multimap\n    std::unordered_multimap<std::string, bool> c_ummap\n    {\n        {\"one\", true}, {\"two\", true}, {\"three\", false}, {\"three\", false}\n    };\n    json j_ummap(c_ummap); // only one entry for key \"three\" is used\n\n    // serialize the JSON objects\n    std::cout << j_object_t << '\\n';\n    std::cout << j_map << '\\n';\n    std::cout << j_umap << '\\n';\n    std::cout << j_mmap << '\\n';\n    std::cout << j_ummap << \"\\n\\n\";\n\n    // ===========\n    // array types\n    // ===========\n\n    // create an array from an array_t value\n    json::array_t array_value = {\"one\", \"two\", 3, 4.5, false};\n    json j_array_t(array_value);\n\n    // create an array from std::vector\n    std::vector<int> c_vector {1, 2, 3, 4};\n    json j_vec(c_vector);\n\n    // create an array from std::valarray\n    std::valarray<short> c_valarray {10, 9, 8, 7};\n    json j_valarray(c_valarray);\n\n    // create an array from std::deque\n    std::deque<double> c_deque {1.2, 2.3, 3.4, 5.6};\n    json j_deque(c_deque);\n\n    // create an array from std::list\n    std::list<bool> c_list {true, true, false, true};\n    json j_list(c_list);\n\n    // create an array from std::forward_list\n    std::forward_list<std::int64_t> c_flist {12345678909876, 23456789098765, 34567890987654, 45678909876543};\n    json j_flist(c_flist);\n\n    // create an array from std::array\n    std::array<unsigned long, 4> c_array {{1, 2, 3, 4}};\n    json j_array(c_array);\n\n    // create an array from std::set\n    std::set<std::string> c_set {\"one\", \"two\", \"three\", \"four\", \"one\"};\n    json j_set(c_set); // only one entry for \"one\" is used\n\n    // create an array from std::unordered_set\n    std::unordered_set<std::string> c_uset {\"one\", \"one\"};\n    json j_uset(c_uset); // only one entry for \"one\" is used\n\n    // create an array from std::multiset\n    std::multiset<std::string> c_mset {\"one\", \"two\", \"one\", \"four\"};\n    json j_mset(c_mset); // both entries for \"one\" are used\n\n    // create an array from std::unordered_multiset\n    std::unordered_multiset<std::string> c_umset {\"one\", \"one\"};\n    json j_umset(c_umset); // both entries for \"one\" are used\n\n    // serialize the JSON arrays\n    std::cout << j_array_t << '\\n';\n    std::cout << j_vec << '\\n';\n    std::cout << j_valarray << '\\n';\n    std::cout << j_deque << '\\n';\n    std::cout << j_list << '\\n';\n    std::cout << j_flist << '\\n';\n    std::cout << j_array << '\\n';\n    std::cout << j_set << '\\n';\n    std::cout << j_uset << '\\n';\n    std::cout << j_mset << '\\n';\n    std::cout << j_umset << \"\\n\\n\";\n\n    // ============\n    // string types\n    // ============\n\n    // create string from a string_t value\n    json::string_t string_value = \"The quick brown fox jumps over the lazy dog.\";\n    json j_string_t(string_value);\n\n    // create a JSON string directly from a string literal\n    json j_string_literal(\"The quick brown fox jumps over the lazy dog.\");\n\n    // create string from std::string\n    std::string s_stdstring = \"The quick brown fox jumps over the lazy dog.\";\n    json j_stdstring(s_stdstring);\n\n    // serialize the JSON strings\n    std::cout << j_string_t << '\\n';\n    std::cout << j_string_literal << '\\n';\n    std::cout << j_stdstring << \"\\n\\n\";\n\n    // ============\n    // number types\n    // ============\n\n    // create a JSON number from number_integer_t\n    json::number_integer_t value_integer_t = -42;\n    json j_integer_t(value_integer_t);\n\n    // create a JSON number from number_unsigned_t\n    json::number_integer_t value_unsigned_t = 17;\n    json j_unsigned_t(value_unsigned_t);\n\n    // create a JSON number from an anonymous enum\n    enum { enum_value = 17 };\n    json j_enum(enum_value);\n\n    // create values of different integer types\n    short n_short = 42;\n    int n_int = -23;\n    long n_long = 1024;\n    int_least32_t n_int_least32_t = -17;\n    uint8_t n_uint8_t = 8;\n\n    // create (integer) JSON numbers\n    json j_short(n_short);\n    json j_int(n_int);\n    json j_long(n_long);\n    json j_int_least32_t(n_int_least32_t);\n    json j_uint8_t(n_uint8_t);\n\n    // create values of different floating-point types\n    json::number_float_t v_ok = 3.141592653589793;\n    json::number_float_t v_nan = NAN;\n    json::number_float_t v_infinity = INFINITY;\n\n    // create values of different floating-point types\n    float n_float = 42.23;\n    float n_float_nan = 1.0f / 0.0f;\n    double n_double = 23.42;\n\n    // create (floating point) JSON numbers\n    json j_ok(v_ok);\n    json j_nan(v_nan);\n    json j_infinity(v_infinity);\n    json j_float(n_float);\n    json j_float_nan(n_float_nan);\n    json j_double(n_double);\n\n    // serialize the JSON numbers\n    std::cout << j_integer_t << '\\n';\n    std::cout << j_unsigned_t << '\\n';\n    std::cout << j_enum << '\\n';\n    std::cout << j_short << '\\n';\n    std::cout << j_int << '\\n';\n    std::cout << j_long << '\\n';\n    std::cout << j_int_least32_t << '\\n';\n    std::cout << j_uint8_t << '\\n';\n    std::cout << j_ok << '\\n';\n    std::cout << j_nan << '\\n';\n    std::cout << j_infinity << '\\n';\n    std::cout << j_float << '\\n';\n    std::cout << j_float_nan << '\\n';\n    std::cout << j_double << \"\\n\\n\";\n\n    // =============\n    // boolean types\n    // =============\n\n    // create boolean values\n    json j_truth = true;\n    json j_falsity = false;\n\n    // serialize the JSON booleans\n    std::cout << j_truth << '\\n';\n    std::cout << j_falsity << '\\n';\n}\n

Output:

{\"one\":1,\"two\":2}\n{\"one\":1,\"three\":3,\"two\":2}\n{\"one\":1.2,\"three\":3.4,\"two\":2.3}\n{\"one\":true,\"three\":false,\"two\":true}\n{\"one\":true,\"three\":false,\"two\":true}\n\n[\"one\",\"two\",3,4.5,false]\n[1,2,3,4]\n[10,9,8,7]\n[1.2,2.3,3.4,5.6]\n[true,true,false,true]\n[12345678909876,23456789098765,34567890987654,45678909876543]\n[1,2,3,4]\n[\"four\",\"one\",\"three\",\"two\"]\n[\"one\"]\n[\"four\",\"one\",\"one\",\"two\"]\n[\"one\",\"one\"]\n\n\"The quick brown fox jumps over the lazy dog.\"\n\"The quick brown fox jumps over the lazy dog.\"\n\"The quick brown fox jumps over the lazy dog.\"\n\n-42\n17\n17\n42\n-23\n1024\n-17\n8\n3.141592653589793\nnull\nnull\n42.22999954223633\nnull\n23.42\n\ntrue\nfalse\n

Note the output is platform-dependent.

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.

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\nusing nlohmann::ordered_json;\n\nint main()\n{\n    // create an ordered_json value; insertion order is preserved\n    ordered_json oj = {{\"c\", 3}, {\"a\", 1}, {\"b\", 2}};\n\n    // convert to json -- overload (4) is used; keys end up sorted\n    json j(oj);\n\n    // convert back to ordered_json -- the original insertion order is lost,\n    // because it was already given up when converting to json\n    ordered_json oj2(j);\n\n    std::cout << oj << '\\n';\n    std::cout << j << '\\n';\n    std::cout << oj2 << '\\n';\n}\n

Output:

{\"c\":3,\"a\":1,\"b\":2}\n{\"a\":1,\"b\":2,\"c\":3}\n{\"a\":1,\"b\":2,\"c\":3}\n
Example: (5) create a container (array or object) from an initializer list

The example below shows how JSON values are created from initializer lists.

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create JSON values\n    json j_empty_init_list = json({});\n    json j_object = { {\"one\", 1}, {\"two\", 2} };\n    json j_array = {1, 2, 3, 4};\n    json j_nested_object = { {\"one\", {1}}, {\"two\", {1, 2}} };\n    json j_nested_array = { {{1}, \"one\"}, {{1, 2}, \"two\"} };\n\n    // serialize the JSON value\n    std::cout << j_empty_init_list << '\\n';\n    std::cout << j_object << '\\n';\n    std::cout << j_array << '\\n';\n    std::cout << j_nested_object << '\\n';\n    std::cout << j_nested_array << '\\n';\n}\n

Output:

{}\n{\"one\":1,\"two\":2}\n[1,2,3,4]\n{\"one\":[1],\"two\":[1,2]}\n[[[1],\"one\"],[[1,2],\"two\"]]\n
Example: (6) construct an array with count copies of a given value

The following code shows examples for creating arrays with several copies of a given value.

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create an array by creating copies of a JSON value\n    json value = \"Hello\";\n    json array_0 = json(0, value);\n    json array_1 = json(1, value);\n    json array_5 = json(5, value);\n\n    // serialize the JSON arrays\n    std::cout << array_0 << '\\n';\n    std::cout << array_1 << '\\n';\n    std::cout << array_5 << '\\n';\n}\n

Output:

[]\n[\"Hello\"]\n[\"Hello\",\"Hello\",\"Hello\",\"Hello\",\"Hello\"]\n
Example: (7) construct a JSON container given an iterator range

The example below shows several ways to create JSON values by specifying a subrange with iterators.

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create JSON values\n    json j_array = {\"alpha\", \"bravo\", \"charly\", \"delta\", \"easy\"};\n    json j_number = 42;\n    json j_object = {{\"one\", \"eins\"}, {\"two\", \"zwei\"}};\n\n    // create copies using iterators\n    json j_array_range(j_array.begin() + 1, j_array.end() - 2);\n    json j_number_range(j_number.begin(), j_number.end());\n    json j_object_range(j_object.begin(), j_object.find(\"two\"));\n\n    // serialize the values\n    std::cout << j_array_range << '\\n';\n    std::cout << j_number_range << '\\n';\n    std::cout << j_object_range << '\\n';\n\n    // example for an exception\n    try\n    {\n        json j_invalid(j_number.begin() + 1, j_number.end());\n    }\n    catch (const json::invalid_iterator& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n}\n

Output:

[\"bravo\",\"charly\"]\n42\n{\"one\":\"eins\"}\n[json.exception.invalid_iterator.204] iterators out of range\n
Example: (8) copy constructor

The following code shows an example for the copy constructor.

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create a JSON array\n    json j1 = {\"one\", \"two\", 3, 4.5, false};\n\n    // create a copy\n    json j2(j1);\n\n    // serialize the JSON array\n    std::cout << j1 << \" = \" << j2 << '\\n';\n    std::cout << std::boolalpha << (j1 == j2) << '\\n';\n}\n

Output:

[\"one\",\"two\",3,4.5,false] = [\"one\",\"two\",3,4.5,false]\ntrue\n
Example: (9) move constructor

The code below shows the move constructor explicitly called via std::move.

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create a JSON value\n    json a = 23;\n\n    // move contents of a to b\n    json b(std::move(a));\n\n    // serialize the JSON arrays\n    std::cout << a << '\\n';\n    std::cout << b << '\\n';\n}\n

Output:

null\n23\n
"},{"location":"api/basic_json/basic_json/#see-also","title":"See also","text":"
  • array - create a JSON array value, forcing array creation from an initializer list even when it looks like an object
  • object - create a JSON object value, forcing object creation from an initializer list
  • binary - create a JSON binary array value
  • operator= - copy assignment operator
  • Creating JSON values - the article on creating JSON values
  • Converting values - which C++ types can be converted
"},{"location":"api/basic_json/basic_json/#version-history","title":"Version history","text":"
  1. Added in version 1.0.0.
  2. Added in version 1.0.0.
  3. Added in version 2.1.0.
  4. Added in version 3.1.2. Explicit for different string types if JSON_USE_IMPLICIT_CONVERSIONS is 0 since version 3.13.0 unreleased.
  5. Added in version 1.0.0.
  6. Added in version 1.0.0.
  7. Added in version 1.0.0. Fixed in version 3.13.0 unreleased 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. Added in version 1.0.0.
  9. Added in version 1.0.0.
"},{"location":"api/basic_json/begin/","title":"nlohmann::basic_json::begin","text":"
iterator begin() noexcept;\nconst_iterator begin() const noexcept;\n

Returns an iterator to the first element.

A row of fifteen elements followed by a dashed past-the-last position. begin() points to the first element and end() points to the past-the-last position. begin end Past-the-last element

begin() points to the first element and end() to the position after the last element; the dashed cell is the past-the-last position, which must not be dereferenced.

"},{"location":"api/basic_json/begin/#return-value","title":"Return value","text":"

iterator to the first element

"},{"location":"api/basic_json/begin/#exception-safety","title":"Exception safety","text":"

No-throw guarantee: this member function never throws exceptions.

"},{"location":"api/basic_json/begin/#complexity","title":"Complexity","text":"

Constant.

"},{"location":"api/basic_json/begin/#examples","title":"Examples","text":"Example

The following code shows an example for begin().

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create an array value\n    json array = {1, 2, 3, 4, 5};\n\n    // get an iterator to the first element\n    json::iterator it = array.begin();\n\n    // serialize the element that the iterator points to\n    std::cout << *it << '\\n';\n}\n

Output:

1\n
"},{"location":"api/basic_json/begin/#see-also","title":"See also","text":"
  • end - returns an iterator to one past the last element
  • cbegin - returns a const iterator to the first element
  • rbegin - returns a reverse iterator to the last element
  • items - returns an iteration proxy to access keys and values during range-based for loops
  • Iterators - the article on iterators
  • basic_json_view::begin - the same iteration on a zero-copy view (in document order, not sorted by key)
"},{"location":"api/basic_json/begin/#version-history","title":"Version history","text":"
  • Added in version 1.0.0.
"},{"location":"api/basic_json/binary/","title":"nlohmann::basic_json::binary","text":"
// (1)\nstatic basic_json binary(const typename binary_t::container_type& init);\nstatic basic_json binary(typename binary_t::container_type&& init);\n\n// (2)\nstatic basic_json binary(const typename binary_t::container_type& init,\n                         typename binary_t::subtype_type subtype);\nstatic basic_json binary(typename binary_t::container_type&& init,\n                         typename binary_t::subtype_type subtype);\n
  1. Creates a JSON binary array value from a given binary container.
  2. Creates a JSON binary array value from a given binary container with subtype.

Binary values are part of various binary formats, such as CBOR, MessagePack, and BSON. This constructor is used to create a value for serialization to those formats.

"},{"location":"api/basic_json/binary/#parameters","title":"Parameters","text":"init (in) container containing bytes to use as a binary type subtype (in) subtype to use in CBOR, MessagePack, and BSON"},{"location":"api/basic_json/binary/#return-value","title":"Return value","text":"

JSON binary array value

"},{"location":"api/basic_json/binary/#exception-safety","title":"Exception safety","text":"

Strong guarantee: if an exception is thrown, there are no changes in the JSON value.

"},{"location":"api/basic_json/binary/#complexity","title":"Complexity","text":"

Linear in the size of init; constant for typename binary_t::container_type&& init versions.

"},{"location":"api/basic_json/binary/#notes","title":"Notes","text":"

Note, this function exists because of the difficulty in correctly specifying the correct template overload in the standard value ctor, as both JSON arrays and JSON binary arrays are backed with some form of a std::vector. Because JSON binary arrays are a non-standard extension, it was decided that it would be best to prevent automatic initialization of a binary array type, for backwards compatibility and so it does not happen on accident.

"},{"location":"api/basic_json/binary/#examples","title":"Examples","text":"Example

The following code shows how to create a binary value.

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create a binary vector\n    std::vector<std::uint8_t> vec = {0xCA, 0xFE, 0xBA, 0xBE};\n\n    // create a binary JSON value with subtype 42\n    json j = json::binary(vec, 42);\n\n    // output type and subtype\n    std::cout << \"type: \" << j.type_name() << \", subtype: \" << j.get_binary().subtype() << '\\n';\n}\n

Output:

type: binary, subtype: 42\n
"},{"location":"api/basic_json/binary/#see-also","title":"See also","text":"
  • Binary formats - formats that can store binary values
  • binary_t - type for binary values
  • get_binary - get a reference to the stored binary value
  • is_binary - return whether the value is binary
  • byte_container_with_subtype - container for binary values with subtype
  • Binary Values - the article on binary values
"},{"location":"api/basic_json/binary/#version-history","title":"Version history","text":"
  • 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.
"},{"location":"api/basic_json/binary_t/","title":"nlohmann::basic_json::binary_t","text":"
using binary_t = byte_container_with_subtype<BinaryType>;\n

This type is a type designed to carry binary data that appears in various serialized formats, such as CBOR's Major Type 2, MessagePack's bin, and BSON's generic binary subtype. This type is NOT a part of standard JSON and exists solely for compatibility with these binary types. As such, it is simply defined as an ordered sequence of zero or more byte values.

Additionally, as an implementation detail, the subtype of the binary data is carried around as a std::uint64_t, which is compatible with both of the binary data formats that use binary subtyping, (though the specific numbering is incompatible with each other, and it is up to the user to translate between them). The subtype is added to BinaryType via the helper type byte_container_with_subtype.

CBOR's RFC 8949 describes this type as:

Major type 2: A byte string. The number of bytes in the string is equal to the argument.

MessagePack's documentation on the bin type family describes this type as:

Bin format family stores a byte array in 2, 3, or 5 bytes of extra bytes in addition to the size of the byte array.

BSON's specifications describe several binary types; however, this type is intended to represent the generic binary type which has the description:

Generic binary subtype - This is the most commonly used binary subtype and should be the 'default' for drivers and tools.

None of these impose any limitations on the internal representation other than the basic unit of storage be some type of array whose parts are decomposable into bytes.

The default representation of this binary format is a std::vector<std::uint8_t>, which is a very common way to represent a byte array in modern C++.

"},{"location":"api/basic_json/binary_t/#template-parameters","title":"Template parameters","text":"BinaryType

container type to store arrays

Although not formally expressed as a C++ concept, BinaryType must be default-constructible, copy/move-constructible, and support push_back(), .data(), and .size(), because byte_container_with_subtype derives directly from it. Its value_type must additionally be exactly one byte wide (e.g., std::uint8_t/char/std::byte): the binary serializers (CBOR, MessagePack, BSON, UBJSON) read and write the container's raw bytes via reinterpret_cast, which is only correct for byte-sized elements \u2014 a container like std::vector<std::intptr_t> will not work as BinaryType. The elements must be stored contiguously, and the binary readers additionally require resize() and operator[]. See Template Parameter Requirements for the full list.

"},{"location":"api/basic_json/binary_t/#notes","title":"Notes","text":""},{"location":"api/basic_json/binary_t/#default-type","title":"Default type","text":"

The default values for BinaryType is std::vector<std::uint8_t>.

"},{"location":"api/basic_json/binary_t/#supported-byte-types","title":"Supported byte types","text":"

std::vector<std::uint8_t>, std::vector<char>, and std::vector<std::byte> are supported. Regardless of which of them is configured, dump writes the bytes as the numbers 0..255.

"},{"location":"api/basic_json/binary_t/#custom-binarytype-behavior","title":"Custom BinaryType behavior","text":"

When a custom BinaryType is configured (other than the default 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 rather than arrays:

using custom_json = nlohmann::ordered_json::with_binary_t<std::vector<std::byte>>;\n\nstd::vector<std::byte> data{std::byte{1}, std::byte{2}, std::byte{3}};\ncustom_json j = data;  // Creates a binary value, not an array\nassert(j.is_binary());\n\n// Round-tripping works seamlessly\nauto extracted = j.get<std::vector<std::byte>>();\nassert(extracted == data);\n

This automatic type detection is a convenience feature that only applies to custom (non-default) BinaryType configurations. The default nlohmann::json continues to treat std::vector<std::uint8_t> as arrays for backward compatibility.

"},{"location":"api/basic_json/binary_t/#storage","title":"Storage","text":"

Binary Arrays are stored as pointers in a basic_json type. That is, for any access to array values, a pointer of the type binary_t* must be dereferenced.

"},{"location":"api/basic_json/binary_t/#notes-on-subtypes","title":"Notes on subtypes","text":"
  • CBOR

    • Binary values are represented as byte strings. Subtypes are written as tags.
  • MessagePack

    • If a subtype is given and the binary array contains exactly 1, 2, 4, 8, or 16 elements, the fixext family (fixext1, fixext2, fixext4, fixext8, fixext16) is used. For other sizes, the ext family (ext8, ext16, ext32) is used. The subtype is then written as the signed 8-bit ext type: subtypes 128 to 255 map to the negative (reserved) ext types, and on reading the ext type is exposed as an unsigned subtype from 0 to 255.
    • If no subtype is given, the bin family (bin8, bin16, bin32) is used.
  • BSON

    • If a subtype is given, it is used and added as an unsigned 8-bit integer.
    • If no subtype is given, the generic binary subtype 0x00 is used.
"},{"location":"api/basic_json/binary_t/#examples","title":"Examples","text":"Example

The following code shows that binary_t is by default, a typedef to nlohmann::byte_container_with_subtype<std::vector<std::uint8_t>>.

#include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    std::cout << std::boolalpha << std::is_same<nlohmann::byte_container_with_subtype<std::vector<std::uint8_t>>, json::binary_t>::value << '\\n';\n}\n

Output:

true\n
"},{"location":"api/basic_json/binary_t/#see-also","title":"See also","text":"
  • Binary values - how binary values and subtypes are handled
  • Binary formats - formats that can store binary values
  • byte_container_with_subtype - container type used by binary values
"},{"location":"api/basic_json/binary_t/#version-history","title":"Version history","text":"
  • Added in version 3.8.0. Changed the type of subtype to std::uint64_t in version 3.10.0.
  • Fixed dump, std::hash, and to_ubjson for byte types that are not integers (e.g., std::byte) in version 3.13.0 unreleased. dump now writes the bytes of a signed byte type (e.g., char) as 0..255 rather than as negative numbers.
"},{"location":"api/basic_json/bjdata_version_t/","title":"nlohmann::basic_json::bjdata_version_t","text":"
enum class bjdata_version_t\n{\n    draft2,\n    draft3\n};\n

This enumeration is used in to_bjdata to choose the version of the BJData specification to write:

draft2 BJData Draft 2 (the default). Binary values are written as arrays of U integers, and ND-arrays with \"_ArrayType_\": \"byte\" are written as regular objects, since the B marker is not part of Draft 2. draft3 BJData Draft 3. Binary values are written as B elements: as an optimized binary array ([$B#) if both use_size and use_type are set, and as an array of B-prefixed elements otherwise. ND-arrays with \"_ArrayType_\": \"byte\" are written as packed arrays ([$B#[...]).

Only the writer is affected by the version. from_bjdata reads the markers of both drafts.

"},{"location":"api/basic_json/bjdata_version_t/#examples","title":"Examples","text":"Example

The example below shows how the different values of the bjdata_version_t influence the serialization of a binary value with to_bjdata.

#include <iomanip>\n#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nvoid print_hex(const char* label, const std::vector<std::uint8_t>& v)\n{\n    std::cout << label << ':';\n    for (auto b : v)\n    {\n        std::cout << ' ' << std::hex << std::setw(2) << std::setfill('0') << static_cast<int>(b);\n    }\n    std::cout << std::dec << std::setfill(' ') << '\\n';\n}\n\nint main()\n{\n    // a binary value\n    json j = json::binary({0xCA, 0xFE, 0xBA, 0xBE});\n\n    // Draft 2 (the default) writes an array of integers\n    auto v2 = json::to_bjdata(j, true, true, json::bjdata_version_t::draft2);\n    print_hex(\"draft2\", v2);\n\n    // Draft 3 writes an optimized binary array\n    auto v3 = json::to_bjdata(j, true, true, json::bjdata_version_t::draft3);\n    print_hex(\"draft3\", v3);\n\n    // reading yields an array for Draft 2 and a binary value for Draft 3\n    std::cout << json::from_bjdata(v2) << '\\n';\n    std::cout << json::from_bjdata(v3) << '\\n';\n}\n

Output:

draft2: 5b 24 55 23 69 04 ca fe ba be\ndraft3: 5b 24 42 23 69 04 ca fe ba be\n[202,254,186,190]\n{\"bytes\":[202,254,186,190],\"subtype\":null}\n
"},{"location":"api/basic_json/bjdata_version_t/#see-also","title":"See also","text":"
  • to_bjdata serializes a JSON value to BJData
  • BJData - the article on the BJData format
"},{"location":"api/basic_json/bjdata_version_t/#version-history","title":"Version history","text":"
  • Added in version 3.12.0.
"},{"location":"api/basic_json/boolean_t/","title":"nlohmann::basic_json::boolean_t","text":"
using boolean_t = BooleanType;\n

The type used to store JSON booleans.

RFC 8259 implicitly describes a boolean as a type which differentiates the two literals true and false.

To store boolean values in C++, a type is defined by the template parameter BooleanType which chooses the type to use.

"},{"location":"api/basic_json/boolean_t/#template-parameters","title":"Template parameters","text":"BooleanType the type to store booleans. As it is stored directly inside a basic_json value (in a union), it must be a trivially default-constructible, trivially copyable, and trivially destructible type that is convertible to and from bool. See Template Parameter Requirements."},{"location":"api/basic_json/boolean_t/#notes","title":"Notes","text":""},{"location":"api/basic_json/boolean_t/#default-type","title":"Default type","text":"

With the default values for BooleanType (bool), the default type for boolean_t is bool.

"},{"location":"api/basic_json/boolean_t/#storage","title":"Storage","text":"

Boolean values are stored directly inside a basic_json type.

"},{"location":"api/basic_json/boolean_t/#examples","title":"Examples","text":"Example

The following code shows that boolean_t is by default, a typedef to bool.

#include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    std::cout << std::boolalpha << std::is_same<bool, json::boolean_t>::value << '\\n';\n}\n

Output:

true\n
"},{"location":"api/basic_json/boolean_t/#see-also","title":"See also","text":"
  • is_boolean - checks whether the JSON value is a boolean
  • Types - how booleans are stored
  • Template Parameter Requirements - requirements on the BooleanType template parameter
"},{"location":"api/basic_json/boolean_t/#version-history","title":"Version history","text":"
  • Added in version 1.0.0.
"},{"location":"api/basic_json/cbegin/","title":"nlohmann::basic_json::cbegin","text":"
const_iterator cbegin() const noexcept;\n

Returns an iterator to the first element.

A row of fifteen elements followed by a dashed past-the-last position. begin() points to the first element and end() points to the past-the-last position. begin end Past-the-last element

cbegin() points to the first element, like begin(), and end() to the position after the last element; the dashed cell is the past-the-last position, which must not be dereferenced.

"},{"location":"api/basic_json/cbegin/#return-value","title":"Return value","text":"

iterator to the first element

"},{"location":"api/basic_json/cbegin/#exception-safety","title":"Exception safety","text":"

No-throw guarantee: this member function never throws exceptions.

"},{"location":"api/basic_json/cbegin/#complexity","title":"Complexity","text":"

Constant.

"},{"location":"api/basic_json/cbegin/#examples","title":"Examples","text":"Example

The following code shows an example for cbegin().

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create an array value\n    const json array = {1, 2, 3, 4, 5};\n\n    // get an iterator to the first element\n    json::const_iterator it = array.cbegin();\n\n    // serialize the element that the iterator points to\n    std::cout << *it << '\\n';\n}\n

Output:

1\n
"},{"location":"api/basic_json/cbegin/#see-also","title":"See also","text":"
  • begin - returns an iterator to the first element
  • cend - returns a const iterator to one past the last element
  • crbegin - returns a const reverse iterator to the last element
  • Iterators - the article on iterators
  • basic_json_view::cbegin - the same iteration on a zero-copy view
"},{"location":"api/basic_json/cbegin/#version-history","title":"Version history","text":"
  • Added in version 1.0.0.
"},{"location":"api/basic_json/cbor_tag_handler_t/","title":"nlohmann::basic_json::cbor_tag_handler_t","text":"
enum class cbor_tag_handler_t\n{\n    error,\n    ignore,\n    store\n};\n

This enumeration is used in from_cbor and sax_parse to choose how to treat tags:

error report a parse error in case of a tag (the from_cbor overloads throw a parse_error exception by default) ignore ignore tags (also in front of a text string map key) store store tagged byte strings (for bytes 0xd8..0xdb) as binary values with the tag as subtype; other tagged values are read as if the tag were ignored. If several tags precede a byte string, only the tag directly in front of it is stored, and only when it has the form 0xd8..0xdb (a tag 0..23 written as 0xc0..0xd7 is skipped). Tags in front of a text string map key are skipped."},{"location":"api/basic_json/cbor_tag_handler_t/#examples","title":"Examples","text":"Example

The example below shows how the different values of the cbor_tag_handler_t influence the behavior of from_cbor when reading a tagged byte string.

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // tagged byte string\n    std::vector<std::uint8_t> vec = {{0xd8, 0x42, 0x44, 0xcA, 0xfe, 0xba, 0xbe}};\n\n    // cbor_tag_handler_t::error throws\n    try\n    {\n        auto b_throw_on_tag = json::from_cbor(vec, true, true, json::cbor_tag_handler_t::error);\n    }\n    catch (const json::parse_error& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n\n    // cbor_tag_handler_t::ignore ignores the tag\n    auto b_ignore_tag = json::from_cbor(vec, true, true, json::cbor_tag_handler_t::ignore);\n    std::cout << b_ignore_tag << '\\n';\n\n    // cbor_tag_handler_t::store stores the tag as binary subtype\n    auto b_store_tag = json::from_cbor(vec, true, true, json::cbor_tag_handler_t::store);\n    std::cout << b_store_tag << '\\n';\n}\n

Output:

[json.exception.parse_error.112] parse error at byte 1: syntax error while parsing CBOR value: invalid byte: 0xD8\n{\"bytes\":[202,254,186,190],\"subtype\":null}\n{\"bytes\":[202,254,186,190],\"subtype\":66}\n
"},{"location":"api/basic_json/cbor_tag_handler_t/#see-also","title":"See also","text":"
  • Binary values - how binary values and subtypes are handled
  • from_cbor - deserializes a JSON value from CBOR
  • input_format_t - the enumeration of supported input formats
  • CBOR - the article on the CBOR format
"},{"location":"api/basic_json/cbor_tag_handler_t/#version-history","title":"Version history","text":"
  • Added in version 3.9.0. Added value store in 3.10.0.
"},{"location":"api/basic_json/cend/","title":"nlohmann::basic_json::cend","text":"
const_iterator cend() const noexcept;\n

Returns an iterator to one past the last element.

A row of fifteen elements followed by a dashed past-the-last position. begin() points to the first element and end() points to the past-the-last position. begin end Past-the-last element

cend() points to the position after the last element, like end(), and begin() to the first element; the dashed cell is the past-the-last position, which must not be dereferenced.

"},{"location":"api/basic_json/cend/#return-value","title":"Return value","text":"

iterator one past the last element

"},{"location":"api/basic_json/cend/#exception-safety","title":"Exception safety","text":"

No-throw guarantee: this member function never throws exceptions.

"},{"location":"api/basic_json/cend/#complexity","title":"Complexity","text":"

Constant.

"},{"location":"api/basic_json/cend/#examples","title":"Examples","text":"Example

The following code shows an example for cend().

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create an array value\n    json array = {1, 2, 3, 4, 5};\n\n    // get an iterator to one past the last element\n    json::const_iterator it = array.cend();\n\n    // decrement the iterator to point to the last element\n    --it;\n\n    // serialize the element that the iterator points to\n    std::cout << *it << '\\n';\n}\n

Output:

5\n
"},{"location":"api/basic_json/cend/#see-also","title":"See also","text":"
  • end - returns an iterator to one past the last element
  • cbegin - returns a const iterator to the first element
  • crend - returns a const reverse iterator to one before the first element
  • Iterators - the article on iterators
  • basic_json_view::cend - the same iteration on a zero-copy view
"},{"location":"api/basic_json/cend/#version-history","title":"Version history","text":"
  • Added in version 1.0.0.
"},{"location":"api/basic_json/clear/","title":"nlohmann::basic_json::clear","text":"
void clear() noexcept;\n

Clears the content of a JSON value and resets it to the default value as if basic_json(value_t) would have been called with the current value type from type():

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

*this = basic_json(type());\n
"},{"location":"api/basic_json/clear/#exception-safety","title":"Exception safety","text":"

No-throw guarantee: this function never throws exceptions.

"},{"location":"api/basic_json/clear/#complexity","title":"Complexity","text":"

Linear in the size of the JSON value.

"},{"location":"api/basic_json/clear/#notes","title":"Notes","text":"

All iterators, pointers, and references related to this container are invalidated.

"},{"location":"api/basic_json/clear/#examples","title":"Examples","text":"Example

The example below shows the effect of clear() to different JSON types.

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create JSON values\n    json j_null;\n    json j_boolean = true;\n    json j_number_integer = 17;\n    json j_number_float = 23.42;\n    json j_object = {{\"one\", 1}, {\"two\", 2}};\n    json j_array = {1, 2, 4, 8, 16};\n    json j_string = \"Hello, world\";\n\n    // call clear()\n    j_null.clear();\n    j_boolean.clear();\n    j_number_integer.clear();\n    j_number_float.clear();\n    j_object.clear();\n    j_array.clear();\n    j_string.clear();\n\n    // serialize the cleared values()\n    std::cout << j_null << '\\n';\n    std::cout << j_boolean << '\\n';\n    std::cout << j_number_integer << '\\n';\n    std::cout << j_number_float << '\\n';\n    std::cout << j_object << '\\n';\n    std::cout << j_array << '\\n';\n    std::cout << j_string << '\\n';\n}\n

Output:

null\nfalse\n0\n0.0\n{}\n[]\n\"\"\n
"},{"location":"api/basic_json/clear/#see-also","title":"See also","text":"
  • erase - removes elements from a JSON value
  • empty - checks whether the JSON value has no elements
  • Modifying values - the article on modifying values
"},{"location":"api/basic_json/clear/#version-history","title":"Version history","text":"
  • Added in version 1.0.0.
  • Added support for binary types in version 3.8.0.
  • Fixed in version 3.13.0 unreleased to also clear the subtype of a binary value; before, the subtype was left unchanged.
"},{"location":"api/basic_json/contains/","title":"nlohmann::basic_json::contains","text":"
// (1)\nbool contains(const typename object_t::key_type& key) const;\n\n// (2)\ntemplate<typename KeyType>\nbool contains(KeyType&& key) const;\n\n// (3)\nbool contains(const json_pointer& ptr) const;\n\n// (4)\ntemplate<typename T>\nbool contains(T) const = delete;\n
  1. Check whether an element exists in a JSON object with a key equivalent to key. If the element is not found or the JSON value is not an object, false is returned.
  2. See 1. This overload is only available if KeyType is comparable with typename object_t::key_type and typename object_comparator_t::is_transparent denotes a type.
  3. Check whether the given JSON pointer ptr can be resolved in the current JSON value.
  4. Deleted: this overload is only available if T is an integral type and is declared as deleted, so that a call with an integer key (for example, j.contains(0)) fails to compile. Otherwise, the integer literal 0 would convert to a null const char* and, from there, to the key type, causing undefined behavior at runtime.
"},{"location":"api/basic_json/contains/#template-parameters","title":"Template parameters","text":"KeyType A type for an object key other than json_pointer that is comparable with string_t using object_comparator_t. This can also be a string view (C++17)."},{"location":"api/basic_json/contains/#parameters","title":"Parameters","text":"key (in) key value to check its existence. ptr (in) JSON pointer to check its existence."},{"location":"api/basic_json/contains/#return-value","title":"Return value","text":"
  1. true if an element with specified key exists. If no such element with such a key is found or the JSON value is not an object, false is returned.
  2. See 1.
  3. true if the JSON pointer can be resolved to a stored value, false otherwise.
  4. Deleted; a call with an integral argument does not compile.
"},{"location":"api/basic_json/contains/#exception-safety","title":"Exception safety","text":"

Strong exception safety: if an exception occurs, the original value stays intact.

"},{"location":"api/basic_json/contains/#exceptions","title":"Exceptions","text":"
  1. The function does not throw exceptions.
  2. The function does not throw exceptions.
  3. The function does not throw exceptions.
  4. Deleted; a call with an integral argument does not compile.
"},{"location":"api/basic_json/contains/#complexity","title":"Complexity","text":"
  1. Logarithmic in the size of the JSON object.
  2. Logarithmic in the size of the JSON object.
  3. At most one lookup per reference token of ptr, each logarithmic in the size of the container at that level: O(n log m) for n reference tokens and containers of size at most m.
  4. Deleted; a call with an integral argument does not compile.
"},{"location":"api/basic_json/contains/#notes","title":"Notes","text":"
  • Overloads (1) and (2) always return false when executed on a JSON type that is not an object. Overload (3) also works on arrays and on primitive values: the empty JSON pointer resolves in every JSON value (so json(1).contains(\"\"_json_pointer) returns true), and json({1, 2}).contains(\"/1\"_json_pointer) returns true.
  • This method can be executed on any JSON value type.
  • Calling this function with an integer argument (for example, contains(0)) does not compile: such an argument would otherwise implicitly convert to a null const char* and, from there, cause undefined behavior when constructing a std::string for the object key. To check for an array element instead, use at, operator[], or compare against size.

Postconditions

If j.contains(x) returns true for a key or JSON pointer x, then it is safe to call j[x].

Deprecation

Overload (3) also accepts a json_pointer 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 for how to update existing code.

"},{"location":"api/basic_json/contains/#examples","title":"Examples","text":"Example: (1) check with key

The example shows how contains() is used.

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\nusing namespace nlohmann::literals;\n\nint main()\n{\n    // create some JSON values\n    json j_object = R\"( {\"key\": \"value\"} )\"_json;\n    json j_array = R\"( [1, 2, 3] )\"_json;\n\n    // call contains\n    std::cout << std::boolalpha <<\n              \"j_object contains 'key': \" << j_object.contains(\"key\") << '\\n' <<\n              \"j_object contains 'another': \" << j_object.contains(\"another\") << '\\n' <<\n              \"j_array contains 'key': \" << j_array.contains(\"key\") << '\\n';\n}\n

Output:

j_object contains 'key': true\nj_object contains 'another': false\nj_array contains 'key': false\n
Example: (2) check with key using string_view

The example shows how contains() is used.

#include <iostream>\n#include <string_view>\n#include <nlohmann/json.hpp>\n\nusing namespace std::string_view_literals;\nusing nlohmann::json;\nusing namespace nlohmann::literals;\n\nint main()\n{\n    // create some JSON values\n    json j_object = R\"( {\"key\": \"value\"} )\"_json;\n    json j_array = R\"( [1, 2, 3] )\"_json;\n\n    // call contains\n    std::cout << std::boolalpha <<\n              \"j_object contains 'key': \" << j_object.contains(\"key\"sv) << '\\n' <<\n              \"j_object contains 'another': \" << j_object.contains(\"another\"sv) << '\\n' <<\n              \"j_array contains 'key': \" << j_array.contains(\"key\"sv) << '\\n';\n}\n

Output:

j_object contains 'key': true\nj_object contains 'another': false\nj_array contains 'key': false\n
Example: (3) check with JSON pointer

The example shows how contains() is used.

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\nusing namespace nlohmann::literals;\n\nint main()\n{\n    // create a JSON value\n    json j =\n    {\n        {\"number\", 1}, {\"string\", \"foo\"}, {\"array\", {1, 2}}\n    };\n\n    std::cout << std::boolalpha\n              << j.contains(\"/number\"_json_pointer) << '\\n'\n              << j.contains(\"/string\"_json_pointer) << '\\n'\n              << j.contains(\"/array\"_json_pointer) << '\\n'\n              << j.contains(\"/array/1\"_json_pointer) << '\\n'\n              << j.contains(\"/array/-\"_json_pointer) << '\\n'\n              << j.contains(\"/array/4\"_json_pointer) << '\\n'\n              << j.contains(\"/baz\"_json_pointer) << '\\n'\n              // an array index with a leading '0' is not found\n              << j.contains(\"/array/01\"_json_pointer) << '\\n'\n              // an array index that is not a number is not found\n              << j.contains(\"/array/one\"_json_pointer) << '\\n';\n}\n

Output:

true\ntrue\ntrue\ntrue\nfalse\nfalse\nfalse\nfalse\nfalse\n
"},{"location":"api/basic_json/contains/#see-also","title":"See also","text":"
  • find - find a value in an object
  • count - returns the number of occurrences of a key
  • basic_json_view::contains - the same check on a zero-copy view
  • Element Access - how to test whether a key exists
"},{"location":"api/basic_json/contains/#version-history","title":"Version history","text":"
  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. Support for keys convertible to std::string_view added in version 3.13.0 unreleased, consistently across the lookup functions.
  3. Added in version 3.7.0.
  4. Deleted overloads for integral key types added in version 3.13.0 unreleased to reject such calls at compile time instead of causing undefined behavior at runtime.
"},{"location":"api/basic_json/count/","title":"nlohmann::basic_json::count","text":"
// (1)\nsize_type count(const typename object_t::key_type& key) const;\n\n// (2)\ntemplate<typename KeyType>\nsize_type count(KeyType&& key) const;\n\n// (3)\ntemplate<typename T>\nsize_type count(T) const = delete;\n
  1. Returns the number of elements with key key. If ObjectType is the default std::map type, the return value will always be 0 (key was not found) or 1 (key was found).
  2. See 1. This overload is only available if KeyType is comparable with typename object_t::key_type and typename object_comparator_t::is_transparent denotes a type.
  3. Deleted: this overload is only available if T is an integral type and is declared as deleted, so that a call with an integer key (for example, j.count(0)) fails to compile. Otherwise, the integer literal 0 would convert to a null const char* and, from there, to the key type, causing undefined behavior at runtime.
"},{"location":"api/basic_json/count/#template-parameters","title":"Template parameters","text":"KeyType A type for an object key other than json_pointer that is comparable with string_t using object_comparator_t. This can also be a string view (C++17)."},{"location":"api/basic_json/count/#parameters","title":"Parameters","text":"key (in) key value of the element to count."},{"location":"api/basic_json/count/#return-value","title":"Return value","text":"

Number of elements with key key. If the JSON value is not an object, the return value will be 0.

"},{"location":"api/basic_json/count/#exception-safety","title":"Exception safety","text":"

Strong exception safety: if an exception occurs, the original value stays intact.

"},{"location":"api/basic_json/count/#complexity","title":"Complexity","text":"

Logarithmic in the size of the JSON object.

"},{"location":"api/basic_json/count/#notes","title":"Notes","text":"
  • 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, count(0)) does not compile: such an argument would otherwise implicitly convert to a null const char* and, from there, cause undefined behavior when constructing a std::string for the object key. To check for an array element instead, use at, operator[], or compare against size.
"},{"location":"api/basic_json/count/#examples","title":"Examples","text":"Example: (1) count number of elements

The example shows how count() is used.

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create a JSON object\n    json j_object = {{\"one\", 1}, {\"two\", 2}};\n\n    // call count()\n    auto count_two = j_object.count(\"two\");\n    auto count_three = j_object.count(\"three\");\n\n    // print values\n    std::cout << \"number of elements with key \\\"two\\\": \" << count_two << '\\n';\n    std::cout << \"number of elements with key \\\"three\\\": \" << count_three << '\\n';\n}\n

Output:

number of elements with key \"two\": 1\nnumber of elements with key \"three\": 0\n
Example: (2) count number of elements using string_view

The example shows how count() is used.

#include <iostream>\n#include <string_view>\n#include <nlohmann/json.hpp>\n\nusing namespace std::string_view_literals;\nusing nlohmann::json;\n\nint main()\n{\n    // create a JSON object\n    json j_object = {{\"one\", 1}, {\"two\", 2}};\n\n    // call count()\n    auto count_two = j_object.count(\"two\"sv);\n    auto count_three = j_object.count(\"three\"sv);\n\n    // print values\n    std::cout << \"number of elements with key \\\"two\\\": \" << count_two << '\\n';\n    std::cout << \"number of elements with key \\\"three\\\": \" << count_three << '\\n';\n}\n

Output:

number of elements with key \"two\": 1\nnumber of elements with key \"three\": 0\n
"},{"location":"api/basic_json/count/#see-also","title":"See also","text":"
  • find - find a value in an object
  • contains - checks whether a key exists
  • basic_json_view::count - the same check on a zero-copy view
  • Element Access - how to test whether a key exists
"},{"location":"api/basic_json/count/#version-history","title":"Version history","text":"
  1. Added in version 3.11.0.
  2. Added in version 1.0.0. Changed to support comparable key types in version 3.11.0. Support for keys convertible to std::string_view added in version 3.13.0 unreleased, consistently across the lookup functions.
  3. Deleted overload for integral key types added in version 3.13.0 unreleased to reject such calls at compile time instead of causing undefined behavior at runtime.
"},{"location":"api/basic_json/crbegin/","title":"nlohmann::basic_json::crbegin","text":"
const_reverse_iterator crbegin() const noexcept;\n

Returns an iterator to the reverse-beginning; that is, the last element.

Two rows of sixteen cells. The upper row shows the reversed sequence: rend() points to a dashed position before the first element and rbegin() to the last element. The lower row shows the forward sequence: begin() points to the first element and end() to a dashed position after the last element. A reverse iterator stores an iterator to the next element, so rend() corresponds to begin() and rbegin() to end(). rend rbegin Reverse past-the-last element A reverse iterator stores an iterator to the next element begin end Past-the-last element

crbegin() points to the last element, like rbegin(), and rend() to the position before the first element. The upper row is the reversed sequence and the lower row the forward sequence; dashed arrows link each reverse iterator to the forward iterator it stores, and dashed cells are past-the-last positions.

"},{"location":"api/basic_json/crbegin/#return-value","title":"Return value","text":"

reverse iterator to the last element

"},{"location":"api/basic_json/crbegin/#exception-safety","title":"Exception safety","text":"

No-throw guarantee: this member function never throws exceptions.

"},{"location":"api/basic_json/crbegin/#complexity","title":"Complexity","text":"

Constant.

"},{"location":"api/basic_json/crbegin/#examples","title":"Examples","text":"Example

The following code shows an example for crbegin().

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create an array value\n    json array = {1, 2, 3, 4, 5};\n\n    // get an iterator to the reverse-beginning\n    json::const_reverse_iterator it = array.crbegin();\n\n    // serialize the element that the iterator points to\n    std::cout << *it << '\\n';\n}\n

Output:

5\n
"},{"location":"api/basic_json/crbegin/#see-also","title":"See also","text":"
  • crend - returns a const reverse iterator to one before the first element
  • rbegin - returns a reverse iterator to the last element
  • cbegin - returns a const iterator to the first element
  • Iterators - the article on iterators
"},{"location":"api/basic_json/crbegin/#version-history","title":"Version history","text":"
  • Added in version 1.0.0.
"},{"location":"api/basic_json/crend/","title":"nlohmann::basic_json::crend","text":"
const_reverse_iterator crend() const noexcept;\n

Returns an iterator to the reverse-end; that is, one before the first element. This element acts as a placeholder, attempting to access it results in undefined behavior.

Two rows of sixteen cells. The upper row shows the reversed sequence: rend() points to a dashed position before the first element and rbegin() to the last element. The lower row shows the forward sequence: begin() points to the first element and end() to a dashed position after the last element. A reverse iterator stores an iterator to the next element, so rend() corresponds to begin() and rbegin() to end(). rend rbegin Reverse past-the-last element A reverse iterator stores an iterator to the next element begin end Past-the-last element

crend() points to the position before the first element, like rend(), and rbegin() to the last element. The upper row is the reversed sequence and the lower row the forward sequence; dashed arrows link each reverse iterator to the forward iterator it stores, and dashed cells are past-the-last positions.

"},{"location":"api/basic_json/crend/#return-value","title":"Return value","text":"

reverse iterator to the element following the last element

"},{"location":"api/basic_json/crend/#exception-safety","title":"Exception safety","text":"

No-throw guarantee: this member function never throws exceptions.

"},{"location":"api/basic_json/crend/#complexity","title":"Complexity","text":"

Constant.

"},{"location":"api/basic_json/crend/#examples","title":"Examples","text":"Example

The following code shows an example for crend().

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create an array value\n    json array = {1, 2, 3, 4, 5};\n\n    // get an iterator to the reverse-end\n    json::const_reverse_iterator it = array.crend();\n\n    // increment the iterator to point to the first element\n    --it;\n\n    // serialize the element that the iterator points to\n    std::cout << *it << '\\n';\n}\n

Output:

1\n
"},{"location":"api/basic_json/crend/#see-also","title":"See also","text":"
  • crbegin - returns a const reverse iterator to the last element
  • rend - returns a reverse iterator to one before the first element
  • cend - returns a const iterator to one past the last element
  • Iterators - the article on iterators
"},{"location":"api/basic_json/crend/#version-history","title":"Version history","text":"
  • Added in version 1.0.0.
"},{"location":"api/basic_json/default_object_comparator_t/","title":"nlohmann::basic_json::default_object_comparator_t","text":"
using default_object_comparator_t = std::less<StringType>;  // until C++14\n\nusing default_object_comparator_t = std::less<>;            // since C++14\n

The default comparator used by object_t.

Since C++14 a transparent comparator is used which prevents unnecessary string construction when looking up a key in an object.

The actual comparator used depends on object_t and can be obtained via object_comparator_t.

"},{"location":"api/basic_json/default_object_comparator_t/#examples","title":"Examples","text":"Example

The example below demonstrates the default comparator.

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    std::cout << std::boolalpha\n              << \"one < two : \" << json::default_object_comparator_t{}(\"one\", \"two\") << \"\\n\"\n              << \"three < four : \" << json::default_object_comparator_t{}(\"three\", \"four\") << '\\n';\n}\n

Output:

one < two : true\nthree < four : false\n
"},{"location":"api/basic_json/default_object_comparator_t/#see-also","title":"See also","text":"
  • object_comparator_t - the comparator actually used by object_t
  • object_t - the type used to store JSON objects
  • Template Parameter Requirements - requirements on the ObjectType template parameter
  • Object order - preserve the insertion order of keys
"},{"location":"api/basic_json/default_object_comparator_t/#version-history","title":"Version history","text":"
  • Added in version 3.11.0.
"},{"location":"api/basic_json/diff/","title":"nlohmann::basic_json::diff","text":"
static basic_json diff(const basic_json& source,\n                       const basic_json& target,\n                       const string_t& path = \"\");\n

Creates a JSON Patch so that value source can be changed into the value target by calling patch function.

For two JSON values source and target, the following code yields true:

source.patch(diff(source, target)) == target;\n

The equality holds up to operator==, so it has the following exceptions:

  • A value that is not equal to itself cannot round-trip. This applies to NaN (also nested in an array or object) and to discarded values: diff emits a replace operation for them. A NaN in the patch is serialized as null, so a patch that was dumped and parsed again would set null.
  • Numbers that compare equal produce no operation, even if their types or signs differ: diff(1, 1.0), diff(1u, 1) (unsigned and signed integer) and diff(0.0, -0.0) all return []. The patched value is then the source and keeps its number type.
"},{"location":"api/basic_json/diff/#parameters","title":"Parameters","text":"source (in) JSON value to compare from target (in) JSON value to compare against path (in) a prefix that is put verbatim in front of the path member of every operation (default: \"\", which addresses the root of the value). The prefix is neither escaped nor validated: diff(1, 2, \"abc\") yields an operation with the path abc, which is not a valid JSON Pointer. Use it with a valid JSON Pointer such as /root and escape ~ and / in its reference tokens (see JSON Pointer)."},{"location":"api/basic_json/diff/#return-value","title":"Return value","text":"

a JSON patch to convert the source to target

"},{"location":"api/basic_json/diff/#exception-safety","title":"Exception safety","text":"

Strong guarantee: source and target are never modified.

"},{"location":"api/basic_json/diff/#complexity","title":"Complexity","text":"

Linear in the total number of values (including nested ones) in source and target, times the cost of a key-based object operation (looking up a key in an object): logarithmic for json, and linear for ordered_json (see ordered_map complexity). For ordered_json, diffing two objects with n and m members therefore takes O((n+m)\u00b2) when their keys do not line up (e.g., a key was added or the keys are in a different order). The size of the patch is proportional to the number of operations times the length of their paths, so a small change deep inside a value yields a long path.

"},{"location":"api/basic_json/diff/#notes","title":"Notes","text":"
  • Currently, only remove, add, and replace operations are generated.
  • The patch is correct, but not guaranteed to be minimal. For instance, diff([1,2,3], [0,1,2,3]) yields three replace operations and one add operation instead of a single insertion.
  • Differences between two arrays are reported index by index. Elements that were added at the end of the array are added with add operations on the path /- (appended in order), and elements that were removed are removed with remove operations from the highest index down to the lowest, so that the remaining indices stay valid.
  • For objects, the operations for the members of source come first (replace, remove, or the operations for nested values, in the iteration order of source), followed by add operations for the members that only target has.
  • For ordered_json, objects with the same keys in a different order are different. As a patch cannot reorder members, diff removes all keys of the source object and adds them again in the order of the target.
  • If source and target differ as a whole (e.g., different types), the patch consists of a single replace operation for the root of the value, i.e., with the path \"\" (or the given path prefix).
  • The value members of the patch hold copies of values of target. A binary value has no JSON representation: when a patch that contains one is serialized, it becomes an object such as {\"bytes\":[1,3],\"subtype\":null}, so a parsed patch no longer holds a binary value (and would set that object instead).
"},{"location":"api/basic_json/diff/#examples","title":"Examples","text":"Example

The following code shows how a JSON patch is created as a diff for two JSON values.

#include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\nusing namespace nlohmann::literals;\n\nint main()\n{\n    // the source document\n    json source = R\"(\n        {\n            \"baz\": \"qux\",\n            \"foo\": \"bar\"\n        }\n    )\"_json;\n\n    // the target document\n    json target = R\"(\n        {\n            \"baz\": \"boo\",\n            \"hello\": [\n                \"world\"\n            ]\n        }\n    )\"_json;\n\n    // create the patch\n    json patch = json::diff(source, target);\n\n    // roundtrip\n    json patched_source = source.patch(patch);\n\n    // output patch and roundtrip result\n    std::cout << std::setw(4) << patch << \"\\n\\n\"\n              << std::setw(4) << patched_source << '\\n';\n}\n

Output:

[\n    {\n        \"op\": \"replace\",\n        \"path\": \"/baz\",\n        \"value\": \"boo\"\n    },\n    {\n        \"op\": \"remove\",\n        \"path\": \"/foo\"\n    },\n    {\n        \"op\": \"add\",\n        \"path\": \"/hello\",\n        \"value\": [\n            \"world\"\n        ]\n    }\n]\n\n{\n    \"baz\": \"boo\",\n    \"hello\": [\n        \"world\"\n    ]\n}\n
"},{"location":"api/basic_json/diff/#see-also","title":"See also","text":"
  • RFC 6902 (JSON Patch) - specification of JSON Patch
  • patch - applies a JSON Patch
  • patch_inplace - applies a JSON Patch in place
  • merge_patch - applies a JSON Merge Patch
  • merge_diff - creates a diff as a JSON Merge Patch
  • JSON Patch and Diff - the article on JSON Patch
"},{"location":"api/basic_json/diff/#version-history","title":"Version history","text":"
  • Added in version 2.0.0.
"},{"location":"api/basic_json/dump/","title":"nlohmann::basic_json::dump","text":"
string_t dump(const int indent = -1,\n              const char indent_char = ' ',\n              const bool ensure_ascii = false,\n              const error_handler_t error_handler = error_handler_t::strict) const;\n

Serialization function for JSON values. The function tries to mimic Python's json.dumps() function, and currently supports its indent and ensure_ascii parameters.

"},{"location":"api/basic_json/dump/#parameters","title":"Parameters","text":"indent (in) If indent is nonnegative, then array elements and object members will be pretty-printed with that indent level. An indent level of 0 will only insert newlines. -1 (the default) selects the most compact representation. indent_char (in) The character to use for indentation if indent is greater than 0. The default is (space). ensure_ascii (in) If ensure_ascii is true, all non-ASCII characters in the output are escaped with \\uXXXX sequences, and the result consists of ASCII characters only. error_handler (in) how to react on decoding errors; there are four possible values (see error_handler_t: strict (throws an exception in case a decoding error occurs; default), replace (replace invalid UTF-8 sequences with U+FFFD), ignore (ignore invalid UTF-8 sequences during serialization; all valid bytes are copied to the output unchanged, and invalid bytes are dropped), and keep (write the ill-formed bytes to the output as is, without escaping them, even if ensure_ascii is true; the result is then not valid UTF-8, but equals the input bytes exactly, and well-formed characters around the ill-formed bytes are still escaped as usual))."},{"location":"api/basic_json/dump/#return-value","title":"Return value","text":"

string containing the serialization of the JSON value

"},{"location":"api/basic_json/dump/#exception-safety","title":"Exception safety","text":"

Strong guarantee: if an exception is thrown, there are no changes to any JSON value.

"},{"location":"api/basic_json/dump/#exceptions","title":"Exceptions","text":"

Throws type_error.316 if a string stored inside the JSON value is not UTF-8 encoded and error_handler is set to strict

Serializing untrusted input

When serializing values that may contain invalid or untrusted UTF-8 (e.g., bytes taken directly from network input), dump() throws type_error.316 in the default strict mode. To serialize such data without throwing, pass error_handler_t::replace (substitutes U+FFFD) or error_handler_t::ignore. Callers that serialize untrusted input on a crash-sensitive path should either choose a non-strict error handler or wrap dump() in a try/catch.

See the FAQ for details.

"},{"location":"api/basic_json/dump/#complexity","title":"Complexity","text":"

Linear.

"},{"location":"api/basic_json/dump/#notes","title":"Notes","text":"

Floating-point numbers are written with the fewest digits that read back as the same value (for double; see number handling).

Binary values are serialized as an object containing two keys:

  • \"bytes\": an array of bytes as integers
  • \"subtype\": the subtype as integer or null if the binary has no subtype
"},{"location":"api/basic_json/dump/#examples","title":"Examples","text":"Example

The following example shows the effect of different indent, indent_char, and ensure_ascii parameters to the result of the serialization.

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create JSON values\n    json j_object = {{\"one\", 1}, {\"two\", 2}};\n    json j_array = {1, 2, 4, 8, 16};\n    json j_string = \"Hell\u00f6 \ud83d\ude00!\";\n\n    // call dump()\n    std::cout << \"objects:\" << '\\n'\n              << j_object.dump() << \"\\n\\n\"\n              << j_object.dump(-1) << \"\\n\\n\"\n              << j_object.dump(0) << \"\\n\\n\"\n              << j_object.dump(4) << \"\\n\\n\"\n              << j_object.dump(1, '\\t') << \"\\n\\n\";\n\n    std::cout << \"arrays:\" << '\\n'\n              << j_array.dump() << \"\\n\\n\"\n              << j_array.dump(-1) << \"\\n\\n\"\n              << j_array.dump(0) << \"\\n\\n\"\n              << j_array.dump(4) << \"\\n\\n\"\n              << j_array.dump(1, '\\t') << \"\\n\\n\";\n\n    std::cout << \"strings:\" << '\\n'\n              << j_string.dump() << '\\n'\n              << j_string.dump(-1, ' ', true) << '\\n';\n\n    // create JSON value with invalid UTF-8 byte sequence\n    json j_invalid = \"\u00e4\\xA9\u00fc\";\n    try\n    {\n        std::cout << j_invalid.dump() << '\\n';\n    }\n    catch (const json::type_error& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n\n    std::cout << \"string with replaced invalid characters: \"\n              << j_invalid.dump(-1, ' ', false, json::error_handler_t::replace)\n              << \"\\nstring with ignored invalid characters: \"\n              << j_invalid.dump(-1, ' ', false, json::error_handler_t::ignore)\n              << '\\n';\n}\n

Output:

objects:\n{\"one\":1,\"two\":2}\n\n{\"one\":1,\"two\":2}\n\n{\n\"one\": 1,\n\"two\": 2\n}\n\n{\n    \"one\": 1,\n    \"two\": 2\n}\n\n{\n    \"one\": 1,\n    \"two\": 2\n}\n\narrays:\n[1,2,4,8,16]\n\n[1,2,4,8,16]\n\n[\n1,\n2,\n4,\n8,\n16\n]\n\n[\n    1,\n    2,\n    4,\n    8,\n    16\n]\n\n[\n    1,\n    2,\n    4,\n    8,\n    16\n]\n\nstrings:\n\"Hell\u00f6 \ud83d\ude00!\"\n\"Hell\\u00f6 \\ud83d\\ude00!\"\n[json.exception.type_error.316] invalid UTF-8 byte at index 2: 0xA9\nstring with replaced invalid characters: \"\u00e4\ufffd\u00fc\"\nstring with ignored invalid characters: \"\u00e4\u00fc\"\n
"},{"location":"api/basic_json/dump/#see-also","title":"See also","text":"
  • to_string - returns a string representation of a JSON value
  • operator<< - serialize to stream
  • basic_json_view::dump - the corresponding function of basic_json_view, serializing directly from a flat index without building a basic_json value
  • Serialization - the serialization article
"},{"location":"api/basic_json/dump/#version-history","title":"Version history","text":"
  • Added in version 1.0.0.
  • Indentation character indent_char, option ensure_ascii and exceptions added in version 3.0.0.
  • Error handlers added in version 3.4.0.
  • Serialization of binary values added in version 3.8.0.
  • Error handler keep added in version 3.13.0 unreleased.
  • Doubles are written with the shortest digits (\u017bmij instead of Grisu2) since version 3.13.0 unreleased; about 0.1% of doubles are written differently, most of them with fewer digits.
"},{"location":"api/basic_json/emplace/","title":"nlohmann::basic_json::emplace","text":"
template<class... Args>\nstd::pair<iterator, bool> emplace(Args&& ... args);\n

Inserts a new element into a JSON object constructed in-place with the given args if there is no element with the key in the container. If the function is called on a JSON null value, an empty object is created before appending the value created from args.

"},{"location":"api/basic_json/emplace/#template-parameters","title":"Template parameters","text":"Args compatible types to create a basic_json object"},{"location":"api/basic_json/emplace/#iterator-invalidation","title":"Iterator invalidation","text":"

For ordered_json, adding a value to an object can yield a reallocation, in which case all iterators (including the end() iterator) and all references to the elements are invalidated.

"},{"location":"api/basic_json/emplace/#parameters","title":"Parameters","text":"args (in) arguments to forward to a constructor of basic_json"},{"location":"api/basic_json/emplace/#return-value","title":"Return value","text":"

a pair consisting of an iterator to the inserted element, or the already-existing element if no insertion happened, and a bool denoting whether the insertion took place.

"},{"location":"api/basic_json/emplace/#exception-safety","title":"Exception safety","text":"

Strong guarantee: if an exception is thrown, there are no changes to any JSON value. As an exception, a null value is converted to an empty object before the element is added and keeps that type if adding the element throws.

"},{"location":"api/basic_json/emplace/#exceptions","title":"Exceptions","text":"

Throws type_error.311 when called on a type other than JSON object or null; example: \"cannot use emplace() with number\"

"},{"location":"api/basic_json/emplace/#complexity","title":"Complexity","text":"

Logarithmic in the size of the container, O(log(size())).

"},{"location":"api/basic_json/emplace/#examples","title":"Examples","text":"Example

The example shows how emplace() can be used to add elements to a JSON object. Note how the null value was silently converted to a JSON object. Further note how no value is added if there was already one value stored with the same key.

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create JSON values\n    json object = {{\"one\", 1}, {\"two\", 2}};\n    json null;\n\n    // print values\n    std::cout << object << '\\n';\n    std::cout << null << '\\n';\n\n    // add values\n    auto res1 = object.emplace(\"three\", 3);\n    null.emplace(\"A\", \"a\");\n    null.emplace(\"B\", \"b\");\n\n    // the following call will not add an object, because there is already\n    // a value stored at key \"B\"\n    auto res2 = null.emplace(\"B\", \"c\");\n\n    // print values\n    std::cout << object << '\\n';\n    std::cout << *res1.first << \" \" << std::boolalpha << res1.second << '\\n';\n\n    std::cout << null << '\\n';\n    std::cout << *res2.first << \" \" << std::boolalpha << res2.second << '\\n';\n}\n

Output:

{\"one\":1,\"two\":2}\nnull\n{\"one\":1,\"three\":3,\"two\":2}\n3 true\n{\"A\":\"a\",\"B\":\"b\"}\n\"b\" false\n
"},{"location":"api/basic_json/emplace/#see-also","title":"See also","text":"
  • emplace_back - add a value to an array
  • insert - add values to an array/object
  • Modifying values - the article on modifying values
"},{"location":"api/basic_json/emplace/#version-history","title":"Version history","text":"
  • Added in version 2.0.8.
  • Fixed in version 3.13.0 unreleased: for ordered_json, the value could previously only be passed as an rvalue; it can now also be passed as an lvalue or a const lvalue, matching the behavior of json.
"},{"location":"api/basic_json/emplace_back/","title":"nlohmann::basic_json::emplace_back","text":"
template<class... Args>\nreference emplace_back(Args&& ... args);\n

Creates a JSON value from the passed parameters args to the end of the JSON value. If the function is called on a JSON null value, an empty array is created before appending the value created from args.

"},{"location":"api/basic_json/emplace_back/#template-parameters","title":"Template parameters","text":"Args compatible types to create a basic_json object"},{"location":"api/basic_json/emplace_back/#iterator-invalidation","title":"Iterator invalidation","text":"

By adding an element to the end of the array, a reallocation can happen, in which case all iterators (including the end() iterator) and all references to the elements are invalidated. Otherwise, only the end() iterator is invalidated.

"},{"location":"api/basic_json/emplace_back/#parameters","title":"Parameters","text":"args (in) arguments to forward to a constructor of basic_json"},{"location":"api/basic_json/emplace_back/#return-value","title":"Return value","text":"

reference to the inserted element

"},{"location":"api/basic_json/emplace_back/#exception-safety","title":"Exception safety","text":"

Strong guarantee: if an exception is thrown, there are no changes to any JSON value. As an exception, a null value is converted to an empty array before the element is added and keeps that type if adding the element throws.

"},{"location":"api/basic_json/emplace_back/#exceptions","title":"Exceptions","text":"

Throws type_error.311 when called on a type other than JSON array or null; example: \"cannot use emplace_back() with number\"

"},{"location":"api/basic_json/emplace_back/#complexity","title":"Complexity","text":"

Amortized constant.

"},{"location":"api/basic_json/emplace_back/#examples","title":"Examples","text":"Example

The example shows how emplace_back() can be used to add elements to a JSON array. Note how the null value was silently converted to a JSON array.

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create JSON values\n    json array = {1, 2, 3, 4, 5};\n    json null;\n\n    // print values\n    std::cout << array << '\\n';\n    std::cout << null << '\\n';\n\n    // add values\n    array.emplace_back(6);\n    null.emplace_back(\"first\");\n    null.emplace_back(3, \"second\");\n\n    // print values\n    std::cout << array << '\\n';\n    std::cout << null << '\\n';\n}\n

Output:

[1,2,3,4,5]\nnull\n[1,2,3,4,5,6]\n[\"first\",[\"second\",\"second\",\"second\"]]\n
"},{"location":"api/basic_json/emplace_back/#see-also","title":"See also","text":"
  • operator+= - add a value to an array/object
  • push_back - add a value to an array/object
  • Modifying values - the article on modifying values
"},{"location":"api/basic_json/emplace_back/#version-history","title":"Version history","text":"
  • Added in version 2.0.8.
  • Returns reference since 3.7.0.
"},{"location":"api/basic_json/empty/","title":"nlohmann::basic_json::empty","text":"
bool empty() const noexcept;\n

Checks if a JSON value has no elements (i.e., whether its size() is 0).

"},{"location":"api/basic_json/empty/#return-value","title":"Return value","text":"

The return value depends on the different types and is defined as follows:

Value type return value null true boolean false string false number false binary false object result of function object_t::empty() array result of function array_t::empty()"},{"location":"api/basic_json/empty/#exception-safety","title":"Exception safety","text":"

No-throw guarantee: this function never throws exceptions.

"},{"location":"api/basic_json/empty/#complexity","title":"Complexity","text":"

Constant, as long as array_t and object_t satisfy the Container concept; that is, their empty() functions have constant complexity.

"},{"location":"api/basic_json/empty/#possible-implementation","title":"Possible implementation","text":"
bool empty() const noexcept\n{\n    return size() == 0;\n}\n
"},{"location":"api/basic_json/empty/#notes","title":"Notes","text":"

This function does not return whether a string stored as JSON value is empty \u2014 it returns whether the JSON container itself is empty which is false in the case of a string.

"},{"location":"api/basic_json/empty/#examples","title":"Examples","text":"Example

The following code uses empty() to check if a JSON object contains any elements.

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create JSON values\n    json j_null;\n    json j_boolean = true;\n    json j_number_integer = 17;\n    json j_number_float = 23.42;\n    json j_object = {{\"one\", 1}, {\"two\", 2}};\n    json j_object_empty(json::value_t::object);\n    json j_array = {1, 2, 4, 8, 16};\n    json j_array_empty(json::value_t::array);\n    json j_string = \"Hello, world\";\n\n    // call empty()\n    std::cout << std::boolalpha;\n    std::cout << j_null.empty() << '\\n';\n    std::cout << j_boolean.empty() << '\\n';\n    std::cout << j_number_integer.empty() << '\\n';\n    std::cout << j_number_float.empty() << '\\n';\n    std::cout << j_object.empty() << '\\n';\n    std::cout << j_object_empty.empty() << '\\n';\n    std::cout << j_array.empty() << '\\n';\n    std::cout << j_array_empty.empty() << '\\n';\n    std::cout << j_string.empty() << '\\n';\n}\n

Output:

true\nfalse\nfalse\nfalse\nfalse\ntrue\nfalse\ntrue\nfalse\n
"},{"location":"api/basic_json/empty/#see-also","title":"See also","text":"
  • size - returns the number of elements
  • clear - clears the content and resets the value to the default value
  • basic_json_view::empty - the same check on a zero-copy view
"},{"location":"api/basic_json/empty/#version-history","title":"Version history","text":"
  • Added in version 1.0.0.
  • Extended to return false for binary types in version 3.8.0.
"},{"location":"api/basic_json/end/","title":"nlohmann::basic_json::end","text":"
iterator end() noexcept;\nconst_iterator end() const noexcept;\n

Returns an iterator to one past the last element.

A row of fifteen elements followed by a dashed past-the-last position. begin() points to the first element and end() points to the past-the-last position. begin end Past-the-last element

end() points to the position after the last element and begin() to the first element; the dashed cell is the past-the-last position, which must not be dereferenced.

"},{"location":"api/basic_json/end/#return-value","title":"Return value","text":"

iterator one past the last element

"},{"location":"api/basic_json/end/#exception-safety","title":"Exception safety","text":"

No-throw guarantee: this member function never throws exceptions.

"},{"location":"api/basic_json/end/#complexity","title":"Complexity","text":"

Constant.

"},{"location":"api/basic_json/end/#examples","title":"Examples","text":"Example

The following code shows an example for end().

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create an array value\n    json array = {1, 2, 3, 4, 5};\n\n    // get an iterator to one past the last element\n    json::iterator it = array.end();\n\n    // decrement the iterator to point to the last element\n    --it;\n\n    // serialize the element that the iterator points to\n    std::cout << *it << '\\n';\n}\n

Output:

5\n
"},{"location":"api/basic_json/end/#see-also","title":"See also","text":"
  • begin - returns an iterator to the first element
  • cend - returns a const iterator to one past the last element
  • rend - returns a reverse iterator to one before the first element
  • Iterators - the article on iterators
  • basic_json_view::end - the same iteration on a zero-copy view
"},{"location":"api/basic_json/end/#version-history","title":"Version history","text":"
  • Added in version 1.0.0.
"},{"location":"api/basic_json/end_pos/","title":"nlohmann::basic_json::end_pos","text":"
#if JSON_DIAGNOSTIC_POSITIONS\nconstexpr std::size_t end_pos() const noexcept;\n#endif\n

Returns the position immediately following the last character of the JSON string from which the value was parsed from.

JSON type return value object position after the closing } array position after the closing ] string position after the closing \" number position after the last character boolean position after e null position after l"},{"location":"api/basic_json/end_pos/#return-value","title":"Return value","text":"

the position of the character following the last character of the given value in the parsed JSON string, if the value was created by the parse function, or std::string::npos if the value was constructed otherwise

"},{"location":"api/basic_json/end_pos/#exception-safety","title":"Exception safety","text":"

No-throw guarantee: this member function never throws exceptions.

"},{"location":"api/basic_json/end_pos/#complexity","title":"Complexity","text":"

Constant.

"},{"location":"api/basic_json/end_pos/#notes","title":"Notes","text":"

Note

The function is only available if macro JSON_DIAGNOSTIC_POSITIONS has been defined to 1 before including the library header.

Invalidation

The returned positions are only valid as long as the JSON value is not changed. The positions are not updated when the JSON value is changed.

"},{"location":"api/basic_json/end_pos/#examples","title":"Examples","text":"Example
#include <iostream>\n\n#define JSON_DIAGNOSTIC_POSITIONS 1\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    std::string json_string = R\"(\n    {\n        \"address\": {\n            \"street\": \"Fake Street\",\n            \"housenumber\": 1\n        }\n    }\n    )\";\n    json j = json::parse(json_string);\n\n    std::cout << \"Root diagnostic positions: \\n\";\n    std::cout << \"\\tstart_pos: \" << j.start_pos() << '\\n';\n    std::cout << \"\\tend_pos:\" << j.end_pos() << \"\\n\";\n    std::cout << \"Original string: \\n\";\n    std::cout << \"{\\n        \\\"address\\\": {\\n            \\\"street\\\": \\\"Fake Street\\\",\\n            \\\"housenumber\\\": 1\\n        }\\n    }\" << \"\\n\";\n    std::cout << \"Parsed string: \\n\";\n    std::cout << json_string.substr(j.start_pos(), j.end_pos() - j.start_pos()) << \"\\n\\n\";\n\n    std::cout << \"address diagnostic positions: \\n\";\n    std::cout << \"\\tstart_pos:\" << j[\"address\"].start_pos() << '\\n';\n    std::cout << \"\\tend_pos:\" << j[\"address\"].end_pos() << \"\\n\\n\";\n    std::cout << \"Original string: \\n\";\n    std::cout << \"{            \\\"street\\\": \\\"Fake Street\\\",\\n            \\\"housenumber\\\": 1\\n        }\" << \"\\n\";\n    std::cout << \"Parsed string: \\n\";\n    std::cout << json_string.substr(j[\"address\"].start_pos(), j[\"address\"].end_pos() - j[\"address\"].start_pos()) << \"\\n\\n\";\n\n    std::cout << \"street diagnostic positions: \\n\";\n    std::cout << \"\\tstart_pos:\" << j[\"address\"][\"street\"].start_pos() << '\\n';\n    std::cout << \"\\tend_pos:\" << j[\"address\"][\"street\"].end_pos() << \"\\n\\n\";\n    std::cout << \"Original string: \\n\";\n    std::cout << \"\\\"Fake Street\\\"\" << \"\\n\";\n    std::cout << \"Parsed string: \\n\";\n    std::cout << json_string.substr(j[\"address\"][\"street\"].start_pos(), j[\"address\"][\"street\"].end_pos() - j[\"address\"][\"street\"].start_pos()) << \"\\n\\n\";\n\n    std::cout << \"housenumber diagnostic positions: \\n\";\n    std::cout << \"\\tstart_pos:\" << j[\"address\"][\"housenumber\"].start_pos() << '\\n';\n    std::cout << \"\\tend_pos:\" << j[\"address\"][\"housenumber\"].end_pos() << \"\\n\\n\";\n    std::cout << \"Original string: \\n\";\n    std::cout << \"1\" << \"\\n\";\n    std::cout << \"Parsed string: \\n\";\n    std::cout << json_string.substr(j[\"address\"][\"housenumber\"].start_pos(), j[\"address\"][\"housenumber\"].end_pos() - j[\"address\"][\"housenumber\"].start_pos()) << \"\\n\\n\";\n}\n

Output:

Root diagnostic positions: \n    start_pos: 5\n    end_pos:109\nOriginal string: \n{\n        \"address\": {\n            \"street\": \"Fake Street\",\n            \"housenumber\": 1\n        }\n    }\nParsed string: \n{\n        \"address\": {\n            \"street\": \"Fake Street\",\n            \"housenumber\": 1\n        }\n    }\n\naddress diagnostic positions: \n    start_pos:26\n    end_pos:103\n\nOriginal string: \n{            \"street\": \"Fake Street\",\n            \"housenumber\": 1\n        }\nParsed string: \n{\n            \"street\": \"Fake Street\",\n            \"housenumber\": 1\n        }\n\nstreet diagnostic positions: \n    start_pos:50\n    end_pos:63\n\nOriginal string: \n\"Fake Street\"\nParsed string: \n\"Fake Street\"\n\nhousenumber diagnostic positions: \n    start_pos:92\n    end_pos:93\n\nOriginal string: \n1\nParsed string: \n1\n

The output shows the start/end positions of all the objects and fields in the JSON string.

"},{"location":"api/basic_json/end_pos/#see-also","title":"See also","text":"
  • start_pos - to access the start position
  • JSON_DIAGNOSTIC_POSITIONS - overview of the supported conversions
  • Parsing and Exceptions - handling parse errors and locating them in the input
"},{"location":"api/basic_json/end_pos/#version-history","title":"Version history","text":"
  • Added in version 3.12.0.
"},{"location":"api/basic_json/erase/","title":"nlohmann::basic_json::erase","text":"
// (1)\niterator erase(iterator pos);\nconst_iterator erase(const_iterator pos);\n\n// (2)\niterator erase(iterator first, iterator last);\nconst_iterator erase(const_iterator first, const_iterator last);\n\n// (3)\nsize_type erase(const typename object_t::key_type& key);\n\n// (4)\ntemplate<typename KeyType>\nsize_type erase(KeyType&& key);\n\n// (5)\nvoid erase(const size_type idx);\n
  1. Removes an element from a JSON value specified by iterator pos. The iterator pos must be valid and dereferenceable. Thus, the end() iterator (which is valid, but is not dereferenceable) cannot be used as a value for pos.

    If called on a primitive type other than null, the resulting JSON value will be null.

  2. Remove an element range specified by [first; last) from a JSON value. The iterator first does not need to be dereferenceable if first == last: erasing an empty range is a no-op.

    If called on a primitive type other than null, the resulting JSON value will be null.

  3. Removes an element from a JSON object by key.

  4. See 3. This overload is only available if KeyType is comparable with typename object_t::key_type and typename object_comparator_t::is_transparent denotes a type.

  5. Removes an element from a JSON array by index.

"},{"location":"api/basic_json/erase/#template-parameters","title":"Template parameters","text":"KeyType A type for an object key other than json_pointer that is comparable with string_t using object_comparator_t. This can also be a string view (C++17)."},{"location":"api/basic_json/erase/#parameters","title":"Parameters","text":"pos (in) iterator to the element to remove first (in) iterator to the beginning of the range to remove last (in) iterator past the end of the range to remove key (in) object key of the elements to remove idx (in) array index of the element to remove"},{"location":"api/basic_json/erase/#return-value","title":"Return value","text":"
  1. Iterator following the last removed element. If the iterator pos refers to the last element, the end() iterator is returned.
  2. Iterator following the last removed element. If the iterator last refers to the last element, the end() iterator is returned.
  3. Number of elements removed. If ObjectType is the default std::map type, the return value will always be 0 (key was not found) or 1 (key was found).
  4. See 3.
  5. (none)
"},{"location":"api/basic_json/erase/#exception-safety","title":"Exception safety","text":"

Strong exception safety: if an exception occurs, the original value stays intact.

"},{"location":"api/basic_json/erase/#exceptions","title":"Exceptions","text":"
  1. The function can throw the following exceptions:
    • Throws type_error.307 if called on a null value; example: \"cannot use erase() with null\"
    • Throws invalid_iterator.202 if called on an iterator which does not belong to the current JSON value; example: \"iterator does not fit current value\"
    • Throws invalid_iterator.205 if called on a primitive type with invalid iterator (i.e., any iterator which is not begin()); example: \"iterator out of range\"
  2. The function can throw the following exceptions:
    • Throws type_error.307 if called on a null value; example: \"cannot use erase() with null\"
    • Throws invalid_iterator.203 if called on iterators which does not belong to the current JSON value; example: \"iterators do not fit current value\"
    • Throws invalid_iterator.204 if called on a primitive type with invalid iterators (i.e., if first != begin() and last != end()); example: \"iterators out of range\"
  3. The function can throw the following exceptions:
    • Throws type_error.307 when called on a type other than JSON object; example: \"cannot use erase() with null\"
  4. See 3.
  5. The function can throw the following exceptions:
    • Throws type_error.307 when called on a type other than JSON array; example: \"cannot use erase() with null\"
    • Throws out_of_range.401 when idx >= size(); example: \"array index 17 is out of range\"
"},{"location":"api/basic_json/erase/#complexity","title":"Complexity","text":"
  1. The complexity depends on the type:
    • objects: amortized constant
    • arrays: linear in distance between pos and the end of the container
    • strings and binary: linear in the length of the member
    • other types: constant
  2. The complexity depends on the type:
    • objects: log(size()) + std::distance(first, last)
    • arrays: linear in the distance between first and last, plus linear in the distance between last and end of the container
    • strings and binary: linear in the length of the member
    • other types: constant
  3. log(size()) + count(key)
  4. log(size()) + count(key)
  5. Linear in distance between idx and the end of the container.
"},{"location":"api/basic_json/erase/#notes","title":"Notes","text":"
  1. Invalidates iterators and references at or after the point of the erase, including the end() iterator.
  2. (none)
  3. References and iterators to the erased elements are invalidated. Other references and iterators are not affected.
  4. See 3.
  5. (none)
"},{"location":"api/basic_json/erase/#examples","title":"Examples","text":"Example: (1) remove element given an iterator

The example shows the effect of erase() for different JSON types using an iterator.

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create JSON values\n    json j_boolean = true;\n    json j_number_integer = 17;\n    json j_number_float = 23.42;\n    json j_object = {{\"one\", 1}, {\"two\", 2}};\n    json j_array = {1, 2, 4, 8, 16};\n    json j_string = \"Hello, world\";\n\n    // call erase()\n    j_boolean.erase(j_boolean.begin());\n    j_number_integer.erase(j_number_integer.begin());\n    j_number_float.erase(j_number_float.begin());\n    j_object.erase(j_object.find(\"two\"));\n    j_array.erase(j_array.begin() + 2);\n    j_string.erase(j_string.begin());\n\n    // print values\n    std::cout << j_boolean << '\\n';\n    std::cout << j_number_integer << '\\n';\n    std::cout << j_number_float << '\\n';\n    std::cout << j_object << '\\n';\n    std::cout << j_array << '\\n';\n    std::cout << j_string << '\\n';\n}\n

Output:

null\nnull\nnull\n{\"one\":1}\n[1,2,8,16]\nnull\n
Example: (2) remove elements given an iterator range

The example shows the effect of erase() for different JSON types using an iterator range.

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create JSON values\n    json j_boolean = true;\n    json j_number_integer = 17;\n    json j_number_float = 23.42;\n    json j_object = {{\"one\", 1}, {\"two\", 2}};\n    json j_array = {1, 2, 4, 8, 16};\n    json j_string = \"Hello, world\";\n\n    // call erase()\n    j_boolean.erase(j_boolean.begin(), j_boolean.end());\n    j_number_integer.erase(j_number_integer.begin(), j_number_integer.end());\n    j_number_float.erase(j_number_float.begin(), j_number_float.end());\n    j_object.erase(j_object.find(\"two\"), j_object.end());\n    j_array.erase(j_array.begin() + 1, j_array.begin() + 3);\n    j_string.erase(j_string.begin(), j_string.end());\n\n    // print values\n    std::cout << j_boolean << '\\n';\n    std::cout << j_number_integer << '\\n';\n    std::cout << j_number_float << '\\n';\n    std::cout << j_object << '\\n';\n    std::cout << j_array << '\\n';\n    std::cout << j_string << '\\n';\n}\n

Output:

null\nnull\nnull\n{\"one\":1}\n[1,8,16]\nnull\n
Example: (3) remove element from a JSON object given a key

The example shows the effect of erase() for different JSON types using an object key.

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create a JSON object\n    json j_object = {{\"one\", 1}, {\"two\", 2}};\n\n    // call erase()\n    auto count_one = j_object.erase(\"one\");\n    auto count_three = j_object.erase(\"three\");\n\n    // print values\n    std::cout << j_object << '\\n';\n    std::cout << count_one << \" \" << count_three << '\\n';\n}\n

Output:

{\"two\":2}\n1 0\n
Example: (4) remove element from a JSON object given a key using string_view

The example shows the effect of erase() for different JSON types using an object key.

#include <iostream>\n#include <string_view>\n#include <nlohmann/json.hpp>\n\nusing namespace std::string_view_literals;\nusing nlohmann::json;\n\nint main()\n{\n    // create a JSON object\n    json j_object = {{\"one\", 1}, {\"two\", 2}};\n\n    // call erase()\n    auto count_one = j_object.erase(\"one\"sv);\n    auto count_three = j_object.erase(\"three\"sv);\n\n    // print values\n    std::cout << j_object << '\\n';\n    std::cout << count_one << \" \" << count_three << '\\n';\n}\n

Output:

{\"two\":2}\n1 0\n
Example: (5) remove element from a JSON array given an index

The example shows the effect of erase() using an array index.

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create a JSON array\n    json j_array = {0, 1, 2, 3, 4, 5};\n\n    // call erase()\n    j_array.erase(2);\n\n    // print values\n    std::cout << j_array << '\\n';\n}\n

Output:

[0,1,3,4,5]\n
"},{"location":"api/basic_json/erase/#see-also","title":"See also","text":"
  • clear - clears the contents
  • insert - add values to an array/object
  • Modifying values - the article on modifying values
"},{"location":"api/basic_json/erase/#version-history","title":"Version history","text":"
  1. Added in version 1.0.0. Added support for binary types in version 3.8.0.
  2. Added in version 1.0.0. Added support for binary types in version 3.8.0.
  3. Added in version 1.0.0.
  4. Added in version 3.11.0. Support for keys convertible to std::string_view added in version 3.13.0 unreleased, consistently across the lookup functions.
  5. Added in version 1.0.0.
"},{"location":"api/basic_json/error_handler_t/","title":"nlohmann::basic_json::error_handler_t","text":"
enum class error_handler_t {\n    strict,\n    replace,\n    ignore,\n    keep\n};\n

This enumeration is used to choose how to treat ill-formed UTF-8 in a string value or object key:

  • dump uses it while serializing a basic_json value to text.
  • to_cbor, to_msgpack, to_ubjson, to_bjdata, and to_bson use it while serializing a basic_json value to that binary format. Their default is keep, as no binary writer checked before this parameter was added. CBOR, UBJSON, BJData, and BSON require valid UTF-8, so for these four the default is strict if JSON_STRICT_BINARY_UTF8 is enabled; MessagePack's specification explicitly allows a string to contain ill-formed UTF-8, so to_msgpack stays at keep. to_bon8 does not take this parameter: BON8 always validates, since UTF-8 lead bytes are structural to that format.
  • from_cbor, from_msgpack, from_ubjson, from_bjdata, and from_bson use it while parsing that binary format, to decide whether to check a string value or object key for well-formed UTF-8 at all; by default (keep) they do not, as no binary reader did before this parameter was added. from_bon8 does not take this parameter, for the same reason to_bon8 does not.

Four values are differentiated:

strict throw a type_error/parse_error exception in case of invalid UTF-8 replace replace invalid UTF-8 sequences with U+FFFD (\ufffd REPLACEMENT CHARACTER) ignore ignore invalid UTF-8 sequences; all valid bytes are copied to the output unchanged, and invalid bytes are dropped keep keep invalid UTF-8 sequences unchanged; only meaningful for the binary formats mentioned above, since dump itself must produce text, and keep there writes the ill-formed bytes to the output as is, so the result is then not valid UTF-8 (but still equals the input bytes exactly, including around any well-formed characters, which are still escaped as usual)"},{"location":"api/basic_json/error_handler_t/#examples","title":"Examples","text":"Example

The example below shows how the different values of the error_handler_t influence the behavior of dump when reading serializing an invalid UTF-8 sequence.

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create JSON value with invalid UTF-8 byte sequence\n    json j_invalid = \"\u00e4\\xA9\u00fc\";\n    try\n    {\n        std::cout << j_invalid.dump() << '\\n';\n    }\n    catch (const json::type_error& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n\n    std::cout << \"string with replaced invalid characters: \"\n              << j_invalid.dump(-1, ' ', false, json::error_handler_t::replace)\n              << \"\\nstring with ignored invalid characters: \"\n              << j_invalid.dump(-1, ' ', false, json::error_handler_t::ignore)\n              << \"\\nstring with the invalid byte kept as is (\" << j_invalid.dump(-1, ' ', false, json::error_handler_t::keep).size()\n              << \" bytes, not valid UTF-8 itself)\\n\";\n}\n

Output:

[json.exception.type_error.316] invalid UTF-8 byte at index 2: 0xA9\nstring with replaced invalid characters: \"\u00e4\ufffd\u00fc\"\nstring with ignored invalid characters: \"\u00e4\u00fc\"\nstring with the invalid byte kept as is (7 bytes, not valid UTF-8 itself)\n
"},{"location":"api/basic_json/error_handler_t/#see-also","title":"See also","text":"
  • dump - serializes a JSON value, with an error_handler_t parameter to configure invalid UTF-8 handling
  • Handling invalid UTF-8 - the article on handling invalid UTF-8
"},{"location":"api/basic_json/error_handler_t/#version-history","title":"Version history","text":"
  • Added in version 3.4.0.
  • Added keep, and made this enumeration apply to the binary readers and writers in addition to dump, in version 3.13.0.
"},{"location":"api/basic_json/exception/","title":"nlohmann::basic_json::exception","text":"
class exception : public std::exception;\n

This class is an extension of std::exception objects with a member id for exception ids. It is used as the base class for all exceptions thrown by the basic_json class. This class can hence be used as \"wildcard\" to catch exceptions, see example below.

classDiagram\n  direction LR\n\n    class std_exception [\"std::exception\"] {\n        <<interface>>\n    }\n\n    class json_exception [\"basic_json::exception\"] {\n        +const int id\n        +const char* what() const\n    }\n\n    class json_parse_error [\"basic_json::parse_error\"] {\n        +const std::size_t byte\n    }\n\n    class json_invalid_iterator [\"basic_json::invalid_iterator\"]\n    class json_type_error [\"basic_json::type_error\"]\n    class json_out_of_range [\"basic_json::out_of_range\"]\n    class json_other_error [\"basic_json::other_error\"]\n\n    std_exception <|-- json_exception\n    json_exception <|-- json_parse_error\n    json_exception <|-- json_invalid_iterator\n    json_exception <|-- json_type_error\n    json_exception <|-- json_out_of_range\n    json_exception <|-- json_other_error\n\n    style json_exception fill:#CCCCFF

Class hierarchy of the library's exceptions; arrows point from a derived class to its base class, and the highlighted box is basic_json::exception.

Subclasses:

  • parse_error for exceptions indicating a parse error
  • invalid_iterator for exceptions indicating errors with iterators
  • type_error for exceptions indicating executing a member function with a wrong type
  • out_of_range for exceptions indicating access out of the defined range
  • other_error for exceptions indicating other library errors
"},{"location":"api/basic_json/exception/#member-functions","title":"Member functions","text":"
  • what - returns explanatory string
"},{"location":"api/basic_json/exception/#member-variables","title":"Member variables","text":"
  • id - the id of the exception
"},{"location":"api/basic_json/exception/#notes","title":"Notes","text":"

To have nothrow-copy-constructible exceptions, we internally use std::runtime_error which can cope with arbitrary-length error messages. Intermediate strings are built with static functions and then passed to the actual constructor.

"},{"location":"api/basic_json/exception/#examples","title":"Examples","text":"Example

The following code shows how arbitrary library exceptions can be caught.

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    try\n    {\n        // calling at() for a non-existing key\n        json j = {{\"foo\", \"bar\"}};\n        json k = j.at(\"non-existing\");\n    }\n    catch (const json::exception& e)\n    {\n        // output exception information\n        std::cout << \"message: \" << e.what() << '\\n'\n                  << \"exception id: \" << e.id << '\\n';\n    }\n}\n

Output:

message: [json.exception.out_of_range.403] key 'non-existing' not found\nexception id: 403\n
"},{"location":"api/basic_json/exception/#see-also","title":"See also","text":"
  • List of exceptions - overview of all exceptions thrown by the library
  • Working Without Exceptions - using the library without exceptions
  • JSON_DIAGNOSTICS - extended exception messages with the path of the failing value
  • Parsing and Exceptions - parsing alternatives that do not throw
  • Debugging - debugging aids
"},{"location":"api/basic_json/exception/#version-history","title":"Version history","text":"
  • Added in version 3.0.0.
"},{"location":"api/basic_json/find/","title":"nlohmann::basic_json::find","text":"
// (1)\niterator find(const typename object_t::key_type& key);\nconst_iterator find(const typename object_t::key_type& key) const;\n\n// (2)\ntemplate<typename KeyType>\niterator find(KeyType&& key);\ntemplate<typename KeyType>\nconst_iterator find(KeyType&& key) const;\n\n// (3)\ntemplate<typename T>\niterator find(T) = delete;\ntemplate<typename T>\nconst_iterator find(T) const = delete;\n
  1. Finds an element in a JSON object with a key equivalent to key. If the element is not found or the JSON value is not an object, end() is returned.
  2. See 1. This overload is only available if KeyType is comparable with typename object_t::key_type and typename object_comparator_t::is_transparent denotes a type.
  3. Deleted: this overload is only available if T is an integral type and is declared as deleted, so that a call with an integer key (for example, j.find(0)) fails to compile. Otherwise, the integer literal 0 would convert to a null const char* and, from there, to the key type, causing undefined behavior at runtime.
"},{"location":"api/basic_json/find/#template-parameters","title":"Template parameters","text":"KeyType A type for an object key other than json_pointer that is comparable with string_t using object_comparator_t. This can also be a string view (C++17)."},{"location":"api/basic_json/find/#parameters","title":"Parameters","text":"key (in) key value of the element to search for."},{"location":"api/basic_json/find/#return-value","title":"Return value","text":"

Iterator to an element with a key equivalent to key. If no such element is found or the JSON value is not an object, a past-the-end iterator (see end()) is returned.

"},{"location":"api/basic_json/find/#exception-safety","title":"Exception safety","text":"

Strong exception safety: if an exception occurs, the original value stays intact.

"},{"location":"api/basic_json/find/#complexity","title":"Complexity","text":"

Logarithmic in the size of the JSON object.

"},{"location":"api/basic_json/find/#notes","title":"Notes","text":"
  • 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, find(0)) does not compile: such an argument would otherwise implicitly convert to a null const char* and, from there, cause undefined behavior when constructing a std::string for the object key. To access an array element instead, use at, operator[], or compare against size.
"},{"location":"api/basic_json/find/#examples","title":"Examples","text":"Example: (1) find object element by key

The example shows how find() is used.

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create a JSON object\n    json j_object = {{\"one\", 1}, {\"two\", 2}};\n\n    // call find\n    auto it_two = j_object.find(\"two\");\n    auto it_three = j_object.find(\"three\");\n\n    // print values\n    std::cout << std::boolalpha;\n    std::cout << \"\\\"two\\\" was found: \" << (it_two != j_object.end()) << '\\n';\n    std::cout << \"value at key \\\"two\\\": \" << *it_two << '\\n';\n    std::cout << \"\\\"three\\\" was found: \" << (it_three != j_object.end()) << '\\n';\n}\n

Output:

\"two\" was found: true\nvalue at key \"two\": 2\n\"three\" was found: false\n
Example: (2) find object element by key using string_view

The example shows how find() is used.

#include <iostream>\n#include <string_view>\n#include <nlohmann/json.hpp>\n\nusing namespace std::string_view_literals;\nusing nlohmann::json;\n\nint main()\n{\n    // create a JSON object\n    json j_object = {{\"one\", 1}, {\"two\", 2}};\n\n    // call find\n    auto it_two = j_object.find(\"two\"sv);\n    auto it_three = j_object.find(\"three\"sv);\n\n    // print values\n    std::cout << std::boolalpha;\n    std::cout << \"\\\"two\\\" was found: \" << (it_two != j_object.end()) << '\\n';\n    std::cout << \"value at key \\\"two\\\": \" << *it_two << '\\n';\n    std::cout << \"\\\"three\\\" was found: \" << (it_three != j_object.end()) << '\\n';\n}\n

Output:

\"two\" was found: true\nvalue at key \"two\": 2\n\"three\" was found: false\n
"},{"location":"api/basic_json/find/#see-also","title":"See also","text":"
  • count - returns the number of occurrences of a key
  • contains - checks whether a key exists
  • basic_json_view::find - the same lookup on a zero-copy view (a duplicate key resolves to the first member, whereas parse() keeps the last)
  • Element Access - how to test whether a key exists
"},{"location":"api/basic_json/find/#version-history","title":"Version history","text":"
  1. Added in version 3.11.0.
  2. Added in version 1.0.0. Changed to support comparable types in version 3.11.0. Support for keys convertible to std::string_view added in version 3.13.0 unreleased, consistently across the lookup functions.
  3. Deleted overloads for integral key types added in version 3.13.0 unreleased to reject such calls at compile time instead of causing undefined behavior at runtime.
"},{"location":"api/basic_json/flatten/","title":"nlohmann::basic_json::flatten","text":"
basic_json flatten() const;\n

The function creates a JSON object whose keys are JSON pointers (see RFC 6901) and whose values are all primitive (see is_primitive() for more information). The original JSON value can be restored using the unflatten() function.

"},{"location":"api/basic_json/flatten/#return-value","title":"Return value","text":"

an object that maps JSON pointers to primitive values

"},{"location":"api/basic_json/flatten/#exception-safety","title":"Exception safety","text":"

Strong exception safety: if an exception occurs, the original value stays intact.

"},{"location":"api/basic_json/flatten/#complexity","title":"Complexity","text":"

Linear in the size of the JSON value.

"},{"location":"api/basic_json/flatten/#notes","title":"Notes","text":"

Empty objects and arrays are flattened to null and will not be reconstructed correctly by the unflatten() function.

"},{"location":"api/basic_json/flatten/#examples","title":"Examples","text":"Example: flatten a JSON object

The following code shows how a JSON object is flattened to an object whose keys consist of JSON pointers.

#include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create JSON value\n    json j =\n    {\n        {\"pi\", 3.141},\n        {\"happy\", true},\n        {\"name\", \"Niels\"},\n        {\"nothing\", nullptr},\n        {\n            \"answer\", {\n                {\"everything\", 42}\n            }\n        },\n        {\"list\", {1, 0, 2}},\n        {\n            \"object\", {\n                {\"currency\", \"USD\"},\n                {\"value\", 42.99}\n            }\n        }\n    };\n\n    // call flatten()\n    std::cout << std::setw(4) << j.flatten() << '\\n';\n}\n

Output:

{\n    \"/answer/everything\": 42,\n    \"/happy\": true,\n    \"/list/0\": 1,\n    \"/list/1\": 0,\n    \"/list/2\": 2,\n    \"/name\": \"Niels\",\n    \"/nothing\": null,\n    \"/object/currency\": \"USD\",\n    \"/object/value\": 42.99,\n    \"/pi\": 3.141\n}\n
Example: empty objects and arrays are flattened to null

The following code shows that an empty object and an empty array are both flattened to null, and that unflatten() restores them as null rather than as empty containers.

#include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create a JSON value with an empty object and an empty array\n    json j =\n    {\n        {\"empty_object\", json::object()},\n        {\"empty_array\", json::array()},\n        {\"name\", \"Niels\"}\n    };\n\n    // call flatten()\n    json flattened = j.flatten();\n    std::cout << std::setw(4) << flattened << \"\\n\\n\";\n\n    // the empty containers cannot be restored by unflatten()\n    std::cout << std::setw(4) << flattened.unflatten() << '\\n';\n}\n

Output:

{\n    \"/empty_array\": null,\n    \"/empty_object\": null,\n    \"/name\": \"Niels\"\n}\n\n{\n    \"empty_array\": null,\n    \"empty_object\": null,\n    \"name\": \"Niels\"\n}\n
"},{"location":"api/basic_json/flatten/#see-also","title":"See also","text":"
  • unflatten - the reverse function
  • JSON Pointer - the article on JSON Pointer and flattening
"},{"location":"api/basic_json/flatten/#version-history","title":"Version history","text":"
  • Added in version 2.0.0.
"},{"location":"api/basic_json/format_as/","title":"format_as(basic_json)","text":"
template <typename BasicJsonType>\nstd::string format_as(const BasicJsonType& j);\n

This function implements the format_as customization point used by the {fmt} library (fmtlib). It has no dependency on any fmt header and no effect at all unless a caller's translation unit also includes fmt and calls fmt::format/fmt::print on a JSON value.

"},{"location":"api/basic_json/format_as/#template-parameters","title":"Template parameters","text":"BasicJsonType a specialization of basic_json"},{"location":"api/basic_json/format_as/#return-value","title":"Return value","text":"

string containing the serialization of the JSON value (same as dump())

"},{"location":"api/basic_json/format_as/#exception-safety","title":"Exception safety","text":"

Strong guarantee: if an exception is thrown, there are no changes to any JSON value.

"},{"location":"api/basic_json/format_as/#exceptions","title":"Exceptions","text":"

Throws type_error.316 if a string stored inside the JSON value is not UTF-8 encoded

"},{"location":"api/basic_json/format_as/#complexity","title":"Complexity","text":"

Linear.

"},{"location":"api/basic_json/format_as/#possible-implementation","title":"Possible implementation","text":"
template <typename BasicJsonType>\nstd::string format_as(const BasicJsonType& j)\n{\n    return j.dump();\n}\n
"},{"location":"api/basic_json/format_as/#notes","title":"Notes","text":"

Version-dependent effect on fmt

fmt only picks up a format_as overload that returns a std::string in fmt 10.0.0 through 11.0.2. Starting with fmt 11.1.0, fmt restricts automatic format_as pickup to overloads that return an arithmetic type, so this function has no effect there (it is simply unused, not a compile error).

If you use fmt >= 11.1.0, or want the same pretty-print spec support that std::formatter<basic_json> has (\"{:#}\", a width to set the indent such as \"{:2}\"/\"{:#2}\", and fill-and-align to pick the indent character such as \"{:.>#}\"), define your own fmt::formatter specialization mirroring the same logic:

template <>\nstruct fmt::formatter<nlohmann::json>\n{\n    // -1 means compact output (dump()); any value >= 0 means pretty-printed\n    // output with that many spaces (or indent_char) per level.\n    int indent = -1;\n    char indent_char = ' ';\n\n    constexpr auto parse(format_parse_context& ctx) -> format_parse_context::iterator\n    {\n        auto it = ctx.begin();\n        const auto end = ctx.end();\n        constexpr auto is_align = [](char c)\n        {\n            return c == '<' || c == '>' || c == '^';\n        };\n\n        // [[fill] align] - repurposed here to pick a custom indent character\n        if (it != end && it + 1 != end && is_align(it[1]))\n        {\n            indent_char = *it;\n            it += 2;\n        }\n        else if (it != end && is_align(*it))\n        {\n            ++it;\n        }\n\n        // ['#'] - \"alternate form\", used here to request pretty-printing with a\n        // default indent of 4 (overridden by an explicit width below, if given)\n        if (it != end && *it == '#')\n        {\n            indent = 4;\n            ++it;\n        }\n\n        // [width] - repurposed here to pick the indent size; a width without '#'\n        // implies pretty-printing since an indent otherwise has no meaning\n        if (it != end && *it >= '1' && *it <= '9')\n        {\n            indent = 0;\n            while (it != end && *it >= '0' && *it <= '9')\n            {\n                indent = (indent * 10) + (*it - '0');\n                ++it;\n            }\n        }\n\n        if (it != end && *it != '}')\n        {\n            throw fmt::format_error(\"invalid format args for nlohmann::json\");\n        }\n\n        return it;\n    }\n\n    auto format(const nlohmann::json& j, format_context& ctx) const\n    {\n        const auto dumped = j.dump(indent, indent_char);\n        return fmt::format_to(ctx.out(), \"{}\", dumped);\n    }\n};\n

This recipe isn't shipped by the library itself, since doing so would make fmt a build dependency (see the FAQ entry on using JSON values with std::format or fmt for more background) \u2014 but it is compiled and exercised against a real, current fmt release as part of the library's own test suite (tests/fmt_formatter, via CMake FetchContent), so it's kept in sync with std::formatter<basic_json> and verified to actually work, not just illustrative.

"},{"location":"api/basic_json/format_as/#examples","title":"Examples","text":"Example

The following code shows how the library's format_as() function integrates with fmt::format, allowing argument-dependent lookup.

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create a JSON value\n    json j = {{\"one\", 1}, {\"two\", 2}};\n\n    // format_as() is found via argument-dependent lookup, the same way\n    // fmt::format/fmt::print would find it\n    auto j_str = format_as(j);\n\n    std::cout << j_str << '\\n';\n}\n

Output:

{\"one\":1,\"two\":2}\n
"},{"location":"api/basic_json/format_as/#see-also","title":"See also","text":"
  • dump - serialize a JSON value to a string
  • std::formatter<basic_json> - the std::format (C++20) equivalent
  • Serialization - the serialization article
"},{"location":"api/basic_json/format_as/#version-history","title":"Version history","text":"
  • Added in version 3.13.0 unreleased.
"},{"location":"api/basic_json/from_bjdata/","title":"nlohmann::basic_json::from_bjdata","text":"
// (1)\ntemplate<typename InputType>\nstatic basic_json from_bjdata(InputType&& i,\n                              const bool strict = true,\n                              const bool allow_exceptions = true,\n                              const error_handler_t error_handler = error_handler_t::keep);\n// (2)\ntemplate<typename IteratorType, typename SentinelType = IteratorType>\nstatic basic_json from_bjdata(IteratorType first, SentinelType last,\n                              const bool strict = true,\n                              const bool allow_exceptions = true,\n                              const error_handler_t error_handler = error_handler_t::keep);\n

Deserializes a given input to a JSON value using the BJData (Binary JData) serialization format.

  1. Reads from a compatible input.
  2. Reads from an iterator range, or an iterator and a sentinel of a different type (C++20 ranges support).

The exact mapping and its limitations are described on a dedicated page.

"},{"location":"api/basic_json/from_bjdata/#template-parameters","title":"Template parameters","text":"InputType

A compatible input, for instance:

  • an std::istream object
  • a FILE pointer
  • a C-style array of characters
  • a pointer to a null-terminated string of single byte characters
  • a container obj for which begin(obj) and end(obj) produce a valid pair of iterators (as found via ADL or member functions, with semantics compatible to std::begin and std::end)
IteratorType a compatible iterator type SentinelType

defaults to IteratorType; may be a different type comparable to IteratorType via operator!=, for instance.

  • a custom sentinel type for C++20 ranges
  • std::default_sentinel_t, when IteratorType is std::counted_iterator
"},{"location":"api/basic_json/from_bjdata/#parameters","title":"Parameters","text":"i (in) an input in BJData format convertible to an input adapter first (in) iterator to the start of the input last (in) iterator to the end of the input, or a sentinel value that compares equal to the end iterator with operator!= strict (in) whether to expect the input to be consumed until EOF (true by default) allow_exceptions (in) whether to throw exceptions in case of a parse error (optional, true by default) error_handler (in) how to treat a string value or object key that is not valid UTF-8; see error_handler_t. BJData does not require a decoder to reject ill-formed UTF-8, so checking is opt-in: the default, keep, does not check at all, as every binary reader did before this parameter was added; strict checks and throws; replace/ignore sanitize the string the same way dump would"},{"location":"api/basic_json/from_bjdata/#return-value","title":"Return value","text":"

deserialized JSON value; in case of a parse error and allow_exceptions set to false, the return value will be value_t::discarded. The latter can be checked with is_discarded.

"},{"location":"api/basic_json/from_bjdata/#exception-safety","title":"Exception safety","text":"

Strong guarantee: if an exception is thrown, there are no changes in the JSON value.

"},{"location":"api/basic_json/from_bjdata/#exceptions","title":"Exceptions","text":"
  • Throws parse_error.110 if the given input ends prematurely or the end of the file was not reached when strict was set to true
  • Throws parse_error.112 if a parse error occurs
  • Throws parse_error.113 if a string could not be parsed successfully, or if a string value or object key is not valid UTF-8 and error_handler is strict
  • Throws parse_error.115 if the text of a high-precision number (H) is not a valid number
  • Throws out_of_range.408 if the size of an optimized container cannot be represented by std::size_t or exceeds the container's max_size(), or if the product of the dimensions of an n-dimensional array overflows
"},{"location":"api/basic_json/from_bjdata/#complexity","title":"Complexity","text":"

Linear in the size of the input.

"},{"location":"api/basic_json/from_bjdata/#examples","title":"Examples","text":"Example

The example shows the deserialization of a byte vector in BJData format to a JSON value.

#include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create byte vector\n    std::vector<std::uint8_t> v = {0x7B, 0x69, 0x07, 0x63, 0x6F, 0x6D, 0x70, 0x61,\n                                   0x63, 0x74, 0x54, 0x69, 0x06, 0x73, 0x63, 0x68,\n                                   0x65, 0x6D, 0x61, 0x69, 0x00, 0x7D\n                                  };\n\n    // deserialize it with BJData\n    json j = json::from_bjdata(v);\n\n    // print the deserialized JSON value\n    std::cout << std::setw(2) << j << '\\n';\n}\n

Output:

{\n  \"compact\": true,\n  \"schema\": 0\n}\n
"},{"location":"api/basic_json/from_bjdata/#see-also","title":"See also","text":"
  • BJData - the format, its byte layout and how values are mapped
  • Binary formats - overview and comparison of the supported binary formats
  • Parsing untrusted input - limits and safe handling of hostile data
  • Binary values - how binary values and subtypes are handled
  • to_bjdata - create a BJData serialization of a JSON value
  • from_cbor - create a JSON value from an input in CBOR format
  • from_msgpack - create a JSON value from an input in MessagePack format
  • from_bson - create a JSON value from an input in BSON format
  • from_ubjson - create a JSON value from an input in UBJSON format
  • from_bon8 - create a JSON value from an input in BON8 format
"},{"location":"api/basic_json/from_bjdata/#version-history","title":"Version history","text":"
  • Added in version 3.11.0.
  • Extended container support (1) to include types with lvalue-only ADL begin/end (matching std::begin/std::end semantics) in version 3.13.0 unreleased.
  • Extended overload (2) to accept heterogeneous iterator+sentinel pairs (C++20 ranges support) in version 3.13.0 unreleased.
  • Added error_handler parameter in version 3.13.0 unreleased.

Deprecation

  • Overload (2) replaces calls to from_bjdata with a pointer and a length as first two parameters, which has been deprecated in version 3.13.0 unreleased. In version 4.0.0 unreleased, this overload will be deleted (= delete) rather than removed. Please replace all calls like from_bjdata(ptr, len, ...); with from_bjdata(ptr, ptr+len, ...);.

You should be warned by your compiler with a -Wdeprecated-declarations warning if you are using a deprecated function.

"},{"location":"api/basic_json/from_bon8/","title":"nlohmann::basic_json::from_bon8","text":"
// (1)\ntemplate<typename InputType>\nstatic basic_json from_bon8(InputType&& i,\n                            const bool strict = true,\n                            const bool allow_exceptions = true);\n// (2)\ntemplate<typename IteratorType, typename SentinelType = IteratorType>\nstatic basic_json from_bon8(IteratorType first, SentinelType last,\n                            const bool strict = true,\n                            const bool allow_exceptions = true);\n

Deserializes a given input to a JSON value using the BON8 (Binary Object Notation 8) serialization format.

  1. Reads from a compatible input.
  2. Reads from an iterator range, or an iterator and a sentinel of a different type (C++20 ranges support).

The exact mapping and its limitations are described on a dedicated page.

"},{"location":"api/basic_json/from_bon8/#template-parameters","title":"Template parameters","text":"InputType

A compatible input, for instance:

  • an std::istream object
  • a FILE pointer
  • a C-style array of characters
  • a pointer to a null-terminated string of single byte characters
  • a container obj for which begin(obj) and end(obj) produce a valid pair of iterators (as found via ADL or member functions, with semantics compatible to std::begin and std::end)
IteratorType a compatible iterator type SentinelType

defaults to IteratorType; may be a different type comparable to IteratorType via operator!=, for instance.

  • a custom sentinel type for C++20 ranges
  • std::default_sentinel_t, when IteratorType is std::counted_iterator
"},{"location":"api/basic_json/from_bon8/#parameters","title":"Parameters","text":"i (in) an input in BON8 format convertible to an input adapter first (in) iterator to the start of the input last (in) iterator to the end of the input, or a sentinel value that compares equal to the end iterator with operator!= strict (in) whether to expect the input to be consumed until EOF (true by default) allow_exceptions (in) whether to throw exceptions in case of a parse error (optional, true by default)"},{"location":"api/basic_json/from_bon8/#return-value","title":"Return value","text":"

deserialized JSON value; in case of a parse error and allow_exceptions set to false, the return value will be value_t::discarded. The latter can be checked with is_discarded.

"},{"location":"api/basic_json/from_bon8/#exception-safety","title":"Exception safety","text":"

Strong guarantee: if an exception is thrown, there are no changes in the JSON value.

"},{"location":"api/basic_json/from_bon8/#exceptions","title":"Exceptions","text":"
  • Throws parse_error.110 if the given input ends prematurely or the end of the file was not reached when strict was set to true
  • Throws parse_error.112 if a parse error occurs, for instance an invalid byte, a string that is not valid UTF-8, or an object key that is not a string

The UTF-8 validity of strings is always checked, independent of JSON_STRICT_BINARY_UTF8, because the end of a BON8 string is determined from its encoding. Duplicate object keys are accepted; the last value wins (see BON8).

"},{"location":"api/basic_json/from_bon8/#complexity","title":"Complexity","text":"

Linear in the size of the input.

"},{"location":"api/basic_json/from_bon8/#examples","title":"Examples","text":"Example

The example shows the deserialization of a byte vector in BON8 format to a JSON value.

#include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create byte vector\n    std::vector<std::uint8_t> v = {0x89, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x63, 0x74,\n                                   0xf9, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0xff,\n                                   0x42, 0x4f, 0x4e, 0x38, 0xff, 0x73, 0x63, 0x68,\n                                   0x65, 0x6d, 0x61, 0x90\n                                  };\n\n    // deserialize it with BON8\n    json j = json::from_bon8(v);\n\n    // print the deserialized JSON value\n    std::cout << std::setw(2) << j << '\\n';\n}\n

Output:

{\n  \"compact\": true,\n  \"format\": \"BON8\",\n  \"schema\": 0\n}\n
"},{"location":"api/basic_json/from_bon8/#see-also","title":"See also","text":"
  • BON8 - the format, its byte layout and how values are mapped
  • Binary formats - overview and comparison of the supported binary formats
  • Parsing untrusted input - limits and safe handling of hostile data
  • to_bon8 - create a BON8 serialization of a JSON value
  • from_cbor - create a JSON value from an input in CBOR format
  • from_msgpack - create a JSON value from an input in MessagePack format
  • from_bson - create a JSON value from an input in BSON format
  • from_ubjson - create a JSON value from an input in UBJSON format
  • from_bjdata - create a JSON value from an input in BJData format
"},{"location":"api/basic_json/from_bon8/#version-history","title":"Version history","text":"
  • Added in version 3.13.0 unreleased.

Deprecation

  • Overload (2) replaces calls to from_bon8 with a pointer and a length as first two parameters, which has been deprecated in version 3.13.0 unreleased. In version 4.0.0 unreleased, this overload will be deleted (= delete) rather than removed. Please replace all calls like from_bon8(ptr, len, ...); with from_bon8(ptr, ptr+len, ...);.

You should be warned by your compiler with a -Wdeprecated-declarations warning if you are using a deprecated function.

"},{"location":"api/basic_json/from_bson/","title":"nlohmann::basic_json::from_bson","text":"
// (1)\ntemplate<typename InputType>\nstatic basic_json from_bson(InputType&& i,\n                            const bool strict = true,\n                            const bool allow_exceptions = true,\n                            const error_handler_t error_handler = error_handler_t::keep);\n// (2)\ntemplate<typename IteratorType, typename SentinelType = IteratorType>\nstatic basic_json from_bson(IteratorType first, SentinelType last,\n                            const bool strict = true,\n                            const bool allow_exceptions = true,\n                            const error_handler_t error_handler = error_handler_t::keep);\n

Deserializes a given input to a JSON value using the BSON (Binary JSON) serialization format.

  1. Reads from a compatible input.
  2. Reads from an iterator range, or an iterator and a sentinel of a different type (C++20 ranges support).

The exact mapping and its limitations are described on a dedicated page.

"},{"location":"api/basic_json/from_bson/#template-parameters","title":"Template parameters","text":"InputType

A compatible input, for instance:

  • an std::istream object
  • a FILE pointer
  • a C-style array of characters
  • a pointer to a null-terminated string of single byte characters
  • a container obj for which begin(obj) and end(obj) produce a valid pair of iterators (as found via ADL or member functions, with semantics compatible to std::begin and std::end)
IteratorType a compatible iterator type SentinelType

defaults to IteratorType; may be a different type comparable to IteratorType via operator!=, for instance.

  • a custom sentinel type for C++20 ranges
  • std::default_sentinel_t, when IteratorType is std::counted_iterator
"},{"location":"api/basic_json/from_bson/#parameters","title":"Parameters","text":"i (in) an input in BSON format convertible to an input adapter first (in) iterator to the start of the input last (in) iterator to the end of the input, or a sentinel value that compares equal to the end iterator with operator!= strict (in) whether to expect the input to be consumed until EOF (true by default) allow_exceptions (in) whether to throw exceptions in case of a parse error (optional, true by default) error_handler (in) how to treat a string value or object key that is not valid UTF-8; see error_handler_t. BSON does not require a decoder to reject ill-formed UTF-8, so checking is opt-in: the default, keep, does not check at all, as every binary reader did before this parameter was added; strict checks and throws; replace/ignore sanitize the string the same way dump would"},{"location":"api/basic_json/from_bson/#return-value","title":"Return value","text":"

deserialized JSON value; in case of a parse error and allow_exceptions set to false, the return value will be value_t::discarded. The latter can be checked with is_discarded.

"},{"location":"api/basic_json/from_bson/#exception-safety","title":"Exception safety","text":"

Strong guarantee: if an exception is thrown, there are no changes in the JSON value.

"},{"location":"api/basic_json/from_bson/#exceptions","title":"Exceptions","text":"
  • Throws parse_error.110 if the given input ends prematurely or the end of the input was not reached when strict was set to true
  • Throws parse_error.112 if a parse error occurs (e.g., an invalid string or byte array length, an invalid inner length of a binary value with subtype 0x02, or a document size that does not match the content; strict does not affect the document size checks)
  • Throws parse_error.114 if an unsupported BSON record type is encountered
  • Throws parse_error.113 if a string value or object key is not valid UTF-8 and error_handler is strict
"},{"location":"api/basic_json/from_bson/#complexity","title":"Complexity","text":"

Linear in the size of the input.

"},{"location":"api/basic_json/from_bson/#examples","title":"Examples","text":"Example

The example shows the deserialization of a byte vector in BSON format to a JSON value.

#include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create byte vector\n    std::vector<std::uint8_t> v = {0x1b, 0x00, 0x00, 0x00, 0x08, 0x63, 0x6f, 0x6d,\n                                   0x70, 0x61, 0x63, 0x74, 0x00, 0x01, 0x10, 0x73,\n                                   0x63, 0x68, 0x65, 0x6d, 0x61, 0x00, 0x00, 0x00,\n                                   0x00, 0x00, 0x00\n                                  };\n\n    // deserialize it with BSON\n    json j = json::from_bson(v);\n\n    // print the deserialized JSON value\n    std::cout << std::setw(2) << j << '\\n';\n}\n

Output:

{\n  \"compact\": true,\n  \"schema\": 0\n}\n
"},{"location":"api/basic_json/from_bson/#see-also","title":"See also","text":"
  • BSON - the format, its byte layout and how values are mapped
  • Binary formats - overview and comparison of the supported binary formats
  • Parsing untrusted input - limits and safe handling of hostile data
  • Binary values - how binary values and subtypes are handled
  • BSON specification - specification of the BSON format
  • to_bson - the analogous serialization
  • from_cbor - the related CBOR format
  • from_msgpack - the related MessagePack format
  • from_ubjson - the related UBJSON format
  • from_bjdata - the related BJData format
  • from_bon8 - the related BON8 format
"},{"location":"api/basic_json/from_bson/#version-history","title":"Version history","text":"
  • Added in version 3.4.0.
  • Extended container support (1) to include types with lvalue-only ADL begin/end (matching std::begin/std::end semantics) in version 3.13.0 unreleased.
  • Extended overload (2) to accept heterogeneous iterator+sentinel pairs (C++20 ranges support) in version 3.13.0 unreleased.
  • Added error_handler parameter in version 3.13.0 unreleased.

Deprecation

  • Overload (2) replaces calls to from_bson with a pointer and a length as first two parameters, which has been deprecated in version 3.8.0. In version 4.0.0 unreleased, this overload will be deleted (= delete) rather than removed. Please replace all calls like from_bson(ptr, len, ...); with from_bson(ptr, ptr+len, ...);.
  • Overload (2) replaces calls to from_bson with a pair of iterators as their first parameter, which has been deprecated in version 3.8.0. This overload will be removed in version 4.0.0. Please replace all calls like from_bson({ptr, ptr+len}, ...); with from_bson(ptr, ptr+len, ...);.

You should be warned by your compiler with a -Wdeprecated-declarations warning if you are using a deprecated function.

See the migration guide for how to update existing code.

"},{"location":"api/basic_json/from_cbor/","title":"nlohmann::basic_json::from_cbor","text":"
// (1)\ntemplate<typename InputType>\nstatic basic_json from_cbor(InputType&& i,\n                            const bool strict = true,\n                            const bool allow_exceptions = true,\n                            const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error,\n                            const error_handler_t error_handler = error_handler_t::keep);\n\n// (2)\ntemplate<typename IteratorType, typename SentinelType = IteratorType>\nstatic basic_json from_cbor(IteratorType first, SentinelType last,\n                            const bool strict = true,\n                            const bool allow_exceptions = true,\n                            const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error,\n                            const error_handler_t error_handler = error_handler_t::keep);\n

Deserializes a given input to a JSON value using the CBOR (Concise Binary Object Representation) serialization format.

  1. Reads from a compatible input.
  2. Reads from an iterator range, or an iterator and a sentinel of a different type (C++20 ranges support).

The exact mapping and its limitations are described on a dedicated page.

"},{"location":"api/basic_json/from_cbor/#template-parameters","title":"Template parameters","text":"InputType

A compatible input, for instance:

  • an std::istream object
  • a FILE pointer
  • a C-style array of characters (its terminating NUL is read as trailing data: parse_error.110 unless strict is false)
  • a pointer to a null-terminated string of single byte characters (read up to the first 0x00 byte, which is a valid CBOR byte)
  • a container obj for which begin(obj) and end(obj) produce a valid pair of iterators (as found via ADL or member functions, with semantics compatible to std::begin and std::end)
IteratorType a compatible iterator type SentinelType

defaults to IteratorType; may be a different type comparable to IteratorType via operator!=, for instance.

  • a custom sentinel type for C++20 ranges
  • std::default_sentinel_t, when IteratorType is std::counted_iterator
"},{"location":"api/basic_json/from_cbor/#parameters","title":"Parameters","text":"i (in) an input in CBOR format convertible to an input adapter first (in) iterator to the start of the input last (in) iterator to the end of the input, or a sentinel value that compares equal to the end iterator with operator!= strict (in) whether to expect the input to be consumed until EOF (true by default) allow_exceptions (in) whether to throw exceptions in case of a parse error (optional, true by default) tag_handler (in) how to treat CBOR tags (optional, error by default); see cbor_tag_handler_t for more information error_handler (in) how to treat a string value or object key that is not valid UTF-8; see error_handler_t. CBOR does not require a decoder to reject ill-formed UTF-8, so checking is opt-in: the default, keep, does not check at all, as every binary reader did before this parameter was added; strict checks and throws; replace/ignore sanitize the string the same way dump would"},{"location":"api/basic_json/from_cbor/#return-value","title":"Return value","text":"

deserialized JSON value; in case of a parse error and allow_exceptions set to false, the return value will be value_t::discarded. The latter can be checked with is_discarded.

"},{"location":"api/basic_json/from_cbor/#exception-safety","title":"Exception safety","text":"

Strong guarantee: if an exception is thrown, there are no changes in the JSON value.

"},{"location":"api/basic_json/from_cbor/#exceptions","title":"Exceptions","text":"
  • Throws parse_error.110 if the given input ends prematurely or the end of the file was not reached when strict was set to true
  • Throws parse_error.112 if unsupported features from CBOR were used in the given input or if the input is not valid CBOR
  • Throws parse_error.113 if a map key is not a string (keys of other types are not supported, as JSON object keys are always strings), if the head of a string or byte string is malformed (including a chunk of the wrong type or an indefinite-length string nested inside an indefinite-length string), or if a string value or object key (or one chunk of an indefinite-length string) is not valid UTF-8 and error_handler is strict
  • Throws out_of_range.408 if an array or map announces a length that std::size_t cannot hold, or that equals std::size_t(-1) (for example 9B FF FF FF FF FF FF FF FF)
  • Throws out_of_range.406 if a floating-point number does not fit into number_float_t
"},{"location":"api/basic_json/from_cbor/#complexity","title":"Complexity","text":"

Linear in the size of the input.

"},{"location":"api/basic_json/from_cbor/#examples","title":"Examples","text":"Example

The example shows the deserialization of a byte vector in CBOR format to a JSON value.

#include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create byte vector\n    std::vector<std::uint8_t> v = {0xa2, 0x67, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x63,\n                                   0x74, 0xf5, 0x66, 0x73, 0x63, 0x68, 0x65, 0x6d,\n                                   0x61, 0x00\n                                  };\n\n    // deserialize it with CBOR\n    json j = json::from_cbor(v);\n\n    // print the deserialized JSON value\n    std::cout << std::setw(2) << j << '\\n';\n}\n

Output:

{\n  \"compact\": true,\n  \"schema\": 0\n}\n
"},{"location":"api/basic_json/from_cbor/#see-also","title":"See also","text":"
  • CBOR - the format, its byte layout and how values are mapped
  • Binary formats - overview and comparison of the supported binary formats
  • Parsing untrusted input - limits and safe handling of hostile data
  • Binary values - how binary values and subtypes are handled
  • to_cbor - create a CBOR serialization of a JSON value
  • from_msgpack - create a JSON value from an input in MessagePack format
  • from_bson - create a JSON value from an input in BSON format
  • from_ubjson - create a JSON value from an input in UBJSON format
  • from_bjdata - create a JSON value from an input in BJData format
  • from_bon8 - create a JSON value from an input in BON8 format
"},{"location":"api/basic_json/from_cbor/#version-history","title":"Version history","text":"
  • Added in version 2.0.9.
  • Parameter start_index since version 2.1.1.
  • Changed to consume input adapters, removed start_index parameter, and added strict parameter in version 3.0.0.
  • Added allow_exceptions parameter in version 3.2.0.
  • Added tag_handler parameter in version 3.9.0.
  • Extended container support (1) to include types with lvalue-only ADL begin/end (matching std::begin/std::end semantics) in version 3.13.0 unreleased.
  • Extended overload (2) to accept heterogeneous iterator+sentinel pairs (C++20 ranges support) in version 3.13.0 unreleased.
  • Added error_handler parameter in version 3.13.0 unreleased.

Deprecation

  • Overload (2) replaces calls to from_cbor with a pointer and a length as first two parameters, which has been deprecated in version 3.8.0. In version 4.0.0 unreleased, this overload will be deleted (= delete) rather than removed. Please replace all calls like from_cbor(ptr, len, ...); with from_cbor(ptr, ptr+len, ...);.
  • Overload (2) replaces calls to from_cbor with a pair of iterators as their first parameter, which has been deprecated in version 3.8.0. This overload will be removed in version 4.0.0. Please replace all calls like from_cbor({ptr, ptr+len}, ...); with from_cbor(ptr, ptr+len, ...);.

You should be warned by your compiler with a -Wdeprecated-declarations warning if you are using a deprecated function.

See the migration guide for how to update existing code.

"},{"location":"api/basic_json/from_msgpack/","title":"nlohmann::basic_json::from_msgpack","text":"
// (1)\ntemplate<typename InputType>\nstatic basic_json from_msgpack(InputType&& i,\n                               const bool strict = true,\n                               const bool allow_exceptions = true,\n                               const error_handler_t error_handler = error_handler_t::keep);\n// (2)\ntemplate<typename IteratorType, typename SentinelType = IteratorType>\nstatic basic_json from_msgpack(IteratorType first, SentinelType last,\n                               const bool strict = true,\n                               const bool allow_exceptions = true,\n                               const error_handler_t error_handler = error_handler_t::keep);\n

Deserializes a given input to a JSON value using the MessagePack serialization format.

  1. Reads from a compatible input.
  2. Reads from an iterator range, or an iterator and a sentinel of a different type (C++20 ranges support).

The exact mapping and its limitations are described on a dedicated page.

"},{"location":"api/basic_json/from_msgpack/#template-parameters","title":"Template parameters","text":"InputType

A compatible input, for instance:

  • an std::istream object
  • a FILE pointer
  • a C-style array of characters
  • a pointer to a null-terminated string of single byte characters
  • a container obj for which begin(obj) and end(obj) produce a valid pair of iterators (as found via ADL or member functions, with semantics compatible to std::begin and std::end)
IteratorType a compatible iterator type SentinelType

defaults to IteratorType; may be a different type comparable to IteratorType via operator!=, for instance.

  • a custom sentinel type for C++20 ranges
  • std::default_sentinel_t, when IteratorType is std::counted_iterator
"},{"location":"api/basic_json/from_msgpack/#parameters","title":"Parameters","text":"i (in) an input in MessagePack format convertible to an input adapter first (in) iterator to the start of the input last (in) iterator to the end of the input, or a sentinel value that compares equal to the end iterator with operator!= strict (in) whether to expect the input to be consumed until EOF (true by default) allow_exceptions (in) whether to throw exceptions in case of a parse error (optional, true by default) error_handler (in) how to treat a string value or object key that is not valid UTF-8; see error_handler_t. MessagePack's specification explicitly allows ill-formed UTF-8, so checking is opt-in: the default, keep, does not check at all, as every binary reader did before this parameter was added; strict checks and throws; replace/ignore sanitize the string the same way dump would"},{"location":"api/basic_json/from_msgpack/#return-value","title":"Return value","text":"

deserialized JSON value; in case of a parse error and allow_exceptions set to false, the return value will be value_t::discarded. The latter can be checked with is_discarded.

"},{"location":"api/basic_json/from_msgpack/#exception-safety","title":"Exception safety","text":"

Strong guarantee: if an exception is thrown, there are no changes in the JSON value.

"},{"location":"api/basic_json/from_msgpack/#exceptions","title":"Exceptions","text":"
  • Throws parse_error.110 if the given input ends prematurely or the end of the file was not reached when strict was set to true
  • Throws parse_error.112 if unsupported features from MessagePack were used in the given input or if the input is not valid MessagePack
  • Throws parse_error.113 if a map key is not a string (keys of other types are not supported, as JSON object keys are always strings), or if a string value or object key is not valid UTF-8 and error_handler is strict
"},{"location":"api/basic_json/from_msgpack/#complexity","title":"Complexity","text":"

Linear in the size of the input.

"},{"location":"api/basic_json/from_msgpack/#examples","title":"Examples","text":"Example

The example shows the deserialization of a byte vector in MessagePack format to a JSON value.

#include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create byte vector\n    std::vector<std::uint8_t> v = {0x82, 0xa7, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x63,\n                                   0x74, 0xc3, 0xa6, 0x73, 0x63, 0x68, 0x65, 0x6d,\n                                   0x61, 0x00\n                                  };\n\n    // deserialize it with MessagePack\n    json j = json::from_msgpack(v);\n\n    // print the deserialized JSON value\n    std::cout << std::setw(2) << j << '\\n';\n}\n

Output:

{\n  \"compact\": true,\n  \"schema\": 0\n}\n
"},{"location":"api/basic_json/from_msgpack/#see-also","title":"See also","text":"
  • MessagePack - the format, its byte layout and how values are mapped
  • Binary formats - overview and comparison of the supported binary formats
  • Parsing untrusted input - limits and safe handling of hostile data
  • Binary values - how binary values and subtypes are handled
  • to_msgpack - create a MessagePack serialization of a JSON value
  • from_cbor - create a JSON value from an input in CBOR format
  • from_bson - create a JSON value from an input in BSON format
  • from_ubjson - create a JSON value from an input in UBJSON format
  • from_bjdata - create a JSON value from an input in BJData format
  • from_bon8 - create a JSON value from an input in BON8 format
"},{"location":"api/basic_json/from_msgpack/#version-history","title":"Version history","text":"
  • Added in version 2.0.9.
  • Parameter start_index since version 2.1.1.
  • Changed to consume input adapters, removed start_index parameter, and added strict parameter in version 3.0.0.
  • Added allow_exceptions parameter in version 3.2.0.
  • Extended container support (1) to include types with lvalue-only ADL begin/end (matching std::begin/std::end semantics) in version 3.13.0 unreleased.
  • Extended overload (2) to accept heterogeneous iterator+sentinel pairs (C++20 ranges support) in version 3.13.0 unreleased.
  • Added error_handler parameter in version 3.13.0 unreleased.

Deprecation

  • Overload (2) replaces calls to from_msgpack with a pointer and a length as first two parameters, which has been deprecated in version 3.8.0. In version 4.0.0 unreleased, this overload will be deleted (= delete) rather than removed. Please replace all calls like from_msgpack(ptr, len, ...); with from_msgpack(ptr, ptr+len, ...);.
  • Overload (2) replaces calls to from_msgpack with a pair of iterators as their first parameter, which has been deprecated in version 3.8.0. This overload will be removed in version 4.0.0. Please replace all calls like from_msgpack({ptr, ptr+len}, ...); with from_msgpack(ptr, ptr+len, ...);.

You should be warned by your compiler with a -Wdeprecated-declarations warning if you are using a deprecated function.

See the migration guide for how to update existing code.

"},{"location":"api/basic_json/from_ubjson/","title":"nlohmann::basic_json::from_ubjson","text":"
// (1)\ntemplate<typename InputType>\nstatic basic_json from_ubjson(InputType&& i,\n                              const bool strict = true,\n                              const bool allow_exceptions = true,\n                              const error_handler_t error_handler = error_handler_t::keep);\n// (2)\ntemplate<typename IteratorType, typename SentinelType = IteratorType>\nstatic basic_json from_ubjson(IteratorType first, SentinelType last,\n                              const bool strict = true,\n                              const bool allow_exceptions = true,\n                              const error_handler_t error_handler = error_handler_t::keep);\n

Deserializes a given input to a JSON value using the UBJSON (Universal Binary JSON) serialization format.

  1. Reads from a compatible input.
  2. Reads from an iterator range, or an iterator and a sentinel of a different type (C++20 ranges support).

The exact mapping and its limitations are described on a dedicated page.

"},{"location":"api/basic_json/from_ubjson/#template-parameters","title":"Template parameters","text":"InputType

A compatible input, for instance:

  • an std::istream object
  • a FILE pointer
  • a C-style array of characters
  • a pointer to a null-terminated string of single byte characters
  • a container obj for which begin(obj) and end(obj) produce a valid pair of iterators (as found via ADL or member functions, with semantics compatible to std::begin and std::end)
IteratorType a compatible iterator type SentinelType

defaults to IteratorType; may be a different type comparable to IteratorType via operator!=, for instance.

  • a custom sentinel type for C++20 ranges
  • std::default_sentinel_t, when IteratorType is std::counted_iterator
"},{"location":"api/basic_json/from_ubjson/#parameters","title":"Parameters","text":"i (in) an input in UBJSON format convertible to an input adapter first (in) iterator to the start of the input last (in) iterator to the end of the input, or a sentinel value that compares equal to the end iterator with operator!= strict (in) whether to expect the input to be consumed until EOF (true by default) allow_exceptions (in) whether to throw exceptions in case of a parse error (optional, true by default) error_handler (in) how to treat a string value or object key that is not valid UTF-8; see error_handler_t. UBJSON does not require a decoder to reject ill-formed UTF-8, so checking is opt-in: the default, keep, does not check at all, as every binary reader did before this parameter was added; strict checks and throws; replace/ignore sanitize the string the same way dump would"},{"location":"api/basic_json/from_ubjson/#return-value","title":"Return value","text":"

deserialized JSON value; in case of a parse error and allow_exceptions set to false, the return value will be value_t::discarded. The latter can be checked with is_discarded.

"},{"location":"api/basic_json/from_ubjson/#exception-safety","title":"Exception safety","text":"

Strong guarantee: if an exception is thrown, there are no changes in the JSON value.

"},{"location":"api/basic_json/from_ubjson/#exceptions","title":"Exceptions","text":"
  • Throws parse_error.110 if the given input ends prematurely or the end of the file was not reached when strict was set to true
  • Throws parse_error.112 if an invalid type marker is read (including a type marker after $ of an optimized container, even if its count is 0), or if $ is not followed by #
  • Throws parse_error.113 if a string could not be parsed successfully (negative or non-integer length, C followed by a byte above 0x7F), if the count of an optimized container is negative, or if a string value or object key is not valid UTF-8 and error_handler is strict
  • Throws parse_error.115 if the text of a high-precision number (H) is not a valid JSON number
  • Throws out_of_range.406 if a high-precision number, or a float64 when number_float_t is float, does not fit into number_float_t
  • Throws out_of_range.408 if the count of an optimized container exceeds the capacity of the container (or of std::size_t), or if an optimized array of Z, T, or F has more than 1,048,576 elements
"},{"location":"api/basic_json/from_ubjson/#complexity","title":"Complexity","text":"

Linear in the size of the input.

"},{"location":"api/basic_json/from_ubjson/#examples","title":"Examples","text":"Example

The example shows the deserialization of a byte vector in UBJSON format to a JSON value.

#include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create byte vector\n    std::vector<std::uint8_t> v = {0x7B, 0x69, 0x07, 0x63, 0x6F, 0x6D, 0x70, 0x61,\n                                   0x63, 0x74, 0x54, 0x69, 0x06, 0x73, 0x63, 0x68,\n                                   0x65, 0x6D, 0x61, 0x69, 0x00, 0x7D\n                                  };\n\n    // deserialize it with UBJSON\n    json j = json::from_ubjson(v);\n\n    // print the deserialized JSON value\n    std::cout << std::setw(2) << j << '\\n';\n}\n

Output:

{\n  \"compact\": true,\n  \"schema\": 0\n}\n
"},{"location":"api/basic_json/from_ubjson/#see-also","title":"See also","text":"
  • UBJSON - the format, its byte layout and how values are mapped
  • Binary formats - overview and comparison of the supported binary formats
  • Parsing untrusted input - limits and safe handling of hostile data
  • Binary values - how binary values and subtypes are handled
  • to_ubjson - create a UBJSON serialization of a JSON value
  • from_cbor - create a JSON value from an input in CBOR format
  • from_msgpack - create a JSON value from an input in MessagePack format
  • from_bson - create a JSON value from an input in BSON format
  • from_bjdata - create a JSON value from an input in BJData format
  • from_bon8 - create a JSON value from an input in BON8 format
"},{"location":"api/basic_json/from_ubjson/#version-history","title":"Version history","text":"
  • Added in version 3.1.0.
  • Added allow_exceptions parameter in version 3.2.0.
  • Extended container support (1) to include types with lvalue-only ADL begin/end (matching std::begin/std::end semantics) in version 3.13.0 unreleased.
  • Extended overload (2) to accept heterogeneous iterator+sentinel pairs (C++20 ranges support) in version 3.13.0 unreleased.
  • Added error_handler parameter in version 3.13.0 unreleased.

Deprecation

  • Overload (2) replaces calls to from_ubjson with a pointer and a length as first two parameters, which has been deprecated in version 3.8.0. In version 4.0.0 unreleased, this overload will be deleted (= delete) rather than removed. Please replace all calls like from_ubjson(ptr, len, ...); with from_ubjson(ptr, ptr+len, ...);.
  • Overload (2) replaces calls to from_ubjson with a pair of iterators as their first parameter, which has been deprecated in version 3.8.0. This overload will be removed in version 4.0.0. Please replace all calls like from_ubjson({ptr, ptr+len}, ...); with from_ubjson(ptr, ptr+len, ...);.

You should be warned by your compiler with a -Wdeprecated-declarations warning if you are using a deprecated function.

See the migration guide for how to update existing code.

"},{"location":"api/basic_json/front/","title":"nlohmann::basic_json::front","text":"
reference front();\nconst_reference front() const;\n

Returns a reference to the first element in the container. For a JSON container c, the expression c.front() is equivalent to *c.begin().

"},{"location":"api/basic_json/front/#return-value","title":"Return value","text":"

In the case of a structured type (array or object), a reference to the first element is returned. In the case of number, string, boolean, or binary values, a reference to the value is returned.

"},{"location":"api/basic_json/front/#exception-safety","title":"Exception safety","text":"

Strong guarantee: if an exception is thrown, there are no changes in the JSON value.

"},{"location":"api/basic_json/front/#exceptions","title":"Exceptions","text":"

If the JSON value is null, exception invalid_iterator.214 is thrown.

"},{"location":"api/basic_json/front/#complexity","title":"Complexity","text":"

Constant.

"},{"location":"api/basic_json/front/#notes","title":"Notes","text":"

Precondition

The array or object must not be empty. Calling front on an empty array or object yields undefined behavior.

"},{"location":"api/basic_json/front/#examples","title":"Examples","text":"Example

The following code shows an example for front().

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create JSON values\n    json j_null;\n    json j_boolean = true;\n    json j_number_integer = 17;\n    json j_number_float = 23.42;\n    json j_object = {{\"one\", 1}, {\"two\", 2}};\n    json j_object_empty(json::value_t::object);\n    json j_array = {1, 2, 4, 8, 16};\n    json j_array_empty(json::value_t::array);\n    json j_string = \"Hello, world\";\n\n    // call front()\n    //std::cout << j_null.front() << '\\n';          // would throw\n    std::cout << j_boolean.front() << '\\n';\n    std::cout << j_number_integer.front() << '\\n';\n    std::cout << j_number_float.front() << '\\n';\n    std::cout << j_object.front() << '\\n';\n    //std::cout << j_object_empty.front() << '\\n';  // undefined behavior\n    std::cout << j_array.front() << '\\n';\n    //std::cout << j_array_empty.front() << '\\n';   // undefined behavior\n    std::cout << j_string.front() << '\\n';\n}\n

Output:

true\n17\n23.42\n1\n1\n\"Hello, world\"\n
"},{"location":"api/basic_json/front/#see-also","title":"See also","text":"
  • back - to access the last element
  • basic_json_view::front - the same access on a zero-copy view (document order, not sorted; duplicate keys are visited)
  • Element Access - overview of all ways to access elements
"},{"location":"api/basic_json/front/#version-history","title":"Version history","text":"
  • Added in version 1.0.0.
  • Binary values are supported since version 3.8.0.
"},{"location":"api/basic_json/get/","title":"nlohmann::basic_json::get","text":"
// (1)\ntemplate<typename ValueType>\nValueType get() const noexcept(\n    noexcept(JSONSerializer<ValueType>::from_json(\n        std::declval<const basic_json_t&>(), std::declval<ValueType&>())));\n\n// (2)\ntemplate<typename BasicJsonType>\nBasicJsonType get() const;\n\n// (3)\ntemplate<typename PointerType>\nPointerType get() noexcept;\n\ntemplate<typename PointerType>\nconst PointerType get() const noexcept;  // constexpr since C++14\n
  1. Explicit type conversion between the JSON value and a compatible value which is CopyConstructible and DefaultConstructible. The value is converted by calling the json_serializer<ValueType> from_json() method.

    The function is equivalent to executing

    ValueType ret;\nJSONSerializer<ValueType>::from_json(*this, ret);\nreturn ret;\n

    This overload is chosen if:

    • ValueType is not basic_json,
    • json_serializer<ValueType> has a from_json() method of the form void from_json(const basic_json&, ValueType&), and
    • json_serializer<ValueType> does not have a from_json() method of the form ValueType from_json(const basic_json&)

    If the type is not CopyConstructible and not DefaultConstructible, the value is converted by calling the json_serializer<ValueType> from_json() method.

    The function is then equivalent to executing

    return JSONSerializer<ValueTypeCV>::from_json(*this);\n

    This overload is chosen if:

    • ValueType is not basic_json and
    • json_serializer<ValueType> has a from_json() method of the form ValueType from_json(const basic_json&)

    If json_serializer<ValueType> has both overloads of from_json(), the latter one is chosen.

  2. Overload for basic_json specializations. The function is equivalent to executing

    return *this;\n

  3. Explicit pointer access to the internally stored JSON value. No copies are made.

"},{"location":"api/basic_json/get/#template-parameters","title":"Template parameters","text":"ValueType the value type to return BasicJsonType a specialization of basic_json PointerType pointer type; must be a pointer to array_t, object_t, string_t, boolean_t, number_integer_t, or number_unsigned_t, number_float_t, or binary_t. Other types will not compile."},{"location":"api/basic_json/get/#return-value","title":"Return value","text":"
  1. copy of the JSON value, converted to ValueType
  2. a copy of *this, converted into BasicJsonType
  3. pointer to the internally stored JSON value if the requested pointer type fits to the JSON value; nullptr otherwise
"},{"location":"api/basic_json/get/#exception-safety","title":"Exception safety","text":"

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 const member function. No-throw guarantee for overload (3): this function never throws exceptions.

"},{"location":"api/basic_json/get/#exceptions","title":"Exceptions","text":"

Depends on what json_serializer<ValueType> from_json() method throws

"},{"location":"api/basic_json/get/#complexity","title":"Complexity","text":"

Depends on the json_serializer<ValueType>::from_json() implementation for overloads (1) and (2); constant for overload (3).

"},{"location":"api/basic_json/get/#notes","title":"Notes","text":"

Undefined behavior for pointers

Writing data to the pointee (overload 3) of the result yields an undefined state.

Undefined behavior for numeric conversions

Conversions between numeric types are performed by the corresponding from_json() implementation using the target C++ type. When converting between numeric types, the library does not check whether the source value is representable by the target type.

If the source value is outside the range of the target type, the behavior is the same as the corresponding C++ conversion. In particular, converting a floating-point value to an integer type that cannot represent the value results in undefined behavior.

See Number conversion for more information.

std::optional conversions

Prior to version 3.13.0 unreleased, get<std::optional<T>>() (and other conversions to std::optional<T>) failed to compile in every configuration, due to an internal implementation bug that made the from_json overload for std::optional unreachable regardless of the JSON_USE_IMPLICIT_CONVERSIONS setting. This has been fixed.

"},{"location":"api/basic_json/get/#examples","title":"Examples","text":"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::map<std::string, json>.

#include <iostream>\n#include <map>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create a JSON value with different types\n    json json_types =\n    {\n        {\"boolean\", true},\n        {\n            \"number\", {\n                {\"integer\", 42},\n                {\"floating-point\", 17.23}\n            }\n        },\n        {\"string\", \"Hello, world!\"},\n        {\"array\", {1, 2, 3, 4, 5}},\n        {\"null\", nullptr}\n    };\n\n    // use explicit conversions\n    auto v1 = json_types[\"boolean\"].get<bool>();\n    auto v2 = json_types[\"number\"][\"integer\"].get<int>();\n    auto v3 = json_types[\"number\"][\"integer\"].get<short>();\n    auto v4 = json_types[\"number\"][\"floating-point\"].get<float>();\n    auto v5 = json_types[\"number\"][\"floating-point\"].get<int>();\n    auto v6 = json_types[\"string\"].get<std::string>();\n    auto v7 = json_types[\"array\"].get<std::vector<short>>();\n    auto v8 = json_types.get<std::map<std::string, json>>();\n\n    // print the conversion results\n    std::cout << v1 << '\\n';\n    std::cout << v2 << ' ' << v3 << '\\n';\n    std::cout << v4 << ' ' << v5 << '\\n';\n    std::cout << v6 << '\\n';\n\n    for (auto i : v7)\n    {\n        std::cout << i << ' ';\n    }\n    std::cout << \"\\n\\n\";\n\n    for (const auto& i : v8)\n    {\n        std::cout << i.first << \": \" << i.second << '\\n';\n    }\n}\n

Output:

1\n42 42\n17.23 17\nHello, world!\n1 2 3 4 5 \n\narray: [1,2,3,4,5]\nboolean: true\nnull: null\nnumber: {\"floating-point\":17.23,\"integer\":42}\nstring: \"Hello, world!\"\n
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>().

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\nusing nlohmann::ordered_json;\n\nint main()\n{\n    // create a JSON value\n    json j = {{\"one\", 1}, {\"two\", 2}, {\"three\", 3}};\n\n    // convert to a different basic_json specialization\n    ordered_json oj = j.get<ordered_json>();\n\n    std::cout << j << '\\n';\n    std::cout << oj << '\\n';\n}\n

Output:

{\"one\":1,\"three\":3,\"two\":2}\n{\"one\":1,\"three\":3,\"two\":2}\n
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.

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create a JSON number\n    json value = 17;\n\n    // explicitly getting pointers\n    const auto* p1 = value.get<const json::number_integer_t*>();\n    auto* p2 = value.get<json::number_integer_t*>();\n    auto* p3 = value.get<json::number_integer_t* const>();\n    const auto* p4 = value.get<const json::number_integer_t* const>();\n    auto* p5 = value.get<json::number_float_t*>();\n\n    // print the pointees\n    std::cout << *p1 << ' ' << *p2 << ' ' << *p3 << ' ' << *p4 << '\\n';\n    std::cout << std::boolalpha << (p5 == nullptr) << '\\n';\n}\n

Output:

17 17 17 17\ntrue\n
"},{"location":"api/basic_json/get/#see-also","title":"See also","text":"
  • get_to - convert and write into a passed value
  • get_ptr - get a pointer to the stored value
  • get_ref - get a reference to the stored value
  • operator ValueType - get a value via implicit conversion
  • Converting values - the type conversions article
  • basic_json_view::get - the same conversion on a zero-copy view (many types are converted without ever building a basic_json value)
  • Arbitrary Type Conversions - make your own types usable with get
"},{"location":"api/basic_json/get/#version-history","title":"Version history","text":"
  1. Added in version 2.1.0.
  2. Added in version 2.1.0. Extended to work with other specializations of basic_json in version 3.1.2.
  3. Added in version 1.0.0.
"},{"location":"api/basic_json/get_allocator/","title":"nlohmann::basic_json::get_allocator","text":"
static allocator_type get_allocator();\n

Returns the allocator associated with the container.

"},{"location":"api/basic_json/get_allocator/#return-value","title":"Return value","text":"

associated allocator

"},{"location":"api/basic_json/get_allocator/#exception-safety","title":"Exception safety","text":"

Strong guarantee: if an exception is thrown, there are no changes to any JSON value.

"},{"location":"api/basic_json/get_allocator/#complexity","title":"Complexity","text":"

Constant.

"},{"location":"api/basic_json/get_allocator/#examples","title":"Examples","text":"Example

The example shows how get_allocator() is used to created json values.

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    auto alloc = json::get_allocator();\n    using traits_t = std::allocator_traits<decltype(alloc)>;\n\n    json* j = traits_t::allocate(alloc, 1);\n    traits_t::construct(alloc, j, \"Hello, world!\");\n\n    std::cout << *j << '\\n';\n\n    traits_t::destroy(alloc, j);\n    traits_t::deallocate(alloc, j, 1);\n}\n

Output:

\"Hello, world!\"\n
"},{"location":"api/basic_json/get_allocator/#see-also","title":"See also","text":"
  • basic_json - the class template, with AllocatorType as one of its template parameters
  • Template Parameter Requirements - the requirements for AllocatorType
"},{"location":"api/basic_json/get_allocator/#version-history","title":"Version history","text":"
  • Added in version 1.0.0.
"},{"location":"api/basic_json/get_binary/","title":"nlohmann::basic_json::get_binary","text":"
binary_t& get_binary();\n\nconst binary_t& get_binary() const;\n

Returns a reference to the stored binary value.

"},{"location":"api/basic_json/get_binary/#return-value","title":"Return value","text":"

Reference to binary value.

"},{"location":"api/basic_json/get_binary/#exception-safety","title":"Exception safety","text":"

Strong exception safety: if an exception occurs, the original value stays intact.

"},{"location":"api/basic_json/get_binary/#exceptions","title":"Exceptions","text":"

Throws type_error.302 if the value is not binary

"},{"location":"api/basic_json/get_binary/#complexity","title":"Complexity","text":"

Constant.

"},{"location":"api/basic_json/get_binary/#examples","title":"Examples","text":"Example

The following code shows how to query a binary value.

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create a binary vector\n    std::vector<std::uint8_t> vec = {0xCA, 0xFE, 0xBA, 0xBE};\n\n    // create a binary JSON value with subtype 42\n    json j = json::binary(vec, 42);\n\n    // output type and subtype\n    std::cout << \"type: \" << j.type_name() << \", subtype: \" << j.get_binary().subtype() << '\\n';\n}\n

Output:

type: binary, subtype: 42\n
"},{"location":"api/basic_json/get_binary/#see-also","title":"See also","text":"
  • Binary values - how binary values and subtypes are handled
  • binary - create a binary value
  • is_binary - check whether a value is binary
  • get - get a value (explicit conversion)
  • get_ref - get a reference to the stored value
"},{"location":"api/basic_json/get_binary/#version-history","title":"Version history","text":"
  • Added in version 3.8.0.
"},{"location":"api/basic_json/get_ptr/","title":"nlohmann::basic_json::get_ptr","text":"
template<typename PointerType>\nPointerType get_ptr() noexcept;\n\ntemplate<typename PointerType>\nconstexpr const PointerType get_ptr() const noexcept;\n

Implicit pointer access to the internally stored JSON value. No copies are made.

"},{"location":"api/basic_json/get_ptr/#template-parameters","title":"Template parameters","text":"PointerType pointer type; must be a pointer to array_t, object_t, string_t, boolean_t, number_integer_t, or number_unsigned_t, number_float_t, or binary_t. Other types will not compile."},{"location":"api/basic_json/get_ptr/#return-value","title":"Return value","text":"

pointer to the internally stored JSON value if the requested pointer type fits to the JSON value; nullptr otherwise

"},{"location":"api/basic_json/get_ptr/#exception-safety","title":"Exception safety","text":"

No-throw guarantee: this function never throws exceptions.

"},{"location":"api/basic_json/get_ptr/#complexity","title":"Complexity","text":"

Constant.

"},{"location":"api/basic_json/get_ptr/#notes","title":"Notes","text":"

Undefined behavior

The pointer becomes invalid if the underlying JSON object changes.

Consider the following example code where the pointer ptr changes after the array is resized. As a result, reading or writing to ptr after the array change would be undefined behavior. The address of the first array element changes, because the underlying std::vector is resized after adding a fifth element.

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    json j = {1, 2, 3, 4};\n    auto* ptr = j[0].get_ptr<std::int64_t*>();\n    std::cout << \"value at \" << ptr << \" is \" << *ptr << std::endl;\n\n    j.push_back(5);\n\n    ptr = j[0].get_ptr<std::int64_t*>();\n    std::cout << \"value at \" << ptr << \" is \" << *ptr << std::endl;\n}\n

Output:

value at 0x6000012fc1c8 is 1\nvalue at 0x6000029fc088 is 1\n
"},{"location":"api/basic_json/get_ptr/#examples","title":"Examples","text":"Example

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 nullptr is returned if the value and the requested pointer type does not match.

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create a JSON number\n    json value = 17;\n\n    // explicitly getting pointers\n    const auto* p1 = value.get_ptr<const json::number_integer_t*>();\n    auto* p2 = value.get_ptr<json::number_integer_t*>();\n    auto* p3 = value.get_ptr<json::number_integer_t* const>();\n    const auto* p4 = value.get_ptr<const json::number_integer_t* const>();\n    auto* p5 = value.get_ptr<json::number_float_t*>();\n\n    // print the pointees\n    std::cout << *p1 << ' ' << *p2 << ' ' << *p3 << ' ' << *p4 << '\\n';\n    std::cout << std::boolalpha << (p5 == nullptr) << '\\n';\n}\n

Output:

17 17 17 17\ntrue\n
"},{"location":"api/basic_json/get_ptr/#see-also","title":"See also","text":"
  • get_ref() - get a reference value
  • Converting values - getting values out, with or without copying
"},{"location":"api/basic_json/get_ptr/#version-history","title":"Version history","text":"
  • Added in version 1.0.0.
  • Extended to binary types in version 3.8.0.
"},{"location":"api/basic_json/get_ref/","title":"nlohmann::basic_json::get_ref","text":"
template<typename ReferenceType>\nReferenceType get_ref();\n\ntemplate<typename ReferenceType>\nconst ReferenceType get_ref() const;\n

Implicit reference access to the internally stored JSON value. No copies are made.

"},{"location":"api/basic_json/get_ref/#template-parameters","title":"Template parameters","text":"ReferenceType reference type; must be a reference to array_t, object_t, string_t, boolean_t, number_integer_t, or number_unsigned_t, number_float_t, or binary_t. Enforced by a static assertion."},{"location":"api/basic_json/get_ref/#return-value","title":"Return value","text":"

reference to the internally stored JSON value if the requested reference type fits to the JSON value; throws type_error.303 otherwise

"},{"location":"api/basic_json/get_ref/#exception-safety","title":"Exception safety","text":"

Strong exception safety: if an exception occurs, the original value stays intact.

"},{"location":"api/basic_json/get_ref/#exceptions","title":"Exceptions","text":"

Throws type_error.303 if the requested reference type does not match the stored JSON value type; example: \"incompatible ReferenceType for get_ref, actual type is binary\".

"},{"location":"api/basic_json/get_ref/#complexity","title":"Complexity","text":"

Constant.

"},{"location":"api/basic_json/get_ref/#notes","title":"Notes","text":"

Undefined behavior

The reference becomes invalid if the underlying JSON object changes.

"},{"location":"api/basic_json/get_ref/#examples","title":"Examples","text":"Example

The example shows several calls to get_ref().

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create a JSON number\n    json value = 17;\n\n    // explicitly getting references\n    auto r1 = value.get_ref<const json::number_integer_t&>();\n    auto r2 = value.get_ref<json::number_integer_t&>();\n\n    // print the values\n    std::cout << r1 << ' ' << r2 << '\\n';\n\n    // incompatible type throws exception\n    try\n    {\n        auto r3 = value.get_ref<json::number_float_t&>();\n    }\n    catch (const json::type_error& ex)\n    {\n        std::cout << ex.what() << '\\n';\n    }\n}\n

Output:

17 17\n[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is number\n
"},{"location":"api/basic_json/get_ref/#see-also","title":"See also","text":"
  • get_ptr() - get a pointer value
  • basic_json_view::get_string - the closest counterpart on a zero-copy view: a string without a copy, but as a view rather than a reference to a value that must already exist
  • Converting values - getting values out, with or without copying
"},{"location":"api/basic_json/get_ref/#version-history","title":"Version history","text":"
  • Added in version 1.1.0.
  • Extended to binary types in version 3.8.0.
"},{"location":"api/basic_json/get_to/","title":"nlohmann::basic_json::get_to","text":"
template<typename ValueType>\nValueType& get_to(ValueType& v) const noexcept(\n    noexcept(JSONSerializer<ValueType>::from_json(\n        std::declval<const basic_json_t&>(), v)));\n

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.

The function is equivalent to executing

ValueType v;\nJSONSerializer<ValueType>::from_json(*this, v);\n

This overload is chosen if:

  • ValueType is not basic_json,
  • json_serializer<ValueType> has a from_json() method of the form void from_json(const basic_json&, ValueType&)

v must not be const. Passing a const object is a compile-time error. For types such as arithmetic types, enums, and C arrays, the error is a static_assert that names the problem. For other types, the overload is not viable, and the compiler reports that no matching get_to was found.

"},{"location":"api/basic_json/get_to/#template-parameters","title":"Template parameters","text":"ValueType the value type to return"},{"location":"api/basic_json/get_to/#return-value","title":"Return value","text":"

the input parameter, allowing chaining calls

"},{"location":"api/basic_json/get_to/#exception-safety","title":"Exception safety","text":"

Depends on what json_serializer<ValueType> from_json() method throws; the JSON value itself is never modified, since get_to() is a const member function.

"},{"location":"api/basic_json/get_to/#exceptions","title":"Exceptions","text":"

Depends on what json_serializer<ValueType> from_json() method throws

"},{"location":"api/basic_json/get_to/#complexity","title":"Complexity","text":"

Depends on the json_serializer<ValueType>::from_json() implementation.

"},{"location":"api/basic_json/get_to/#examples","title":"Examples","text":"Example

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::map<std::string, json>.

#include <iostream>\n#include <map>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create a JSON value with different types\n    json json_types =\n    {\n        {\"boolean\", true},\n        {\n            \"number\", {\n                {\"integer\", 42},\n                {\"floating-point\", 17.23}\n            }\n        },\n        {\"string\", \"Hello, world!\"},\n        {\"array\", {1, 2, 3, 4, 5}},\n        {\"null\", nullptr}\n    };\n\n    bool v1;\n    int v2;\n    short v3;\n    float v4;\n    int v5;\n    std::string v6;\n    std::vector<short> v7;\n    std::map<std::string, json> v8;\n\n    // use explicit conversions\n    json_types[\"boolean\"].get_to(v1);\n    json_types[\"number\"][\"integer\"].get_to(v2);\n    json_types[\"number\"][\"integer\"].get_to(v3);\n    json_types[\"number\"][\"floating-point\"].get_to(v4);\n    json_types[\"number\"][\"floating-point\"].get_to(v5);\n    json_types[\"string\"].get_to(v6);\n    json_types[\"array\"].get_to(v7);\n    json_types.get_to(v8);\n\n    // print the conversion results\n    std::cout << v1 << '\\n';\n    std::cout << v2 << ' ' << v3 << '\\n';\n    std::cout << v4 << ' ' << v5 << '\\n';\n    std::cout << v6 << '\\n';\n\n    for (auto i : v7)\n    {\n        std::cout << i << ' ';\n    }\n    std::cout << \"\\n\\n\";\n\n    for (const auto& i : v8)\n    {\n        std::cout << i.first << \": \" << i.second << '\\n';\n    }\n}\n

Output:

1\n42 42\n17.23 17\nHello, world!\n1 2 3 4 5 \n\narray: [1,2,3,4,5]\nboolean: true\nnull: null\nnumber: {\"floating-point\":17.23,\"integer\":42}\nstring: \"Hello, world!\"\n
"},{"location":"api/basic_json/get_to/#see-also","title":"See also","text":"
  • get - get a value (explicit conversion)
  • get_ref - get a reference to the stored value
  • get_ptr - get a pointer to the stored value
  • Converting values - the type conversions article
  • basic_json_view::get_to - the same conversion on a zero-copy view
  • Arbitrary Type Conversions - make your own types usable with get_to
"},{"location":"api/basic_json/get_to/#version-history","title":"Version history","text":"
  • Added in version 3.3.0.
  • Added a static_assert with a clear message for const arguments in version 3.13.0 unreleased.
"},{"location":"api/basic_json/input_format_t/","title":"nlohmann::basic_json::input_format_t","text":"
enum class input_format_t {\n    json,\n    cbor,\n    msgpack,\n    ubjson,\n    bson,\n    bjdata,\n    bon8\n};\n

This enumeration is used in the sax_parse function to choose the input format to parse:

json JSON (JavaScript Object Notation) cbor CBOR (Concise Binary Object Representation) msgpack MessagePack ubjson UBJSON (Universal Binary JSON) bson BSON (Binary JSON) bjdata BJData (Binary JData) bon8 BON8 (Binary Object Notation 8)"},{"location":"api/basic_json/input_format_t/#examples","title":"Examples","text":"Example

The example below shows how an input_format_t enum value is passed to sax_parse to set the input format to CBOR.

#include <iostream>\n#include <iomanip>\n#include <sstream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\n// a simple event consumer that collects string representations of the passed\n// values; note inheriting from json::json_sax_t is not required, but can\n// help not to forget a required function\nclass sax_event_consumer : public json::json_sax_t\n{\n  public:\n    std::vector<std::string> events;\n\n    bool null() override\n    {\n        events.push_back(\"null()\");\n        return true;\n    }\n\n    bool boolean(bool val) override\n    {\n        events.push_back(\"boolean(val=\" + std::string(val ? \"true\" : \"false\") + \")\");\n        return true;\n    }\n\n    bool number_integer(number_integer_t val) override\n    {\n        events.push_back(\"number_integer(val=\" + std::to_string(val) + \")\");\n        return true;\n    }\n\n    bool number_unsigned(number_unsigned_t val) override\n    {\n        events.push_back(\"number_unsigned(val=\" + std::to_string(val) + \")\");\n        return true;\n    }\n\n    bool number_float(number_float_t val, const string_t& s) override\n    {\n        events.push_back(\"number_float(val=\" + std::to_string(val) + \", s=\" + s + \")\");\n        return true;\n    }\n\n    bool string(string_t& val) override\n    {\n        events.push_back(\"string(val=\" + val + \")\");\n        return true;\n    }\n\n    bool start_object(std::size_t elements) override\n    {\n        events.push_back(\"start_object(elements=\" + std::to_string(elements) + \")\");\n        return true;\n    }\n\n    bool end_object() override\n    {\n        events.push_back(\"end_object()\");\n        return true;\n    }\n\n    bool start_array(std::size_t elements) override\n    {\n        events.push_back(\"start_array(elements=\" + std::to_string(elements) + \")\");\n        return true;\n    }\n\n    bool end_array() override\n    {\n        events.push_back(\"end_array()\");\n        return true;\n    }\n\n    bool key(string_t& val) override\n    {\n        events.push_back(\"key(val=\" + val + \")\");\n        return true;\n    }\n\n    bool binary(json::binary_t& val) override\n    {\n        events.push_back(\"binary(val=[...])\");\n        return true;\n    }\n\n    bool parse_error(std::size_t position, const std::string& last_token, const json::exception& ex) override\n    {\n        events.push_back(\"parse_error(position=\" + std::to_string(position) + \", last_token=\" + last_token + \",\\n            ex=\" + std::string(ex.what()) + \")\");\n        return false;\n    }\n};\n\nint main()\n{\n    // CBOR byte string\n    std::vector<std::uint8_t> vec = {{0x44, 0xcA, 0xfe, 0xba, 0xbe}};\n\n    // create a SAX event consumer object\n    sax_event_consumer sec;\n\n    // parse CBOR\n    bool result = json::sax_parse(vec, &sec, json::input_format_t::cbor);\n\n    // output the recorded events\n    for (auto& event : sec.events)\n    {\n        std::cout << event << \"\\n\";\n    }\n\n    // output the result of sax_parse\n    std::cout << \"\\nresult: \" << std::boolalpha << result << '\\n';\n}\n

Output:

binary(val=[...])\n\nresult: true\n
"},{"location":"api/basic_json/input_format_t/#see-also","title":"See also","text":"
  • sax_parse - generic SAX parse interface, taking an input_format_t to select the input format
  • cbor_tag_handler_t - configures how CBOR tags are treated while parsing
  • Binary Formats - CBOR, MessagePack, BSON, and other formats
"},{"location":"api/basic_json/input_format_t/#version-history","title":"Version history","text":"
  • Added in version 3.2.0.
"},{"location":"api/basic_json/insert/","title":"nlohmann::basic_json::insert","text":"
// (1)\niterator insert(const_iterator pos, const basic_json& val);\niterator insert(const_iterator pos, basic_json&& val);\n\n// (2)\niterator insert(const_iterator pos, size_type cnt, const basic_json& val);\n\n// (3)\niterator insert(const_iterator pos, const_iterator first, const_iterator last);\n\n// (4)\niterator insert(const_iterator pos, initializer_list_t ilist);\n\n// (5)\nvoid insert(const_iterator first, const_iterator last);\n
  1. Inserts element val into an array before iterator pos.
  2. Inserts cnt copies of val into an array before iterator pos.
  3. Inserts elements from range [first, last) into an array before iterator pos.
  4. Inserts elements from initializer list ilist into an array before iterator pos.
  5. Inserts elements from range [first, last) into an object.
"},{"location":"api/basic_json/insert/#iterator-invalidation","title":"Iterator invalidation","text":"

For all cases where an element is added to an array, a reallocation can happen, in which case all iterators (including the end() iterator) and all references to the elements are invalidated. Otherwise, only the end() iterator is invalidated. Also, any iterator or reference after the insertion point will point to the same index, which is now a different value.

For ordered_json, also adding an element to an object can yield a reallocation which again invalidates all iterators and all references. Also, any iterator or reference after the insertion point will point to the same index, which is now a different value.

"},{"location":"api/basic_json/insert/#parameters","title":"Parameters","text":"pos (in) iterator before which the content will be inserted; may be the end() iterator val (in) value to insert cnt (in) number of copies of val to insert first (in) the start of the range of elements to insert last (in) the end of the range of elements to insert ilist (in) initializer list to insert the values from"},{"location":"api/basic_json/insert/#return-value","title":"Return value","text":"
  1. iterator pointing to the inserted val.
  2. iterator pointing to the first element inserted, or pos if cnt==0
  3. iterator pointing to the first element inserted, or pos if first==last
  4. iterator pointing to the first element inserted, or pos if ilist is empty
  5. (none)
"},{"location":"api/basic_json/insert/#exception-safety","title":"Exception safety","text":"

Strong exception safety: if an exception occurs, the original value stays intact.

"},{"location":"api/basic_json/insert/#exceptions","title":"Exceptions","text":"
  1. The function can throw the following exceptions:
    • Throws type_error.309 if called on JSON values other than arrays; example: \"cannot use insert() with string\"
    • Throws invalid_iterator.202 if called on an iterator which does not belong to the current JSON value; example: \"iterator does not fit current value\"
  2. The function can throw the following exceptions:
    • Throws type_error.309 if called on JSON values other than arrays; example: \"cannot use insert() with string\"
    • Throws invalid_iterator.202 if called on an iterator which does not belong to the current JSON value; example: \"iterator does not fit current value\"
  3. The function can throw the following exceptions:
    • Throws type_error.309 if called on JSON values other than arrays; example: \"cannot use insert() with string\"
    • Throws invalid_iterator.202 if called on an iterator which does not belong to the current JSON value; example: \"iterator does not fit current value\"
    • Throws invalid_iterator.210 if first and last do not belong to the same JSON value; example: \"iterators do not fit\"
    • Throws invalid_iterator.211 if first or last are iterators into container for which insert is called; example: \"passed iterators may not belong to container\"
    • Throws invalid_iterator.202 if first or last do not point to an array; example: \"iterators first and last must point to arrays\"
  4. The function can throw the following exceptions:
    • Throws type_error.309 if called on JSON values other than arrays; example: \"cannot use insert() with string\"
    • Throws invalid_iterator.202 if called on an iterator which does not belong to the current JSON value; example: \"iterator does not fit current value\"
  5. The function can throw the following exceptions:
    • Throws type_error.309 if called on JSON values other than objects; example: \"cannot use insert() with string\"
    • Throws invalid_iterator.202 if first or last do not point to an object; example: \"iterators first and last must point to objects\"
    • Throws invalid_iterator.210 if first and last do not belong to the same JSON value; example: \"iterators do not fit\"
"},{"location":"api/basic_json/insert/#complexity","title":"Complexity","text":"
  1. Constant plus linear in the distance between pos and end of the container.
  2. Linear in cnt plus linear in the distance between pos and end of the container.
  3. Linear in 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. O(N*log(size() + N)), where N is the number of elements to insert.
"},{"location":"api/basic_json/insert/#examples","title":"Examples","text":"Example: (1) insert element into array

The example shows how insert() is used.

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create a JSON array\n    json v = {1, 2, 3, 4};\n\n    // insert number 10 before number 3\n    auto new_pos = v.insert(v.begin() + 2, 10);\n\n    // output new array and result of insert call\n    std::cout << *new_pos << '\\n';\n    std::cout << v << '\\n';\n}\n

Output:

10\n[1,2,10,3,4]\n
Example: (2) insert copies of element into array

The example shows how insert() is used.

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create a JSON array\n    json v = {1, 2, 3, 4};\n\n    // insert number 7 copies of number 7 before number 3\n    auto new_pos = v.insert(v.begin() + 2, 7, 7);\n\n    // output new array and result of insert call\n    std::cout << *new_pos << '\\n';\n    std::cout << v << '\\n';\n}\n

Output:

7\n[1,2,7,7,7,7,7,7,7,3,4]\n
Example: (3) insert a range of elements into an array

The example shows how insert() is used.

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create a JSON array\n    json v = {1, 2, 3, 4};\n\n    // create a JSON array to copy values from\n    json v2 = {\"one\", \"two\", \"three\", \"four\"};\n\n    // insert range from v2 before the end of array v\n    auto new_pos = v.insert(v.end(), v2.begin(), v2.end());\n\n    // output new array and result of insert call\n    std::cout << *new_pos << '\\n';\n    std::cout << v << '\\n';\n}\n

Output:

\"one\"\n[1,2,3,4,\"one\",\"two\",\"three\",\"four\"]\n
Example: (4) insert elements from an initializer list into an array

The example shows how insert() is used.

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create a JSON array\n    json v = {1, 2, 3, 4};\n\n    // insert range from v2 before the end of array v\n    auto new_pos = v.insert(v.end(), {7, 8, 9});\n\n    // output new array and result of insert call\n    std::cout << *new_pos << '\\n';\n    std::cout << v << '\\n';\n}\n

Output:

7\n[1,2,3,4,7,8,9]\n
Example: (5) insert a range of elements into an object

The example shows how insert() is used.

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create two JSON objects\n    json j1 = {{\"one\", \"eins\"}, {\"two\", \"zwei\"}};\n    json j2 = {{\"eleven\", \"elf\"}, {\"seventeen\", \"siebzehn\"}};\n\n    // output objects\n    std::cout << j1 << '\\n';\n    std::cout << j2 << '\\n';\n\n    // insert range from j2 to j1\n    j1.insert(j2.begin(), j2.end());\n\n    // output result of insert call\n    std::cout << j1 << '\\n';\n}\n

Output:

{\"one\":\"eins\",\"two\":\"zwei\"}\n{\"eleven\":\"elf\",\"seventeen\":\"siebzehn\"}\n{\"eleven\":\"elf\",\"one\":\"eins\",\"seventeen\":\"siebzehn\",\"two\":\"zwei\"}\n
"},{"location":"api/basic_json/insert/#see-also","title":"See also","text":"
  • emplace - add a value to an object
  • emplace_back - add a value to an array
  • push_back - add a value to an array/object
  • update - merges objects
  • Modifying values - the article on modifying values
"},{"location":"api/basic_json/insert/#version-history","title":"Version history","text":"
  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. Fixed in version 3.13.0 unreleased 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.
"},{"location":"api/basic_json/invalid_iterator/","title":"nlohmann::basic_json::invalid_iterator","text":"
class invalid_iterator : public exception;\n

This exception is thrown if iterators passed to a library function do not match the expected semantics.

Exceptions have ids 2xx (see list of iterator errors).

classDiagram\n  direction LR\n\n    class std_exception [\"std::exception\"] {\n        <<interface>>\n    }\n\n    class json_exception [\"basic_json::exception\"] {\n        +const int id\n        +const char* what() const\n    }\n\n    class json_parse_error [\"basic_json::parse_error\"] {\n        +const std::size_t byte\n    }\n\n    class json_invalid_iterator [\"basic_json::invalid_iterator\"]\n    class json_type_error [\"basic_json::type_error\"]\n    class json_out_of_range [\"basic_json::out_of_range\"]\n    class json_other_error [\"basic_json::other_error\"]\n\n    std_exception <|-- json_exception\n    json_exception <|-- json_parse_error\n    json_exception <|-- json_invalid_iterator\n    json_exception <|-- json_type_error\n    json_exception <|-- json_out_of_range\n    json_exception <|-- json_other_error\n\n    style json_invalid_iterator fill:#CCCCFF

Class hierarchy of the library's exceptions; arrows point from a derived class to its base class, and the highlighted box is basic_json::invalid_iterator.

"},{"location":"api/basic_json/invalid_iterator/#member-functions","title":"Member functions","text":"
  • what - returns explanatory string
"},{"location":"api/basic_json/invalid_iterator/#member-variables","title":"Member variables","text":"
  • id - the id of the exception
"},{"location":"api/basic_json/invalid_iterator/#examples","title":"Examples","text":"Example

The following code shows how a invalid_iterator exception can be caught.

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    try\n    {\n        // calling iterator::key() on non-object iterator\n        json j = \"string\";\n        json::iterator it = j.begin();\n        auto k = it.key();\n    }\n    catch (const json::invalid_iterator& e)\n    {\n        // output exception information\n        std::cout << \"message: \" << e.what() << '\\n'\n                  << \"exception id: \" << e.id << '\\n';\n    }\n}\n

Output:

message: [json.exception.invalid_iterator.207] cannot use key() for non-object iterators\nexception id: 207\n
"},{"location":"api/basic_json/invalid_iterator/#see-also","title":"See also","text":"
  • exception - the base class of all exceptions thrown by the library
  • List of iterator errors - overview of iterator errors (invalid_iterator)
  • parse_error - exceptions indicating a parse error
  • type_error - exceptions indicating executing a member function with a wrong type
  • out_of_range - exceptions indicating access out of the defined range
  • other_error - exceptions indicating other library errors
  • Exceptions - all exceptions and their error codes
  • JSON_DIAGNOSTICS - extended exception messages with the path of the failing value
"},{"location":"api/basic_json/invalid_iterator/#version-history","title":"Version history","text":"
  • Added in version 3.0.0.
"},{"location":"api/basic_json/is_array/","title":"nlohmann::basic_json::is_array","text":"
constexpr bool is_array() const noexcept;\n

This function returns true if and only if the JSON value is an array.

"},{"location":"api/basic_json/is_array/#return-value","title":"Return value","text":"

true if type is an array, false otherwise.

"},{"location":"api/basic_json/is_array/#exception-safety","title":"Exception safety","text":"

No-throw guarantee: this member function never throws exceptions.

"},{"location":"api/basic_json/is_array/#complexity","title":"Complexity","text":"

Constant.

"},{"location":"api/basic_json/is_array/#examples","title":"Examples","text":"Example

The following code exemplifies is_array() for all JSON types.

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create JSON values\n    json j_null;\n    json j_boolean = true;\n    json j_number_integer = 17;\n    json j_number_unsigned_integer = 12345678987654321u;\n    json j_number_float = 23.42;\n    json j_object = {{\"one\", 1}, {\"two\", 2}};\n    json j_array = {1, 2, 4, 8, 16};\n    json j_string = \"Hello, world\";\n    json j_binary = json::binary({1, 2, 3});\n\n    // call is_array()\n    std::cout << std::boolalpha;\n    std::cout << j_null.is_array() << '\\n';\n    std::cout << j_boolean.is_array() << '\\n';\n    std::cout << j_number_integer.is_array() << '\\n';\n    std::cout << j_number_unsigned_integer.is_array() << '\\n';\n    std::cout << j_number_float.is_array() << '\\n';\n    std::cout << j_object.is_array() << '\\n';\n    std::cout << j_array.is_array() << '\\n';\n    std::cout << j_string.is_array() << '\\n';\n    std::cout << j_binary.is_array() << '\\n';\n}\n

Output:

false\nfalse\nfalse\nfalse\nfalse\nfalse\ntrue\nfalse\nfalse\n
"},{"location":"api/basic_json/is_array/#see-also","title":"See also","text":"
  • is_object - checks whether the JSON value is an object
  • is_structured - checks whether the JSON value is structured (array or object)
  • type - returns the type of the JSON value
  • array_t - the type used to store JSON arrays
  • basic_json_view::is_array - the same check on a zero-copy view
  • Types - the JSON value types and how they are stored
"},{"location":"api/basic_json/is_array/#version-history","title":"Version history","text":"
  • Added in version 1.0.0.
"},{"location":"api/basic_json/is_binary/","title":"nlohmann::basic_json::is_binary","text":"
constexpr bool is_binary() const noexcept;\n

This function returns true if and only if the JSON value is a binary array.

"},{"location":"api/basic_json/is_binary/#return-value","title":"Return value","text":"

true if type is binary, false otherwise.

"},{"location":"api/basic_json/is_binary/#exception-safety","title":"Exception safety","text":"

No-throw guarantee: this member function never throws exceptions.

"},{"location":"api/basic_json/is_binary/#complexity","title":"Complexity","text":"

Constant.

"},{"location":"api/basic_json/is_binary/#examples","title":"Examples","text":"Example

The following code exemplifies is_binary() for all JSON types.

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create JSON values\n    json j_null;\n    json j_boolean = true;\n    json j_number_integer = 17;\n    json j_number_unsigned_integer = 12345678987654321u;\n    json j_number_float = 23.42;\n    json j_object = {{\"one\", 1}, {\"two\", 2}};\n    json j_array = {1, 2, 4, 8, 16};\n    json j_string = \"Hello, world\";\n    json j_binary = json::binary({1, 2, 3});\n\n    // call is_binary()\n    std::cout << std::boolalpha;\n    std::cout << j_null.is_binary() << '\\n';\n    std::cout << j_boolean.is_binary() << '\\n';\n    std::cout << j_number_integer.is_binary() << '\\n';\n    std::cout << j_number_unsigned_integer.is_binary() << '\\n';\n    std::cout << j_number_float.is_binary() << '\\n';\n    std::cout << j_object.is_binary() << '\\n';\n    std::cout << j_array.is_binary() << '\\n';\n    std::cout << j_string.is_binary() << '\\n';\n    std::cout << j_binary.is_binary() << '\\n';\n}\n

Output:

false\nfalse\nfalse\nfalse\nfalse\nfalse\nfalse\nfalse\ntrue\n
"},{"location":"api/basic_json/is_binary/#see-also","title":"See also","text":"
  • Binary values - how binary values and subtypes are handled
  • is_primitive - checks whether the JSON value is primitive
  • binary_t - the type used to store binary values
  • get_binary - returns a reference to the stored binary value
  • basic_json_view::is_binary - the same check on a zero-copy view
"},{"location":"api/basic_json/is_binary/#version-history","title":"Version history","text":"
  • Added in version 3.8.0.
"},{"location":"api/basic_json/is_boolean/","title":"nlohmann::basic_json::is_boolean","text":"
constexpr bool is_boolean() const noexcept;\n

This function returns true if and only if the JSON value is true or false.

"},{"location":"api/basic_json/is_boolean/#return-value","title":"Return value","text":"

true if type is boolean, false otherwise.

"},{"location":"api/basic_json/is_boolean/#exception-safety","title":"Exception safety","text":"

No-throw guarantee: this member function never throws exceptions.

"},{"location":"api/basic_json/is_boolean/#complexity","title":"Complexity","text":"

Constant.

"},{"location":"api/basic_json/is_boolean/#examples","title":"Examples","text":"Example

The following code exemplifies is_boolean() for all JSON types.

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create JSON values\n    json j_null;\n    json j_boolean = true;\n    json j_number_integer = 17;\n    json j_number_unsigned_integer = 12345678987654321u;\n    json j_number_float = 23.42;\n    json j_object = {{\"one\", 1}, {\"two\", 2}};\n    json j_array = {1, 2, 4, 8, 16};\n    json j_string = \"Hello, world\";\n    json j_binary = json::binary({1, 2, 3});\n\n    // call is_boolean()\n    std::cout << std::boolalpha;\n    std::cout << j_null.is_boolean() << '\\n';\n    std::cout << j_boolean.is_boolean() << '\\n';\n    std::cout << j_number_integer.is_boolean() << '\\n';\n    std::cout << j_number_unsigned_integer.is_boolean() << '\\n';\n    std::cout << j_number_float.is_boolean() << '\\n';\n    std::cout << j_object.is_boolean() << '\\n';\n    std::cout << j_array.is_boolean() << '\\n';\n    std::cout << j_string.is_boolean() << '\\n';\n    std::cout << j_binary.is_boolean() << '\\n';\n}\n

Output:

false\ntrue\nfalse\nfalse\nfalse\nfalse\nfalse\nfalse\nfalse\n
"},{"location":"api/basic_json/is_boolean/#see-also","title":"See also","text":"
  • boolean_t - the type used to store JSON booleans
  • is_primitive - checks whether the JSON value is primitive
  • basic_json_view::is_boolean - the same check on a zero-copy view
  • Types - the JSON value types and how they are stored
"},{"location":"api/basic_json/is_boolean/#version-history","title":"Version history","text":"
  • Added in version 1.0.0.
"},{"location":"api/basic_json/is_discarded/","title":"nlohmann::basic_json::is_discarded","text":"
constexpr bool is_discarded() const noexcept;\n

This function returns true for a JSON value if either:

  • the value was discarded during parsing with a callback function (see parser_callback_t), or
  • the value is the result of parsing invalid JSON with parameter allow_exceptions set to false; see parse for more information.
"},{"location":"api/basic_json/is_discarded/#return-value","title":"Return value","text":"

true if type is discarded, false otherwise.

"},{"location":"api/basic_json/is_discarded/#exception-safety","title":"Exception safety","text":"

No-throw guarantee: this member function never throws exceptions.

"},{"location":"api/basic_json/is_discarded/#complexity","title":"Complexity","text":"

Constant.

"},{"location":"api/basic_json/is_discarded/#notes","title":"Notes","text":"

Comparisons

Discarded values are never compared equal with operator==. That is, checking whether a JSON value j is discarded will only work via:

j.is_discarded()\n

because

j == json::value_t::discarded\n

will always be false.

Removal during parsing with callback functions

When a value is discarded by a callback function (see parser_callback_t) during parsing, then it is removed when it is part of a structured value. For instance, if the second value of an array is discarded, instead of [null, discarded, false], the array [null, false] is returned. If the top-level value itself is discarded by the callback, the parse call returns a null value.

After a successful parse, this function always returns false: discarded values can only occur during parsing and are either removed when inside a structured value or replaced by null at the top level. The exception is parsing with allow_exceptions set to false: a parse error then yields a discarded value for which this function returns true (see parse).

"},{"location":"api/basic_json/is_discarded/#examples","title":"Examples","text":"Example: is_discarded() for ordinary JSON values

The following code exemplifies is_discarded() for all JSON types.

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create JSON values\n    json j_null;\n    json j_boolean = true;\n    json j_number_integer = 17;\n    json j_number_unsigned_integer = 12345678987654321u;\n    json j_number_float = 23.42;\n    json j_object = {{\"one\", 1}, {\"two\", 2}};\n    json j_array = {1, 2, 4, 8, 16};\n    json j_string = \"Hello, world\";\n    json j_binary = json::binary({1, 2, 3});\n\n    // call is_discarded()\n    std::cout << std::boolalpha;\n    std::cout << j_null.is_discarded() << '\\n';\n    std::cout << j_boolean.is_discarded() << '\\n';\n    std::cout << j_number_integer.is_discarded() << '\\n';\n    std::cout << j_number_unsigned_integer.is_discarded() << '\\n';\n    std::cout << j_number_float.is_discarded() << '\\n';\n    std::cout << j_object.is_discarded() << '\\n';\n    std::cout << j_array.is_discarded() << '\\n';\n    std::cout << j_string.is_discarded() << '\\n';\n    std::cout << j_binary.is_discarded() << '\\n';\n}\n

Output:

false\nfalse\nfalse\nfalse\nfalse\nfalse\nfalse\nfalse\nfalse\n
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 false, and a parser callback that discards the top-level value (which is replaced by null and therefore does not remain discarded).

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // parsing invalid JSON without exceptions yields a discarded value\n    json j_invalid = json::parse(\"[1,2,3\", nullptr, false);\n\n    // a callback that discards the top-level value does not leave it\n    // \"discarded\" -- it is replaced by null instead\n    json j_discarded_by_callback = json::parse(\"[1,2,3]\", [](int /*depth*/, json::parse_event_t event, json& /*parsed*/)\n    {\n        return event != json::parse_event_t::array_start;\n    });\n\n    std::cout << std::boolalpha;\n    std::cout << \"j_invalid.is_discarded()               = \" << j_invalid.is_discarded() << '\\n';\n    std::cout << \"j_discarded_by_callback                = \" << j_discarded_by_callback << '\\n';\n    std::cout << \"j_discarded_by_callback.is_discarded() = \" << j_discarded_by_callback.is_discarded() << '\\n';\n}\n

Output:

j_invalid.is_discarded()               = true\nj_discarded_by_callback                = null\nj_discarded_by_callback.is_discarded() = false\n
"},{"location":"api/basic_json/is_discarded/#see-also","title":"See also","text":"
  • basic_json_view::is_discarded - the corresponding check on a zero-copy view, which is true if the view refers to no value
  • Types - the JSON value types and how they are stored
"},{"location":"api/basic_json/is_discarded/#version-history","title":"Version history","text":"
  • Added in version 1.0.0.
"},{"location":"api/basic_json/is_null/","title":"nlohmann::basic_json::is_null","text":"
constexpr bool is_null() const noexcept;\n

This function returns true if and only if the JSON value is null.

"},{"location":"api/basic_json/is_null/#return-value","title":"Return value","text":"

true if type is null, false otherwise.

"},{"location":"api/basic_json/is_null/#exception-safety","title":"Exception safety","text":"

No-throw guarantee: this member function never throws exceptions.

"},{"location":"api/basic_json/is_null/#complexity","title":"Complexity","text":"

Constant.

"},{"location":"api/basic_json/is_null/#examples","title":"Examples","text":"Example

The following code exemplifies is_null() for all JSON types.

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create JSON values\n    json j_null;\n    json j_boolean = true;\n    json j_number_integer = 17;\n    json j_number_unsigned_integer = 12345678987654321u;\n    json j_number_float = 23.42;\n    json j_object = {{\"one\", 1}, {\"two\", 2}};\n    json j_array = {1, 2, 4, 8, 16};\n    json j_string = \"Hello, world\";\n    json j_binary = json::binary({1, 2, 3});\n\n    // call is_null()\n    std::cout << std::boolalpha;\n    std::cout << j_null.is_null() << '\\n';\n    std::cout << j_boolean.is_null() << '\\n';\n    std::cout << j_number_integer.is_null() << '\\n';\n    std::cout << j_number_unsigned_integer.is_null() << '\\n';\n    std::cout << j_number_float.is_null() << '\\n';\n    std::cout << j_object.is_null() << '\\n';\n    std::cout << j_array.is_null() << '\\n';\n    std::cout << j_string.is_null() << '\\n';\n    std::cout << j_binary.is_null() << '\\n';\n}\n

Output:

true\nfalse\nfalse\nfalse\nfalse\nfalse\nfalse\nfalse\nfalse\n
"},{"location":"api/basic_json/is_null/#see-also","title":"See also","text":"
  • is_array - checks whether the JSON value is an array
  • is_object - checks whether the JSON value is an object
  • type - returns the type of the JSON value
  • value_t - the enumeration of JSON types
  • basic_json_view::is_null - the same check on a zero-copy view
  • Types - the JSON value types and how they are stored
"},{"location":"api/basic_json/is_null/#version-history","title":"Version history","text":"
  • Added in version 1.0.0.
"},{"location":"api/basic_json/is_number/","title":"nlohmann::basic_json::is_number","text":"
constexpr bool is_number() const noexcept;\n

This function returns true if and only if the JSON value is a number. This includes both integer (signed and unsigned) and floating-point values.

"},{"location":"api/basic_json/is_number/#return-value","title":"Return value","text":"

true if type is number (regardless whether integer, unsigned integer, or floating-point), false otherwise.

"},{"location":"api/basic_json/is_number/#exception-safety","title":"Exception safety","text":"

No-throw guarantee: this member function never throws exceptions.

"},{"location":"api/basic_json/is_number/#complexity","title":"Complexity","text":"

Constant.

"},{"location":"api/basic_json/is_number/#possible-implementation","title":"Possible implementation","text":"
constexpr bool is_number() const noexcept\n{\n    return is_number_integer() || is_number_float();\n}\n
"},{"location":"api/basic_json/is_number/#examples","title":"Examples","text":"Example

The following code exemplifies is_number() for all JSON types.

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create JSON values\n    json j_null;\n    json j_boolean = true;\n    json j_number_integer = 17;\n    json j_number_unsigned_integer = 12345678987654321u;\n    json j_number_float = 23.42;\n    json j_object = {{\"one\", 1}, {\"two\", 2}};\n    json j_array = {1, 2, 4, 8, 16};\n    json j_string = \"Hello, world\";\n    json j_binary = json::binary({1, 2, 3});\n\n    // call is_number()\n    std::cout << std::boolalpha;\n    std::cout << j_null.is_number() << '\\n';\n    std::cout << j_boolean.is_number() << '\\n';\n    std::cout << j_number_integer.is_number() << '\\n';\n    std::cout << j_number_unsigned_integer.is_number() << '\\n';\n    std::cout << j_number_float.is_number() << '\\n';\n    std::cout << j_object.is_number() << '\\n';\n    std::cout << j_array.is_number() << '\\n';\n    std::cout << j_string.is_number() << '\\n';\n    std::cout << j_binary.is_number() << '\\n';\n}\n

Output:

false\nfalse\ntrue\ntrue\ntrue\nfalse\nfalse\nfalse\nfalse\n
"},{"location":"api/basic_json/is_number/#see-also","title":"See also","text":"
  • is_number_integer() - check if the value is an integer or unsigned integer number
  • is_number_unsigned() - check if the value is an unsigned integer number
  • is_number_float() - check if the value is a floating-point number
  • basic_json_view::is_number - the same check on a zero-copy view
  • Types - the JSON value types and how they are stored
  • Number Handling - how numbers are stored and converted
"},{"location":"api/basic_json/is_number/#version-history","title":"Version history","text":"
  • Added in version 1.0.0.
  • Extended to also return true for unsigned integers in 2.0.0.
"},{"location":"api/basic_json/is_number_float/","title":"nlohmann::basic_json::is_number_float","text":"
constexpr bool is_number_float() const noexcept;\n

This function returns true if and only if the JSON value is a floating-point number. This excludes signed and unsigned integer values.

"},{"location":"api/basic_json/is_number_float/#return-value","title":"Return value","text":"

true if type is a floating-point number, false otherwise.

"},{"location":"api/basic_json/is_number_float/#exception-safety","title":"Exception safety","text":"

No-throw guarantee: this member function never throws exceptions.

"},{"location":"api/basic_json/is_number_float/#complexity","title":"Complexity","text":"

Constant.

"},{"location":"api/basic_json/is_number_float/#examples","title":"Examples","text":"Example

The following code exemplifies is_number_float() for all JSON types.

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create JSON values\n    json j_null;\n    json j_boolean = true;\n    json j_number_integer = 17;\n    json j_number_unsigned_integer = 12345678987654321u;\n    json j_number_float = 23.42;\n    json j_object = {{\"one\", 1}, {\"two\", 2}};\n    json j_array = {1, 2, 4, 8, 16};\n    json j_string = \"Hello, world\";\n    json j_binary = json::binary({1, 2, 3});\n\n    // call is_number_float()\n    std::cout << std::boolalpha;\n    std::cout << j_null.is_number_float() << '\\n';\n    std::cout << j_boolean.is_number_float() << '\\n';\n    std::cout << j_number_integer.is_number_float() << '\\n';\n    std::cout << j_number_unsigned_integer.is_number_float() << '\\n';\n    std::cout << j_number_float.is_number_float() << '\\n';\n    std::cout << j_object.is_number_float() << '\\n';\n    std::cout << j_array.is_number_float() << '\\n';\n    std::cout << j_string.is_number_float() << '\\n';\n    std::cout << j_binary.is_number_float() << '\\n';\n}\n

Output:

false\nfalse\nfalse\nfalse\ntrue\nfalse\nfalse\nfalse\nfalse\n
"},{"location":"api/basic_json/is_number_float/#see-also","title":"See also","text":"
  • is_number() - check if the value is a number
  • is_number_integer() - check if the value is an integer or unsigned integer number
  • is_number_unsigned() - check if the value is an unsigned integer number
  • basic_json_view::is_number_float - the same check on a zero-copy view
  • Types - the JSON value types and how they are stored
  • Number Handling - how numbers are stored and converted
"},{"location":"api/basic_json/is_number_float/#version-history","title":"Version history","text":"
  • Added in version 1.0.0.
"},{"location":"api/basic_json/is_number_integer/","title":"nlohmann::basic_json::is_number_integer","text":"
constexpr bool is_number_integer() const noexcept;\n

This function returns true if and only if the JSON value is a signed or unsigned integer number. This excludes floating-point values.

"},{"location":"api/basic_json/is_number_integer/#return-value","title":"Return value","text":"

true if type is an integer or unsigned integer number, false otherwise.

"},{"location":"api/basic_json/is_number_integer/#exception-safety","title":"Exception safety","text":"

No-throw guarantee: this member function never throws exceptions.

"},{"location":"api/basic_json/is_number_integer/#complexity","title":"Complexity","text":"

Constant.

"},{"location":"api/basic_json/is_number_integer/#examples","title":"Examples","text":"Example

The following code exemplifies is_number_integer() for all JSON types.

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create JSON values\n    json j_null;\n    json j_boolean = true;\n    json j_number_integer = 17;\n    json j_number_unsigned_integer = 12345678987654321u;\n    json j_number_float = 23.42;\n    json j_object = {{\"one\", 1}, {\"two\", 2}};\n    json j_array = {1, 2, 4, 8, 16};\n    json j_string = \"Hello, world\";\n    json j_binary = json::binary({1, 2, 3});\n\n    // call is_number_integer()\n    std::cout << std::boolalpha;\n    std::cout << j_null.is_number_integer() << '\\n';\n    std::cout << j_boolean.is_number_integer() << '\\n';\n    std::cout << j_number_integer.is_number_integer() << '\\n';\n    std::cout << j_number_unsigned_integer.is_number_integer() << '\\n';\n    std::cout << j_number_float.is_number_integer() << '\\n';\n    std::cout << j_object.is_number_integer() << '\\n';\n    std::cout << j_array.is_number_integer() << '\\n';\n    std::cout << j_string.is_number_integer() << '\\n';\n    std::cout << j_binary.is_number_integer() << '\\n';\n}\n

Output:

false\nfalse\ntrue\ntrue\nfalse\nfalse\nfalse\nfalse\nfalse\n
"},{"location":"api/basic_json/is_number_integer/#see-also","title":"See also","text":"
  • is_number() - check if the value is a number
  • is_number_unsigned() - check if the value is an unsigned integer number
  • is_number_float() - check if the value is a floating-point number
  • basic_json_view::is_number_integer - the same check on a zero-copy view
  • Types - the JSON value types and how they are stored
  • Number Handling - how numbers are stored and converted
"},{"location":"api/basic_json/is_number_integer/#version-history","title":"Version history","text":"
  • Added in version 1.0.0.
  • Extended to also return true for unsigned integers in 2.0.0.
"},{"location":"api/basic_json/is_number_unsigned/","title":"nlohmann::basic_json::is_number_unsigned","text":"
constexpr bool is_number_unsigned() const noexcept;\n

This function returns true if and only if the JSON value is an unsigned integer number. This excludes floating-point and signed integer values.

If number_unsigned_t is the same type as number_integer_t, every integer is stored as number_integer_t, and this function always returns false.

"},{"location":"api/basic_json/is_number_unsigned/#return-value","title":"Return value","text":"

true if type is an unsigned integer number, false otherwise.

"},{"location":"api/basic_json/is_number_unsigned/#exception-safety","title":"Exception safety","text":"

No-throw guarantee: this member function never throws exceptions.

"},{"location":"api/basic_json/is_number_unsigned/#complexity","title":"Complexity","text":"

Constant.

"},{"location":"api/basic_json/is_number_unsigned/#examples","title":"Examples","text":"Example

The following code exemplifies is_number_unsigned() for all JSON types.

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create JSON values\n    json j_null;\n    json j_boolean = true;\n    json j_number_integer = 17;\n    json j_number_unsigned_integer = 12345678987654321u;\n    json j_number_float = 23.42;\n    json j_object = {{\"one\", 1}, {\"two\", 2}};\n    json j_array = {1, 2, 4, 8, 16};\n    json j_string = \"Hello, world\";\n    json j_binary = json::binary({1, 2, 3});\n\n    // call is_number_unsigned()\n    std::cout << std::boolalpha;\n    std::cout << j_null.is_number_unsigned() << '\\n';\n    std::cout << j_boolean.is_number_unsigned() << '\\n';\n    std::cout << j_number_integer.is_number_unsigned() << '\\n';\n    std::cout << j_number_unsigned_integer.is_number_unsigned() << '\\n';\n    std::cout << j_number_float.is_number_unsigned() << '\\n';\n    std::cout << j_object.is_number_unsigned() << '\\n';\n    std::cout << j_array.is_number_unsigned() << '\\n';\n    std::cout << j_string.is_number_unsigned() << '\\n';\n    std::cout << j_binary.is_number_unsigned() << '\\n';\n}\n

Output:

false\nfalse\nfalse\ntrue\nfalse\nfalse\nfalse\nfalse\nfalse\n
"},{"location":"api/basic_json/is_number_unsigned/#see-also","title":"See also","text":"
  • is_number() - check if the value is a number
  • is_number_integer() - check if the value is an integer or unsigned integer number
  • is_number_float() - check if the value is a floating-point number
  • basic_json_view::is_number_unsigned - the same check on a zero-copy view
  • Types - the JSON value types and how they are stored
  • Number Handling - how numbers are stored and converted
"},{"location":"api/basic_json/is_number_unsigned/#version-history","title":"Version history","text":"
  • Added in version 2.0.0.
"},{"location":"api/basic_json/is_object/","title":"nlohmann::basic_json::is_object","text":"
constexpr bool is_object() const noexcept;\n

This function returns true if and only if the JSON value is an object.

"},{"location":"api/basic_json/is_object/#return-value","title":"Return value","text":"

true if type is an object, false otherwise.

"},{"location":"api/basic_json/is_object/#exception-safety","title":"Exception safety","text":"

No-throw guarantee: this member function never throws exceptions.

"},{"location":"api/basic_json/is_object/#complexity","title":"Complexity","text":"

Constant.

"},{"location":"api/basic_json/is_object/#examples","title":"Examples","text":"Example

The following code exemplifies is_object() for all JSON types.

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create JSON values\n    json j_null;\n    json j_boolean = true;\n    json j_number_integer = 17;\n    json j_number_float = 23.42;\n    json j_number_unsigned_integer = 12345678987654321u;\n    json j_object = {{\"one\", 1}, {\"two\", 2}};\n    json j_array = {1, 2, 4, 8, 16};\n    json j_string = \"Hello, world\";\n    json j_binary = json::binary({1, 2, 3});\n\n    // call is_object()\n    std::cout << std::boolalpha;\n    std::cout << j_null.is_object() << '\\n';\n    std::cout << j_boolean.is_object() << '\\n';\n    std::cout << j_number_integer.is_object() << '\\n';\n    std::cout << j_number_unsigned_integer.is_object() << '\\n';\n    std::cout << j_number_float.is_object() << '\\n';\n    std::cout << j_object.is_object() << '\\n';\n    std::cout << j_array.is_object() << '\\n';\n    std::cout << j_string.is_object() << '\\n';\n    std::cout << j_binary.is_object() << '\\n';\n}\n

Output:

false\nfalse\nfalse\nfalse\nfalse\ntrue\nfalse\nfalse\nfalse\n
"},{"location":"api/basic_json/is_object/#see-also","title":"See also","text":"
  • is_array - checks whether the JSON value is an array
  • is_structured - checks whether the JSON value is structured (array or object)
  • type - returns the type of the JSON value
  • object_t - the type used to store JSON objects
  • basic_json_view::is_object - the same check on a zero-copy view
  • Types - the JSON value types and how they are stored
"},{"location":"api/basic_json/is_object/#version-history","title":"Version history","text":"
  • Added in version 1.0.0.
"},{"location":"api/basic_json/is_primitive/","title":"nlohmann::basic_json::is_primitive","text":"
constexpr bool is_primitive() const noexcept;\n

This function returns true if and only if the JSON type is primitive (string, number, boolean, null, binary).

"},{"location":"api/basic_json/is_primitive/#return-value","title":"Return value","text":"

true if type is primitive (string, number, boolean, null, or binary), false otherwise.

"},{"location":"api/basic_json/is_primitive/#exception-safety","title":"Exception safety","text":"

No-throw guarantee: this member function never throws exceptions.

"},{"location":"api/basic_json/is_primitive/#complexity","title":"Complexity","text":"

Constant.

"},{"location":"api/basic_json/is_primitive/#possible-implementation","title":"Possible implementation","text":"
constexpr bool is_primitive() const noexcept\n{\n    return is_null() || is_string() || is_boolean() || is_number() || is_binary();\n}\n
"},{"location":"api/basic_json/is_primitive/#notes","title":"Notes","text":"

The term primitive stems from RFC 8259:

JSON can represent four primitive types (strings, numbers, booleans, and null) and two structured types (objects and arrays).

This library extends primitive types to binary types, because binary types are roughly comparable to strings. Hence, is_primitive() returns true for binary values.

"},{"location":"api/basic_json/is_primitive/#examples","title":"Examples","text":"Example

The following code exemplifies is_primitive() for all JSON types.

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create JSON values\n    json j_null;\n    json j_boolean = true;\n    json j_number_integer = 17;\n    json j_number_float = 23.42;\n    json j_number_unsigned_integer = 12345678987654321u;\n    json j_object = {{\"one\", 1}, {\"two\", 2}};\n    json j_array = {1, 2, 4, 8, 16};\n    json j_string = \"Hello, world\";\n    json j_binary = json::binary({1, 2, 3});\n\n    // call is_primitive()\n    std::cout << std::boolalpha;\n    std::cout << j_null.is_primitive() << '\\n';\n    std::cout << j_boolean.is_primitive() << '\\n';\n    std::cout << j_number_integer.is_primitive() << '\\n';\n    std::cout << j_number_unsigned_integer.is_primitive() << '\\n';\n    std::cout << j_number_float.is_primitive() << '\\n';\n    std::cout << j_object.is_primitive() << '\\n';\n    std::cout << j_array.is_primitive() << '\\n';\n    std::cout << j_string.is_primitive() << '\\n';\n    std::cout << j_binary.is_primitive() << '\\n';\n}\n

Output:

true\ntrue\ntrue\ntrue\ntrue\nfalse\nfalse\ntrue\ntrue\n
"},{"location":"api/basic_json/is_primitive/#see-also","title":"See also","text":"
  • is_structured() - returns whether the JSON value is structured
  • is_null() - returns whether the JSON value is null
  • is_string() - returns whether the JSON value is a string
  • is_boolean() - returns whether the JSON value is a boolean
  • is_number() - returns whether the JSON value is a number
  • is_binary() - returns whether the JSON value is a binary array
  • basic_json_view::is_primitive - the same check on a zero-copy view
  • Types - the JSON value types and how they are stored
"},{"location":"api/basic_json/is_primitive/#version-history","title":"Version history","text":"
  • Added in version 1.0.0.
  • Extended to return true for binary types in version 3.8.0.
"},{"location":"api/basic_json/is_string/","title":"nlohmann::basic_json::is_string","text":"
constexpr bool is_string() const noexcept;\n

This function returns true if and only if the JSON value is a string.

"},{"location":"api/basic_json/is_string/#return-value","title":"Return value","text":"

true if type is a string, false otherwise.

"},{"location":"api/basic_json/is_string/#exception-safety","title":"Exception safety","text":"

No-throw guarantee: this member function never throws exceptions.

"},{"location":"api/basic_json/is_string/#complexity","title":"Complexity","text":"

Constant.

"},{"location":"api/basic_json/is_string/#examples","title":"Examples","text":"Example

The following code exemplifies is_string() for all JSON types.

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create JSON values\n    json j_null;\n    json j_boolean = true;\n    json j_number_integer = 17;\n    json j_number_float = 23.42;\n    json j_number_unsigned_integer = 12345678987654321u;\n    json j_object = {{\"one\", 1}, {\"two\", 2}};\n    json j_array = {1, 2, 4, 8, 16};\n    json j_string = \"Hello, world\";\n    json j_binary = json::binary({1, 2, 3});\n\n    // call is_string()\n    std::cout << std::boolalpha;\n    std::cout << j_null.is_string() << '\\n';\n    std::cout << j_boolean.is_string() << '\\n';\n    std::cout << j_number_integer.is_string() << '\\n';\n    std::cout << j_number_unsigned_integer.is_string() << '\\n';\n    std::cout << j_number_float.is_string() << '\\n';\n    std::cout << j_object.is_string() << '\\n';\n    std::cout << j_array.is_string() << '\\n';\n    std::cout << j_string.is_string() << '\\n';\n    std::cout << j_binary.is_string() << '\\n';\n}\n

Output:

false\nfalse\nfalse\nfalse\nfalse\nfalse\nfalse\ntrue\nfalse\n
"},{"location":"api/basic_json/is_string/#see-also","title":"See also","text":"
  • is_primitive - checks whether the JSON value is primitive
  • type - returns the type of the JSON value
  • string_t - the type used to store JSON strings
  • basic_json_view::is_string - the same check on a zero-copy view
  • Types - the JSON value types and how they are stored
"},{"location":"api/basic_json/is_string/#version-history","title":"Version history","text":"
  • Added in version 1.0.0.
"},{"location":"api/basic_json/is_structured/","title":"nlohmann::basic_json::is_structured","text":"
constexpr bool is_structured() const noexcept;\n

This function returns true if and only if the JSON type is structured (array or object).

"},{"location":"api/basic_json/is_structured/#return-value","title":"Return value","text":"

true if type is structured (array or object), false otherwise.

"},{"location":"api/basic_json/is_structured/#exception-safety","title":"Exception safety","text":"

No-throw guarantee: this member function never throws exceptions.

"},{"location":"api/basic_json/is_structured/#complexity","title":"Complexity","text":"

Constant.

"},{"location":"api/basic_json/is_structured/#possible-implementation","title":"Possible implementation","text":"
constexpr bool is_structured() const noexcept\n{\n    return is_array() || is_object();\n}\n
"},{"location":"api/basic_json/is_structured/#notes","title":"Notes","text":"

The term structured stems from RFC 8259:

JSON can represent four primitive types (strings, numbers, booleans, and null) and two structured types (objects and arrays).

Note that though strings are containers in C++, they are treated as primitive values in JSON.

"},{"location":"api/basic_json/is_structured/#examples","title":"Examples","text":"Example

The following code exemplifies is_structured() for all JSON types.

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create JSON values\n    json j_null;\n    json j_boolean = true;\n    json j_number_integer = 17;\n    json j_number_float = 23.42;\n    json j_number_unsigned_integer = 12345678987654321u;\n    json j_object = {{\"one\", 1}, {\"two\", 2}};\n    json j_array = {1, 2, 4, 8, 16};\n    json j_string = \"Hello, world\";\n    json j_binary = json::binary({1, 2, 3});\n\n    // call is_structured()\n    std::cout << std::boolalpha;\n    std::cout << j_null.is_structured() << '\\n';\n    std::cout << j_boolean.is_structured() << '\\n';\n    std::cout << j_number_integer.is_structured() << '\\n';\n    std::cout << j_number_unsigned_integer.is_structured() << '\\n';\n    std::cout << j_number_float.is_structured() << '\\n';\n    std::cout << j_object.is_structured() << '\\n';\n    std::cout << j_array.is_structured() << '\\n';\n    std::cout << j_string.is_structured() << '\\n';\n    std::cout << j_binary.is_structured() << '\\n';\n}\n

Output:

false\nfalse\nfalse\nfalse\nfalse\ntrue\ntrue\nfalse\nfalse\n
"},{"location":"api/basic_json/is_structured/#see-also","title":"See also","text":"
  • is_primitive() - returns whether JSON value is primitive
  • is_array() - returns whether the value is an array
  • is_object() - returns whether the value is an object
  • basic_json_view::is_structured - the same check on a zero-copy view
  • Types - the JSON value types and how they are stored
"},{"location":"api/basic_json/is_structured/#version-history","title":"Version history","text":"
  • Added in version 1.0.0.
"},{"location":"api/basic_json/items/","title":"nlohmann::basic_json::items","text":"
iteration_proxy<iterator> items() noexcept;\niteration_proxy<const_iterator> items() const noexcept;\n

This function allows accessing iterator::key() and iterator::value() during range-based for loops. In these loops, a reference to the JSON values is returned, so there is no access to the underlying iterator.

For loop without items() function:

for (auto it = j_object.begin(); it != j_object.end(); ++it)\n{\n    std::cout << \"key: \" << it.key() << \", value:\" << it.value() << '\\n';\n}\n

Range-based for loop without items() function:

for (auto it : j_object)\n{\n    // \"it\" is of type json::reference and has no key() member\n    std::cout << \"value: \" << it << '\\n';\n}\n

Range-based for loop with items() function:

for (auto& el : j_object.items())\n{\n    std::cout << \"key: \" << el.key() << \", value:\" << el.value() << '\\n';\n}\n

The items() function also allows using structured bindings (C++17):

for (auto& [key, val] : j_object.items())\n{\n    std::cout << \"key: \" << key << \", value:\" << val << '\\n';\n}\n

If you need to name the type of the dereferenced element explicitly (e.g., to write a standalone function that takes it as a parameter, or to use items() with std::for_each), use decltype:

using element_type = decltype(*j_object.items().begin());\n

The per-element type (iteration_proxy_value) lives in the library's internal detail namespace and is intentionally unspecified as a stable, named type \u2014 decltype is the supported way to obtain it, but its exact name/definition may change between versions.

"},{"location":"api/basic_json/items/#return-value","title":"Return value","text":"

iteration proxy object wrapping the current value with an interface to use in range-based for loops

"},{"location":"api/basic_json/items/#exception-safety","title":"Exception safety","text":"

Strong guarantee: if an exception is thrown, there are no changes in the JSON value.

"},{"location":"api/basic_json/items/#complexity","title":"Complexity","text":"

Constant.

"},{"location":"api/basic_json/items/#notes","title":"Notes","text":"

When iterating over an array, key() will return the index of the element as string (see example). For primitive types (e.g., numbers), key() returns an empty string.

Lifetime issues

Using items() on temporary objects is dangerous. Make sure the object's lifetime exceeds the iteration. See #2040 for more information.

"},{"location":"api/basic_json/items/#examples","title":"Examples","text":"Example

The following code shows an example for items().

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create JSON values\n    json j_object = {{\"one\", 1}, {\"two\", 2}};\n    json j_array = {1, 2, 4, 8, 16};\n\n    // example for an object\n    for (const auto& x : j_object.items())\n    {\n        std::cout << \"key: \" << x.key() << \", value: \" << x.value() << '\\n';\n    }\n\n    // example for an array\n    for (const auto& x : j_array.items())\n    {\n        std::cout << \"key: \" << x.key() << \", value: \" << x.value() << '\\n';\n    }\n}\n

Output:

key: one, value: 1\nkey: two, value: 2\nkey: 0, value: 1\nkey: 1, value: 2\nkey: 2, value: 4\nkey: 3, value: 8\nkey: 4, value: 16\n
"},{"location":"api/basic_json/items/#see-also","title":"See also","text":"
  • begin - returns an iterator to the first element
  • end - returns an iterator to one past the last element
  • basic_json_view::items - the same range on a zero-copy view (const auto, not const auto&: items are produced on the fly; document order, not sorted; duplicate keys are visited)
  • Iterators - the article on iterating over keys and values
"},{"location":"api/basic_json/items/#version-history","title":"Version history","text":"
  • Added in version 3.1.0 as the replacement of the static function iterator_wrapper, which was available since version 1.0.0 and is deprecated since version 3.1.0.
  • Added structured binding support in version 3.5.0.

Deprecation

This function replaces the static function iterator_wrapper which was introduced in version 1.0.0, but has been deprecated in version 3.1.0. Function iterator_wrapper will be removed in version 4.0.0. Please replace all occurrences of iterator_wrapper(j) with j.items().

You should be warned by your compiler with a -Wdeprecated-declarations warning if you are using a deprecated function.

See the migration guide for how to update existing code.

"},{"location":"api/basic_json/json_base_class_t/","title":"nlohmann::basic_json::json_base_class_t","text":"
using json_base_class_t = detail::json_base_class<CustomBaseClass>;\n

The base class used to inject custom functionality into each instance of basic_json. Examples of such functionality might be metadata, additional member functions (e.g., visitors), or other application-specific code.

"},{"location":"api/basic_json/json_base_class_t/#template-parameters","title":"Template parameters","text":"CustomBaseClass the base class to be added to basic_json"},{"location":"api/basic_json/json_base_class_t/#notes","title":"Notes","text":""},{"location":"api/basic_json/json_base_class_t/#default-type","title":"Default type","text":"

The default value for CustomBaseClass is void. In this case, an empty base class is used and no additional functionality is injected.

"},{"location":"api/basic_json/json_base_class_t/#limitations","title":"Limitations","text":"

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. A CustomBaseClass with non-static data members forfeits basic_json's standard layout guarantee. See Template Parameter Requirements.

"},{"location":"api/basic_json/json_base_class_t/#name-conflicts","title":"Name conflicts","text":"

Since basic_json derives from CustomBaseClass, members of basic_json hide members of CustomBaseClass with the same name. Hidden members remain accessible via as_base_class or by casting the value to json_base_class_t.

Avoid generic member names

Future versions of the library may add members to basic_json that hide members of CustomBaseClass that are accessible today. To reduce the risk of such conflicts, avoid generic names for the members of CustomBaseClass, for instance by using a distinctive prefix.

"},{"location":"api/basic_json/json_base_class_t/#examples","title":"Examples","text":"Example

The following code shows how to inject custom data and methods for each node.

#include <iostream>\n#include <nlohmann/json.hpp>\n\nclass visitor_adaptor_with_metadata\n{\n  public:\n    template <class Fnc>\n    void visit(const Fnc& fnc) const;\n\n    int metadata = 42;\n  private:\n    template <class Ptr, class Fnc>\n    void do_visit(const Ptr& ptr, const Fnc& fnc) const;\n};\n\nusing json = nlohmann::json::with_base_class_t<visitor_adaptor_with_metadata>;\n\ntemplate <class Fnc>\nvoid visitor_adaptor_with_metadata::visit(const Fnc& fnc) const\n{\n    do_visit(json::json_pointer{}, fnc);\n}\n\ntemplate <class Ptr, class Fnc>\nvoid visitor_adaptor_with_metadata::do_visit(const Ptr& ptr, const Fnc& fnc) const\n{\n    using nlohmann::detail::value_t;\n    const json& j = *static_cast<const json*>(this);\n    switch (j.type())\n    {\n        case value_t::object:\n            fnc(ptr, j);\n            for (const auto& entry : j.items())\n            {\n                entry.value().do_visit(ptr / entry.key(), fnc);\n            }\n            break;\n        case value_t::array:\n            fnc(ptr, j);\n            for (std::size_t i = 0; i < j.size(); ++i)\n            {\n                j.at(i).do_visit(ptr / std::to_string(i), fnc);\n            }\n            break;\n        case value_t::null:\n        case value_t::string:\n        case value_t::boolean:\n        case value_t::number_integer:\n        case value_t::number_unsigned:\n        case value_t::number_float:\n        case value_t::binary:\n            fnc(ptr, j);\n            break;\n        case value_t::discarded:\n        default:\n            break;\n    }\n}\n\nint main()\n{\n    // create a json object\n    json j;\n    j[\"null\"];\n    j[\"object\"][\"uint\"] = 1U;\n    j[\"object\"].metadata = 21;\n\n    // visit and output\n    j.visit(\n         [&](const json::json_pointer & p,\n             const json & j)\n    {\n        std::cout << (p.empty() ? std::string{\"/\"} : p.to_string())\n                  << \" - metadata = \" << j.metadata << \" -> \" << j.dump() << '\\n';\n    });\n}\n

Output:

/ - metadata = 42 -> {\"null\":null,\"object\":{\"uint\":1}}\n/null - metadata = 42 -> null\n/object - metadata = 21 -> {\"uint\":1}\n/object/uint - metadata = 42 -> 1\n
"},{"location":"api/basic_json/json_base_class_t/#see-also","title":"See also","text":"
  • as_base_class - access the custom base class
  • Template Parameter Requirements - the requirements for CustomBaseClass
"},{"location":"api/basic_json/json_base_class_t/#version-history","title":"Version history","text":"
  • Added in version 3.11.3.
  • Made a public member type in version 3.13.0 unreleased; it was private before, so it could not be named outside the class.
"},{"location":"api/basic_json/json_serializer/","title":"nlohmann::basic_json::json_serializer","text":"
template<typename T, typename SFINAE>\nusing json_serializer = JSONSerializer<T, SFINAE>;\n
"},{"location":"api/basic_json/json_serializer/#template-parameters","title":"Template parameters","text":"T type to convert; will be used in the to_json/from_json functions SFINAE type to add compile type checks via SFINAE; usually void"},{"location":"api/basic_json/json_serializer/#notes","title":"Notes","text":""},{"location":"api/basic_json/json_serializer/#default-type","title":"Default type","text":"

The default values for json_serializer is adl_serializer.

"},{"location":"api/basic_json/json_serializer/#requirements","title":"Requirements","text":"

A custom serializer must provide static void to_json(basic_json&, T) for every type it serializes, and either static void from_json(const basic_json&, T&) or static T from_json(const basic_json&) for every type it deserializes. See Template Parameter Requirements.

"},{"location":"api/basic_json/json_serializer/#examples","title":"Examples","text":"Example

The example below shows how a conversion of a non-default-constructible type is implemented via a specialization of the adl_serializer.

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nnamespace ns\n{\n// a simple struct to model a person (not default constructible)\nstruct person\n{\n    person(std::string n, std::string a, int aa)\n        : name(std::move(n)), address(std::move(a)), age(aa)\n    {}\n\n    std::string name;\n    std::string address;\n    int age;\n};\n} // namespace ns\n\nnamespace nlohmann\n{\ntemplate <>\nstruct adl_serializer<ns::person>\n{\n    static ns::person from_json(const json& j)\n    {\n        return {j.at(\"name\"), j.at(\"address\"), j.at(\"age\")};\n    }\n\n    // Here's the catch! You must provide a to_json method! Otherwise, you\n    // will not be able to convert person to json, since you fully\n    // specialized adl_serializer on that type\n    static void to_json(json& j, ns::person p)\n    {\n        j[\"name\"] = p.name;\n        j[\"address\"] = p.address;\n        j[\"age\"] = p.age;\n    }\n};\n} // namespace nlohmann\n\nint main()\n{\n    json j;\n    j[\"name\"] = \"Ned Flanders\";\n    j[\"address\"] = \"744 Evergreen Terrace\";\n    j[\"age\"] = 60;\n\n    auto p = j.get<ns::person>();\n\n    std::cout << p.name << \" (\" << p.age << \") lives in \" << p.address << '\\n';\n}\n

Output:

Ned Flanders (60) lives in 744 Evergreen Terrace\n
"},{"location":"api/basic_json/json_serializer/#see-also","title":"See also","text":"
  • adl_serializer - the default json_serializer
  • get - explicit type conversion using the json_serializer's from_json() method
  • get_to - explicit type conversion into a variable using the json_serializer's from_json() method
  • Arbitrary Type Conversions - the article on converting between JSON values and arbitrary types
  • Template Parameter Requirements - requirements on the JSONSerializer template parameter
"},{"location":"api/basic_json/json_serializer/#version-history","title":"Version history","text":"
  • Added in version 2.1.0.
"},{"location":"api/basic_json/max_size/","title":"nlohmann::basic_json::max_size","text":"
size_type max_size() const noexcept;\n

Returns the maximum number of elements a JSON value is able to hold due to system or library implementation limitations, i.e. std::distance(begin(), end()) for the JSON value.

"},{"location":"api/basic_json/max_size/#return-value","title":"Return value","text":"

The return value depends on the different types and is defined as follows:

Value type return value null 0 (same as size()) boolean 1 (same as size()) string 1 (same as size()) number 1 (same as size()) binary 1 (same as size()) object result of function object_t::max_size() array result of function array_t::max_size()"},{"location":"api/basic_json/max_size/#exception-safety","title":"Exception safety","text":"

No-throw guarantee: this function never throws exceptions.

"},{"location":"api/basic_json/max_size/#complexity","title":"Complexity","text":"

Constant, as long as array_t and object_t satisfy the Container concept; that is, their max_size() functions have constant complexity.

"},{"location":"api/basic_json/max_size/#notes","title":"Notes","text":"

This function does not return the maximal length of a string stored as JSON value \u2014 it returns the maximal number of string elements the JSON value can store which is 1.

"},{"location":"api/basic_json/max_size/#examples","title":"Examples","text":"Example

The following code calls max_size() on the different value types.

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create JSON values\n    json j_null;\n    json j_boolean = true;\n    json j_number_integer = 17;\n    json j_number_float = 23.42;\n    json j_object = {{\"one\", 1}, {\"two\", 2}};\n    json j_array = {1, 2, 4, 8, 16};\n    json j_string = \"Hello, world\";\n\n    // call max_size()\n    std::cout << j_null.max_size() << '\\n';\n    std::cout << j_boolean.max_size() << '\\n';\n    std::cout << j_number_integer.max_size() << '\\n';\n    std::cout << j_number_float.max_size() << '\\n';\n    std::cout << j_object.max_size() << '\\n';\n    std::cout << j_array.max_size() << '\\n';\n    std::cout << j_string.max_size() << '\\n';\n}\n

Output:

0\n1\n1\n1\n115292150460684697\n576460752303423487\n1\n

Note the output is platform-dependent.

"},{"location":"api/basic_json/max_size/#see-also","title":"See also","text":"
  • size - returns the number of elements
  • array_t - the type used to store JSON arrays
  • object_t - the type used to store JSON objects
"},{"location":"api/basic_json/max_size/#version-history","title":"Version history","text":"
  • Added in version 1.0.0.
  • Extended to return 1 for binary types in version 3.8.0.
"},{"location":"api/basic_json/merge_diff/","title":"nlohmann::basic_json::merge_diff","text":"
static basic_json merge_diff(const basic_json& source,\n                             const basic_json& target);\n

Creates a JSON Merge Patch so that value source can be changed into the value target by calling the merge_patch function. The patch contains only what differs: changed and added members with their new values, and removed members with the value null. Nested objects are compared member by member; any other value that differs, including an array, is replaced as a whole.

For two JSON values source and target, where target contains no object member whose value is null, the following code always yields true (for ordered_json, see the notes below):

basic_json patched = source;\npatched.merge_patch(merge_diff(source, target));\npatched == target;\n

"},{"location":"api/basic_json/merge_diff/#parameters","title":"Parameters","text":"source (in) JSON value to compare from target (in) JSON value to compare against"},{"location":"api/basic_json/merge_diff/#return-value","title":"Return value","text":"

a JSON Merge Patch to convert the source to target

"},{"location":"api/basic_json/merge_diff/#exception-safety","title":"Exception safety","text":"

Strong guarantee: source and target are never modified.

"},{"location":"api/basic_json/merge_diff/#complexity","title":"Complexity","text":"

Linear in the total number of values (including nested ones) in source and target, times the cost of a key-based object operation (looking up a key, or adding one to the patch): logarithmic for json, and linear for ordered_json (see ordered_map complexity). For ordered_json, diffing two objects with n and m members therefore takes O((n+m)\u00b2).

"},{"location":"api/basic_json/merge_diff/#notes","title":"Notes","text":"
  • A merge patch uses null to remove a member, so it cannot set a member to null. As in RFC 7396, a null member of target is treated as absent: the patch removes the member from source instead of setting it to null. A member that is null in both source and target is unchanged and left out of the patch, so source keeps it.
  • A merge patch cannot reorder object members, and merge_patch appends added members at the end. For ordered_json, the patched value therefore has the same members as target, but not necessarily in the same order, and may compare unequal to it. The patch lists changed and removed members in the order of source, followed by added members in the order of target.
"},{"location":"api/basic_json/merge_diff/#examples","title":"Examples","text":"Example

The following code shows how a JSON Merge Patch is created as a diff for two JSON values.

#include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\nusing namespace nlohmann::literals;\n\nint main()\n{\n    // the source document\n    json source = R\"(\n        {\n            \"title\": \"Goodbye!\",\n            \"author\": {\n                \"givenName\": \"John\",\n                \"familyName\": \"Doe\"\n            },\n            \"tags\": [\n                \"example\",\n                \"sample\"\n            ],\n            \"content\": \"This will be unchanged\"\n        }\n    )\"_json;\n\n    // the target document\n    json target = R\"(\n        {\n            \"title\": \"Hello!\",\n            \"author\": {\n                \"givenName\": \"John\"\n            },\n            \"tags\": [\n                \"example\"\n            ],\n            \"content\": \"This will be unchanged\",\n            \"phoneNumber\": \"+01-123-456-7890\"\n        }\n    )\"_json;\n\n    // create the patch\n    json patch = json::merge_diff(source, target);\n\n    // roundtrip\n    json patched_source = source;\n    patched_source.merge_patch(patch);\n\n    // output patch and roundtrip result\n    std::cout << std::setw(4) << patch << \"\\n\\n\"\n              << std::setw(4) << patched_source << '\\n';\n}\n

Output:

{\n    \"author\": {\n        \"familyName\": null\n    },\n    \"phoneNumber\": \"+01-123-456-7890\",\n    \"tags\": [\n        \"example\"\n    ],\n    \"title\": \"Hello!\"\n}\n\n{\n    \"author\": {\n        \"givenName\": \"John\"\n    },\n    \"content\": \"This will be unchanged\",\n    \"phoneNumber\": \"+01-123-456-7890\",\n    \"tags\": [\n        \"example\"\n    ],\n    \"title\": \"Hello!\"\n}\n
"},{"location":"api/basic_json/merge_diff/#see-also","title":"See also","text":"
  • RFC 7396 (JSON Merge Patch) - specification of JSON Merge Patch
  • merge_patch - applies a JSON Merge Patch
  • diff - creates a diff as a JSON Patch
  • JSON Merge Patch - the article on JSON Merge Patch
"},{"location":"api/basic_json/merge_diff/#version-history","title":"Version history","text":"
  • Added in version 3.13.0 unreleased.
"},{"location":"api/basic_json/merge_patch/","title":"nlohmann::basic_json::merge_patch","text":"
void merge_patch(const basic_json& apply_patch);\n

The merge patch format is primarily intended for use with the HTTP PATCH method as a means of describing a set of modifications to a target resource's content. This function applies a merge patch to the current JSON value.

The function implements the following algorithm from Section 2 of RFC 7396 (JSON Merge Patch):

define MergePatch(Target, Patch):\n  if Patch is an Object:\n    if Target is not an Object:\n      Target = {} // Ignore the contents and set it to an empty Object\n    for each Name/Value pair in Patch:\n      if Value is null:\n        if Name exists in Target:\n          remove the Name/Value pair from Target\n      else:\n        Target[Name] = MergePatch(Target[Name], Value)\n    return Target\n  else:\n    return Patch\n

Thereby, Target is the current object; that is, the patch is applied to the current value.

"},{"location":"api/basic_json/merge_patch/#parameters","title":"Parameters","text":"apply_patch (in) the patch to apply"},{"location":"api/basic_json/merge_patch/#exception-safety","title":"Exception safety","text":"

Basic guarantee: if an exception is thrown during the operation, the JSON value may be partially modified.

"},{"location":"api/basic_json/merge_patch/#complexity","title":"Complexity","text":"

Linear in the total number of values (including nested ones) in apply_patch, times the cost of a key-based object operation (looking up, adding, or erasing a member): logarithmic for json, and linear for ordered_json (see ordered_map complexity). For ordered_json, patching an object that has n members with a patch that has m members therefore takes O(n\u00b7m). The cost also includes one copy of apply_patch (see the notes below).

"},{"location":"api/basic_json/merge_patch/#notes","title":"Notes","text":"
  • apply_patch may be *this itself or refer to a value contained in *this (for example, a subobject returned by (*this)[key]); it is read as it was when merge_patch() was called, before any modification of *this. To make this possible, the function copies apply_patch before it modifies *this, so the cost includes one copy of the patch.
  • A merge patch uses null to remove a member, so it cannot set a member to null: applying {\"a\":null} to {\"a\":1} gives {}.
  • Arrays are not merged: an array in the patch replaces the target value as a whole, and a null inside an array is kept as an element. null members of the target that the patch does not mention are preserved.
  • A null in the patch only removes a member; it does not prevent the creation of the enclosing objects. Applying {\"a\":{\"b\":null}} to {} gives {\"a\":{}} (see example 15 in Appendix A of the RFC).
  • If apply_patch is not an object, it replaces the target as a whole. In particular, a null patch turns the target into null. If apply_patch is an object and the target is not, the target is first replaced by an empty object, so applying {} to 1 gives {}.
  • A merge patch cannot express every change; for example, it cannot reorder array elements or remove a specific array element. Use JSON Patch (RFC 6902) for that. merge_diff has a matching limitation, see its notes.
  • A discarded value is treated like any other non-object value: a discarded apply_patch turns the target into a discarded value, and an object patch replaces a discarded target by an object as described above.
"},{"location":"api/basic_json/merge_patch/#examples","title":"Examples","text":"Example

The following code shows how a JSON Merge Patch is applied to a JSON document.

#include <iostream>\n#include <nlohmann/json.hpp>\n#include <iomanip> // for std::setw\n\nusing nlohmann::json;\nusing namespace nlohmann::literals;\n\nint main()\n{\n    // the original document\n    json document = R\"({\n                \"title\": \"Goodbye!\",\n                \"author\": {\n                    \"givenName\": \"John\",\n                    \"familyName\": \"Doe\"\n                },\n                \"tags\": [\n                    \"example\",\n                    \"sample\"\n                ],\n                \"content\": \"This will be unchanged\"\n            })\"_json;\n\n    // the patch\n    json patch = R\"({\n                \"title\": \"Hello!\",\n                \"phoneNumber\": \"+01-123-456-7890\",\n                \"author\": {\n                    \"familyName\": null\n                },\n                \"tags\": [\n                    \"example\"\n                ]\n            })\"_json;\n\n    // apply the patch\n    document.merge_patch(patch);\n\n    // output original and patched document\n    std::cout << std::setw(4) << document << '\\n';\n}\n

Output:

{\n    \"author\": {\n        \"givenName\": \"John\"\n    },\n    \"content\": \"This will be unchanged\",\n    \"phoneNumber\": \"+01-123-456-7890\",\n    \"tags\": [\n        \"example\"\n    ],\n    \"title\": \"Hello!\"\n}\n
"},{"location":"api/basic_json/merge_patch/#see-also","title":"See also","text":"
  • RFC 7396 (JSON Merge Patch) - specification of JSON Merge Patch
  • patch - apply a JSON patch
  • merge_diff - creates a diff as a JSON Merge Patch
  • JSON Merge Patch - the article on JSON Merge Patch
"},{"location":"api/basic_json/merge_patch/#version-history","title":"Version history","text":"
  • Added in version 3.1.0.
  • Fixed use of freed or relocated memory when apply_patch is *this or refers to a value contained in *this, in version 3.13.0 unreleased.
"},{"location":"api/basic_json/meta/","title":"nlohmann::basic_json::meta","text":"
static basic_json meta();\n

This function returns a JSON object with information about the library, including the version number and information on the platform and compiler.

"},{"location":"api/basic_json/meta/#return-value","title":"Return value","text":"

JSON object holding version information

key description compiler Information on the used compiler. It is an object with the following keys: c++ (the used C++ standard), family (the compiler family; possible values are clang, icc, gcc, hp, ilecpp, msvc, pgcpp, sunpro, and unknown), and version (the compiler version). copyright The copyright line for the library as string. name The name of the library as string. platform The used platform as string. Possible values are win32, linux, apple, unix, and unknown. url The URL of the project as string. version The version of the library. It is an object with the following keys: major, minor, and patch as defined by Semantic Versioning, and string (the version string)."},{"location":"api/basic_json/meta/#exception-safety","title":"Exception safety","text":"

Strong guarantee: if an exception is thrown, there are no changes to any JSON value.

"},{"location":"api/basic_json/meta/#complexity","title":"Complexity","text":"

Constant.

"},{"location":"api/basic_json/meta/#examples","title":"Examples","text":"Example

The following code shows an example output of the meta() function.

#include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // call meta()\n    std::cout << std::setw(4) << json::meta() << '\\n';\n}\n

Output:

{\n    \"compiler\": {\n        \"c++\": \"201103\",\n        \"family\": \"gcc\",\n        \"version\": \"12.4.0\"\n    },\n    \"copyright\": \"(C) 2013-2026 Niels Lohmann\",\n    \"name\": \"JSON for Modern C++\",\n    \"platform\": \"apple\",\n    \"url\": \"https://github.com/nlohmann/json\",\n    \"version\": {\n        \"major\": 3,\n        \"minor\": 12,\n        \"patch\": 0,\n        \"string\": \"3.12.0\"\n    }\n}\n

Note the output is platform-dependent.

"},{"location":"api/basic_json/meta/#see-also","title":"See also","text":"
  • NLOHMANN_JSON_VERSION_MAJOR / NLOHMANN_JSON_VERSION_MINOR / NLOHMANN_JSON_VERSION_PATCH - library version information
  • Integration - integrate the library
  • Supported Macros - guide to all supported macros
"},{"location":"api/basic_json/meta/#version-history","title":"Version history","text":"
  • Added in version 2.1.0.
"},{"location":"api/basic_json/number_float_t/","title":"nlohmann::basic_json::number_float_t","text":"
using number_float_t = NumberFloatType;\n

The type used to store JSON numbers (floating-point).

RFC 8259 describes numbers as follows:

The representation of numbers is similar to that used in most programming languages. A number is represented in base 10 using decimal digits. It contains an integer component that may be prefixed with an optional minus sign, which may be followed by a fraction part and/or an exponent part. Leading zeros are not allowed. (...) Numeric values that cannot be represented in the grammar below (such as Infinity and NaN) are not permitted.

This description includes both integer and floating-point numbers. However, C++ allows more precise storage if it is known whether the number is a signed integer, an unsigned integer, or a floating-point number. Therefore, three different types, number_integer_t, number_unsigned_t and number_float_t are used.

To store floating-point numbers in C++, a type is defined by the template parameter NumberFloatType which chooses the type to use.

"},{"location":"api/basic_json/number_float_t/#template-parameters","title":"Template parameters","text":"NumberFloatType the type to store floating-point numbers. The type must be float, double, or long double. The parser converts float, double, and a long double that is IEEE 754 binary64 itself. It converts other long double formats with std::from_chars where available, or with std::strtold otherwise. Serialization falls back to std::snprintf. The binary formats additionally require float or double, because they have no encoding for long double. See Template Parameter Requirements."},{"location":"api/basic_json/number_float_t/#notes","title":"Notes","text":""},{"location":"api/basic_json/number_float_t/#default-type","title":"Default type","text":"

With the default values for NumberFloatType (double), the default type for number_float_t is double.

"},{"location":"api/basic_json/number_float_t/#default-behavior","title":"Default behavior","text":"
  • 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.
"},{"location":"api/basic_json/number_float_t/#limits","title":"Limits","text":"

RFC 8259 states:

This specification allows implementations to set limits on the range and precision of numbers accepted. Since software that implements IEEE 754-2008 binary64 (double precision) numbers is generally available and widely used, good interoperability can be achieved by implementations that expect no more precision or range than these provide, in the sense that implementations will approximate JSON numbers within the expected precision.

This implementation does exactly follow this approach, as it uses double precision floating-point numbers by default. Note that with the default double, numbers smaller than -1.79769313486232e+308 or greater than 1.79769313486232e+308 are rejected during parsing with out_of_range.406. Non-finite values (NaN and infinity) can only be stored by assigning them directly and are serialized to null.

During deserialization (from JSON text or any of the binary formats), a finite number that does not fit into number_float_t is rejected with out_of_range.406, for example a double-precision number in a binary format when number_float_t is float.

"},{"location":"api/basic_json/number_float_t/#storage","title":"Storage","text":"

Floating-point number values are stored directly inside a basic_json type.

"},{"location":"api/basic_json/number_float_t/#examples","title":"Examples","text":"Example

The following code shows that number_float_t is by default, a typedef to double.

#include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    std::cout << std::boolalpha << std::is_same<double, json::number_float_t>::value << '\\n';\n}\n

Output:

true\n
"},{"location":"api/basic_json/number_float_t/#see-also","title":"See also","text":"
  • number_integer_t - the type used to store JSON integer numbers
  • number_unsigned_t - the type used to store JSON unsigned integer numbers
  • is_number_float - checks whether the JSON value is a floating-point number
  • Number Handling - the article on number handling
  • Template Parameter Requirements - requirements on the number template parameters
"},{"location":"api/basic_json/number_float_t/#version-history","title":"Version history","text":"
  • Added in version 1.0.0.
"},{"location":"api/basic_json/number_integer_t/","title":"nlohmann::basic_json::number_integer_t","text":"
using number_integer_t = NumberIntegerType;\n

The type used to store JSON numbers (integers).

RFC 8259 describes numbers as follows:

The representation of numbers is similar to that used in most programming languages. A number is represented in base 10 using decimal digits. It contains an integer component that may be prefixed with an optional minus sign, which may be followed by a fraction part and/or an exponent part. Leading zeros are not allowed. (...) Numeric values that cannot be represented in the grammar below (such as Infinity and NaN) are not permitted.

This description includes both integer and floating-point numbers. However, C++ allows more precise storage if it is known whether the number is a signed integer, an unsigned integer, or a floating-point number. Therefore, three different types, number_integer_t, number_unsigned_t and number_float_t are used.

To store integer numbers in C++, a type is defined by the template parameter NumberIntegerType which chooses the type to use.

"},{"location":"api/basic_json/number_integer_t/#template-parameters","title":"Template parameters","text":"NumberIntegerType the type to store signed integers. It must be a signed integral type (std::is_integral) with a std::numeric_limits specialization, and it is stored directly inside a basic_json value. See Template Parameter Requirements."},{"location":"api/basic_json/number_integer_t/#notes","title":"Notes","text":""},{"location":"api/basic_json/number_integer_t/#default-type","title":"Default type","text":"

With the default values for NumberIntegerType (std::int64_t), the default type for number_integer_t is std::int64_t.

"},{"location":"api/basic_json/number_integer_t/#default-behavior","title":"Default behavior","text":"
  • 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.
"},{"location":"api/basic_json/number_integer_t/#limits","title":"Limits","text":"

RFC 8259 specifies:

An implementation may set limits on the range and precision of numbers.

When the default type is used, the maximal integer number that can be stored is 9223372036854775807 (INT64_MAX) and the minimal integer number that can be stored is -9223372036854775808 (INT64_MIN). Integer numbers that are out of range will yield over/underflow when used in a constructor. During deserialization (from JSON text or any of the binary formats), too large or small integer numbers will automatically be stored as number_unsigned_t or number_float_t.

RFC 8259 further states:

Note that when such software is used, numbers that are integers and are in the range [-253+1, 253-1] are interoperable in the sense that implementations will agree exactly on their numeric values.

As this range is a subrange of the exactly supported range [INT64_MIN, INT64_MAX], this class's integer type is interoperable.

"},{"location":"api/basic_json/number_integer_t/#storage","title":"Storage","text":"

Integer number values are stored directly inside a basic_json type.

"},{"location":"api/basic_json/number_integer_t/#examples","title":"Examples","text":"Example

The following code shows that number_integer_t is by default, a typedef to std::int64_t.

#include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    std::cout << std::boolalpha << std::is_same<std::int64_t, json::number_integer_t>::value << '\\n';\n}\n

Output:

true\n
"},{"location":"api/basic_json/number_integer_t/#see-also","title":"See also","text":"
  • number_unsigned_t - the type used to store JSON unsigned integer numbers
  • number_float_t - the type used to store JSON floating-point numbers
  • is_number_integer - checks whether the JSON value is a signed integer number
  • Number Handling - the article on number handling
  • Template Parameter Requirements - requirements on the number template parameters
"},{"location":"api/basic_json/number_integer_t/#version-history","title":"Version history","text":"
  • Added in version 1.0.0.
"},{"location":"api/basic_json/number_unsigned_t/","title":"nlohmann::basic_json::number_unsigned_t","text":"
using number_unsigned_t = NumberUnsignedType;\n

The type used to store JSON numbers (unsigned).

RFC 8259 describes numbers as follows:

The representation of numbers is similar to that used in most programming languages. A number is represented in base 10 using decimal digits. It contains an integer component that may be prefixed with an optional minus sign, which may be followed by a fraction part and/or an exponent part. Leading zeros are not allowed. (...) Numeric values that cannot be represented in the grammar below (such as Infinity and NaN) are not permitted.

This description includes both integer and floating-point numbers. However, C++ allows more precise storage if it is known whether the number is a signed integer, an unsigned integer, or a floating-point number. Therefore, three different types, number_integer_t, number_unsigned_t and number_float_t are used.

To store unsigned integer numbers in C++, a type is defined by the template parameter NumberUnsignedType which chooses the type to use.

"},{"location":"api/basic_json/number_unsigned_t/#template-parameters","title":"Template parameters","text":"NumberUnsignedType the type to store unsigned integers. It must be an unsigned integral type (std::is_integral) with a std::numeric_limits specialization, and it must be able to represent the absolute value of every number_integer_t value. Alternatively, it can be the same type as number_integer_t; then every integer is stored as number_integer_t. See Template Parameter Requirements."},{"location":"api/basic_json/number_unsigned_t/#notes","title":"Notes","text":""},{"location":"api/basic_json/number_unsigned_t/#default-type","title":"Default type","text":"

With the default values for NumberUnsignedType (std::uint64_t), the default type for number_unsigned_t is std::uint64_t.

"},{"location":"api/basic_json/number_unsigned_t/#default-behavior","title":"Default behavior","text":"
  • 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.
"},{"location":"api/basic_json/number_unsigned_t/#limits","title":"Limits","text":"

RFC 8259 specifies:

An implementation may set limits on the range and precision of numbers.

When the default type is used, the maximal integer number that can be stored is 18446744073709551615 (UINT64_MAX) and the minimal integer number that can be stored is 0. Integer numbers that are out of range will yield over/underflow when used in a constructor. During deserialization (from JSON text or any of the binary formats), too large or small integer numbers will automatically be stored as number_integer_t or number_float_t.

RFC 8259 further states:

Note that when such software is used, numbers that are integers and are in the range [-253+1, 253-1] are interoperable in the sense that implementations will agree exactly on their numeric values.

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.

"},{"location":"api/basic_json/number_unsigned_t/#storage","title":"Storage","text":"

Integer number values are stored directly inside a basic_json type.

"},{"location":"api/basic_json/number_unsigned_t/#examples","title":"Examples","text":"Example

The following code shows that number_unsigned_t is by default, a typedef to std::uint64_t.

#include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    std::cout << std::boolalpha << std::is_same<std::uint64_t, json::number_unsigned_t>::value << '\\n';\n}\n

Output:

true\n
"},{"location":"api/basic_json/number_unsigned_t/#see-also","title":"See also","text":"
  • number_integer_t - the type used to store JSON integer numbers
  • number_float_t - the type used to store JSON floating-point numbers
  • is_number_unsigned - checks whether the JSON value is an unsigned integer number
  • Number Handling - the article on number handling
  • Template Parameter Requirements - requirements on the number template parameters
"},{"location":"api/basic_json/number_unsigned_t/#version-history","title":"Version history","text":"
  • Added in version 2.0.0.
  • Can be the same type as number_integer_t since version 3.13.0 unreleased.
"},{"location":"api/basic_json/object/","title":"nlohmann::basic_json::object","text":"
static basic_json object(initializer_list_t init = {});\n

Creates a JSON object value from a given initializer list. The initializer lists elements must be pairs, and their first elements must be strings. If the initializer list is empty, the empty object {} is created.

"},{"location":"api/basic_json/object/#parameters","title":"Parameters","text":"init (in) initializer list with JSON values to create an object from (optional)"},{"location":"api/basic_json/object/#return-value","title":"Return value","text":"

JSON object value

"},{"location":"api/basic_json/object/#exception-safety","title":"Exception safety","text":"

Strong guarantee: if an exception is thrown, there are no changes in the JSON value.

"},{"location":"api/basic_json/object/#exceptions","title":"Exceptions","text":"

Throws type_error.301 if init is not a list of pairs whose first elements are strings. In this case, no object can be created. When such a value is passed to basic_json(initializer_list_t, bool, value_t), an array would have been created from the passed initializer list init. See the example below.

"},{"location":"api/basic_json/object/#complexity","title":"Complexity","text":"

Linear in the size of init.

"},{"location":"api/basic_json/object/#notes","title":"Notes","text":"

This function is only added for symmetry reasons. In contrast to the related function array(initializer_list_t), there are no cases that can only be expressed by this function. That is, any initializer list init can also be passed to the initializer list constructor basic_json(initializer_list_t, bool, value_t).

"},{"location":"api/basic_json/object/#examples","title":"Examples","text":"Example

The following code shows an example for the object function.

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create JSON objects\n    json j_no_init_list = json::object();\n    json j_empty_init_list = json::object({});\n    json j_list_of_pairs = json::object({ {\"one\", 1}, {\"two\", 2} });\n\n    // serialize the JSON objects\n    std::cout << j_no_init_list << '\\n';\n    std::cout << j_empty_init_list << '\\n';\n    std::cout << j_list_of_pairs << '\\n';\n\n    // example for an exception\n    try\n    {\n        // can only create an object from a list of pairs\n        json j_invalid_object = json::object({{ \"one\", 1, 2 }});\n    }\n    catch (const json::type_error& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n}\n

Output:

{}\n{}\n{\"one\":1,\"two\":2}\n[json.exception.type_error.301] cannot create object from initializer list\n
"},{"location":"api/basic_json/object/#see-also","title":"See also","text":"
  • basic_json(initializer_list_t) - create a JSON value from an initializer list
  • array - create a JSON array value from an initializer list
  • Creating JSON values - the article on creating JSON values
"},{"location":"api/basic_json/object/#version-history","title":"Version history","text":"
  • Added in version 1.0.0.
"},{"location":"api/basic_json/object_comparator_t/","title":"nlohmann::basic_json::object_comparator_t","text":"
using object_comparator_t = typename object_t::key_compare;\n// or\nusing object_comparator_t = default_object_comparator_t;\n

The comparator used by object_t. Defined as typename object_t::key_compare if available, and default_object_comparator_t otherwise.

"},{"location":"api/basic_json/object_comparator_t/#examples","title":"Examples","text":"Example

The example below demonstrates the used object comparator.

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    std::cout << std::boolalpha\n              << \"json::object_comparator_t(\\\"one\\\", \\\"two\\\") = \" << json::object_comparator_t{}(\"one\", \"two\") << \"\\n\"\n              << \"json::object_comparator_t(\\\"three\\\", \\\"four\\\") = \" << json::object_comparator_t{}(\"three\", \"four\") << '\\n';\n}\n

Output:

json::object_comparator_t(\"one\", \"two\") = true\njson::object_comparator_t(\"three\", \"four\") = false\n
"},{"location":"api/basic_json/object_comparator_t/#see-also","title":"See also","text":"
  • object_t - the type used to store JSON objects
  • default_object_comparator_t - the fallback comparator used when object_t has no key_compare member type
  • Template Parameter Requirements - requirements on the ObjectType template parameter
  • Object order - preserve the insertion order of keys
"},{"location":"api/basic_json/object_comparator_t/#version-history","title":"Version history","text":"
  • Added in version 3.0.0.
  • Changed to be conditionally defined as typename object_t::key_compare or default_object_comparator_t in version 3.11.0.
  • Fixed the fallback to default_object_comparator_t, which previously failed to compile for object types without a key_compare member type, in version 3.13.0 unreleased.
"},{"location":"api/basic_json/object_t/","title":"nlohmann::basic_json::object_t","text":"
using object_t = ObjectType<StringType,\n                            basic_json,\n                            default_object_comparator_t,\n                            AllocatorType<std::pair<const StringType, basic_json>>>;\n

The type used to store JSON objects.

RFC 8259 describes JSON objects as follows:

An object is an unordered collection of zero or more name/value pairs, where a name is a string and a value is a string, number, boolean, null, object, or array.

To store objects in C++, a type is defined by the template parameters described below.

"},{"location":"api/basic_json/object_t/#template-parameters","title":"Template parameters","text":"ObjectType the container to store objects. Its template parameters must have the same order and meaning as those of std::map; in particular, the third parameter is a comparator. std::unordered_map, whose third parameter is a hash function, therefore needs an adapter \u2014 see Template Parameter Requirements for the full list of requirements, an adapter example, and the containers that are known to work. StringType the type of the keys or names (e.g., std::string). The comparison function std::less<StringType> is used to order elements inside the container. AllocatorType the allocator to use for objects (e.g., std::allocator)"},{"location":"api/basic_json/object_t/#notes","title":"Notes","text":""},{"location":"api/basic_json/object_t/#default-type","title":"Default type","text":"

With the default values for ObjectType (std::map), StringType (std::string), and AllocatorType (std::allocator), the default type for object_t is:

// until C++14\nstd::map<\n  std::string, // key_type\n  basic_json, // value_type\n  std::less<std::string>, // key_compare\n  std::allocator<std::pair<const std::string, basic_json>> // allocator_type\n>\n\n// since C++14\nstd::map<\n  std::string, // key_type\n  basic_json, // value_type\n  std::less<>, // key_compare\n  std::allocator<std::pair<const std::string, basic_json>> // allocator_type\n>\n

See default_object_comparator_t for more information.

"},{"location":"api/basic_json/object_t/#behavior","title":"Behavior","text":"

The choice of object_t influences the behavior of the JSON class. With the default type, objects have the following behavior:

  • When all names are unique, objects will be interoperable in the sense that all software implementations receiving that object will agree on the name-value mappings.
  • When the names within an object are not unique, it is unspecified which one of the values for a given key will be chosen. For instance, {\"key\": 2, \"key\": 1} could be equal to either {\"key\": 1} or {\"key\": 2}. To reject duplicate keys instead of silently resolving them one way or another, see this parsing recipe.
  • Internally, name/value pairs are stored in lexicographical order of the names. Objects will also be serialized (see dump) in this order. For instance, {\"b\": 1, \"a\": 2} and {\"a\": 2, \"b\": 1} will be stored and serialized as {\"a\": 2, \"b\": 1}.
  • When comparing objects, the order of the name/value pairs is irrelevant. This makes objects interoperable in the sense that they will not be affected by these differences. For instance, {\"b\": 1, \"a\": 2} and {\"a\": 2, \"b\": 1} will be treated as equal.
"},{"location":"api/basic_json/object_t/#limits","title":"Limits","text":"

RFC 8259 specifies:

An implementation may set limits on the maximum depth of nesting.

In this class, the object's limit of nesting is not explicitly constrained. However, a maximum depth of nesting may be introduced by the compiler or runtime environment. A theoretical limit can be queried by calling the max_size function of a JSON object.

"},{"location":"api/basic_json/object_t/#storage","title":"Storage","text":"

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.

"},{"location":"api/basic_json/object_t/#object-key-order","title":"Object key order","text":"

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 alphabetical order as std::map with std::less is used by default. Please note this behavior conforms to RFC 8259, because any order implements the specified \"unordered\" nature of JSON objects.

"},{"location":"api/basic_json/object_t/#cross-basic_json-conversion-requirements","title":"Cross-basic_json conversion requirements","text":"

When converting an object from one basic_json specialization to another via the converting constructor (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 issue #3425 for details and an example.

"},{"location":"api/basic_json/object_t/#examples","title":"Examples","text":"Example

The following code shows that object_t is by default, a typedef to std::map<json::string_t, json>.

#include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    std::cout << std::boolalpha << std::is_same<std::map<json::string_t, json>, json::object_t>::value << '\\n';\n}\n

Output:

true\n
"},{"location":"api/basic_json/object_t/#see-also","title":"See also","text":"
  • array_t - the type used to store JSON arrays
  • string_t - the type used to store JSON strings
  • object_comparator_t - the comparator used to order object keys
  • Object Order - the article on object key ordering
  • Types - how objects are stored
  • Template Parameter Requirements - requirements on the ObjectType template parameter
"},{"location":"api/basic_json/object_t/#version-history","title":"Version history","text":"
  • Added in version 1.0.0.
  • Allowed object types whose erase(iterator) returns void in version 3.13.0 unreleased.
"},{"location":"api/basic_json/operator%2B%3D/","title":"nlohmann::basic_json::operator+=","text":"
// (1)\nreference operator+=(basic_json&& val);\nreference operator+=(const basic_json& val);\n\n// (2)\nreference operator+=(const typename object_t::value_type& val);\n\n// (3)\nreference operator+=(initializer_list_t init);\n
  1. Appends the given element val to the end of the JSON array. If the function is called on a JSON null value, an empty array is created before appending val.

  2. Inserts the given element val to the JSON object. If the function is called on a JSON null value, an empty object is created before inserting val.

  3. This function allows using operator+= with an initializer list. In case

    1. the current value is an object,
    2. the initializer list init contains only two elements, and
    3. the first element of init is a string,

    init is converted into an object element and added using operator+=(const typename object_t::value_type&). Otherwise, init is converted to a JSON value and added using operator+=(basic_json&&).

"},{"location":"api/basic_json/operator%2B%3D/#iterator-invalidation","title":"Iterator invalidation","text":"

For all cases where an element is added to an array, a reallocation can happen, in which case all iterators (including the end() iterator) and all references to the elements are invalidated. Otherwise, only the end() iterator is invalidated.

For ordered_json, also adding an element to an object can yield a reallocation which again invalidates all iterators and all references.

"},{"location":"api/basic_json/operator%2B%3D/#parameters","title":"Parameters","text":"val (in) the value to add to the JSON array/object init (in) an initializer list"},{"location":"api/basic_json/operator%2B%3D/#return-value","title":"Return value","text":"

*this

"},{"location":"api/basic_json/operator%2B%3D/#exception-safety","title":"Exception safety","text":"

Strong guarantee: if an exception is thrown, there are no changes to any JSON value. As an exception, a null value is converted to an empty array or object before the element is added and keeps that type if adding the element throws.

"},{"location":"api/basic_json/operator%2B%3D/#exceptions","title":"Exceptions","text":"
  1. Throws type_error.308 when called on a type other than JSON array or null; example: \"cannot use push_back() with number\"
  2. Throws type_error.308 when called on a type other than JSON object or null; example: \"cannot use push_back() with number\"
  3. Throws type_error.308 when called on a type other than JSON array or null; example: \"cannot use push_back() with number\"
"},{"location":"api/basic_json/operator%2B%3D/#complexity","title":"Complexity","text":"
  1. Amortized constant.
  2. Logarithmic in the size of the container, O(log(size())).
  3. Linear in the size of the initializer list init.
"},{"location":"api/basic_json/operator%2B%3D/#notes","title":"Notes","text":"

(3) This function is required to resolve an ambiguous overload error, because pairs like {\"key\", \"value\"} can be both interpreted as object_t::value_type or std::initializer_list<basic_json>, see #235 for more information.

"},{"location":"api/basic_json/operator%2B%3D/#examples","title":"Examples","text":"Example: (1) add element to array

The example shows how push_back() and += can be used to add elements to a JSON array. Note how the null value was silently converted to a JSON array.

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create JSON values\n    json array = {1, 2, 3, 4, 5};\n    json null;\n\n    // print values\n    std::cout << array << '\\n';\n    std::cout << null << '\\n';\n\n    // add values\n    array.push_back(6);\n    array += 7;\n    null += \"first\";\n    null += \"second\";\n\n    // print values\n    std::cout << array << '\\n';\n    std::cout << null << '\\n';\n}\n

Output:

[1,2,3,4,5]\nnull\n[1,2,3,4,5,6,7]\n[\"first\",\"second\"]\n
Example: (2) add element to object

The example shows how push_back() and += can be used to add elements to a JSON object. Note how the null value was silently converted to a JSON object.

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create JSON values\n    json object = {{\"one\", 1}, {\"two\", 2}};\n    json null;\n\n    // print values\n    std::cout << object << '\\n';\n    std::cout << null << '\\n';\n\n    // add values\n    object.push_back(json::object_t::value_type(\"three\", 3));\n    object += json::object_t::value_type(\"four\", 4);\n    null += json::object_t::value_type(\"A\", \"a\");\n    null += json::object_t::value_type(\"B\", \"b\");\n\n    // print values\n    std::cout << object << '\\n';\n    std::cout << null << '\\n';\n}\n

Output:

{\"one\":1,\"two\":2}\nnull\n{\"four\":4,\"one\":1,\"three\":3,\"two\":2}\n{\"A\":\"a\",\"B\":\"b\"}\n
Example: (3) add to object from initializer list

The example shows how initializer lists are treated as objects when possible.

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create JSON values\n    json object = {{\"one\", 1}, {\"two\", 2}};\n    json null;\n\n    // print values\n    std::cout << object << '\\n';\n    std::cout << null << '\\n';\n\n    // add values:\n    object.push_back({\"three\", 3});  // object is extended\n    object += {\"four\", 4};           // object is extended\n    null.push_back({\"five\", 5});     // null is converted to array\n\n    // print values\n    std::cout << object << '\\n';\n    std::cout << null << '\\n';\n\n    // would throw:\n    //object.push_back({1, 2, 3});\n}\n

Output:

{\"one\":1,\"two\":2}\nnull\n{\"four\":4,\"one\":1,\"three\":3,\"two\":2}\n[[\"five\",5]]\n
"},{"location":"api/basic_json/operator%2B%3D/#see-also","title":"See also","text":"
  • emplace_back - add a value to an array
  • push_back - add a value to an array/object
  • Modifying values - the article on modifying values
"},{"location":"api/basic_json/operator%2B%3D/#version-history","title":"Version history","text":"
  1. Added in version 1.0.0.
  2. Added in version 1.0.0.
  3. Added in version 2.0.0.
"},{"location":"api/basic_json/operator%3D/","title":"nlohmann::basic_json::operator=","text":"
basic_json& operator=(basic_json other) noexcept (\n    std::is_nothrow_move_constructible<value_t>::value &&\n    std::is_nothrow_move_assignable<value_t>::value &&\n    std::is_nothrow_move_constructible<json_value>::value &&\n    std::is_nothrow_move_assignable<json_value>::value &&\n    std::is_nothrow_move_assignable<json_base_class_t>::value\n);\n

Copy assignment operator. Copies a JSON value via the \"copy and swap\" strategy: It is expressed in terms of the copy constructor, destructor, and the swap() member function.

"},{"location":"api/basic_json/operator%3D/#parameters","title":"Parameters","text":"other (in) value to copy from"},{"location":"api/basic_json/operator%3D/#exception-safety","title":"Exception safety","text":"

Strong guarantee: if an exception is thrown while copying other, there are no changes to *this.

"},{"location":"api/basic_json/operator%3D/#complexity","title":"Complexity","text":"

Linear.

"},{"location":"api/basic_json/operator%3D/#examples","title":"Examples","text":"Example

The code below shows and example for the copy assignment. It creates a copy of value a which is then swapped with b. Finally, the copy of a (which is the null value after the swap) is destroyed.

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create JSON values\n    json a = 23;\n    json b = 42;\n\n    // copy-assign a to b\n    b = a;\n\n    // serialize the JSON arrays\n    std::cout << a << '\\n';\n    std::cout << b << '\\n';\n}\n

Output:

23\n23\n
"},{"location":"api/basic_json/operator%3D/#see-also","title":"See also","text":"
  • basic_json - create a JSON value
  • swap - exchanges the contents of two JSON values
  • Creating JSON values - ways to create and assign JSON values
"},{"location":"api/basic_json/operator%3D/#version-history","title":"Version history","text":"
  • Added in version 1.0.0.
"},{"location":"api/basic_json/operator%5B%5D/","title":"nlohmann::basic_json::operator[]","text":"
// (1)\nreference operator[](size_type idx);\nconst_reference operator[](size_type idx) const;\n\n// (2)\nreference operator[](typename object_t::key_type key);\nconst_reference operator[](const typename object_t::key_type& key) const;\n\n// (3)\ntemplate<typename KeyType>\nreference operator[](KeyType&& key);\ntemplate<typename KeyType>\nconst_reference operator[](KeyType&& key) const;\n\n// (4)\nreference operator[](const json_pointer& ptr);\nconst_reference operator[](const json_pointer& ptr) const;\n
  1. Returns a reference to the array element at specified location idx.
  2. Returns a reference to the object element with specified key key. The non-const qualified overload takes the key by value.
  3. See 2. This overload is only available if KeyType is comparable with typename object_t::key_type and typename object_comparator_t::is_transparent denotes a type.
  4. Returns a reference to the element with specified JSON pointer ptr.
"},{"location":"api/basic_json/operator%5B%5D/#template-parameters","title":"Template parameters","text":"KeyType A type for an object key other than json_pointer that is comparable with string_t using object_comparator_t. This can also be a string view (C++17)."},{"location":"api/basic_json/operator%5B%5D/#iterator-invalidation","title":"Iterator invalidation","text":"

For the non-const versions 1. and 4., when passing an array index that does not exist, it is created and filled with a null value before a reference to it is returned. For this, a reallocation can happen, in which case all iterators (including the end() iterator) and all references to the elements are invalidated.

For ordered_json, also passing an object key to the non-const versions 2., 3., and 4., a reallocation can happen which again invalidates all iterators and all references.

"},{"location":"api/basic_json/operator%5B%5D/#parameters","title":"Parameters","text":"idx (in) index of the element to access key (in) object key of the element to access ptr (in) JSON pointer to the desired element"},{"location":"api/basic_json/operator%5B%5D/#return-value","title":"Return value","text":"
  1. (const) reference to the element at index idx
  2. (const) reference to the element at key key
  3. (const) reference to the element at key key
  4. (const) reference to the element pointed to by ptr
"},{"location":"api/basic_json/operator%5B%5D/#exception-safety","title":"Exception safety","text":"

Strong exception safety: if an exception occurs, the original value stays intact.

"},{"location":"api/basic_json/operator%5B%5D/#exceptions","title":"Exceptions","text":"
  1. The function can throw the following exceptions:
    • Throws type_error.305 if the JSON value is not an array or null; in that case, using the [] operator with an index makes no sense.
    • Throws 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 throws.)
  2. The function can throw the following exceptions:
    • Throws type_error.305 if the JSON value is not an object or null; in that case, using the [] operator with a key makes no sense.
  3. See 2.
  4. The function can throw the following exceptions:

    • Throws parse_error.106 if an array index in the passed JSON pointer ptr begins with '0'.
    • Throws parse_error.109 if an array index in the passed JSON pointer ptr is not a number.
    • Throws out_of_range.402 if the array index '-' is used in the passed JSON pointer ptr for the const version.
    • Throws out_of_range.404 if the JSON pointer ptr can not be resolved.
    • Throws out_of_range.410 if an array index in the passed JSON pointer ptr exceeds the range of size_type (e.g., on 32-bit platforms).

    For the const version, an object key or array index in ptr that does not exist is not reported by an exception, but is undefined behavior (see the notes below). Use at for checked access.

"},{"location":"api/basic_json/operator%5B%5D/#complexity","title":"Complexity","text":"
  1. Constant if idx is in the range of the array. Otherwise, linear in idx - size().
  2. Logarithmic in the size of the container.
  3. Logarithmic in the size of the container.
  4. Logarithmic in the size of the container.
"},{"location":"api/basic_json/operator%5B%5D/#notes","title":"Notes","text":"

Undefined behavior and runtime assertions

The following cases apply to the const overloads; the non-const overloads instead insert the missing element (see the notes below).

  1. If the element at index idx does not exist, the behavior is undefined and is guarded by a runtime assertion!
  2. If the element with key key does not exist, the behavior is undefined and is guarded by a runtime assertion!
  3. If the JSON pointer ptr refers to an object key or an array index that does not exist, the behavior is undefined and is guarded by a runtime assertion!
  1. The non-const version may add values: If idx is beyond the range of the array (i.e., idx >= size()), then the array is silently filled up with null values to make idx a valid reference to the last stored element. In case the value was null before, it is converted to an array.

  2. If key is not found in the object, then it is silently added to the object and filled with a null value to make key a valid reference. In case the value was null before, it is converted to an object.

  3. See 2.

  4. null values are created in arrays and objects if necessary.

    In particular:

    • If the JSON pointer points to an object key that does not exist, it is created and filled with a null value before a reference to it is returned.
    • If the JSON pointer points to an array index that does not exist, it is created and filled with a null value before a reference to it is returned. All indices between the current maximum and the given index are also filled with null.
    • The special value - is treated as a synonym for the index past the end.

    Creating intermediate levels that don't exist yet

    When the JSON pointer traverses intermediate levels that don't exist at all yet (not just a missing leaf), each missing level is created as an array or an object depending on whether the corresponding pointer token is a valid array index: the token 0, a sequence of digits that does not begin with 0, or the token - creates an array, and every other token creates an object. For example, on an initially null value, /foo/0/0/0 creates nested arrays, while /foo/one/one/one creates nested objects. Tokens such as 01 or the empty token cannot be array indices (cf. RFC 6901, Sect. 4) and therefore create objects, just as they would if the level already existed as an object. This is not specified by the JSON Pointer RFC; it is this library's own, intentional disambiguation rule. See also JSON Pointer.

Deprecation

Overload (4) also accepts a json_pointer 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 for how to update existing code.

"},{"location":"api/basic_json/operator%5B%5D/#examples","title":"Examples","text":"Example: (1) access specified array element

The example below shows how array elements can be read and written using [] operator. Note the addition of null values.

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create a JSON array\n    json array = {1, 2, 3, 4, 5};\n\n    // output element at index 3 (fourth element)\n    std::cout << array[3] << '\\n';\n\n    // change last element to 6\n    array[array.size() - 1] = 6;\n\n    // output changed array\n    std::cout << array << '\\n';\n\n    // write beyond array limit\n    array[10] = 11;\n\n    // output changed array\n    std::cout << array << '\\n';\n}\n

Output:

4\n[1,2,3,4,6]\n[1,2,3,4,6,null,null,null,null,null,11]\n
Example: (1) access specified array element (const)

The example below shows how array elements can be read using the [] operator.

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create JSON array\n    const json array = {\"first\", \"2nd\", \"third\", \"fourth\"};\n\n    // output element at index 2 (third element)\n    std::cout << array.at(2) << '\\n';\n}\n

Output:

\"third\"\n
Example: (2) access specified object element

The example below shows how object elements can be read and written using the [] operator.

#include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create a JSON object\n    json object =\n    {\n        {\"one\", 1}, {\"two\", 2}, {\"three\", 2.9}\n    };\n\n    // output element with key \"two\"\n    std::cout << object[\"two\"] << \"\\n\\n\";\n\n    // change element with key \"three\"\n    object[\"three\"] = 3;\n\n    // output changed array\n    std::cout << std::setw(4) << object << \"\\n\\n\";\n\n    // mention nonexisting key\n    object[\"four\"];\n\n    // write to nonexisting key\n    object[\"five\"][\"really\"][\"nested\"] = true;\n\n    // output changed object\n    std::cout << std::setw(4) << object << '\\n';\n}\n

Output:

2\n\n{\n    \"one\": 1,\n    \"three\": 3,\n    \"two\": 2\n}\n\n{\n    \"five\": {\n        \"really\": {\n            \"nested\": true\n        }\n    },\n    \"four\": null,\n    \"one\": 1,\n    \"three\": 3,\n    \"two\": 2\n}\n
Example: (2) access specified object element (const)

The example below shows how object elements can be read using the [] operator.

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create a JSON object\n    const json object =\n    {\n        {\"one\", 1}, {\"two\", 2}, {\"three\", 2.9}\n    };\n\n    // output element with key \"two\"\n    std::cout << object[\"two\"] << '\\n';\n}\n

Output:

2\n
Example: (3) access specified object element using string_view

The example below shows how object elements can be read using the [] operator.

#include <iostream>\n#include <iomanip>\n#include <string_view>\n#include <nlohmann/json.hpp>\n\nusing namespace std::string_view_literals;\nusing nlohmann::json;\n\nint main()\n{\n    // create a JSON object\n    json object =\n    {\n        {\"one\", 1}, {\"two\", 2}, {\"three\", 2.9}\n    };\n\n    // output element with key \"two\"\n    std::cout << object[\"two\"sv] << \"\\n\\n\";\n\n    // change element with key \"three\"\n    object[\"three\"sv] = 3;\n\n    // output changed array\n    std::cout << std::setw(4) << object << \"\\n\\n\";\n\n    // mention nonexisting key\n    object[\"four\"sv];\n\n    // write to nonexisting key\n    object[\"five\"sv][\"really\"sv][\"nested\"sv] = true;\n\n    // output changed object\n    std::cout << std::setw(4) << object << '\\n';\n}\n

Output:

2\n\n{\n    \"one\": 1,\n    \"three\": 3,\n    \"two\": 2\n}\n\n{\n    \"five\": {\n        \"really\": {\n            \"nested\": true\n        }\n    },\n    \"four\": null,\n    \"one\": 1,\n    \"three\": 3,\n    \"two\": 2\n}\n
Example: (3) access specified object element using string_view (const)

The example below shows how object elements can be read using the [] operator.

#include <iostream>\n#include <string_view>\n#include <nlohmann/json.hpp>\n\nusing namespace std::string_view_literals;\nusing nlohmann::json;\n\nint main()\n{\n    // create a JSON object\n    const json object =\n    {\n        {\"one\", 1}, {\"two\", 2}, {\"three\", 2.9}\n    };\n\n    // output element with key \"two\"\n    std::cout << object[\"two\"sv] << '\\n';\n}\n

Output:

2\n
Example: (4) access specified element via JSON Pointer

The example below shows how values can be read and written using JSON Pointers.

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\nusing namespace nlohmann::literals;\n\nint main()\n{\n    // create a JSON value\n    json j =\n    {\n        {\"number\", 1}, {\"string\", \"foo\"}, {\"array\", {1, 2}}\n    };\n\n    // read-only access\n\n    // output element with JSON pointer \"/number\"\n    std::cout << j[\"/number\"_json_pointer] << '\\n';\n    // output element with JSON pointer \"/string\"\n    std::cout << j[\"/string\"_json_pointer] << '\\n';\n    // output element with JSON pointer \"/array\"\n    std::cout << j[\"/array\"_json_pointer] << '\\n';\n    // output element with JSON pointer \"/array/1\"\n    std::cout << j[\"/array/1\"_json_pointer] << '\\n';\n\n    // writing access\n\n    // change the string\n    j[\"/string\"_json_pointer] = \"bar\";\n    // output the changed string\n    std::cout << j[\"string\"] << '\\n';\n\n    // \"change\" a nonexisting object entry\n    j[\"/boolean\"_json_pointer] = true;\n    // output the changed object\n    std::cout << j << '\\n';\n\n    // change an array element\n    j[\"/array/1\"_json_pointer] = 21;\n    // \"change\" an array element with nonexisting index\n    j[\"/array/4\"_json_pointer] = 44;\n    // output the changed array\n    std::cout << j[\"array\"] << '\\n';\n\n    // \"change\" the array element past the end\n    j[\"/array/-\"_json_pointer] = 55;\n    // output the changed array\n    std::cout << j[\"array\"] << '\\n';\n}\n

Output:

1\n\"foo\"\n[1,2]\n2\n\"bar\"\n{\"array\":[1,2],\"boolean\":true,\"number\":1,\"string\":\"bar\"}\n[1,21,null,null,44]\n[1,21,null,null,44,55]\n
Example: (4) access specified element via JSON Pointer (const)

The example below shows how values can be read using JSON Pointers.

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\nusing namespace nlohmann::literals;\n\nint main()\n{\n    // create a JSON value\n    const json j =\n    {\n        {\"number\", 1}, {\"string\", \"foo\"}, {\"array\", {1, 2}}\n    };\n\n    // read-only access\n\n    // output element with JSON pointer \"/number\"\n    std::cout << j[\"/number\"_json_pointer] << '\\n';\n    // output element with JSON pointer \"/string\"\n    std::cout << j[\"/string\"_json_pointer] << '\\n';\n    // output element with JSON pointer \"/array\"\n    std::cout << j[\"/array\"_json_pointer] << '\\n';\n    // output element with JSON pointer \"/array/1\"\n    std::cout << j[\"/array/1\"_json_pointer] << '\\n';\n}\n

Output:

1\n\"foo\"\n[1,2]\n2\n
"},{"location":"api/basic_json/operator%5B%5D/#see-also","title":"See also","text":"
  • Unchecked access - element access without range checking
  • Runtime assertions - assertions guarding against undefined behavior
  • at - access by reference with range checking
  • value - access with default value
  • basic_json_view::operator[] - the same access on a zero-copy view (a duplicate key resolves to the first member, whereas parse() keeps the last; a missing key gives a discarded view instead of undefined behavior)
  • Element Access - overview of all ways to access elements
  • JSON Pointer - access nested values with a pointer
"},{"location":"api/basic_json/operator%5B%5D/#version-history","title":"Version history","text":"
  1. Added in version 1.0.0. Fixed in version 3.13.0 unreleased to throw std::length_error instead of emptying the array and accessing it out of bounds when idx equals the maximum value of size_type. A missing index in the const version is guarded by a runtime assertion since version 3.13.0 unreleased.
  2. Added in version 1.0.0. Added overloads for T* key in version 1.1.0. The T* key overloads forward to overload 3 since version 3.11.0.
  3. Added in version 3.11.0. Support for keys convertible to std::string_view added in version 3.13.0 unreleased, consistently across the lookup functions.
  4. Added in version 2.0.0. A missing array index in the const version is guarded by a runtime assertion since version 3.13.0 unreleased. Throws parse_error.109 instead of out_of_range.404 for a one-character array index that is not a digit (e.g., /x) in version 3.13.0 unreleased, as it already did for longer ones.
"},{"location":"api/basic_json/operator_ValueType/","title":"nlohmann::basic_json::operator ValueType","text":"
template<typename ValueType>\nJSON_EXPLICIT operator ValueType() const;\n

Implicit type conversion between the JSON value and a compatible value. The call is realized by calling get(). See Notes for the meaning of JSON_EXPLICIT.

"},{"location":"api/basic_json/operator_ValueType/#template-parameters","title":"Template parameters","text":"ValueType the value type to return"},{"location":"api/basic_json/operator_ValueType/#return-value","title":"Return value","text":"

copy of the JSON value, converted to ValueType

"},{"location":"api/basic_json/operator_ValueType/#exception-safety","title":"Exception safety","text":"

Depends on what json_serializer<ValueType> from_json() method throws; the JSON value itself is never modified, since operator ValueType() is a const member function that only calls get().

"},{"location":"api/basic_json/operator_ValueType/#exceptions","title":"Exceptions","text":"

Depends on what json_serializer<ValueType> from_json() method throws

"},{"location":"api/basic_json/operator_ValueType/#complexity","title":"Complexity","text":"

Linear in the size of the JSON value.

"},{"location":"api/basic_json/operator_ValueType/#notes","title":"Notes","text":"

Definition of JSON_EXPLICIT

By default JSON_EXPLICIT is defined to the empty string, so the signature is:

template<typename ValueType>\noperator ValueType() const;\n

If JSON_USE_IMPLICIT_CONVERSIONS is set to 0, JSON_EXPLICIT is defined to explicit:

template<typename ValueType>\nexplicit operator ValueType() const;\n

That is, implicit conversions can be switched off by defining JSON_USE_IMPLICIT_CONVERSIONS to 0.

Future behavior change

Implicit conversions will be switched off by default in the next major release of the library. That is, JSON_EXPLICIT will be set to explicit by default.

You can prepare existing code by already defining JSON_USE_IMPLICIT_CONVERSIONS to 0 and replace any implicit conversions with calls to get.

See the migration guide for how to update existing code.

"},{"location":"api/basic_json/operator_ValueType/#examples","title":"Examples","text":"Example

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::map<std::string, json>.

#include <iostream>\n#include <map>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create a JSON value with different types\n    json json_types =\n    {\n        {\"boolean\", true},\n        {\n            \"number\", {\n                {\"integer\", 42},\n                {\"floating-point\", 17.23}\n            }\n        },\n        {\"string\", \"Hello, world!\"},\n        {\"array\", {1, 2, 3, 4, 5}},\n        {\"null\", nullptr}\n    };\n\n    // use implicit conversions\n    bool v1 = json_types[\"boolean\"];\n    int v2 = json_types[\"number\"][\"integer\"];\n    short v3 = json_types[\"number\"][\"integer\"];\n    float v4 = json_types[\"number\"][\"floating-point\"];\n    int v5 = json_types[\"number\"][\"floating-point\"];\n    std::string v6 = json_types[\"string\"];\n    std::vector<short> v7 = json_types[\"array\"];\n    std::map<std::string, json> v8 = json_types;\n\n    // print the conversion results\n    std::cout << v1 << '\\n';\n    std::cout << v2 << ' ' << v3 << '\\n';\n    std::cout << v4 << ' ' << v5 << '\\n';\n    std::cout << v6 << '\\n';\n\n    for (auto i : v7)\n    {\n        std::cout << i << ' ';\n    }\n    std::cout << \"\\n\\n\";\n\n    for (const auto& i : v8)\n    {\n        std::cout << i.first << \": \" << i.second << '\\n';\n    }\n\n    // example for an exception\n    try\n    {\n        bool v1 = json_types[\"string\"];\n    }\n    catch (const json::type_error& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n}\n

Output:

1\n42 42\n17.23 17\nHello, world!\n1 2 3 4 5 \n\narray: [1,2,3,4,5]\nboolean: true\nnull: null\nnumber: {\"floating-point\":17.23,\"integer\":42}\nstring: \"Hello, world!\"\n[json.exception.type_error.302] type must be boolean, but is string\n
"},{"location":"api/basic_json/operator_ValueType/#see-also","title":"See also","text":"
  • get - get a value (explicit conversion)
  • Converting values - the type conversions article
"},{"location":"api/basic_json/operator_ValueType/#version-history","title":"Version history","text":"
  • Added in version 1.0.0.
  • Macros JSON_EXPLICIT/JSON_USE_IMPLICIT_CONVERSIONS added in version 3.9.0.
"},{"location":"api/basic_json/operator_eq/","title":"nlohmann::basic_json::operator==","text":"
// until C++20\nbool operator==(const_reference lhs, const_reference rhs) noexcept;   // (1)\n\ntemplate<typename ScalarType>\nbool operator==(const_reference lhs, const ScalarType rhs) noexcept(/* see below */); // (2)\n\ntemplate<typename ScalarType>\nbool operator==(ScalarType lhs, const const_reference rhs) noexcept(/* see below */); // (2)\n\n// since C++20\nbool operator==(const_reference rhs) const noexcept;             // (1)\n\ntemplate<typename ScalarType>\nbool operator==(ScalarType rhs) const noexcept(/* see below */); // (2)\n
  1. Compares two JSON values for equality according to the following rules:

    • Two JSON values are equal if (1) neither value is discarded, and (2) they are of the same type and their stored values are the same according to their respective operator==.
    • Integer and floating-point numbers are compared by their exact values, without converting the integer to floating-point. For instance, 9007199254740993 and 9007199254740992.0 are not equal.
  2. Compares a JSON value and a scalar or a scalar and a JSON value for equality by converting the scalar to a JSON value and comparing both JSON values according to 1.

"},{"location":"api/basic_json/operator_eq/#template-parameters","title":"Template parameters","text":"ScalarType a scalar type according to std::is_scalar<ScalarType>::value"},{"location":"api/basic_json/operator_eq/#parameters","title":"Parameters","text":"lhs (in) first value to consider rhs (in) second value to consider"},{"location":"api/basic_json/operator_eq/#return-value","title":"Return value","text":"

whether the values lhs/*this and rhs are equal

"},{"location":"api/basic_json/operator_eq/#exception-safety","title":"Exception safety","text":"
  1. No-throw guarantee: this function never throws exceptions.
  2. No-throw guarantee if converting the scalar to a JSON value cannot throw, as for numbers, Booleans, and nullptr; the function is noexcept exactly in that case. Otherwise, it throws what the conversion throws, for example std::bad_alloc when converting a string, or out_of_range.410 for an enum value not mapped by NLOHMANN_JSON_SERIALIZE_ENUM_STRICT.
"},{"location":"api/basic_json/operator_eq/#complexity","title":"Complexity","text":"

Linear.

"},{"location":"api/basic_json/operator_eq/#notes","title":"Notes","text":"

Comparing special values

  • NaN values are unordered within the domain of numbers. The following comparisons all yield false:
    1. Comparing a NaN with itself.
    2. Comparing a NaN with another NaN.
    3. Comparing a NaN and any other number.
  • JSON null values are all equal.
  • Discarded values never compare equal to themselves.

Comparing floating-point numbers

Floating-point numbers inside JSON values numbers are compared with json::number_float_t::operator== which is double::operator== by default. To compare floating-point while respecting an epsilon, an alternative comparison function could be used, for instance

template<typename T, typename = typename std::enable_if<std::is_floating_point<T>::value, T>::type>\ninline bool is_same(T a, T b, T epsilon = std::numeric_limits<T>::epsilon()) noexcept\n{\n    return std::abs(a - b) <= epsilon;\n}\n

Or you can define your own equality function like this:

bool my_equal(const_reference lhs, const_reference rhs)\n{\n    const auto lhs_type = lhs.type();\n    const auto rhs_type = rhs.type();\n    if (lhs_type == rhs_type)\n    {\n        switch(lhs_type)\n            // self_defined case\n            case value_t::number_float:\n                return std::abs(lhs - rhs) <= std::numeric_limits<float>::epsilon();\n            // other cases remain the same with the original\n            ...\n    }\n...\n}\n

Comparing different basic_json specializations

Comparing different basic_json specializations can have surprising effects. For instance, the result of comparing the JSON objects

{\n   \"version\": 1,\n   \"type\": \"integer\"\n}\n

and

{\n   \"type\": \"integer\",\n   \"version\": 1\n}\n

depends on whether nlohmann::json or nlohmann::ordered_json is used:

#include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    nlohmann::json uj1 = {{\"version\", 1}, {\"type\", \"integer\"}};\n    nlohmann::json uj2 = {{\"type\", \"integer\"}, {\"version\", 1}};\n\n    nlohmann::ordered_json oj1 = {{\"version\", 1}, {\"type\", \"integer\"}};\n    nlohmann::ordered_json oj2 = {{\"type\", \"integer\"}, {\"version\", 1}};\n\n    std::cout << std::boolalpha << (uj1 == uj2) << '\\n' << (oj1 == oj2) << '\\n';\n}\n

Output:

true\nfalse\n
"},{"location":"api/basic_json/operator_eq/#examples","title":"Examples","text":"Example: (1) compare JSON values

The example demonstrates comparing several JSON types.

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create several JSON values\n    json array_1 = {1, 2, 3};\n    json array_2 = {1, 2, 4};\n    json object_1 = {{\"A\", \"a\"}, {\"B\", \"b\"}};\n    json object_2 = {{\"B\", \"b\"}, {\"A\", \"a\"}};\n    json number_1 = 17;\n    json number_2 = 17.000000000000001L;\n    json string_1 = \"foo\";\n    json string_2 = \"bar\";\n\n    // output values and comparisons\n    std::cout << std::boolalpha;\n    std::cout << array_1 << \" == \" << array_2 << \" \" << (array_1 == array_2) << '\\n';\n    std::cout << object_1 << \" == \" << object_2 << \" \" << (object_1 == object_2) << '\\n';\n    std::cout << number_1 << \" == \" << number_2 << \" \" << (number_1 == number_2) << '\\n';\n    std::cout << string_1 << \" == \" << string_2 << \" \" << (string_1 == string_2) << '\\n';\n}\n

Output:

[1,2,3] == [1,2,4] false\n{\"A\":\"a\",\"B\":\"b\"} == {\"A\":\"a\",\"B\":\"b\"} true\n17 == 17.0 true\n\"foo\" == \"bar\" false\n
Example: (2) compare JSON values with nullptr

The example demonstrates comparing several JSON types against the null pointer (JSON null).

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create several JSON values\n    json array = {1, 2, 3};\n    json object = {{\"A\", \"a\"}, {\"B\", \"b\"}};\n    json number = 17;\n    json string = \"foo\";\n    json null;\n\n    // output values and comparisons\n    std::cout << std::boolalpha;\n    std::cout << array << \" == nullptr \" << (array == nullptr) << '\\n';\n    std::cout << object << \" == nullptr \" << (object == nullptr) << '\\n';\n    std::cout << number << \" == nullptr \" << (number == nullptr) << '\\n';\n    std::cout << string << \" == nullptr \" << (string == nullptr) << '\\n';\n    std::cout << null << \" == nullptr \" << (null == nullptr) << '\\n';\n}\n

Output:

[1,2,3] == nullptr false\n{\"A\":\"a\",\"B\":\"b\"} == nullptr false\n17 == nullptr false\n\"foo\" == nullptr false\nnull == nullptr true\n
"},{"location":"api/basic_json/operator_eq/#see-also","title":"See also","text":"
  • operator!= - compare for inequality
  • operator<=> - comparison: 3-way (C++20)
  • basic_json_view::operator== - the same comparison on a zero-copy view, without building a basic_json value for it
"},{"location":"api/basic_json/operator_eq/#version-history","title":"Version history","text":"
  1. Added in version 1.0.0. Added C++20 member functions in version 3.11.0.
  2. Added in version 1.0.0. Added C++20 member functions in version 3.11.0. Made conditionally noexcept in version 3.13.0 unreleased; before, a throwing conversion called std::terminate.
"},{"location":"api/basic_json/operator_ge/","title":"nlohmann::basic_json::operator>=","text":"
// until C++20\nbool operator>=(const_reference lhs, const_reference rhs) noexcept;   // (1)\n\ntemplate<typename ScalarType>\nbool operator>=(const_reference lhs, const ScalarType rhs) noexcept(/* see below */); // (2)\n\ntemplate<typename ScalarType>\nbool operator>=(ScalarType lhs, const const_reference rhs) noexcept(/* see below */); // (2)\n
  1. Compares whether one JSON value lhs is greater than or equal to another JSON value rhs according to the following rules:

    • The comparison always yields false if (1) either operand is discarded, or (2) either operand is NaN and the other operand is either NaN or any other number.
    • Otherwise, returns the result of !(lhs < rhs) (see operator<).
  2. Compares whether a JSON value is greater than or equal to a scalar or a scalar is greater than or equal to a JSON value by converting the scalar to a JSON value and comparing both JSON values according to 1.

"},{"location":"api/basic_json/operator_ge/#template-parameters","title":"Template parameters","text":"ScalarType a scalar type according to std::is_scalar<ScalarType>::value"},{"location":"api/basic_json/operator_ge/#parameters","title":"Parameters","text":"lhs (in) first value to consider rhs (in) second value to consider"},{"location":"api/basic_json/operator_ge/#return-value","title":"Return value","text":"

whether lhs is greater than or equal to rhs

"},{"location":"api/basic_json/operator_ge/#exception-safety","title":"Exception safety","text":"
  1. No-throw guarantee: this function never throws exceptions.
  2. No-throw guarantee if converting the scalar to a JSON value cannot throw, as for numbers, Booleans, and nullptr; the function is noexcept exactly in that case. Otherwise, it throws what the conversion throws, for example std::bad_alloc when converting a string, or out_of_range.410 for an enum value not mapped by NLOHMANN_JSON_SERIALIZE_ENUM_STRICT.
"},{"location":"api/basic_json/operator_ge/#complexity","title":"Complexity","text":"

Linear.

"},{"location":"api/basic_json/operator_ge/#notes","title":"Notes","text":"

Comparing NaN

NaN values are unordered within the domain of numbers. The following comparisons all yield false: 1. Comparing a NaN with itself. 2. Comparing a NaN with another NaN. 3. Comparing a NaN and any other number.

Operator overload resolution

Since C++20 overload resolution will consider the rewritten candidate generated from operator<=>.

Deprecation

If JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON is defined to 1, the library declares a member 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 for how to update existing code.

"},{"location":"api/basic_json/operator_ge/#examples","title":"Examples","text":"Example

The example demonstrates comparing several JSON types.

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create several JSON values\n    json array_1 = {1, 2, 3};\n    json array_2 = {1, 2, 4};\n    json object_1 = {{\"A\", \"a\"}, {\"B\", \"b\"}};\n    json object_2 = {{\"B\", \"b\"}, {\"A\", \"a\"}};\n    json number_1 = 17;\n    json number_2 = 17.0000000000001L;\n    json string_1 = \"foo\";\n    json string_2 = \"bar\";\n\n    // output values and comparisons\n    std::cout << std::boolalpha;\n    std::cout << array_1 << \" >= \" << array_2 << \" \" << (array_1 >= array_2) << '\\n';\n    std::cout << object_1 << \" >= \" << object_2 << \" \" << (object_1 >= object_2) << '\\n';\n    std::cout << number_1 << \" >= \" << number_2 << \" \" << (number_1 >= number_2) << '\\n';\n    std::cout << string_1 << \" >= \" << string_2 << \" \" << (string_1 >= string_2) << '\\n';\n}\n

Output:

[1,2,3] >= [1,2,4] false\n{\"A\":\"a\",\"B\":\"b\"} >= {\"A\":\"a\",\"B\":\"b\"} true\n17 >= 17.0000000000001 false\n\"foo\" >= \"bar\" true\n
"},{"location":"api/basic_json/operator_ge/#see-also","title":"See also","text":"
  • operator<=> - comparison: 3-way
"},{"location":"api/basic_json/operator_ge/#version-history","title":"Version history","text":"
  1. Added in version 1.0.0. Conditionally removed since C++20 in version 3.11.0.
  2. Added in version 1.0.0. Conditionally removed since C++20 in version 3.11.0. Made conditionally noexcept in version 3.13.0 unreleased; before, a throwing conversion called std::terminate.
"},{"location":"api/basic_json/operator_gt/","title":"nlohmann::basic_json::operator>","text":"
// until C++20\nbool operator>(const_reference lhs, const_reference rhs) noexcept;   // (1)\n\ntemplate<typename ScalarType>\nbool operator>(const_reference lhs, const ScalarType rhs) noexcept(/* see below */); // (2)\n\ntemplate<typename ScalarType>\nbool operator>(ScalarType lhs, const const_reference rhs) noexcept(/* see below */); // (2)\n
  1. Compares whether one JSON value lhs is greater than another JSON value rhs according to the following rules:

    • The comparison always yields false if (1) either operand is discarded, or (2) either operand is NaN and the other operand is either NaN or any other number.
    • Otherwise, returns the result of !(lhs <= rhs) (see operator<=).
  2. Compares whether a JSON value is greater than a scalar or a scalar is greater than a JSON value by converting the scalar to a JSON value and comparing both JSON values according to 1.

"},{"location":"api/basic_json/operator_gt/#template-parameters","title":"Template parameters","text":"ScalarType a scalar type according to std::is_scalar<ScalarType>::value"},{"location":"api/basic_json/operator_gt/#parameters","title":"Parameters","text":"lhs (in) first value to consider rhs (in) second value to consider"},{"location":"api/basic_json/operator_gt/#return-value","title":"Return value","text":"

whether lhs is greater than rhs

"},{"location":"api/basic_json/operator_gt/#exception-safety","title":"Exception safety","text":"
  1. No-throw guarantee: this function never throws exceptions.
  2. No-throw guarantee if converting the scalar to a JSON value cannot throw, as for numbers, Booleans, and nullptr; the function is noexcept exactly in that case. Otherwise, it throws what the conversion throws, for example std::bad_alloc when converting a string, or out_of_range.410 for an enum value not mapped by NLOHMANN_JSON_SERIALIZE_ENUM_STRICT.
"},{"location":"api/basic_json/operator_gt/#complexity","title":"Complexity","text":"

Linear.

"},{"location":"api/basic_json/operator_gt/#notes","title":"Notes","text":"

Comparing NaN

NaN values are unordered within the domain of numbers. The following comparisons all yield false: 1. Comparing a NaN with itself. 2. Comparing a NaN with another NaN. 3. Comparing a NaN and any other number.

Operator overload resolution

Since C++20 overload resolution will consider the rewritten candidate generated from operator<=>.

"},{"location":"api/basic_json/operator_gt/#examples","title":"Examples","text":"Example

The example demonstrates comparing several JSON types.

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create several JSON values\n    json array_1 = {1, 2, 3};\n    json array_2 = {1, 2, 4};\n    json object_1 = {{\"A\", \"a\"}, {\"B\", \"b\"}};\n    json object_2 = {{\"B\", \"b\"}, {\"A\", \"a\"}};\n    json number_1 = 17;\n    json number_2 = 17.0000000000001L;\n    json string_1 = \"foo\";\n    json string_2 = \"bar\";\n\n    // output values and comparisons\n    std::cout << std::boolalpha;\n    std::cout << array_1 << \" > \" << array_2 << \" \" << (array_1 > array_2) << '\\n';\n    std::cout << object_1 << \" > \" << object_2 << \" \" << (object_1 > object_2) << '\\n';\n    std::cout << number_1 << \" > \" << number_2 << \" \" << (number_1 > number_2) << '\\n';\n    std::cout << string_1 << \" > \" << string_2 << \" \" << (string_1 > string_2) << '\\n';\n}\n

Output:

[1,2,3] > [1,2,4] false\n{\"A\":\"a\",\"B\":\"b\"} > {\"A\":\"a\",\"B\":\"b\"} false\n17 > 17.0000000000001 false\n\"foo\" > \"bar\" true\n
"},{"location":"api/basic_json/operator_gt/#see-also","title":"See also","text":"
  • operator<=> - comparison: 3-way
"},{"location":"api/basic_json/operator_gt/#version-history","title":"Version history","text":"
  1. Added in version 1.0.0. Conditionally removed since C++20 in version 3.11.0.
  2. Added in version 1.0.0. Conditionally removed since C++20 in version 3.11.0. Made conditionally noexcept in version 3.13.0 unreleased; before, a throwing conversion called std::terminate.
"},{"location":"api/basic_json/operator_le/","title":"nlohmann::basic_json::operator<=","text":"
// until C++20\nbool operator<=(const_reference lhs, const_reference rhs) noexcept;   // (1)\n\ntemplate<typename ScalarType>\nbool operator<=(const_reference lhs, const ScalarType rhs) noexcept(/* see below */); // (2)\n\ntemplate<typename ScalarType>\nbool operator<=(ScalarType lhs, const const_reference rhs) noexcept(/* see below */); // (2)\n
  1. Compares whether one JSON value lhs is less than or equal to another JSON value rhs according to the following rules:

    • The comparison always yields false if (1) either operand is discarded, or (2) either operand is NaN and the other operand is either NaN or any other number.
    • Otherwise, returns the result of !(rhs < lhs) (see operator<).
  2. Compares whether a JSON value is less than or equal to a scalar or a scalar is less than or equal to a JSON value by converting the scalar to a JSON value and comparing both JSON values according to 1.

"},{"location":"api/basic_json/operator_le/#template-parameters","title":"Template parameters","text":"ScalarType a scalar type according to std::is_scalar<ScalarType>::value"},{"location":"api/basic_json/operator_le/#parameters","title":"Parameters","text":"lhs (in) first value to consider rhs (in) second value to consider"},{"location":"api/basic_json/operator_le/#return-value","title":"Return value","text":"

whether lhs is less than or equal to rhs

"},{"location":"api/basic_json/operator_le/#exception-safety","title":"Exception safety","text":"
  1. No-throw guarantee: this function never throws exceptions.
  2. No-throw guarantee if converting the scalar to a JSON value cannot throw, as for numbers, Booleans, and nullptr; the function is noexcept exactly in that case. Otherwise, it throws what the conversion throws, for example std::bad_alloc when converting a string, or out_of_range.410 for an enum value not mapped by NLOHMANN_JSON_SERIALIZE_ENUM_STRICT.
"},{"location":"api/basic_json/operator_le/#complexity","title":"Complexity","text":"

Linear.

"},{"location":"api/basic_json/operator_le/#notes","title":"Notes","text":"

Comparing NaN

NaN values are unordered within the domain of numbers. The following comparisons all yield false: 1. Comparing a NaN with itself. 2. Comparing a NaN with another NaN. 3. Comparing a NaN and any other number.

Operator overload resolution

Since C++20 overload resolution will consider the rewritten candidate generated from operator<=>.

Deprecation

If JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON is defined to 1, the library declares a member 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 for how to update existing code.

"},{"location":"api/basic_json/operator_le/#examples","title":"Examples","text":"Example

The example demonstrates comparing several JSON types.

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create several JSON values\n    json array_1 = {1, 2, 3};\n    json array_2 = {1, 2, 4};\n    json object_1 = {{\"A\", \"a\"}, {\"B\", \"b\"}};\n    json object_2 = {{\"B\", \"b\"}, {\"A\", \"a\"}};\n    json number_1 = 17;\n    json number_2 = 17.0000000000001L;\n    json string_1 = \"foo\";\n    json string_2 = \"bar\";\n\n    // output values and comparisons\n    std::cout << std::boolalpha;\n    std::cout << array_1 << \" <= \" << array_2 << \" \" << (array_1 <= array_2) << '\\n';\n    std::cout << object_1 << \" <= \" << object_2 << \" \" << (object_1 <= object_2) << '\\n';\n    std::cout << number_1 << \" <= \" << number_2 << \" \" << (number_1 <= number_2) << '\\n';\n    std::cout << string_1 << \" <= \" << string_2 << \" \" << (string_1 <= string_2) << '\\n';\n}\n

Output:

[1,2,3] <= [1,2,4] true\n{\"A\":\"a\",\"B\":\"b\"} <= {\"A\":\"a\",\"B\":\"b\"} true\n17 <= 17.0000000000001 true\n\"foo\" <= \"bar\" false\n
"},{"location":"api/basic_json/operator_le/#see-also","title":"See also","text":"
  • operator<=> - comparison: 3-way
"},{"location":"api/basic_json/operator_le/#version-history","title":"Version history","text":"
  1. Added in version 1.0.0. Conditionally removed since C++20 in version 3.11.0.
  2. Added in version 1.0.0. Conditionally removed since C++20 in version 3.11.0. Made conditionally noexcept in version 3.13.0 unreleased; before, a throwing conversion called std::terminate.
"},{"location":"api/basic_json/operator_lt/","title":"nlohmann::basic_json::operator<","text":"
// until C++20\nbool operator<(const_reference lhs, const_reference rhs) noexcept;   // (1)\n\ntemplate<typename ScalarType>\nbool operator<(const_reference lhs, const ScalarType rhs) noexcept(/* see below */); // (2)\n\ntemplate<typename ScalarType>\nbool operator<(ScalarType lhs, const const_reference rhs) noexcept(/* see below */); // (2)\n
  1. Compares whether one JSON value lhs is less than another JSON value rhs according to the following rules:

    • If either operand is discarded, the comparison yields false.
    • If both operands have the same type, the values are compared using their respective operator<.
    • Integer and floating-point numbers are compared by their exact values, without converting the integer to floating-point. For instance, 9007199254740992.0 is less than 9007199254740993.
    • In case lhs and rhs have different types, the values are ignored and the order of the types is considered, which is:
      1. null
      2. boolean
      3. number (all types)
      4. object
      5. array
      6. string
      7. binary For instance, any boolean value is considered less than any string.
  2. Compares whether a JSON value is less than a scalar or a scalar is less than a JSON value by converting the scalar to a JSON value and comparing both JSON values according to 1.

"},{"location":"api/basic_json/operator_lt/#template-parameters","title":"Template parameters","text":"ScalarType a scalar type according to std::is_scalar<ScalarType>::value"},{"location":"api/basic_json/operator_lt/#parameters","title":"Parameters","text":"lhs (in) first value to consider rhs (in) second value to consider"},{"location":"api/basic_json/operator_lt/#return-value","title":"Return value","text":"

whether lhs is less than rhs

"},{"location":"api/basic_json/operator_lt/#exception-safety","title":"Exception safety","text":"
  1. No-throw guarantee: this function never throws exceptions.
  2. No-throw guarantee if converting the scalar to a JSON value cannot throw, as for numbers, Booleans, and nullptr; the function is noexcept exactly in that case. Otherwise, it throws what the conversion throws, for example std::bad_alloc when converting a string, or out_of_range.410 for an enum value not mapped by NLOHMANN_JSON_SERIALIZE_ENUM_STRICT.
"},{"location":"api/basic_json/operator_lt/#complexity","title":"Complexity","text":"

Linear.

"},{"location":"api/basic_json/operator_lt/#notes","title":"Notes","text":"

Comparing NaN

NaN values are unordered within the domain of numbers. The following comparisons all yield false: 1. Comparing a NaN with itself. 2. Comparing a NaN with another NaN. 3. Comparing a NaN and any other number.

Operator overload resolution

Since C++20 overload resolution will consider the rewritten candidate generated from operator<=>.

"},{"location":"api/basic_json/operator_lt/#examples","title":"Examples","text":"Example

The example demonstrates comparing several JSON types.

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create several JSON values\n    json array_1 = {1, 2, 3};\n    json array_2 = {1, 2, 4};\n    json object_1 = {{\"A\", \"a\"}, {\"B\", \"b\"}};\n    json object_2 = {{\"B\", \"b\"}, {\"A\", \"a\"}};\n    json number_1 = 17;\n    json number_2 = 17.0000000000001L;\n    json string_1 = \"foo\";\n    json string_2 = \"bar\";\n\n    // output values and comparisons\n    std::cout << std::boolalpha;\n    std::cout << array_1 << \" == \" << array_2 << \" \" << (array_1 < array_2) << '\\n';\n    std::cout << object_1 << \" == \" << object_2 << \" \" << (object_1 < object_2) << '\\n';\n    std::cout << number_1 << \" == \" << number_2 << \" \" << (number_1 < number_2) << '\\n';\n    std::cout << string_1 << \" == \" << string_2 << \" \" << (string_1 < string_2) << '\\n';\n}\n

Output:

[1,2,3] == [1,2,4] true\n{\"A\":\"a\",\"B\":\"b\"} == {\"A\":\"a\",\"B\":\"b\"} false\n17 == 17.0000000000001 true\n\"foo\" == \"bar\" false\n
"},{"location":"api/basic_json/operator_lt/#see-also","title":"See also","text":"
  • operator<=> - comparison: 3-way
"},{"location":"api/basic_json/operator_lt/#version-history","title":"Version history","text":"
  1. Added in version 1.0.0. Conditionally removed since C++20 in version 3.11.0.
  2. Added in version 1.0.0. Conditionally removed since C++20 in version 3.11.0. Made conditionally noexcept in version 3.13.0 unreleased; before, a throwing conversion called std::terminate.
"},{"location":"api/basic_json/operator_ne/","title":"nlohmann::basic_json::operator!=","text":"
// until C++20\nbool operator!=(const_reference lhs, const_reference rhs) noexcept;   // (1)\n\ntemplate<typename ScalarType>\nbool operator!=(const_reference lhs, const ScalarType rhs) noexcept(/* see below */); // (2)\n\ntemplate<typename ScalarType>\nbool operator!=(ScalarType lhs, const const_reference rhs) noexcept(/* see below */); // (2)\n
  1. Compares two JSON values for inequality. Returns !(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 value and comparing both JSON values according to 1.

"},{"location":"api/basic_json/operator_ne/#template-parameters","title":"Template parameters","text":"ScalarType a scalar type according to std::is_scalar<ScalarType>::value"},{"location":"api/basic_json/operator_ne/#parameters","title":"Parameters","text":"lhs (in) first value to consider rhs (in) second value to consider"},{"location":"api/basic_json/operator_ne/#return-value","title":"Return value","text":"

whether the values lhs/*this and rhs are not equal

"},{"location":"api/basic_json/operator_ne/#exception-safety","title":"Exception safety","text":"
  1. No-throw guarantee: this function never throws exceptions.
  2. No-throw guarantee if converting the scalar to a JSON value cannot throw, as for numbers, Booleans, and nullptr; the function is noexcept exactly in that case. Otherwise, it throws what the conversion throws, for example std::bad_alloc when converting a string, or out_of_range.410 for an enum value not mapped by NLOHMANN_JSON_SERIALIZE_ENUM_STRICT.
"},{"location":"api/basic_json/operator_ne/#complexity","title":"Complexity","text":"

Linear.

"},{"location":"api/basic_json/operator_ne/#notes","title":"Notes","text":"

C++20

Since C++20, basic_json declares no operator!=. The compiler rewrites a != b as !(a == b) using operator==, so the result is the same as described above.

Comparing NaN and discarded

Since operator!= is defined as !(a == b), the behavior for special values follows that of operator==:

  • For NaN values: NaN == NaN yields false, so NaN != NaN yields true.
  • For discarded values: discarded == x yields false for any x, so discarded != x yields true.
"},{"location":"api/basic_json/operator_ne/#examples","title":"Examples","text":"Example: (1) compare JSON values

The example demonstrates comparing several JSON types.

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create several JSON values\n    json array_1 = {1, 2, 3};\n    json array_2 = {1, 2, 4};\n    json object_1 = {{\"A\", \"a\"}, {\"B\", \"b\"}};\n    json object_2 = {{\"B\", \"b\"}, {\"A\", \"a\"}};\n    json number_1 = 17;\n    json number_2 = 17.000000000000001L;\n    json string_1 = \"foo\";\n    json string_2 = \"bar\";\n\n    // output values and comparisons\n    std::cout << std::boolalpha;\n    std::cout << array_1 << \" != \" << array_2 << \" \" << (array_1 != array_2) << '\\n';\n    std::cout << object_1 << \" != \" << object_2 << \" \" << (object_1 != object_2) << '\\n';\n    std::cout << number_1 << \" != \" << number_2 << \" \" << (number_1 != number_2) << '\\n';\n    std::cout << string_1 << \" != \" << string_2 << \" \" << (string_1 != string_2) << '\\n';\n}\n

Output:

[1,2,3] != [1,2,4] true\n{\"A\":\"a\",\"B\":\"b\"} != {\"A\":\"a\",\"B\":\"b\"} false\n17 != 17.0 false\n\"foo\" != \"bar\" true\n
Example: (2) compare JSON values with nullptr

The example demonstrates comparing several JSON types against the null pointer (JSON null).

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create several JSON values\n    json array = {1, 2, 3};\n    json object = {{\"A\", \"a\"}, {\"B\", \"b\"}};\n    json number = 17;\n    json string = \"foo\";\n    json null;\n\n    // output values and comparisons\n    std::cout << std::boolalpha;\n    std::cout << array << \" != nullptr \" << (array != nullptr) << '\\n';\n    std::cout << object << \" != nullptr \" << (object != nullptr) << '\\n';\n    std::cout << number << \" != nullptr \" << (number != nullptr) << '\\n';\n    std::cout << string << \" != nullptr \" << (string != nullptr) << '\\n';\n    std::cout << null << \" != nullptr \" << (null != nullptr) << '\\n';\n}\n

Output:

[1,2,3] != nullptr true\n{\"A\":\"a\",\"B\":\"b\"} != nullptr true\n17 != nullptr true\n\"foo\" != nullptr true\nnull != nullptr false\n
"},{"location":"api/basic_json/operator_ne/#see-also","title":"See also","text":"
  • operator== - comparison: equal
  • operator<=> - comparison: 3-way (C++20)
  • basic_json_view::operator!= - the same comparison on a zero-copy view, without building a basic_json value for it
"},{"location":"api/basic_json/operator_ne/#version-history","title":"Version history","text":"
  1. Added in version 1.0.0. Added a C++20 member function in version 3.11.0. Changed in version 3.13.0 unreleased 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 unreleased; since C++20, the compiler rewrites a != b using operator==.
  2. Added in version 1.0.0. Changed in version 3.13.0 unreleased 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==. Made conditionally noexcept in version 3.13.0 unreleased; before, a throwing conversion called std::terminate.
"},{"location":"api/basic_json/operator_spaceship/","title":"nlohmann::basic_json::operator<=>","text":"
// since C++20\nstd::partial_ordering operator<=>(const_reference rhs) const noexcept;                   // (1)\n\ntemplate<typename ScalarType>\nstd::partial_ordering operator<=>(const ScalarType rhs) const noexcept(/* see below */); // (2)\n
  1. 3-way compares two JSON values producing a result of type std::partial_ordering according to the following rules:

    • Two JSON values compare with a result of std::partial_ordering::unordered if either value is discarded.
    • If both JSON values are of the same type, the result is produced by 3-way comparing their stored values using their respective operator<=>.
    • Integer and floating-point numbers are 3-way compared by their exact values, without converting the integer to floating-point. For instance, 9007199254740993 compares greater than 9007199254740992.0.
    • Otherwise, yields a result by comparing the type (see value_t).
  2. 3-way compares a JSON value and a scalar or a scalar and a JSON value by converting the scalar to a JSON value and 3-way comparing both JSON values (see 1).

"},{"location":"api/basic_json/operator_spaceship/#template-parameters","title":"Template parameters","text":"ScalarType a scalar type according to std::is_scalar<ScalarType>::value"},{"location":"api/basic_json/operator_spaceship/#parameters","title":"Parameters","text":"rhs (in) second value to consider"},{"location":"api/basic_json/operator_spaceship/#return-value","title":"Return value","text":"

the std::partial_ordering of the 3-way comparison of *this and rhs

"},{"location":"api/basic_json/operator_spaceship/#exception-safety","title":"Exception safety","text":"
  1. No-throw guarantee: this function never throws exceptions.
  2. No-throw guarantee if converting the scalar to a JSON value cannot throw, as for numbers, Booleans, and nullptr; the function is noexcept exactly in that case. Otherwise, it throws what the conversion throws, for example std::bad_alloc when converting a string, or out_of_range.410 for an enum value not mapped by NLOHMANN_JSON_SERIALIZE_ENUM_STRICT.
"},{"location":"api/basic_json/operator_spaceship/#complexity","title":"Complexity","text":"

Linear.

"},{"location":"api/basic_json/operator_spaceship/#notes","title":"Notes","text":"

Comparing NaN

  • NaN values are unordered within the domain of numbers. The following comparisons all yield std::partial_ordering::unordered:
    1. Comparing a NaN with itself.
    2. Comparing a NaN with another NaN.
    3. Comparing a NaN and any other number.
"},{"location":"api/basic_json/operator_spaceship/#examples","title":"Examples","text":"Example: (1) comparing JSON values

The example demonstrates comparing several JSON values.

#include <compare>\n#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nconst char* to_string(const std::partial_ordering& po)\n{\n    if (std::is_lt(po))\n    {\n        return \"less\";\n    }\n    else if (std::is_gt(po))\n    {\n        return \"greater\";\n    }\n    else if (std::is_eq(po))\n    {\n        return \"equivalent\";\n    }\n    return \"unordered\";\n}\n\nint main()\n{\n    // create several JSON values\n    json array_1 = {1, 2, 3};\n    json array_2 = {1, 2, 4};\n    json object_1 = {{\"A\", \"a\"}, {\"B\", \"b\"}};\n    json object_2 = {{\"B\", \"b\"}, {\"A\", \"a\"}};\n    json number = 17;\n    json string = \"foo\";\n    json discarded = json(json::value_t::discarded);\n\n    // output values and comparisons\n    std::cout << array_1 << \" <=> \" << array_2 << \" := \" << to_string(array_1 <=> array_2) << '\\n'; // *NOPAD*\n    std::cout << object_1 << \" <=> \" << object_2 << \" := \" << to_string(object_1 <=> object_2) << '\\n'; // *NOPAD*\n    std::cout << string << \" <=> \" << number << \" := \" << to_string(string <=> number) << '\\n'; // *NOPAD*\n    std::cout << string << \" <=> \" << discarded << \" := \" << to_string(string <=> discarded) << '\\n'; // *NOPAD*\n}\n

Output:

[1,2,3] <=> [1,2,4] := less\n{\"A\":\"a\",\"B\":\"b\"} <=> {\"A\":\"a\",\"B\":\"b\"} := equivalent\n\"foo\" <=> 17 := greater\n\"foo\" <=> <discarded> := unordered\n
Example: (2) comparing JSON values and scalars

The example demonstrates comparing several JSON values and scalars.

#include <compare>\n#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nconst char* to_string(const std::partial_ordering& po)\n{\n    if (std::is_lt(po))\n    {\n        return \"less\";\n    }\n    else if (std::is_gt(po))\n    {\n        return \"greater\";\n    }\n    else if (std::is_eq(po))\n    {\n        return \"equivalent\";\n    }\n    return \"unordered\";\n}\n\nint main()\n{\n    using float_limits = std::numeric_limits<json::number_float_t>;\n    constexpr auto nan = float_limits::quiet_NaN();\n\n    // create several JSON values\n    json boolean = false;\n    json number = 17;\n    json string = \"17\";\n\n    // output values and comparisons\n    std::cout << std::boolalpha << std::fixed;\n    std::cout << boolean << \" <=> \" << true << \" := \" << to_string(boolean <=> true) << '\\n'; // *NOPAD*\n    std::cout << number << \" <=> \" << 17.0 << \" := \" << to_string(number <=> 17.0) << '\\n'; // *NOPAD*\n    std::cout << number << \" <=> \" << nan << \" := \" << to_string(number <=> nan) << '\\n'; // *NOPAD*\n    std::cout << string << \" <=> \" << 17 << \" := \" << to_string(string <=> 17) << '\\n'; // *NOPAD*\n}\n

Output:

false <=> true := less\n17 <=> 17.000000 := equivalent\n17 <=> nan := unordered\n\"17\" <=> 17 := greater\n
"},{"location":"api/basic_json/operator_spaceship/#see-also","title":"See also","text":"
  • operator== - comparison: equal
  • operator!= - comparison: not equal
  • operator< - comparison: less than
  • operator<= - comparison: less than or equal
  • operator> - comparison: greater than
  • operator>= - comparison: greater than or equal
"},{"location":"api/basic_json/operator_spaceship/#version-history","title":"Version history","text":"
  1. Added in version 3.11.0.
  2. Added in version 3.11.0. Made conditionally noexcept in version 3.13.0 unreleased; before, a throwing conversion called std::terminate.
"},{"location":"api/basic_json/operator_value_t/","title":"nlohmann::basic_json::operator value_t","text":"
constexpr operator value_t() const noexcept;\n

Return the type of the JSON value as a value from the value_t enumeration.

"},{"location":"api/basic_json/operator_value_t/#return-value","title":"Return value","text":"

the type of the JSON value

Value type return value null value_t::null boolean value_t::boolean string value_t::string number (integer) value_t::number_integer number (unsigned integer) value_t::number_unsigned number (floating-point) value_t::number_float object value_t::object array value_t::array binary value_t::binary discarded value_t::discarded"},{"location":"api/basic_json/operator_value_t/#exception-safety","title":"Exception safety","text":"

No-throw guarantee: this member function never throws exceptions.

"},{"location":"api/basic_json/operator_value_t/#complexity","title":"Complexity","text":"

Constant.

"},{"location":"api/basic_json/operator_value_t/#examples","title":"Examples","text":"Example

The following code exemplifies operator value_t() for all JSON types.

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create JSON values\n    json j_null;\n    json j_boolean = true;\n    json j_number_integer = -17;\n    json j_number_unsigned = 42u;\n    json j_number_float = 23.42;\n    json j_object = {{\"one\", 1}, {\"two\", 2}};\n    json j_array = {1, 2, 4, 8, 16};\n    json j_string = \"Hello, world\";\n\n    // call operator value_t()\n    json::value_t t_null = j_null;\n    json::value_t t_boolean = j_boolean;\n    json::value_t t_number_integer = j_number_integer;\n    json::value_t t_number_unsigned = j_number_unsigned;\n    json::value_t t_number_float = j_number_float;\n    json::value_t t_object = j_object;\n    json::value_t t_array = j_array;\n    json::value_t t_string = j_string;\n\n    // print types\n    std::cout << std::boolalpha;\n    std::cout << (t_null == json::value_t::null) << '\\n';\n    std::cout << (t_boolean == json::value_t::boolean) << '\\n';\n    std::cout << (t_number_integer == json::value_t::number_integer) << '\\n';\n    std::cout << (t_number_unsigned == json::value_t::number_unsigned) << '\\n';\n    std::cout << (t_number_float == json::value_t::number_float) << '\\n';\n    std::cout << (t_object == json::value_t::object) << '\\n';\n    std::cout << (t_array == json::value_t::array) << '\\n';\n    std::cout << (t_string == json::value_t::string) << '\\n';\n}\n

Output:

true\ntrue\ntrue\ntrue\ntrue\ntrue\ntrue\ntrue\n
"},{"location":"api/basic_json/operator_value_t/#see-also","title":"See also","text":"
  • type - named member function equivalent to this implicit conversion operator
  • value_t - the enumeration of JSON types
  • Types - the JSON value types
"},{"location":"api/basic_json/operator_value_t/#version-history","title":"Version history","text":"
  • Added in version 1.0.0.
  • Added unsigned integer type in version 2.0.0.
  • Added binary type in version 3.8.0.
"},{"location":"api/basic_json/other_error/","title":"nlohmann::basic_json::other_error","text":"
class other_error : public exception;\n

This exception is thrown in case of errors that cannot be classified with the other exception types.

Exceptions have ids 5xx (see list of other errors).

classDiagram\n  direction LR\n\n    class std_exception [\"std::exception\"] {\n        <<interface>>\n    }\n\n    class json_exception [\"basic_json::exception\"] {\n        +const int id\n        +const char* what() const\n    }\n\n    class json_parse_error [\"basic_json::parse_error\"] {\n        +const std::size_t byte\n    }\n\n    class json_invalid_iterator [\"basic_json::invalid_iterator\"]\n    class json_type_error [\"basic_json::type_error\"]\n    class json_out_of_range [\"basic_json::out_of_range\"]\n    class json_other_error [\"basic_json::other_error\"]\n\n    std_exception <|-- json_exception\n    json_exception <|-- json_parse_error\n    json_exception <|-- json_invalid_iterator\n    json_exception <|-- json_type_error\n    json_exception <|-- json_out_of_range\n    json_exception <|-- json_other_error\n\n    style json_other_error fill:#CCCCFF

Class hierarchy of the library's exceptions; arrows point from a derived class to its base class, and the highlighted box is basic_json::other_error.

"},{"location":"api/basic_json/other_error/#member-functions","title":"Member functions","text":"
  • what - returns explanatory string
"},{"location":"api/basic_json/other_error/#member-variables","title":"Member variables","text":"
  • id - the id of the exception
"},{"location":"api/basic_json/other_error/#examples","title":"Examples","text":"Example

The following code shows how a other_error exception can be caught.

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\nusing namespace nlohmann::literals;\n\nint main()\n{\n    try\n    {\n        // executing a failing JSON Patch operation\n        json value = R\"({\n            \"best_biscuit\": {\n                \"name\": \"Oreo\"\n            }\n        })\"_json;\n        json patch = R\"([{\n            \"op\": \"test\",\n            \"path\": \"/best_biscuit/name\",\n            \"value\": \"Choco Leibniz\"\n        }])\"_json;\n        value.patch(patch);\n    }\n    catch (const json::other_error& e)\n    {\n        // output exception information\n        std::cout << \"message: \" << e.what() << '\\n'\n                  << \"exception id: \" << e.id << '\\n';\n    }\n}\n

Output:

message: [json.exception.other_error.501] unsuccessful: {\"op\":\"test\",\"path\":\"/best_biscuit/name\",\"value\":\"Choco Leibniz\"}\nexception id: 501\n
"},{"location":"api/basic_json/other_error/#see-also","title":"See also","text":"
  • exception - the base class of all exceptions thrown by the library
  • List of other errors - overview of further errors (other_error)
  • parse_error - exceptions indicating a parse error
  • invalid_iterator - exceptions indicating errors with iterators
  • type_error - exceptions indicating executing a member function with a wrong type
  • out_of_range - exceptions indicating access out of the defined range
  • Exceptions - all exceptions and their error codes
  • JSON_DIAGNOSTICS - extended exception messages with the path of the failing value
"},{"location":"api/basic_json/other_error/#version-history","title":"Version history","text":"
  • Added in version 3.0.0.
"},{"location":"api/basic_json/out_of_range/","title":"nlohmann::basic_json::out_of_range","text":"
class out_of_range : public exception;\n

This exception is thrown in case a library function is called on an input parameter that exceeds the expected range, for instance, in the case of array indices or nonexisting object keys.

Exceptions have ids 4xx (see list of out-of-range errors).

classDiagram\n  direction LR\n\n    class std_exception [\"std::exception\"] {\n        <<interface>>\n    }\n\n    class json_exception [\"basic_json::exception\"] {\n        +const int id\n        +const char* what() const\n    }\n\n    class json_parse_error [\"basic_json::parse_error\"] {\n        +const std::size_t byte\n    }\n\n    class json_invalid_iterator [\"basic_json::invalid_iterator\"]\n    class json_type_error [\"basic_json::type_error\"]\n    class json_out_of_range [\"basic_json::out_of_range\"]\n    class json_other_error [\"basic_json::other_error\"]\n\n    std_exception <|-- json_exception\n    json_exception <|-- json_parse_error\n    json_exception <|-- json_invalid_iterator\n    json_exception <|-- json_type_error\n    json_exception <|-- json_out_of_range\n    json_exception <|-- json_other_error\n\n    style json_out_of_range fill:#CCCCFF

Class hierarchy of the library's exceptions; arrows point from a derived class to its base class, and the highlighted box is basic_json::out_of_range.

"},{"location":"api/basic_json/out_of_range/#member-functions","title":"Member functions","text":"
  • what - returns explanatory string
"},{"location":"api/basic_json/out_of_range/#member-variables","title":"Member variables","text":"
  • id - the id of the exception
"},{"location":"api/basic_json/out_of_range/#examples","title":"Examples","text":"Example

The following code shows how a out_of_range exception can be caught.

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    try\n    {\n        // calling at() for an invalid index\n        json j = {1, 2, 3, 4};\n        j.at(4) = 10;\n    }\n    catch (const json::out_of_range& e)\n    {\n        // output exception information\n        std::cout << \"message: \" << e.what() << '\\n'\n                  << \"exception id: \" << e.id << '\\n';\n    }\n}\n

Output:

message: [json.exception.out_of_range.401] array index 4 is out of range\nexception id: 401\n
"},{"location":"api/basic_json/out_of_range/#see-also","title":"See also","text":"
  • exception - the base class of all exceptions thrown by the library
  • List of out-of-range errors - overview of out-of-range errors (out_of_range)
  • parse_error - exceptions indicating a parse error
  • invalid_iterator - exceptions indicating errors with iterators
  • type_error - exceptions indicating executing a member function with a wrong type
  • other_error - exceptions indicating other library errors
  • Exceptions - all exceptions and their error codes
  • JSON_DIAGNOSTICS - extended exception messages with the path of the failing value
"},{"location":"api/basic_json/out_of_range/#version-history","title":"Version history","text":"
  • Added in version 3.0.0.
"},{"location":"api/basic_json/parse/","title":"nlohmann::basic_json::parse","text":"
// (1)\ntemplate<typename InputType>\nstatic basic_json parse(InputType&& i,\n                        const parser_callback_t cb = nullptr,\n                        const bool allow_exceptions = true,\n                        const bool ignore_comments = false,\n                        const bool ignore_trailing_commas = false);\n\n// (2)\ntemplate<typename IteratorType, typename SentinelType = IteratorType>\nstatic basic_json parse(IteratorType first, SentinelType last,\n                        const parser_callback_t cb = nullptr,\n                        const bool allow_exceptions = true,\n                        const bool ignore_comments = false,\n                        const bool ignore_trailing_commas = false);\n
  1. Deserialize from a compatible input.
  2. Deserialize from a pair of character iterators, or an iterator and a sentinel of a different type (C++20 ranges support)

    The value_type of the iterator must be an integral type with size of 1, 2, or 4 bytes, which will be interpreted respectively as UTF-8, UTF-16, and UTF-32. If SentinelType differs from IteratorType, it must be comparable to the iterator type with operator!=.

    Ill-formed UTF-16 and UTF-32 sequences are rejected: a lone surrogate, a high surrogate that is not followed by its low surrogate, and a code point above U+10FFFF all yield a parse_error.101.

"},{"location":"api/basic_json/parse/#template-parameters","title":"Template parameters","text":"InputType

A compatible input, for instance:

  • an std::istream object
  • a FILE pointer (throws if null)
  • a C-style array of characters
  • a pointer to a null-terminated string of single byte characters (throws if null)
  • a std::string or a std::string_view (C++17)
  • a container obj for which begin(obj) and end(obj) produce a valid pair of iterators (as found via ADL or member functions, with semantics compatible to std::begin and std::end)
  • wide characters (wchar_t, char16_t, char32_t), which are converted to UTF-8: a wide string object (std::wstring, std::u16string, std::u32string) or an array (e.g. a wide string literal); a pointer to a null-terminated wide string (e.g. std::u16string::c_str()) is not supported
IteratorType

a compatible iterator type, for instance.

  • a pair of std::string::iterator or std::vector<std::uint8_t>::iterator
  • a pair of pointers such as ptr and ptr + len
SentinelType

defaults to IteratorType; may be a different type comparable to IteratorType via operator!=, for instance.

  • a custom sentinel type for C++20 ranges
  • std::default_sentinel_t, when IteratorType is std::counted_iterator
"},{"location":"api/basic_json/parse/#parameters","title":"Parameters","text":"i (in) Input to parse from. cb (in) a parser callback function of type parser_callback_t which is used to control the deserialization by filtering unwanted values (optional) allow_exceptions (in) whether to throw exceptions in case of a parse error (optional, true by default) ignore_comments (in) whether comments should be ignored and treated like whitespace (true) or yield a parse error (false); (optional, false by default) ignore_trailing_commas (in) whether trailing commas in arrays or objects should be ignored and treated like whitespace (true) or yield a parse error (false); (optional, false by default) first (in) iterator to the start of a character range last (in) iterator to the end of a character range, or a sentinel value that compares equal to the end iterator with operator!="},{"location":"api/basic_json/parse/#return-value","title":"Return value","text":"

Deserialized JSON value; in case of a parse error and allow_exceptions set to false, the return value will be value_t::discarded. The latter can be checked with is_discarded.

"},{"location":"api/basic_json/parse/#exception-safety","title":"Exception safety","text":"

Strong guarantee: if an exception is thrown, there are no changes in the JSON value.

"},{"location":"api/basic_json/parse/#exceptions","title":"Exceptions","text":"
  • Throws parse_error.101 in case of an unexpected token, or empty input like a null FILE* or char* pointer, or an std::istream without a stream buffer (i.rdbuf() == nullptr, for instance std::istream(nullptr)).
  • If reading from an std::istream reaches the end of the input and eofbit is part of the stream's 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.
"},{"location":"api/basic_json/parse/#complexity","title":"Complexity","text":"

Linear in the length of the input. The parser is a predictive LL(1) parser. The complexity can be higher if the parser callback function cb or reading from (1) the input i or (2) the iterator range [first, last] has a super-linear complexity.

"},{"location":"api/basic_json/parse/#notes","title":"Notes","text":"

A UTF-8 byte order mark is silently ignored.

Invalid Unicode escapes and unpaired surrogates in the input are reported as parse_error.101 with a detailed message.

By default, a '\\0' (NUL) byte anywhere in the input is treated as end of input, rather than as an ordinary (and, outside of a string, invalid) byte; see the FAQ entry for details and the JSON_STRICT_NUL_HANDLING macro to opt into rejecting it instead.

Parsing into a document instead of a value

basic_json_document::parse accepts the same inputs and the same options, but keeps the result as a flat index of the parsed values instead of a tree of basic_json values. It is faster and uses less memory when only parts of the document are read, and it also accepts a pointer to a null-terminated wide string, which parse() does not. See Zero-copy JSON views.

Performance

Contiguous inputs (strings, string views, vectors, arrays, pointer ranges) are the fastest to parse. A std::istream comes close: the parser scans the characters its stream buffer holds in bulk, without reading ahead, so the stream is left exactly where it would be after reading one character at a time. A FILE* is read one character at a time, but the file is locked only once, so other threads that use the same FILE object wait until parsing is done. See input sources and performance, JSON_DISABLE_STREAM_BULK_SCAN, and JSON_DISABLE_UNLOCKED_FILE_IO.

"},{"location":"api/basic_json/parse/#examples","title":"Examples","text":"Example: (1) parse from a character array

The example below demonstrates the parse() function reading from an array.

#include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // a JSON text\n    char text[] = R\"(\n    {\n        \"Image\": {\n            \"Width\":  800,\n            \"Height\": 600,\n            \"Title\":  \"View from 15th Floor\",\n            \"Thumbnail\": {\n                \"Url\":    \"http://www.example.com/image/481989943\",\n                \"Height\": 125,\n                \"Width\":  100\n            },\n            \"Animated\" : false,\n            \"IDs\": [116, 943, 234, 38793]\n        }\n    }\n    )\";\n\n    // parse and serialize JSON\n    json j_complete = json::parse(text);\n    std::cout << std::setw(4) << j_complete << \"\\n\\n\";\n}\n

Output:

{\n    \"Image\": {\n        \"Animated\": false,\n        \"Height\": 600,\n        \"IDs\": [\n            116,\n            943,\n            234,\n            38793\n        ],\n        \"Thumbnail\": {\n            \"Height\": 125,\n            \"Url\": \"http://www.example.com/image/481989943\",\n            \"Width\": 100\n        },\n        \"Title\": \"View from 15th Floor\",\n        \"Width\": 800\n    }\n}\n
Example: (1) parse from a string

The example below demonstrates the parse() function with and without callback function.

#include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // a JSON text\n    const auto* text = R\"(\n    {\n        \"Image\": {\n            \"Width\":  800,\n            \"Height\": 600,\n            \"Title\":  \"View from 15th Floor\",\n            \"Thumbnail\": {\n                \"Url\":    \"http://www.example.com/image/481989943\",\n                \"Height\": 125,\n                \"Width\":  100\n            },\n            \"Animated\" : false,\n            \"IDs\": [116, 943, 234, 38793]\n        }\n    }\n    )\";\n\n    // parse and serialize JSON\n    json j_complete = json::parse(text);\n    std::cout << std::setw(4) << j_complete << \"\\n\\n\";\n\n    // define parser callback\n    json::parser_callback_t cb = [](int depth, json::parse_event_t event, json & parsed)\n    {\n        // skip object elements with key \"Thumbnail\"\n        if (event == json::parse_event_t::key and parsed == json(\"Thumbnail\"))\n        {\n            return false;\n        }\n        else\n        {\n            return true;\n        }\n    };\n\n    // parse (with callback) and serialize JSON\n    json j_filtered = json::parse(text, cb);\n    std::cout << std::setw(4) << j_filtered << '\\n';\n}\n

Output:

{\n    \"Image\": {\n        \"Animated\": false,\n        \"Height\": 600,\n        \"IDs\": [\n            116,\n            943,\n            234,\n            38793\n        ],\n        \"Thumbnail\": {\n            \"Height\": 125,\n            \"Url\": \"http://www.example.com/image/481989943\",\n            \"Width\": 100\n        },\n        \"Title\": \"View from 15th Floor\",\n        \"Width\": 800\n    }\n}\n\n{\n    \"Image\": {\n        \"Animated\": false,\n        \"Height\": 600,\n        \"IDs\": [\n            116,\n            943,\n            234,\n            38793\n        ],\n        \"Title\": \"View from 15th Floor\",\n        \"Width\": 800\n    }\n}\n
Example: (1) parse from an input stream

The example below demonstrates the parse() function with and without callback function.

#include <iostream>\n#include <iomanip>\n#include <sstream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // a JSON text\n    const auto* text = R\"(\n    {\n        \"Image\": {\n            \"Width\":  800,\n            \"Height\": 600,\n            \"Title\":  \"View from 15th Floor\",\n            \"Thumbnail\": {\n                \"Url\":    \"http://www.example.com/image/481989943\",\n                \"Height\": 125,\n                \"Width\":  100\n            },\n            \"Animated\" : false,\n            \"IDs\": [116, 943, 234, 38793]\n        }\n    }\n    )\";\n\n    // fill a stream with JSON text\n    std::stringstream ss;\n    ss << text;\n\n    // parse and serialize JSON\n    json j_complete = json::parse(ss);\n    std::cout << std::setw(4) << j_complete << \"\\n\\n\";\n\n    // define parser callback\n    json::parser_callback_t cb = [](int depth, json::parse_event_t event, json & parsed)\n    {\n        // skip object elements with key \"Thumbnail\"\n        if (event == json::parse_event_t::key and parsed == json(\"Thumbnail\"))\n        {\n            return false;\n        }\n        else\n        {\n            return true;\n        }\n    };\n\n    // fill a stream with JSON text\n    ss.clear();\n    ss << text;\n\n    // parse (with callback) and serialize JSON\n    json j_filtered = json::parse(ss, cb);\n    std::cout << std::setw(4) << j_filtered << '\\n';\n}\n

Output:

{\n    \"Image\": {\n        \"Animated\": false,\n        \"Height\": 600,\n        \"IDs\": [\n            116,\n            943,\n            234,\n            38793\n        ],\n        \"Thumbnail\": {\n            \"Height\": 125,\n            \"Url\": \"http://www.example.com/image/481989943\",\n            \"Width\": 100\n        },\n        \"Title\": \"View from 15th Floor\",\n        \"Width\": 800\n    }\n}\n\n{\n    \"Image\": {\n        \"Animated\": false,\n        \"Height\": 600,\n        \"IDs\": [\n            116,\n            943,\n            234,\n            38793\n        ],\n        \"Title\": \"View from 15th Floor\",\n        \"Width\": 800\n    }\n}\n
Example: (1) parse from a contiguous container

The example below demonstrates the parse() function reading from a contiguous container.

#include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // a JSON text given as std::vector\n    std::vector<std::uint8_t> text = {'[', '1', ',', '2', ',', '3', ']', '\\0'};\n\n    // parse and serialize JSON\n    json j_complete = json::parse(text);\n    std::cout << std::setw(4) << j_complete << \"\\n\\n\";\n}\n

Output:

[\n    1,\n    2,\n    3\n]\n
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.

#include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // a JSON text given as string that is not null-terminated\n    const char* ptr = \"[1,2,3]another value\";\n\n    // parse and serialize JSON\n    json j_complete = json::parse(ptr, ptr + 7);\n    std::cout << std::setw(4) << j_complete << \"\\n\\n\";\n}\n

Output:

[\n    1,\n    2,\n    3\n]\n
Example: (2) parse from an iterator pair

The example below demonstrates the parse() function reading from an iterator pair.

#include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // a JSON text given an input with other values\n    std::vector<std::uint8_t> input = {'[', '1', ',', '2', ',', '3', ']', 'o', 't', 'h', 'e', 'r'};\n\n    // parse and serialize JSON\n    json j_complete = json::parse(input.begin(), input.begin() + 7);\n    std::cout << std::setw(4) << j_complete << \"\\n\\n\";\n}\n

Output:

[\n    1,\n    2,\n    3\n]\n
Example: effect of allow_exceptions parameter

The example below demonstrates the effect of the allow_exceptions parameter in the parse() function.

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // an invalid JSON text\n    std::string text = R\"(\n    {\n        \"key\": \"value without closing quotes\n    }\n    )\";\n\n    // parse with exceptions\n    try\n    {\n        json j = json::parse(text);\n    }\n    catch (const json::parse_error& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n\n    // parse without exceptions\n    json j = json::parse(text, nullptr, false);\n\n    if (j.is_discarded())\n    {\n        std::cout << \"the input is invalid JSON\" << '\\n';\n    }\n    else\n    {\n        std::cout << \"the input is valid JSON: \" << j << '\\n';\n    }\n}\n

Output:

[json.exception.parse_error.101] parse error at line 4, column 0: syntax error while parsing value - invalid string: control character U+000A (LF) must be escaped to \\u000A or \\n; last read: '\"value without closing quotes<U+000A>'\nthe input is invalid JSON\n
Example: effect of ignore_comments parameter

The example below demonstrates the effect of the ignore_comments parameter in the parse() function.

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    std::string s = R\"(\n    {\n        // update in 2006: removed Pluto\n        \"planets\": [\"Mercury\", \"Venus\", \"Earth\", \"Mars\",\n                    \"Jupiter\", \"Uranus\", \"Neptune\" /*, \"Pluto\" */]\n    }\n    )\";\n\n    try\n    {\n        json j = json::parse(s);\n    }\n    catch (json::exception& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n\n    json j = json::parse(s,\n                         /* callback */ nullptr,\n                         /* allow exceptions */ true,\n                         /* ignore_comments */ true);\n    std::cout << j.dump(2) << '\\n';\n}\n

Output:

[json.exception.parse_error.101] parse error at line 3, column 9: syntax error while parsing object key - invalid literal; last read: '<U+000A>    {<U+000A>        /'; expected string literal\n{\n  \"planets\": [\n    \"Mercury\",\n    \"Venus\",\n    \"Earth\",\n    \"Mars\",\n    \"Jupiter\",\n    \"Uranus\",\n    \"Neptune\"\n  ]\n}\n
Example: effect of ignore_trailing_commas parameter

The example below demonstrates the effect of the ignore_trailing_commas parameter in the parse() function.

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    std::string s = R\"(\n    {\n        \"planets\": [\n            \"Mercury\",\n            \"Venus\",\n            \"Earth\",\n            \"Mars\",\n            \"Jupiter\",\n            \"Uranus\",\n            \"Neptune\",\n        ]\n    }\n    )\";\n\n    try\n    {\n        json j = json::parse(s);\n    }\n    catch (json::exception& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n\n    json j = json::parse(s,\n                         /* callback */ nullptr,\n                         /* allow exceptions */ true,\n                         /* ignore_comments */ false,\n                         /* ignore_trailing_commas */ true);\n    std::cout << j.dump(2) << '\\n';\n}\n

Output:

[json.exception.parse_error.101] parse error at line 11, column 9: syntax error while parsing value - unexpected ']'; expected '[', '{', or a literal\n{\n  \"planets\": [\n    \"Mercury\",\n    \"Venus\",\n    \"Earth\",\n    \"Mars\",\n    \"Jupiter\",\n    \"Uranus\",\n    \"Neptune\"\n  ]\n}\n
Example: parse from UTF-16, UTF-32, and wide strings

The encoding is deduced from the character type of the input; std::u16string and std::u32string are interpreted as UTF-16 and UTF-32, and std::wstring uses the platform's wchar_t width. String literals like u\"...\", U\"...\", and L\"...\" work as well, as do iterators over wide characters.

#include <iostream>\n#include <string>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // the same JSON text, given in different encodings\n    const std::string utf8 = \"{\\\"name\\\":\\\"\\u00e9\\\"}\";\n    const std::u16string utf16 = u\"{\\\"name\\\":\\\"\\u00e9\\\"}\";\n    const std::u32string utf32 = U\"{\\\"name\\\":\\\"\\u00e9\\\"}\";\n    const std::wstring wide = L\"{\\\"name\\\":\\\"\\u00e9\\\"}\";\n\n    // the encoding is deduced from the character type of the input, and all\n    // of them yield the same value\n    std::cout << json::parse(utf8) << '\\n'\n              << json::parse(utf16) << '\\n'\n              << json::parse(utf32) << '\\n'\n              << json::parse(wide) << '\\n';\n\n    // a wide string literal works as well: u\"...\" is UTF-16, U\"...\" is UTF-32\n    std::cout << json::parse(u\"[1, 2, 3]\") << '\\n';\n\n    // iterators over wide characters work as well\n    std::cout << json::parse(utf16.begin(), utf16.end()) << '\\n';\n}\n

Output:

{\"name\":\"\u00e9\"}\n{\"name\":\"\u00e9\"}\n{\"name\":\"\u00e9\"}\n{\"name\":\"\u00e9\"}\n[1,2,3]\n{\"name\":\"\u00e9\"}\n
"},{"location":"api/basic_json/parse/#see-also","title":"See also","text":"
  • accept - check if the input is valid JSON
  • sax_parse - parse input using the SAX interface
  • operator>> - deserialize from stream
  • JSON_STRICT_NUL_HANDLING - opt in to rejecting a NUL byte in the input instead of treating it as end of input
  • JSON_DISABLE_STREAM_BULK_SCAN - read a std::istream one character at a time
  • JSON_DISABLE_UNLOCKED_FILE_IO - read a FILE* with the locking stdio functions
  • Parsing - overview of the parsing functions
  • Comments - ignore // and /* */ comments while parsing
  • Trailing Commas - accept trailing commas in arrays and objects
  • Parser Callbacks - filter or inspect values while parsing
  • Parsing and Exceptions - handling parse errors and locating them in the input
  • Parsing Untrusted Input - limits and checks for input you do not control
"},{"location":"api/basic_json/parse/#version-history","title":"Version history","text":"
  • Added in version 1.0.0.
  • Overload for contiguous containers (1) added in version 2.0.3.
  • Ignoring comments via ignore_comments added in version 3.9.0.
  • Changed runtime assertion in case of FILE* null pointers to exception in version 3.12.0.
  • Added ignore_trailing_commas in version 3.13.0 unreleased.
  • Extended container support (1) to include types with lvalue-only ADL begin/end (matching std::begin/std::end semantics) in version 3.13.0 unreleased.
  • Extended overload (2) to accept heterogeneous iterator+sentinel pairs (C++20 ranges support) in version 3.13.0 unreleased.
  • JSON_STRICT_NUL_HANDLING added in version 3.13.0 unreleased 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 unreleased.
  • Parsing from an std::istream scans the characters in its stream buffer in bulk in version 3.13.0 unreleased (JSON_DISABLE_STREAM_BULK_SCAN restores reading one character at a time).
  • Parsing from a FILE* locks the file once instead of once per character in version 3.13.0 unreleased (JSON_DISABLE_UNLOCKED_FILE_IO restores std::fgetc).
  • Ill-formed UTF-16 and UTF-32 input (a lone surrogate, a high surrogate that is not followed by its low surrogate, or a code point above U+10FFFF) is rejected with parse_error.101 in version 3.13.0 unreleased; before that, some such sequences were accepted or ended the input silently.

Deprecation

Overload (2) replaces calls to 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 parse({ptr, ptr+len}, ...); with parse(ptr, ptr+len, ...);.

You should be warned by your compiler with a -Wdeprecated-declarations warning if you are using a deprecated function.

See the migration guide for how to update existing code.

"},{"location":"api/basic_json/parse_error/","title":"nlohmann::basic_json::parse_error","text":"
class parse_error : public exception;\n

The library throws this exception when a parse error occurs. Parse errors can occur during the deserialization of JSON text, BJData, BON8, BSON, CBOR, MessagePack, UBJSON, as well as when using JSON Patch.

Member byte holds the byte index of the last read character in the input file (see note below).

Exceptions have ids 1xx (see list of parse errors).

classDiagram\n  direction LR\n\n    class std_exception [\"std::exception\"] {\n        <<interface>>\n    }\n\n    class json_exception [\"basic_json::exception\"] {\n        +const int id\n        +const char* what() const\n    }\n\n    class json_parse_error [\"basic_json::parse_error\"] {\n        +const std::size_t byte\n    }\n\n    class json_invalid_iterator [\"basic_json::invalid_iterator\"]\n    class json_type_error [\"basic_json::type_error\"]\n    class json_out_of_range [\"basic_json::out_of_range\"]\n    class json_other_error [\"basic_json::other_error\"]\n\n    std_exception <|-- json_exception\n    json_exception <|-- json_parse_error\n    json_exception <|-- json_invalid_iterator\n    json_exception <|-- json_type_error\n    json_exception <|-- json_out_of_range\n    json_exception <|-- json_other_error\n\n    style json_parse_error fill:#CCCCFF

Class hierarchy of the library's exceptions; arrows point from a derived class to its base class, and the highlighted box is basic_json::parse_error.

"},{"location":"api/basic_json/parse_error/#member-functions","title":"Member functions","text":"
  • what - returns explanatory string
"},{"location":"api/basic_json/parse_error/#member-variables","title":"Member variables","text":"
  • id - the id of the exception
  • byte - byte index of the parse error
"},{"location":"api/basic_json/parse_error/#notes","title":"Notes","text":"

For an input with n bytes, 1 is the index of the first character and n+1 is the index of the terminating null byte or the end of file. This also holds true when reading a byte vector for binary formats.

"},{"location":"api/basic_json/parse_error/#examples","title":"Examples","text":"Example

The following code shows how a parse_error exception can be caught.

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    try\n    {\n        // parsing input with a syntax error\n        json j = json::parse(\"[1,2,3,]\");\n    }\n    catch (const json::parse_error& e)\n    {\n        // output exception information\n        std::cout << \"message: \" << e.what() << '\\n'\n                  << \"exception id: \" << e.id << '\\n'\n                  << \"byte position of error: \" << e.byte << '\\n';\n    }\n}\n

Output:

message: [json.exception.parse_error.101] parse error at line 1, column 8: syntax error while parsing value - unexpected ']'; expected '[', '{', or a literal\nexception id: 101\nbyte position of error: 8\n
"},{"location":"api/basic_json/parse_error/#see-also","title":"See also","text":"
  • exception - the base class of all exceptions thrown by the library
  • List of parse errors - overview of parse errors (parse_error)
  • invalid_iterator - exceptions indicating errors with iterators
  • type_error - exceptions indicating executing a member function with a wrong type
  • out_of_range - exceptions indicating access out of the defined range
  • other_error - exceptions indicating other library errors
  • Parsing and Exceptions - handling parse errors and locating them in the input
  • Working Without Exceptions - error handling when exceptions are disabled
"},{"location":"api/basic_json/parse_error/#version-history","title":"Version history","text":"
  • Added in version 3.0.0.
"},{"location":"api/basic_json/parse_event_t/","title":"nlohmann::basic_json::parse_event_t","text":"
enum class parse_event_t : std::uint8_t {\n    object_start,\n    object_end,\n    array_start,\n    array_end,\n    key,\n    value\n};\n

The parser callback distinguishes the following events:

  • object_start: the parser read { and started to process a JSON object
  • key: the parser read a key of a value in an object
  • object_end: the parser read } and finished processing a JSON object
  • array_start: the parser read [ and started to process a JSON array
  • array_end: the parser read ] and finished processing a JSON array
  • value: the parser finished reading a JSON value
"},{"location":"api/basic_json/parse_event_t/#examples","title":"Examples","text":"

Example of the parse events a callback sees for the J\u200bSON text {\"name\": \"Berlin\", \"location\": [52.519444, 13.406667]}: object_start after the opening brace, key after each key, array_start after the opening bracket, value after each value, array_end after the closing bracket, and object_end after the closing brace. Every array and object also produces a value event when it is complete. J\u200bSON to parse callback events { \"name\" : \"Berlin\" , \"location\" : [ 52.519444 , 13.406667 ] } object_start key object_end array_start array_end value

Each coloured dot marks where the parser reports a parse_event_t event while reading the JSON text on the left; the legend on the right names the event per colour.

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 true).

#include <iostream>\n#include <string>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\n// translate a parse_event_t to a human-readable name\nstd::string event_name(json::parse_event_t event)\n{\n    switch (event)\n    {\n        case json::parse_event_t::object_start:\n            return \"object_start\";\n        case json::parse_event_t::object_end:\n            return \"object_end\";\n        case json::parse_event_t::array_start:\n            return \"array_start\";\n        case json::parse_event_t::array_end:\n            return \"array_end\";\n        case json::parse_event_t::key:\n            return \"key\";\n        case json::parse_event_t::value:\n            return \"value\";\n        default:\n            return \"unknown\";\n    }\n}\n\nint main()\n{\n    // a small JSON text\n    const auto* text = R\"({\"pi\": 3.141, \"numbers\": [1, 2]})\";\n\n    // parse the text and report every event together with its depth;\n    // returning true keeps every value unchanged\n    json j = json::parse(text, [](int depth, json::parse_event_t event, json& /*parsed*/)\n    {\n        std::cout << depth << \" \" << event_name(event) << '\\n';\n        return true;\n    });\n\n    // the callback did not change anything, so the parsed value is unaffected\n    std::cout << j << '\\n';\n}\n

Output:

0 object_start\n1 key\n1 value\n1 key\n1 array_start\n2 value\n2 value\n1 array_end\n0 object_end\n{\"numbers\":[1,2],\"pi\":3.141}\n
"},{"location":"api/basic_json/parse_event_t/#see-also","title":"See also","text":"
  • parser_callback_t - callback function type for the parser
  • parse - deserialize from a compatible input
  • Parser Callbacks - filter or inspect values while parsing
"},{"location":"api/basic_json/parse_event_t/#version-history","title":"Version history","text":"
  • Added in version 1.0.0.
"},{"location":"api/basic_json/parser_callback_t/","title":"nlohmann::basic_json::parser_callback_t","text":"
template<typename BasicJsonType>\nusing parser_callback_t =\n    std::function<bool(int depth, parse_event_t event, BasicJsonType& parsed)>;\n

With a parser callback function, the result of parsing a JSON text can be influenced. When passed to parse, it is called on certain events (passed as parse_event_t via parameter event) with a set recursion depth depth and context JSON value parsed. The return value of the callback function is a boolean indicating whether the element that emitted the callback shall be kept or not.

We distinguish six scenarios (determined by the event type) in which the callback function can be called. The following table describes the values of the parameters depth, event, and parsed.

parameter event description parameter depth parameter parsed parse_event_t::object_start the parser read { and started to process a JSON object depth of the parent of the JSON object a JSON value with type discarded parse_event_t::key the parser read a key of a value in an object depth of the currently parsed JSON object a JSON string containing the key parse_event_t::object_end the parser read } and finished processing a JSON object depth of the parent of the JSON object the parsed JSON object parse_event_t::array_start the parser read [ and started to process a JSON array depth of the parent of the JSON array a JSON value with type discarded parse_event_t::array_end the parser read ] and finished processing a JSON array depth of the parent of the JSON array the parsed JSON array parse_event_t::value the parser finished reading a JSON value depth of the value the parsed JSON value

Example of the parse events a callback sees for the J\u200bSON text {\"name\": \"Berlin\", \"location\": [52.519444, 13.406667]}: object_start after the opening brace, key after each key, array_start after the opening bracket, value after each value, array_end after the closing bracket, and object_end after the closing brace. Every array and object also produces a value event when it is complete. J\u200bSON to parse callback events { \"name\" : \"Berlin\" , \"location\" : [ 52.519444 , 13.406667 ] } object_start key object_end array_start array_end value

Parse events for a small JSON text: each coloured dot marks the position at which the parser calls the callback, and the legend on the right names the event per colour.

Discarding a value (i.e., returning false) has different effects depending on the context in which function was called:

  • Discarded values in structured types are skipped. That is, the parser will behave as if the discarded value was never read. This holds for every value type and for both kinds of parent: a discarded element is removed from the surrounding array, and a discarded member is removed from the surrounding object together with its key.
  • Arrays and objects can be discarded either at their parse_event_t::array_start/parse_event_t::object_start event or at their parse_event_t::array_end/parse_event_t::object_end event, and both remove the whole value. Discarding it at the start event also means the callback is called neither for the content of the value nor for its matching end event.
  • Discarding a parse_event_t::key event discards the whole object member. The callback is still called for the associated value, but its return value has no further effect.
  • In case a value outside a structured type is skipped, it is replaced with null. This case happens if the top-level element is skipped.
"},{"location":"api/basic_json/parser_callback_t/#parameters","title":"Parameters","text":"depth (in) the depth of the recursion during parsing event (in) an event of type parse_event_t indicating the context in the callback function has been called parsed (in, out) the current intermediate parse result; note that writing to this value has no effect for parse_event_t::key events"},{"location":"api/basic_json/parser_callback_t/#return-value","title":"Return value","text":"

Whether the JSON value which called the function during parsing should be kept (true) or not (false). In the latter case, it is skipped completely, or replaced by null if it is the top-level value.

"},{"location":"api/basic_json/parser_callback_t/#examples","title":"Examples","text":"Example: skip an object key while parsing

The example below demonstrates the parse() function with and without callback function.

#include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // a JSON text\n    const auto* text = R\"(\n    {\n        \"Image\": {\n            \"Width\":  800,\n            \"Height\": 600,\n            \"Title\":  \"View from 15th Floor\",\n            \"Thumbnail\": {\n                \"Url\":    \"http://www.example.com/image/481989943\",\n                \"Height\": 125,\n                \"Width\":  100\n            },\n            \"Animated\" : false,\n            \"IDs\": [116, 943, 234, 38793]\n        }\n    }\n    )\";\n\n    // parse and serialize JSON\n    json j_complete = json::parse(text);\n    std::cout << std::setw(4) << j_complete << \"\\n\\n\";\n\n    // define parser callback\n    json::parser_callback_t cb = [](int depth, json::parse_event_t event, json & parsed)\n    {\n        // skip object elements with key \"Thumbnail\"\n        if (event == json::parse_event_t::key and parsed == json(\"Thumbnail\"))\n        {\n            return false;\n        }\n        else\n        {\n            return true;\n        }\n    };\n\n    // parse (with callback) and serialize JSON\n    json j_filtered = json::parse(text, cb);\n    std::cout << std::setw(4) << j_filtered << '\\n';\n}\n

Output:

{\n    \"Image\": {\n        \"Animated\": false,\n        \"Height\": 600,\n        \"IDs\": [\n            116,\n            943,\n            234,\n            38793\n        ],\n        \"Thumbnail\": {\n            \"Height\": 125,\n            \"Url\": \"http://www.example.com/image/481989943\",\n            \"Width\": 100\n        },\n        \"Title\": \"View from 15th Floor\",\n        \"Width\": 800\n    }\n}\n\n{\n    \"Image\": {\n        \"Animated\": false,\n        \"Height\": 600,\n        \"IDs\": [\n            116,\n            943,\n            234,\n            38793\n        ],\n        \"Title\": \"View from 15th Floor\",\n        \"Width\": 800\n    }\n}\n
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.

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // a JSON text with an array and a number inside an object\n    const auto* text = R\"({\"IDs\": [116, 943], \"Width\": 800})\";\n\n    // discard the array when the parser reads its opening bracket\n    json j_array_start = json::parse(text, [](int /*depth*/, json::parse_event_t event, json& /*parsed*/)\n    {\n        return event != json::parse_event_t::array_start;\n    });\n\n    // discard the same array when the parser reads its closing bracket\n    json j_array_end = json::parse(text, [](int /*depth*/, json::parse_event_t event, json& /*parsed*/)\n    {\n        return event != json::parse_event_t::array_end;\n    });\n\n    // discard the number, but keep its key\n    json j_value = json::parse(text, [](int /*depth*/, json::parse_event_t event, json & parsed)\n    {\n        return !(event == json::parse_event_t::value && parsed == json(800));\n    });\n\n    // discard the key of the number\n    json j_key = json::parse(text, [](int /*depth*/, json::parse_event_t event, json & parsed)\n    {\n        return !(event == json::parse_event_t::key && parsed == json(\"Width\"));\n    });\n\n    // discard the top-level object\n    json j_root = json::parse(text, [](int /*depth*/, json::parse_event_t event, json& /*parsed*/)\n    {\n        return event != json::parse_event_t::object_end;\n    });\n\n    // in every case, the discarded value is removed together with its key\n    std::cout << j_array_start << '\\n'\n              << j_array_end << '\\n'\n              << j_value << '\\n'\n              << j_key << '\\n'\n              << j_root << '\\n';\n}\n

Output:

{\"Width\":800}\n{\"Width\":800}\n{\"IDs\":[116,943]}\n{\"IDs\":[116,943]}\nnull\n
"},{"location":"api/basic_json/parser_callback_t/#see-also","title":"See also","text":"
  • parse - deserialize from a compatible input
  • parse_event_t - enumeration of parser events
  • Parser Callbacks - filter or inspect values while parsing
"},{"location":"api/basic_json/parser_callback_t/#version-history","title":"Version history","text":"
  • Added in version 1.0.0.
  • Fixed in version 3.13.0 unreleased 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 unreleased 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.
"},{"location":"api/basic_json/patch/","title":"nlohmann::basic_json::patch","text":"
basic_json patch(const basic_json& json_patch) const;\n

JSON Patch defines a JSON document structure for expressing a sequence of operations to apply to a JSON document. With this function, a JSON Patch is applied to the current JSON value by executing all operations from the patch.

"},{"location":"api/basic_json/patch/#parameters","title":"Parameters","text":"json_patch (in) JSON patch document"},{"location":"api/basic_json/patch/#return-value","title":"Return value","text":"

patched document

"},{"location":"api/basic_json/patch/#exception-safety","title":"Exception safety","text":"

Strong guarantee: if an exception is thrown, there are no changes in the JSON value.

"},{"location":"api/basic_json/patch/#exceptions","title":"Exceptions","text":"
  • Throws parse_error.104 if the JSON patch does not consist of an array of objects.
  • Throws parse_error.105 if the JSON patch is malformed (e.g., mandatory attributes are missing); example: \"operation 'add' must have member 'path'\".
  • Throws out_of_range.401 if an array index is out of range.
  • Throws parse_error.106 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 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 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 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 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 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 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 if JSON pointer has no parent (\"remove\", \"move\")
  • Throws out_of_range.411 if an \"add\" operation's target location has a parent that is neither an object nor an array.
  • Throws out_of_range.413 if a \"remove\" operation's target location has a parent that is neither an object nor an array.
  • Throws out_of_range.414 if a \"move\" operation's \"from\" location is a proper prefix of its \"path\" location.
  • Throws other_error.501 if \"test\" operation was unsuccessful. A \"test\" operation whose \"path\" does not exist is unsuccessful, too: the failed lookup is reported as a failed test, even if the operation has no \"value\" member (which would otherwise be parse_error.105). Which of the two errors is reported for this combination depends on the order in which the operands of a comparison are evaluated, so do not rely on it.
"},{"location":"api/basic_json/patch/#complexity","title":"Complexity","text":"

Linear in the size of the JSON value and the length of the JSON patch. As usually the patch affects only a fraction of the JSON value, the complexity can usually be neglected.

"},{"location":"api/basic_json/patch/#notes","title":"Notes","text":"

The application of a patch is atomic: Either all operations succeed and the patched document is returned or an exception is thrown. In any case, the original value is not changed: the patch is applied to a copy of the value.

Duplicate member names inside an operation object are resolved by the parser before the patch is applied (the last one is kept, see object_t), so {\"op\": \"add\", \"op\": \"remove\", \"path\": \"/a\"} is a remove operation.

"},{"location":"api/basic_json/patch/#examples","title":"Examples","text":"Example: apply a JSON patch

The following code shows how a JSON patch is applied to a value.

#include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\nusing namespace nlohmann::literals;\n\nint main()\n{\n    // the original document\n    json doc = R\"(\n        {\n          \"baz\": \"qux\",\n          \"foo\": \"bar\"\n        }\n    )\"_json;\n\n    // the patch\n    json patch = R\"(\n        [\n          { \"op\": \"replace\", \"path\": \"/baz\", \"value\": \"boo\" },\n          { \"op\": \"add\", \"path\": \"/hello\", \"value\": [\"world\"] },\n          { \"op\": \"remove\", \"path\": \"/foo\"}\n        ]\n    )\"_json;\n\n    // apply the patch\n    json patched_doc = doc.patch(patch);\n\n    // output original and patched document\n    std::cout << std::setw(4) << doc << \"\\n\\n\"\n              << std::setw(4) << patched_doc << '\\n';\n}\n

Output:

{\n    \"baz\": \"qux\",\n    \"foo\": \"bar\"\n}\n\n{\n    \"baz\": \"boo\",\n    \"hello\": [\n        \"world\"\n    ]\n}\n
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.

#include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\nusing namespace nlohmann::literals;\n\nint main()\n{\n    // the original document\n    json doc = R\"(\n        {\n          \"a\": { \"b\": 1 }\n        }\n    )\"_json;\n\n    // a patch that tries to move \"/a\" into one of its own children\n    json patch = R\"(\n        [\n          { \"op\": \"move\", \"from\": \"/a\", \"path\": \"/a/b\" }\n        ]\n    )\"_json;\n\n    // exception out_of_range.414\n    try\n    {\n        json patched_doc = doc.patch(patch);\n    }\n    catch (const json::out_of_range& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n\n    // the original document is unchanged\n    std::cout << std::setw(4) << doc << '\\n';\n}\n

Output:

[json.exception.out_of_range.414] cannot move value: 'from' path '/a' is a proper prefix of 'path' '/a/b'\n{\n    \"a\": {\n        \"b\": 1\n    }\n}\n
"},{"location":"api/basic_json/patch/#see-also","title":"See also","text":"
  • RFC 6902 (JSON Patch) - specification of JSON Patch
  • RFC 6901 (JSON Pointer) - specification of JSON Pointer
  • patch_inplace - applies a JSON Patch without creating a copy of the document
  • merge_patch - applies a JSON Merge Patch
  • JSON Patch and Diff - the article on JSON Patch
  • JSON Pointer - the addressing scheme used for patch paths
"},{"location":"api/basic_json/patch/#version-history","title":"Version history","text":"
  • Added in version 2.0.0.
  • Added out_of_range.411 and stopped relying on an internal assertion when an \"add\" operation's target location has a non-object/non-array parent in version 3.13.0 unreleased. This includes a null parent, which was previously silently converted to an object, in version 3.13.0 unreleased.
  • Added out_of_range.413 and stopped silently ignoring a \"remove\" operation whose target location has a non-object/non-array parent in version 3.13.0 unreleased.
  • Added out_of_range.414 and rejected a \"move\" operation whose \"from\" location is a proper prefix of its \"path\" location instead of silently producing a corrupted result in version 3.13.0 unreleased.
  • Throws parse_error.109 instead of out_of_range.404 for a one-character array index that is not a digit (e.g., /x) in version 3.13.0 unreleased, as it already did for longer ones.
"},{"location":"api/basic_json/patch_inplace/","title":"nlohmann::basic_json::patch_inplace","text":"
void patch_inplace(const basic_json& json_patch);\n

JSON Patch defines a JSON document structure for expressing a sequence of operations to apply to a JSON document. With this function, a JSON Patch is applied to the current JSON value by executing all operations from the patch. This function applies a JSON patch in place and returns void.

"},{"location":"api/basic_json/patch_inplace/#parameters","title":"Parameters","text":"json_patch (in) JSON patch document"},{"location":"api/basic_json/patch_inplace/#exception-safety","title":"Exception safety","text":"

No guarantees, value may be corrupted by an unsuccessful patch operation.

"},{"location":"api/basic_json/patch_inplace/#exceptions","title":"Exceptions","text":"
  • Throws parse_error.104 if the JSON patch does not consist of an array of objects.
  • Throws parse_error.105 if the JSON patch is malformed (e.g., mandatory attributes are missing); example: \"operation 'add' must have member 'path'\".
  • Throws out_of_range.401 if an array index is out of range.
  • Throws parse_error.106 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 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 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 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 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 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 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 if JSON pointer has no parent (\"remove\", \"move\")
  • Throws out_of_range.411 if an \"add\" operation's target location has a parent that is neither an object nor an array.
  • Throws out_of_range.413 if a \"remove\" operation's target location has a parent that is neither an object nor an array.
  • Throws out_of_range.414 if a \"move\" operation's \"from\" location is a proper prefix of its \"path\" location.
  • Throws other_error.501 if \"test\" operation was unsuccessful. A \"test\" operation whose \"path\" does not exist is unsuccessful, too: the failed lookup is reported as a failed test, even if the operation has no \"value\" member (which would otherwise be parse_error.105). Which of the two errors is reported for this combination depends on the order in which the operands of a comparison are evaluated, so do not rely on it.
"},{"location":"api/basic_json/patch_inplace/#complexity","title":"Complexity","text":"

Linear in the size of the JSON value and the length of the JSON patch. As usually the patch affects only a fraction of the JSON value, the complexity can usually be neglected.

"},{"location":"api/basic_json/patch_inplace/#notes","title":"Notes","text":"

Unlike patch, patch_inplace applies the operation \"in place\" and no copy of the JSON value is created. That makes it faster for large documents by avoiding the copy. However, the JSON value might be corrupted if the function throws an exception.

Duplicate member names inside an operation object are resolved by the parser before the patch is applied (the last one is kept, see object_t), so {\"op\": \"add\", \"op\": \"remove\", \"path\": \"/a\"} is a remove operation.

"},{"location":"api/basic_json/patch_inplace/#examples","title":"Examples","text":"Example: apply a JSON patch in place

The following code shows how a JSON patch is applied to a value.

#include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\nusing namespace nlohmann::literals;\n\nint main()\n{\n    // the original document\n    json doc = R\"(\n        {\n          \"baz\": \"qux\",\n          \"foo\": \"bar\"\n        }\n    )\"_json;\n\n    // the patch\n    json patch = R\"(\n        [\n          { \"op\": \"replace\", \"path\": \"/baz\", \"value\": \"boo\" },\n          { \"op\": \"add\", \"path\": \"/hello\", \"value\": [\"world\"] },\n          { \"op\": \"remove\", \"path\": \"/foo\"}\n        ]\n    )\"_json;\n\n    // output original document\n    std::cout << \"Before\\n\" << std::setw(4) << doc << '\\n';\n\n    // apply the patch\n    doc.patch_inplace(patch);\n\n    // output patched document\n    std::cout << \"\\nAfter\\n\" << std::setw(4) << doc << '\\n';\n}\n

Output:

Before\n{\n    \"baz\": \"qux\",\n    \"foo\": \"bar\"\n}\n\nAfter\n{\n    \"baz\": \"boo\",\n    \"hello\": [\n        \"world\"\n    ]\n}\n
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.

#include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\nusing namespace nlohmann::literals;\n\nint main()\n{\n    // the original document\n    json doc = R\"(\n        {\n          \"a\": 1,\n          \"b\": 2\n        }\n    )\"_json;\n\n    // a patch whose second operation fails\n    json patch = R\"(\n        [\n          { \"op\": \"replace\", \"path\": \"/a\", \"value\": 99 },\n          { \"op\": \"remove\", \"path\": \"/nonexistent\" }\n        ]\n    )\"_json;\n\n    // exception out_of_range.403\n    try\n    {\n        doc.patch_inplace(patch);\n    }\n    catch (const json::out_of_range& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n\n    // the first operation has already been applied to doc\n    std::cout << std::setw(4) << doc << '\\n';\n}\n

Output:

[json.exception.out_of_range.403] key 'nonexistent' not found\n{\n    \"a\": 99,\n    \"b\": 2\n}\n
"},{"location":"api/basic_json/patch_inplace/#see-also","title":"See also","text":"
  • RFC 6902 (JSON Patch) - specification of JSON Patch
  • RFC 6901 (JSON Pointer) - specification of JSON Pointer
  • patch - applies a JSON Patch
  • merge_patch - applies a JSON Merge Patch
  • JSON Patch and Diff - the article on JSON Patch
"},{"location":"api/basic_json/patch_inplace/#version-history","title":"Version history","text":"
  • Added in version 3.11.0.
  • Added out_of_range.411 and stopped relying on an internal assertion when an \"add\" operation's target location has a non-object/non-array parent in version 3.13.0 unreleased. This includes a null parent, which was previously silently converted to an object, in version 3.13.0 unreleased.
  • Added out_of_range.413 and stopped silently ignoring a \"remove\" operation whose target location has a non-object/non-array parent in version 3.13.0 unreleased.
  • Added out_of_range.414 and rejected a \"move\" operation whose \"from\" location is a proper prefix of its \"path\" location instead of silently producing a corrupted result in version 3.13.0 unreleased.
  • Throws parse_error.109 instead of out_of_range.404 for a one-character array index that is not a digit (e.g., /x) in version 3.13.0 unreleased, as it already did for longer ones.
"},{"location":"api/basic_json/push_back/","title":"nlohmann::basic_json::push_back","text":"
// (1)\nvoid push_back(basic_json&& val);\nvoid push_back(const basic_json& val);\n\n// (2)\nvoid push_back(const typename object_t::value_type& val);\n\n// (3)\nvoid push_back(initializer_list_t init);\n
  1. Appends the given element val to the end of the JSON array. If the function is called on a JSON null value, an empty array is created before appending val.

  2. Inserts the given element val to the JSON object. If the function is called on a JSON null value, an empty object is created before inserting val.

  3. This function allows using push_back with an initializer list. In case

    1. the current value is an object,
    2. the initializer list init contains only two elements, and
    3. the first element of init is a string,

    init is converted into an object element and added using push_back(const typename object_t::value_type&). Otherwise, init is converted to a JSON value and added using push_back(basic_json&&).

"},{"location":"api/basic_json/push_back/#iterator-invalidation","title":"Iterator invalidation","text":"

For all cases where an element is added to an array, a reallocation can happen, in which case all iterators (including the end() iterator) and all references to the elements are invalidated. Otherwise, only the end() iterator is invalidated.

For ordered_json, also adding an element to an object can yield a reallocation which again invalidates all iterators and all references.

"},{"location":"api/basic_json/push_back/#parameters","title":"Parameters","text":"val (in) the value to add to the JSON array/object init (in) an initializer list"},{"location":"api/basic_json/push_back/#exception-safety","title":"Exception safety","text":"

Strong guarantee: if an exception is thrown, there are no changes to any JSON value. As an exception, a null value is converted to an empty array or object before the element is added and keeps that type if adding the element throws.

"},{"location":"api/basic_json/push_back/#exceptions","title":"Exceptions","text":"
  1. Throws type_error.308 when called on a type other than JSON array or null; example: \"cannot use push_back() with number\"
  2. Throws type_error.308 when called on a type other than JSON object or null; example: \"cannot use push_back() with number\"
  3. Throws type_error.308 when called on a type other than JSON array or null; example: \"cannot use push_back() with number\"
"},{"location":"api/basic_json/push_back/#complexity","title":"Complexity","text":"
  1. Amortized constant.
  2. Logarithmic in the size of the container, O(log(size())).
  3. Linear in the size of the initializer list init.
"},{"location":"api/basic_json/push_back/#notes","title":"Notes","text":"

(3) This function is required to resolve an ambiguous overload error, because pairs like {\"key\", \"value\"} can be both interpreted as object_t::value_type or std::initializer_list<basic_json>, see #235 for more information.

"},{"location":"api/basic_json/push_back/#examples","title":"Examples","text":"Example: (1) add element to array

The example shows how push_back() and += can be used to add elements to a JSON array. Note how the null value was silently converted to a JSON array.

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create JSON values\n    json array = {1, 2, 3, 4, 5};\n    json null;\n\n    // print values\n    std::cout << array << '\\n';\n    std::cout << null << '\\n';\n\n    // add values\n    array.push_back(6);\n    array += 7;\n    null += \"first\";\n    null += \"second\";\n\n    // print values\n    std::cout << array << '\\n';\n    std::cout << null << '\\n';\n}\n

Output:

[1,2,3,4,5]\nnull\n[1,2,3,4,5,6,7]\n[\"first\",\"second\"]\n
Example: (2) add element to object

The example shows how push_back() and += can be used to add elements to a JSON object. Note how the null value was silently converted to a JSON object.

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create JSON values\n    json object = {{\"one\", 1}, {\"two\", 2}};\n    json null;\n\n    // print values\n    std::cout << object << '\\n';\n    std::cout << null << '\\n';\n\n    // add values\n    object.push_back(json::object_t::value_type(\"three\", 3));\n    object += json::object_t::value_type(\"four\", 4);\n    null += json::object_t::value_type(\"A\", \"a\");\n    null += json::object_t::value_type(\"B\", \"b\");\n\n    // print values\n    std::cout << object << '\\n';\n    std::cout << null << '\\n';\n}\n

Output:

{\"one\":1,\"two\":2}\nnull\n{\"four\":4,\"one\":1,\"three\":3,\"two\":2}\n{\"A\":\"a\",\"B\":\"b\"}\n
Example: (3) add to object from initializer list

The example shows how initializer lists are treated as objects when possible.

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create JSON values\n    json object = {{\"one\", 1}, {\"two\", 2}};\n    json null;\n\n    // print values\n    std::cout << object << '\\n';\n    std::cout << null << '\\n';\n\n    // add values:\n    object.push_back({\"three\", 3});  // object is extended\n    object += {\"four\", 4};           // object is extended\n    null.push_back({\"five\", 5});     // null is converted to array\n\n    // print values\n    std::cout << object << '\\n';\n    std::cout << null << '\\n';\n\n    // would throw:\n    //object.push_back({1, 2, 3});\n}\n

Output:

{\"one\":1,\"two\":2}\nnull\n{\"four\":4,\"one\":1,\"three\":3,\"two\":2}\n[[\"five\",5]]\n
"},{"location":"api/basic_json/push_back/#see-also","title":"See also","text":"
  • emplace_back - add a value to an array
  • operator+= - add a value to an array/object
  • Modifying values - the article on modifying values
"},{"location":"api/basic_json/push_back/#version-history","title":"Version history","text":"
  1. Added in version 1.0.0.
  2. Added in version 1.0.0.
  3. Added in version 2.0.0.
"},{"location":"api/basic_json/rbegin/","title":"nlohmann::basic_json::rbegin","text":"
reverse_iterator rbegin() noexcept;\nconst_reverse_iterator rbegin() const noexcept;\n

Returns an iterator to the reverse-beginning; that is, the last element.

Two rows of sixteen cells. The upper row shows the reversed sequence: rend() points to a dashed position before the first element and rbegin() to the last element. The lower row shows the forward sequence: begin() points to the first element and end() to a dashed position after the last element. A reverse iterator stores an iterator to the next element, so rend() corresponds to begin() and rbegin() to end(). rend rbegin Reverse past-the-last element A reverse iterator stores an iterator to the next element begin end Past-the-last element

rbegin() points to the last element and rend() to the position before the first element. The upper row is the reversed sequence and the lower row the forward sequence; dashed arrows link each reverse iterator to the forward iterator it stores, and dashed cells are past-the-last positions.

"},{"location":"api/basic_json/rbegin/#return-value","title":"Return value","text":"

reverse iterator to the last element

"},{"location":"api/basic_json/rbegin/#exception-safety","title":"Exception safety","text":"

No-throw guarantee: this member function never throws exceptions.

"},{"location":"api/basic_json/rbegin/#complexity","title":"Complexity","text":"

Constant.

"},{"location":"api/basic_json/rbegin/#examples","title":"Examples","text":"Example

The following code shows an example for rbegin().

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create an array value\n    json array = {1, 2, 3, 4, 5};\n\n    // get an iterator to the reverse-beginning\n    json::reverse_iterator it = array.rbegin();\n\n    // serialize the element that the iterator points to\n    std::cout << *it << '\\n';\n}\n

Output:

5\n
"},{"location":"api/basic_json/rbegin/#see-also","title":"See also","text":"
  • rend - returns a reverse iterator to one before the first element
  • crbegin - returns a const reverse iterator to the last element
  • begin - returns an iterator to the first element
  • Iterators - the article on iterators
"},{"location":"api/basic_json/rbegin/#version-history","title":"Version history","text":"
  • Added in version 1.0.0.
"},{"location":"api/basic_json/rend/","title":"nlohmann::basic_json::rend","text":"
reverse_iterator rend() noexcept;\nconst_reverse_iterator rend() const noexcept;\n

Returns an iterator to the reverse-end; that is, one before the first element. This element acts as a placeholder, attempting to access it results in undefined behavior.

Two rows of sixteen cells. The upper row shows the reversed sequence: rend() points to a dashed position before the first element and rbegin() to the last element. The lower row shows the forward sequence: begin() points to the first element and end() to a dashed position after the last element. A reverse iterator stores an iterator to the next element, so rend() corresponds to begin() and rbegin() to end(). rend rbegin Reverse past-the-last element A reverse iterator stores an iterator to the next element begin end Past-the-last element

rend() points to the position before the first element and rbegin() to the last element. The upper row is the reversed sequence and the lower row the forward sequence; dashed arrows link each reverse iterator to the forward iterator it stores, and dashed cells are past-the-last positions.

"},{"location":"api/basic_json/rend/#return-value","title":"Return value","text":"

reverse iterator to the element following the last element

"},{"location":"api/basic_json/rend/#exception-safety","title":"Exception safety","text":"

No-throw guarantee: this member function never throws exceptions.

"},{"location":"api/basic_json/rend/#complexity","title":"Complexity","text":"

Constant.

"},{"location":"api/basic_json/rend/#examples","title":"Examples","text":"Example

The following code shows an example for rend().

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create an array value\n    json array = {1, 2, 3, 4, 5};\n\n    // get an iterator to the reverse-end\n    json::reverse_iterator it = array.rend();\n\n    // increment the iterator to point to the first element\n    --it;\n\n    // serialize the element that the iterator points to\n    std::cout << *it << '\\n';\n}\n

Output:

1\n
"},{"location":"api/basic_json/rend/#see-also","title":"See also","text":"
  • rbegin - returns a reverse iterator to the last element
  • crend - returns a const reverse iterator to one before the first element
  • end - returns an iterator to one past the last element
  • Iterators - the article on iterators
"},{"location":"api/basic_json/rend/#version-history","title":"Version history","text":"
  • Added in version 1.0.0.
"},{"location":"api/basic_json/sax_parse/","title":"nlohmann::basic_json::sax_parse","text":"
// (1)\ntemplate <typename InputType, typename SAX>\nstatic bool sax_parse(InputType&& i,\n                      SAX* sax,\n                      input_format_t format = input_format_t::json,\n                      const bool strict = true,\n                      const bool ignore_comments = false,\n                      const bool ignore_trailing_commas = false,\n                      const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error);\n\n// (2)\ntemplate<class IteratorType, class SAX, class SentinelType = IteratorType>\nstatic bool sax_parse(IteratorType first, SentinelType last,\n                      SAX* sax,\n                      input_format_t format = input_format_t::json,\n                      const bool strict = true,\n                      const bool ignore_comments = false,\n                      const bool ignore_trailing_commas = false,\n                      const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error);\n

Read from input and generate SAX events

  1. Read from a compatible input.
  2. Read from a pair of character iterators, or an iterator and a sentinel of a different type (C++20 ranges support).

    The value_type of the iterator must be an integral type with a size of 1, 2, or 4 bytes, which will be interpreted respectively as UTF-8, UTF-16, and UTF-32. If SentinelType differs from IteratorType, it must be comparable to the iterator type with operator!=.

    Ill-formed UTF-16 and UTF-32 sequences are rejected: a lone surrogate, a high surrogate that is not followed by its low surrogate, and a code point above U+10FFFF all yield a parse_error.101.

The SAX event lister must follow the interface of json_sax.

"},{"location":"api/basic_json/sax_parse/#template-parameters","title":"Template parameters","text":"InputType

A compatible input, for instance:

  • an std::istream object
  • a FILE pointer
  • a C-style array of characters
  • a pointer to a null-terminated string of single byte characters
  • a std::string or a std::string_view (C++17)
  • a container obj for which begin(obj) and end(obj) produce a valid pair of iterators (as found via ADL or member functions, with semantics compatible to std::begin and std::end)
  • wide characters (wchar_t, char16_t, char32_t), which are converted to UTF-8: a wide string object (std::wstring, std::u16string, std::u32string) or an array (e.g. a wide string literal); a pointer to a null-terminated wide string (e.g. std::u16string::c_str()) is not supported
IteratorType a compatible iterator type for overload (2); a pair of character iterators whose value_type is an integral type with a size of 1, 2, or 4 bytes (interpreted respectively as UTF-8, UTF-16, and UTF-32) SentinelType

defaults to IteratorType; may be a different type comparable to IteratorType via operator!=, for overload (2), for instance.

  • a custom sentinel type for C++20 ranges
  • std::default_sentinel_t, when IteratorType is std::counted_iterator
SAX a class fulfilling the SAX event listener interface; see json_sax"},{"location":"api/basic_json/sax_parse/#parameters","title":"Parameters","text":"i (in) Input to parse from sax (in) SAX event listener (must not be null) format (in) the format to parse (JSON, BJData, BON8, BSON, CBOR, MessagePack, or UBJSON) (optional, input_format_t::json by default), see input_format_t for more information strict (in) whether the input has to be consumed completely (optional, true by default); when false and the input is a std::istream, the character that terminates a number is consumed unless JSON_PRECISE_STREAM_POSITION is defined to 1; see operator>> ignore_comments (in) whether comments should be ignored and treated like whitespace (true) or yield a parse error (false); (optional, false by default) ignore_trailing_commas (in) whether trailing commas in arrays or objects should be ignored and treated like whitespace (true) or yield a parse error (false); (optional, false by default) tag_handler (in) how to handle CBOR tags; see cbor_tag_handler_t. Ignored for formats other than CBOR (optional, cbor_tag_handler_t::error by default). first (in) iterator to the start of a character range last (in) iterator to the end of a character range, or a sentinel value that compares equal to the end iterator with operator!="},{"location":"api/basic_json/sax_parse/#return-value","title":"Return value","text":"

return value of the last processed SAX event

"},{"location":"api/basic_json/sax_parse/#exception-safety","title":"Exception safety","text":"

Strong guarantee: if an exception is thrown, there are no changes in the JSON value.

"},{"location":"api/basic_json/sax_parse/#exceptions","title":"Exceptions","text":"
  • Throws parse_error.101 in case of an unexpected token, or empty input like a null FILE* or char* pointer.
"},{"location":"api/basic_json/sax_parse/#complexity","title":"Complexity","text":"

Linear in the length of the input. The parser is a predictive LL(1) parser. The complexity can be higher if the SAX consumer sax has a super-linear complexity.

"},{"location":"api/basic_json/sax_parse/#notes","title":"Notes","text":"

A UTF-8 byte order mark is silently ignored.

When reading from a FILE*, the file is locked while it is parsed. The lock is recursive, so the SAX handler may use the same file with stdio functions, but it must not wait for another thread that uses the same FILE object; see JSON_DISABLE_UNLOCKED_FILE_IO.

"},{"location":"api/basic_json/sax_parse/#examples","title":"Examples","text":"Example

The example below demonstrates the sax_parse() function reading from string and processing the events with a user-defined SAX event consumer.

#include <iostream>\n#include <iomanip>\n#include <sstream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\n// a simple event consumer that collects string representations of the passed\n// values; note inheriting from json::json_sax_t is not required, but can\n// help not to forget a required function\nclass sax_event_consumer : public json::json_sax_t\n{\n  public:\n    std::vector<std::string> events;\n\n    bool null() override\n    {\n        events.push_back(\"null()\");\n        return true;\n    }\n\n    bool boolean(bool val) override\n    {\n        events.push_back(\"boolean(val=\" + std::string(val ? \"true\" : \"false\") + \")\");\n        return true;\n    }\n\n    bool number_integer(number_integer_t val) override\n    {\n        events.push_back(\"number_integer(val=\" + std::to_string(val) + \")\");\n        return true;\n    }\n\n    bool number_unsigned(number_unsigned_t val) override\n    {\n        events.push_back(\"number_unsigned(val=\" + std::to_string(val) + \")\");\n        return true;\n    }\n\n    bool number_float(number_float_t val, const string_t& s) override\n    {\n        events.push_back(\"number_float(val=\" + std::to_string(val) + \", s=\" + s + \")\");\n        return true;\n    }\n\n    bool string(string_t& val) override\n    {\n        events.push_back(\"string(val=\" + val + \")\");\n        return true;\n    }\n\n    bool start_object(std::size_t elements) override\n    {\n        events.push_back(\"start_object(elements=\" + std::to_string(elements) + \")\");\n        return true;\n    }\n\n    bool end_object() override\n    {\n        events.push_back(\"end_object()\");\n        return true;\n    }\n\n    bool start_array(std::size_t elements) override\n    {\n        events.push_back(\"start_array(elements=\" + std::to_string(elements) + \")\");\n        return true;\n    }\n\n    bool end_array() override\n    {\n        events.push_back(\"end_array()\");\n        return true;\n    }\n\n    bool key(string_t& val) override\n    {\n        events.push_back(\"key(val=\" + val + \")\");\n        return true;\n    }\n\n    bool binary(json::binary_t& val) override\n    {\n        events.push_back(\"binary(val=[...])\");\n        return true;\n    }\n\n    bool parse_error(std::size_t position, const std::string& last_token, const json::exception& ex) override\n    {\n        events.push_back(\"parse_error(position=\" + std::to_string(position) + \", last_token=\" + last_token + \",\\n            ex=\" + std::string(ex.what()) + \")\");\n        return false;\n    }\n};\n\nint main()\n{\n    // a JSON text\n    const auto* text = R\"(\n    {\n        \"Image\": {\n            \"Width\":  800,\n            \"Height\": 600,\n            \"Title\":  \"View from 15th Floor\",\n            \"Thumbnail\": {\n                \"Url\":    \"http://www.example.com/image/481989943\",\n                \"Height\": 125,\n                \"Width\":  100\n            },\n            \"Animated\" : false,\n            \"IDs\": [116, 943, 234, -38793],\n            \"DeletionDate\": null,\n            \"Distance\": 12.723374634\n        }\n    }]\n    )\";\n\n    // create a SAX event consumer object\n    sax_event_consumer sec;\n\n    // parse JSON\n    bool result = json::sax_parse(text, &sec);\n\n    // output the recorded events\n    for (auto& event : sec.events)\n    {\n        std::cout << event << \"\\n\";\n    }\n\n    // output the result of sax_parse\n    std::cout << \"\\nresult: \" << std::boolalpha << result << '\\n';\n}\n

Output:

start_object(elements=18446744073709551615)\nkey(val=Image)\nstart_object(elements=18446744073709551615)\nkey(val=Width)\nnumber_unsigned(val=800)\nkey(val=Height)\nnumber_unsigned(val=600)\nkey(val=Title)\nstring(val=View from 15th Floor)\nkey(val=Thumbnail)\nstart_object(elements=18446744073709551615)\nkey(val=Url)\nstring(val=http://www.example.com/image/481989943)\nkey(val=Height)\nnumber_unsigned(val=125)\nkey(val=Width)\nnumber_unsigned(val=100)\nend_object()\nkey(val=Animated)\nboolean(val=false)\nkey(val=IDs)\nstart_array(elements=18446744073709551615)\nnumber_unsigned(val=116)\nnumber_unsigned(val=943)\nnumber_unsigned(val=234)\nnumber_integer(val=-38793)\nend_array()\nkey(val=DeletionDate)\nnull()\nkey(val=Distance)\nnumber_float(val=12.723375, s=12.723374634)\nend_object()\nend_object()\nparse_error(position=460, last_token=12.723374634<U+000A>        }<U+000A>    }],\n            ex=[json.exception.parse_error.101] parse error at line 17, column 6: syntax error while parsing value - unexpected ']'; expected end of input)\n\nresult: false\n
"},{"location":"api/basic_json/sax_parse/#see-also","title":"See also","text":"
  • parse - deserialize from a compatible input
  • accept - check if the input is valid JSON
  • JSON_DISABLE_STREAM_BULK_SCAN - read a std::istream one character at a time
  • JSON_DISABLE_UNLOCKED_FILE_IO - read a FILE* with the locking stdio functions
  • SAX Interface - guide to event-based parsing
  • Large, Streamed, and Partial Input - chunked, concatenated, and very large input
"},{"location":"api/basic_json/sax_parse/#version-history","title":"Version history","text":"
  • Added in version 3.2.0.
  • Ignoring comments via ignore_comments added in version 3.9.0.
  • Added ignore_trailing_commas in version 3.13.0 unreleased.
  • Added tag_handler in version 3.13.0 unreleased.
  • Extended container support (1) to include types with lvalue-only ADL begin/end (matching std::begin/std::end semantics) in version 3.13.0 unreleased.
  • Extended overload (2) to accept heterogeneous iterator+sentinel pairs (C++20 ranges support) in version 3.13.0 unreleased.
  • JSON_PRECISE_STREAM_POSITION added in version 3.13.0 unreleased to optionally leave a std::istream positioned right after the parsed value when strict is false.
  • Parsing from an std::istream scans the characters in its stream buffer in bulk in version 3.13.0 unreleased (JSON_DISABLE_STREAM_BULK_SCAN).
  • Parsing from a FILE* locks the file once instead of once per character in version 3.13.0 unreleased (JSON_DISABLE_UNLOCKED_FILE_IO).
  • Ill-formed UTF-16 and UTF-32 input (a lone surrogate, a high surrogate that is not followed by its low surrogate, or a code point above U+10FFFF) is rejected with parse_error.101 in version 3.13.0 unreleased; before that, some such sequences were accepted or ended the input silently.

Deprecation

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 sax_parse({ptr, ptr+len}); with sax_parse(ptr, ptr+len);.

See the migration guide for how to update existing code.

"},{"location":"api/basic_json/size/","title":"nlohmann::basic_json::size","text":"
size_type size() const noexcept;\n

Returns the number of elements in a JSON value.

"},{"location":"api/basic_json/size/#return-value","title":"Return value","text":"

The return value depends on the different types and is defined as follows:

Value type return value null 0 boolean 1 string 1 number 1 binary 1 object result of function object_t::size() array result of function array_t::size()"},{"location":"api/basic_json/size/#exception-safety","title":"Exception safety","text":"

No-throw guarantee: this function never throws exceptions.

"},{"location":"api/basic_json/size/#complexity","title":"Complexity","text":"

Constant, as long as array_t and object_t satisfy the Container concept; that is, their size() functions have constant complexity.

"},{"location":"api/basic_json/size/#notes","title":"Notes","text":"

This function does not return the length of a string stored as JSON value \u2014 it returns the number of elements in the JSON value which is 1 in the case of a string.

"},{"location":"api/basic_json/size/#examples","title":"Examples","text":"Example

The following code calls size() on the different value types.

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create JSON values\n    json j_null;\n    json j_boolean = true;\n    json j_number_integer = 17;\n    json j_number_float = 23.42;\n    json j_object = {{\"one\", 1}, {\"two\", 2}};\n    json j_object_empty(json::value_t::object);\n    json j_array = {1, 2, 4, 8, 16};\n    json j_array_empty(json::value_t::array);\n    json j_string = \"Hello, world\";\n\n    // call size()\n    std::cout << j_null.size() << '\\n';\n    std::cout << j_boolean.size() << '\\n';\n    std::cout << j_number_integer.size() << '\\n';\n    std::cout << j_number_float.size() << '\\n';\n    std::cout << j_object.size() << '\\n';\n    std::cout << j_object_empty.size() << '\\n';\n    std::cout << j_array.size() << '\\n';\n    std::cout << j_array_empty.size() << '\\n';\n    std::cout << j_string.size() << '\\n';\n}\n

Output:

0\n1\n1\n1\n2\n0\n5\n0\n1\n
"},{"location":"api/basic_json/size/#see-also","title":"See also","text":"
  • empty - checks whether the JSON value has no elements
  • max_size - returns the maximum possible number of elements
  • basic_json_view::size - the same function on a zero-copy view
"},{"location":"api/basic_json/size/#version-history","title":"Version history","text":"
  • Added in version 1.0.0.
  • Extended to return 1 for binary types in version 3.8.0.
"},{"location":"api/basic_json/start_pos/","title":"nlohmann::basic_json::start_pos","text":"
#if JSON_DIAGNOSTIC_POSITIONS\nconstexpr std::size_t start_pos() const noexcept;\n#endif\n

Returns the position of the first character in the JSON string from which the value was parsed from.

JSON type return value object position of the opening { array position of the opening [ string position of the opening \" number position of the first character boolean position of t for true and f for false null position of n"},{"location":"api/basic_json/start_pos/#return-value","title":"Return value","text":"

the position of the first character of the value in the parsed JSON string, if the value was created by the parse function, or std::string::npos if the value was constructed otherwise

"},{"location":"api/basic_json/start_pos/#exception-safety","title":"Exception safety","text":"

No-throw guarantee: this member function never throws exceptions.

"},{"location":"api/basic_json/start_pos/#complexity","title":"Complexity","text":"

Constant.

"},{"location":"api/basic_json/start_pos/#notes","title":"Notes","text":"

Note

The function is only available if macro JSON_DIAGNOSTIC_POSITIONS has been defined to 1 before including the library header.

Invalidation

The returned positions are only valid as long as the JSON value is not changed. The positions are not updated when the JSON value is changed.

"},{"location":"api/basic_json/start_pos/#examples","title":"Examples","text":"Example
#include <iostream>\n\n#define JSON_DIAGNOSTIC_POSITIONS 1\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    std::string json_string = R\"(\n    {\n        \"address\": {\n            \"street\": \"Fake Street\",\n            \"housenumber\": 1\n        }\n    }\n    )\";\n    json j = json::parse(json_string);\n\n    std::cout << \"Root diagnostic positions: \\n\";\n    std::cout << \"\\tstart_pos: \" << j.start_pos() << '\\n';\n    std::cout << \"\\tend_pos:\" << j.end_pos() << \"\\n\";\n    std::cout << \"Original string: \\n\";\n    std::cout << \"{\\n        \\\"address\\\": {\\n            \\\"street\\\": \\\"Fake Street\\\",\\n            \\\"housenumber\\\": 1\\n        }\\n    }\" << \"\\n\";\n    std::cout << \"Parsed string: \\n\";\n    std::cout << json_string.substr(j.start_pos(), j.end_pos() - j.start_pos()) << \"\\n\\n\";\n\n    std::cout << \"address diagnostic positions: \\n\";\n    std::cout << \"\\tstart_pos:\" << j[\"address\"].start_pos() << '\\n';\n    std::cout << \"\\tend_pos:\" << j[\"address\"].end_pos() << \"\\n\\n\";\n    std::cout << \"Original string: \\n\";\n    std::cout << \"{            \\\"street\\\": \\\"Fake Street\\\",\\n            \\\"housenumber\\\": 1\\n        }\" << \"\\n\";\n    std::cout << \"Parsed string: \\n\";\n    std::cout << json_string.substr(j[\"address\"].start_pos(), j[\"address\"].end_pos() - j[\"address\"].start_pos()) << \"\\n\\n\";\n\n    std::cout << \"street diagnostic positions: \\n\";\n    std::cout << \"\\tstart_pos:\" << j[\"address\"][\"street\"].start_pos() << '\\n';\n    std::cout << \"\\tend_pos:\" << j[\"address\"][\"street\"].end_pos() << \"\\n\\n\";\n    std::cout << \"Original string: \\n\";\n    std::cout << \"\\\"Fake Street\\\"\" << \"\\n\";\n    std::cout << \"Parsed string: \\n\";\n    std::cout << json_string.substr(j[\"address\"][\"street\"].start_pos(), j[\"address\"][\"street\"].end_pos() - j[\"address\"][\"street\"].start_pos()) << \"\\n\\n\";\n\n    std::cout << \"housenumber diagnostic positions: \\n\";\n    std::cout << \"\\tstart_pos:\" << j[\"address\"][\"housenumber\"].start_pos() << '\\n';\n    std::cout << \"\\tend_pos:\" << j[\"address\"][\"housenumber\"].end_pos() << \"\\n\\n\";\n    std::cout << \"Original string: \\n\";\n    std::cout << \"1\" << \"\\n\";\n    std::cout << \"Parsed string: \\n\";\n    std::cout << json_string.substr(j[\"address\"][\"housenumber\"].start_pos(), j[\"address\"][\"housenumber\"].end_pos() - j[\"address\"][\"housenumber\"].start_pos()) << \"\\n\\n\";\n}\n

Output:

Root diagnostic positions: \n    start_pos: 5\n    end_pos:109\nOriginal string: \n{\n        \"address\": {\n            \"street\": \"Fake Street\",\n            \"housenumber\": 1\n        }\n    }\nParsed string: \n{\n        \"address\": {\n            \"street\": \"Fake Street\",\n            \"housenumber\": 1\n        }\n    }\n\naddress diagnostic positions: \n    start_pos:26\n    end_pos:103\n\nOriginal string: \n{            \"street\": \"Fake Street\",\n            \"housenumber\": 1\n        }\nParsed string: \n{\n            \"street\": \"Fake Street\",\n            \"housenumber\": 1\n        }\n\nstreet diagnostic positions: \n    start_pos:50\n    end_pos:63\n\nOriginal string: \n\"Fake Street\"\nParsed string: \n\"Fake Street\"\n\nhousenumber diagnostic positions: \n    start_pos:92\n    end_pos:93\n\nOriginal string: \n1\nParsed string: \n1\n

The output shows the start/end positions of all the objects and fields in the JSON string.

"},{"location":"api/basic_json/start_pos/#see-also","title":"See also","text":"
  • end_pos - to access the end position
  • JSON_DIAGNOSTIC_POSITIONS - overview of the supported conversions
  • Parsing and Exceptions - handling parse errors and locating them in the input
"},{"location":"api/basic_json/start_pos/#version-history","title":"Version history","text":"
  • Added in version 3.12.0.
"},{"location":"api/basic_json/std_formatter/","title":"std::formatter<nlohmann::basic_json>","text":"
namespace std {\n    template <>\n    struct formatter<nlohmann::basic_json, char>;\n}\n

Specialization to make JSON values formattable with std::format (and the other members of C++20's <format> header, such as std::format_to).

A subset of the standard format spec grammar is supported, repurposed for JSON pretty-printing; any other spec component (sign, the 0 flag, precision, L, a dynamic width such as \"{:{}}\", or a trailing type character) throws std::format_error:

  • \"{}\" serializes the value the same way as dump() (compact, no whitespace).
  • \"{:#}\" (\"alternate form\") serializes the value the same way as dump(4) (pretty-printed with an indent of 4).
  • A width, with or without \"#\" (e.g. \"{:2}\" or \"{:#2}\"), serializes the value the same way as dump(width) \u2014 a width on its own implies pretty-printing, since an indent size has no meaning for compact output.
  • fill-and-align (e.g. \"{:.>#}\" or \"{:.>3}\") picks a custom indent character, the same way as dump(indent, indent_char). The alignment direction itself ('<', '>', '^') has no separate meaning for JSON values \u2014 only the fill character before it is used, and any of the three directions is accepted.

This specialization is only available for char-based JSON values and only if the standard library provides <format>, controlled by the JSON_HAS_STD_FORMAT macro.

"},{"location":"api/basic_json/std_formatter/#examples","title":"Examples","text":"Example

The example shows how to format JSON values with std::format.

#include <format>\n#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    json j = {{\"one\", 1}, {\"two\", 2}};\n\n    // compact formatting, like dump()\n    std::cout << std::format(\"{}\", j) << \"\\n\\n\";\n\n    // pretty-printed formatting, like dump(4)\n    std::cout << std::format(\"{:#}\", j) << \"\\n\\n\";\n\n    // a width sets the indent, like dump(2)\n    std::cout << std::format(\"{:2}\", j) << \"\\n\\n\";\n\n    // fill-and-align sets the indent character, like dump(4, '.')\n    std::cout << std::format(\"{:.>#}\", j) << std::endl;\n}\n

Output:

{\"one\":1,\"two\":2}\n\n{\n    \"one\": 1,\n    \"two\": 2\n}\n\n{\n  \"one\": 1,\n  \"two\": 2\n}\n\n{\n....\"one\": 1,\n....\"two\": 2\n}\n
"},{"location":"api/basic_json/std_formatter/#see-also","title":"See also","text":"
  • dump - serialization
  • operator<<(std::ostream&) - serialize to stream
  • format_as - customization point used by fmt::format (fmtlib)
  • Serialization - the serialization article
"},{"location":"api/basic_json/std_formatter/#version-history","title":"Version history","text":"
  • Added in version 3.13.0 unreleased.
"},{"location":"api/basic_json/std_hash/","title":"std::hash<nlohmann::basic_json>","text":"
namespace std {\n    struct hash<nlohmann::basic_json>;\n}\n

Return a hash value for a JSON object. The hash function tries to rely on std::hash where possible. Furthermore, the type of the JSON value is taken into account, so null, false, and numbers may hash differently from each other. Numbers that compare equal under operator== always hash equally, regardless of whether they are stored as signed integer, unsigned integer, or floating-point number.

Numbers are hashed by their value converted to number_float_t. Converting an integer to number_float_t therefore keeps its hash, but converting a floating-point number to an integer type is lossy and can change it: 0.5 converts to 0, which need not have the same hash. Unequal numbers can also share a hash value, for example two large integers that convert to the same number_float_t.

"},{"location":"api/basic_json/std_hash/#examples","title":"Examples","text":"Example

The example shows how to calculate hash values for different JSON values.

#include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\nusing namespace nlohmann::literals;\n\nint main()\n{\n    std::cout << \"hash(null) = \" << std::hash<json> {}(json(nullptr)) << '\\n'\n              << \"hash(false) = \" << std::hash<json> {}(json(false)) << '\\n'\n              << \"hash(0) = \" << std::hash<json> {}(json(0)) << '\\n'\n              << \"hash(0U) = \" << std::hash<json> {}(json(0U)) << '\\n'\n              << \"hash(0.0) = \" << std::hash<json> {}(json(0.0)) << '\\n'\n              << \"hash(\\\"\\\") = \" << std::hash<json> {}(json(\"\")) << '\\n'\n              << \"hash({}) = \" << std::hash<json> {}(json::object()) << '\\n'\n              << \"hash([]) = \" << std::hash<json> {}(json::array()) << '\\n'\n              << \"hash({\\\"hello\\\": \\\"world\\\"}) = \" << std::hash<json> {}(\"{\\\"hello\\\": \\\"world\\\"}\"_json)\n              << '\\n';\n}\n

Output:

hash(null) = 2654435769\nhash(false) = 2654436030\nhash(0) = 2654436221\nhash(0U) = 2654436221\nhash(0.0) = 2654436221\nhash(\"\") = 11160318156688833227\nhash({}) = 2654435832\nhash([]) = 2654435899\nhash({\"hello\": \"world\"}) = 3701319991624763853\n

The hash values shown are examples only. They depend on the platform, the compiler, and the compiler version, and they can change between versions of this library. Do not persist them or rely on specific values.

"},{"location":"api/basic_json/std_hash/#see-also","title":"See also","text":"
  • operator== - compares two JSON values for equality, consistent with equal hash values
  • Types - the JSON value types and how they compare
"},{"location":"api/basic_json/std_hash/#version-history","title":"Version history","text":"
  • Added in version 1.0.0.
  • Extended for arbitrary basic_json types in version 3.10.5.
  • Numbers that compare equal hash equally since version 3.13.0 unreleased; before, 0, 0U, and 0.0 had different hash values.
"},{"location":"api/basic_json/std_swap/","title":"std::swap<basic_json>","text":"
namespace std {\n    void swap(nlohmann::basic_json& j1, nlohmann::basic_json& j2);\n}\n

Exchanges the values of two JSON objects.

"},{"location":"api/basic_json/std_swap/#parameters","title":"Parameters","text":"j1 (in, out) value to be replaced by j2 j2 (in, out) value to be replaced by j1"},{"location":"api/basic_json/std_swap/#exception-safety","title":"Exception safety","text":"

No-throw guarantee: this function never throws exceptions.

"},{"location":"api/basic_json/std_swap/#complexity","title":"Complexity","text":"

Constant.

"},{"location":"api/basic_json/std_swap/#possible-implementation","title":"Possible implementation","text":"
void swap(nlohmann::basic_json& j1, nlohmann::basic_json& j2)\n{\n    j1.swap(j2);\n}\n
"},{"location":"api/basic_json/std_swap/#examples","title":"Examples","text":"Example

The following code shows how two values are swapped with std::swap.

#include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create JSON values\n    json j1 = {{\"one\", 1}, {\"two\", 2}};\n    json j2 = {1, 2, 4, 8, 16};\n\n    std::cout << \"j1 = \" << j1 << \" | j2 = \" << j2 << '\\n';\n\n    // swap values\n    std::swap(j1, j2);\n\n    std::cout << \"j1 = \" << j1 << \" | j2 = \" << j2 << '\\n';\n}\n

Output:

j1 = {\"one\":1,\"two\":2} | j2 = [1,2,4,8,16]\nj1 = [1,2,4,8,16] | j2 = {\"one\":1,\"two\":2}\n
"},{"location":"api/basic_json/std_swap/#see-also","title":"See also","text":"
  • swap - exchange the contents of two JSON values
"},{"location":"api/basic_json/std_swap/#version-history","title":"Version history","text":"
  • Added in version 1.0.0.
  • Extended for arbitrary basic_json types in version 3.10.5.
"},{"location":"api/basic_json/string_t/","title":"nlohmann::basic_json::string_t","text":"
using string_t = StringType;\n

The type used to store JSON strings.

RFC 8259 describes JSON strings as follows:

A string is a sequence of zero or more Unicode characters.

To store strings in C++, a type is defined by the template parameter described below. Unicode values are split by the JSON class into byte-sized characters during deserialization.

"},{"location":"api/basic_json/string_t/#template-parameters","title":"Template parameters","text":"StringType

the container to store strings (e.g., std::string). Note this container is used for keys/names in objects, see object_t.

StringType must have a char-compatible value_type: the library relies on UTF-8/char-based storage and processing internally, so std::wstring, std::u16string, and std::u32string are not valid choices for StringType. To work with wide-character data, convert it to/from UTF-8 at the boundary instead \u2014 see the FAQ's wide string handling section for a conversion recipe.

Beyond the character type, the library expects a substantial part of the std::string interface (contiguous null-terminated data(), substr(), find(), append(), ...). See Template Parameter Requirements for the full list and for the string types that are known to work.

"},{"location":"api/basic_json/string_t/#notes","title":"Notes","text":""},{"location":"api/basic_json/string_t/#default-type","title":"Default type","text":"

With the default values for StringType (std::string), the default type for string_t is std::string.

"},{"location":"api/basic_json/string_t/#encoding","title":"Encoding","text":"

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.

"},{"location":"api/basic_json/string_t/#string-comparison","title":"String comparison","text":"

RFC 8259 states:

Software implementations are typically required to test names of object members for equality. Implementations that transform the textual representation into sequences of Unicode code units and then perform the comparison numerically, code unit by code unit, are interoperable in the sense that implementations will agree in all cases on equality or inequality of two strings. For example, implementations that compare strings with escaped characters unconverted may incorrectly find that \"a\\\\b\" and \"a\\u005Cb\" are not equal.

This implementation is interoperable as it does compare strings code unit by code unit.

"},{"location":"api/basic_json/string_t/#storage","title":"Storage","text":"

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.

"},{"location":"api/basic_json/string_t/#cross-basic_json-conversion-requirements","title":"Cross-basic_json conversion requirements","text":"

When converting a string value from one basic_json specialization to another via the converting constructor (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 for details and an example.

"},{"location":"api/basic_json/string_t/#examples","title":"Examples","text":"Example

The following code shows that string_t is by default, a typedef to std::string.

#include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    std::cout << std::boolalpha << std::is_same<std::string, json::string_t>::value << '\\n';\n}\n

Output:

true\n
"},{"location":"api/basic_json/string_t/#see-also","title":"See also","text":"
  • object_t - the type used to store JSON objects (and their keys, which are also string_t)
  • binary_t - the type used to store binary values
  • get_ptr - returns a pointer to the stored string value
  • Types - how strings are stored
  • Template Parameter Requirements - requirements on the StringType template parameter
"},{"location":"api/basic_json/string_t/#version-history","title":"Version history","text":"
  • Added in version 1.0.0.
  • Removed the requirement that string_t be implicitly convertible from std::string, which the BSON writer and the UBJSON reader relied on, in version 3.13.0 unreleased.
"},{"location":"api/basic_json/swap/","title":"nlohmann::basic_json::swap","text":"
// (1)\nvoid swap(reference other) noexcept (\n    std::is_nothrow_move_constructible<value_t>::value &&\n    std::is_nothrow_move_assignable<value_t>::value &&\n    std::is_nothrow_move_constructible<json_value>::value &&\n    std::is_nothrow_move_assignable<json_value>::value &&\n    std::is_nothrow_move_constructible<json_base_class_t>::value &&\n    std::is_nothrow_move_assignable<json_base_class_t>::value\n);\n\n// (2)\nfriend void swap(reference left, reference right) noexcept (\n    std::is_nothrow_move_constructible<value_t>::value &&\n    std::is_nothrow_move_assignable<value_t>::value &&\n    std::is_nothrow_move_constructible<json_value>::value &&\n    std::is_nothrow_move_assignable<json_value>::value &&\n    std::is_nothrow_move_constructible<json_base_class_t>::value &&\n    std::is_nothrow_move_assignable<json_base_class_t>::value\n);\n\n// (3)\nvoid swap(array_t& other);\n\n// (4)\nvoid swap(object_t& other);\n\n// (5)\nvoid swap(string_t& other);\n\n// (6)\nvoid swap(binary_t& other);\n\n// (7)\nvoid swap(typename binary_t::container_type& other);\n
  1. Exchanges the contents of the JSON value 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. If macro JSON_DIAGNOSTIC_POSITIONS is defined to 1, the start_pos()/end_pos() diagnostic positions are exchanged along with the value. The json_base_class_t 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 is defined to 1, the start_pos()/end_pos() diagnostic positions are exchanged along with the value. The json_base_class_t 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 individual elements. All iterators and references remain valid. The past-the-end iterator is invalidated.
  5. Exchanges the contents of a JSON string 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.
  6. Exchanges the contents of a binary value 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.
  7. Exchanges the contents of a binary value 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. Unlike version (6), no binary subtype is involved.
"},{"location":"api/basic_json/swap/#parameters","title":"Parameters","text":"other (in, out) value to exchange the contents with left (in, out) value to exchange the contents with right (in, out) value to exchange the contents with"},{"location":"api/basic_json/swap/#exception-safety","title":"Exception safety","text":"
  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.
"},{"location":"api/basic_json/swap/#exceptions","title":"Exceptions","text":"
  1. No-throw guarantee: this function never throws exceptions.
  2. No-throw guarantee: this function never throws exceptions.
  3. Throws type_error.310 if called on JSON values other than arrays; example: \"cannot use swap(array_t&) with boolean\"
  4. Throws type_error.310 if called on JSON values other than objects; example: \"cannot use swap(object_t&) with boolean\"
  5. Throws type_error.310 if called on JSON values other than strings; example: \"cannot use swap(string_t&) with boolean\"
  6. Throws type_error.310 if called on JSON values other than binaries; example: \"cannot use swap(binary_t&) with boolean\"
  7. Throws type_error.310 if called on JSON values other than binaries; example: \"cannot use swap(binary_t::container_type&) with boolean\"
"},{"location":"api/basic_json/swap/#complexity","title":"Complexity","text":"

Constant.

"},{"location":"api/basic_json/swap/#examples","title":"Examples","text":"Example: (1, 2) swap JSON values

The example below shows how JSON values can be swapped with swap().

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create two JSON values\n    json j1 = {1, 2, 3, 4, 5};\n    json j2 = {{\"pi\", 3.141592653589793}, {\"e\", 2.718281828459045}};\n\n    // swap the values\n    j1.swap(j2);\n\n    // output the values\n    std::cout << \"j1 = \" << j1 << '\\n';\n    std::cout << \"j2 = \" << j2 << '\\n';\n}\n

Output:

j1 = {\"e\":2.718281828459045,\"pi\":3.141592653589793}\nj2 = [1,2,3,4,5]\n
Example: (3) swap array

The example below shows how arrays can be swapped with swap().

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create a JSON value\n    json value = {{\"array\", {1, 2, 3, 4}}};\n\n    // create an array_t\n    json::array_t array = {\"Snap\", \"Crackle\", \"Pop\"};\n\n    // swap the array stored in the JSON value\n    value[\"array\"].swap(array);\n\n    // output the values\n    std::cout << \"value = \" << value << '\\n';\n    std::cout << \"array = \" << array << '\\n';\n}\n

Output:

value = {\"array\":[\"Snap\",\"Crackle\",\"Pop\"]}\narray = [1,2,3,4]\n
Example: (4) swap object

The example below shows how objects can be swapped with swap().

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create a JSON value\n    json value = { {\"translation\", {{\"one\", \"eins\"}, {\"two\", \"zwei\"}}} };\n\n    // create an object_t\n    json::object_t object = {{\"cow\", \"Kuh\"}, {\"dog\", \"Hund\"}};\n\n    // swap the object stored in the JSON value\n    value[\"translation\"].swap(object);\n\n    // output the values\n    std::cout << \"value = \" << value << '\\n';\n    std::cout << \"object = \" << object << '\\n';\n}\n

Output:

value = {\"translation\":{\"cow\":\"Kuh\",\"dog\":\"Hund\"}}\nobject = {\"one\":\"eins\",\"two\":\"zwei\"}\n
Example: (5) swap string

The example below shows how strings can be swapped with swap().

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create a JSON value\n    json value = { \"the good\", \"the bad\", \"the ugly\" };\n\n    // create string_t\n    json::string_t string = \"the fast\";\n\n    // swap the object stored in the JSON value\n    value[1].swap(string);\n\n    // output the values\n    std::cout << \"value = \" << value << '\\n';\n    std::cout << \"string = \" << string << '\\n';\n}\n

Output:

value = [\"the good\",\"the fast\",\"the ugly\"]\nstring = the bad\n
Example: (6) swap binary

The example below shows how binary values can be swapped with swap().

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create a binary value\n    json value = json::binary({1, 2, 3});\n\n    // create a binary_t\n    json::binary_t binary = {{4, 5, 6}};\n\n    // swap the object stored in the JSON value\n    value.swap(binary);\n\n    // output the values\n    std::cout << \"value = \" << value << '\\n';\n    std::cout << \"binary = \" << json(binary) << '\\n';\n}\n

Output:

value = {\"bytes\":[4,5,6],\"subtype\":null}\nbinary = {\"bytes\":[1,2,3],\"subtype\":null}\n
"},{"location":"api/basic_json/swap/#see-also","title":"See also","text":"
  • std::swap<basic_json\\> - specialization of std::swap for JSON values
  • operator= - copy assignment
  • basic_json - create a JSON value
"},{"location":"api/basic_json/swap/#version-history","title":"Version history","text":"
  1. Added in version 1.0.0. Exchanges the json_base_class_t subobject along with the value since version 3.13.0 unreleased.
  2. Added in version 1.0.0. Exchanges the json_base_class_t subobject along with the value since version 3.13.0 unreleased.
  3. Added in version 1.0.0.
  4. Added in version 1.0.0.
  5. Added in version 1.0.0.
  6. Added in version 3.8.0.
  7. Added in version 3.8.0.
"},{"location":"api/basic_json/to_bjdata/","title":"nlohmann::basic_json::to_bjdata","text":"
// (1)\nstatic std::vector<std::uint8_t> to_bjdata(const basic_json& j,\n                                           const bool use_size = false,\n                                           const bool use_type = false,\n                                           const bjdata_version_t version = bjdata_version_t::draft2,\n                                           const error_handler_t error_handler = error_handler_t::keep);\n\n// (2)\nstatic void to_bjdata(const basic_json& j, detail::output_adapter<std::uint8_t> o,\n                      const bool use_size = false, const bool use_type = false,\n                      const bjdata_version_t version = bjdata_version_t::draft2,\n                      const error_handler_t error_handler = error_handler_t::keep);\nstatic void to_bjdata(const basic_json& j, detail::output_adapter<char> o,\n                      const bool use_size = false, const bool use_type = false,\n                      const bjdata_version_t version = bjdata_version_t::draft2,\n                      const error_handler_t error_handler = error_handler_t::keep);\n

Serializes a given JSON value j to a byte vector using the BJData (Binary JData) serialization format. BJData aims to be more compact than JSON itself, yet more efficient to parse.

  1. Returns a byte vector containing the BJData serialization.
  2. Writes the BJData serialization to an output adapter.

The exact mapping and its limitations are described on a dedicated page.

"},{"location":"api/basic_json/to_bjdata/#parameters","title":"Parameters","text":"j (in) JSON value to serialize o (in) output adapter to write serialization to use_size (in) whether to add size annotations to container types; optional, false by default. use_type (in) whether to add type annotations to container types (must be combined with use_size = true); optional, false by default. version (in) which version of BJData to use, see bjdata_version_t and the note on \"Binary values\" on BJData; optional, bjdata_version_t::draft2 by default. error_handler (in) how to treat a string or object key in j that is not valid UTF-8; see error_handler_t. The default, keep, writes the ill-formed bytes to the output as is, as every version of to_bjdata did before this parameter was added; strict throws; replace/ignore sanitize it the same way dump would. If JSON_STRICT_BINARY_UTF8 is enabled, the default is strict instead."},{"location":"api/basic_json/to_bjdata/#return-value","title":"Return value","text":"
  1. BJData serialization as byte vector
  2. (none)
"},{"location":"api/basic_json/to_bjdata/#exception-safety","title":"Exception safety","text":"

Strong guarantee: if an exception is thrown, there are no changes in the JSON value.

"},{"location":"api/basic_json/to_bjdata/#exceptions","title":"Exceptions","text":"
  • Throws other_error.502 if use_type is true and use_size is false, and j contains a non-empty array or object, or a non-empty binary value (with version = bjdata_version_t::draft3, any binary value, including an empty one). Scalars, empty arrays, and empty objects do not throw.
  • Throws type_error.316 if a string or object key in j is not valid UTF-8 and error_handler is strict (the default only if JSON_STRICT_BINARY_UTF8 is enabled)
  • Throws type_error.321 if j or a value nested in it is discarded; example: \"cannot serialize discarded value to BJData\"
"},{"location":"api/basic_json/to_bjdata/#complexity","title":"Complexity","text":"

Linear in the size of the JSON value j.

"},{"location":"api/basic_json/to_bjdata/#examples","title":"Examples","text":"Example: serialize a JSON value to BJData

The example shows the serialization of a JSON value to a byte vector in BJData format.

#include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\nusing namespace nlohmann::literals;\n\n// function to print BJData's diagnostic format\nvoid print_byte(uint8_t byte)\n{\n    if (32 < byte and byte < 128)\n    {\n        std::cout << static_cast<char>(byte);\n    }\n    else\n    {\n        std::cout << static_cast<int>(byte);\n    }\n}\n\nint main()\n{\n    // create a JSON value\n    json j = R\"({\"compact\": true, \"schema\": false})\"_json;\n\n    // serialize it to BJData\n    std::vector<std::uint8_t> v = json::to_bjdata(j);\n\n    // print the vector content\n    for (auto& byte : v)\n    {\n        print_byte(byte);\n    }\n    std::cout << '\\n';\n\n    // create an array of numbers\n    json array = {1, 2, 3, 4, 5, 6, 7, 8};\n\n    // serialize it to BJData using default representation\n    std::vector<std::uint8_t> v_array = json::to_bjdata(array);\n    // serialize it to BJData using size optimization\n    std::vector<std::uint8_t> v_array_size = json::to_bjdata(array, true);\n    // serialize it to BJData using type optimization\n    std::vector<std::uint8_t> v_array_size_and_type = json::to_bjdata(array, true, true);\n\n    // print the vector contents\n    for (auto& byte : v_array)\n    {\n        print_byte(byte);\n    }\n    std::cout << '\\n';\n\n    for (auto& byte : v_array_size)\n    {\n        print_byte(byte);\n    }\n    std::cout << '\\n';\n\n    for (auto& byte : v_array_size_and_type)\n    {\n        print_byte(byte);\n    }\n    std::cout << '\\n';\n}\n

Output:

{i7compactTi6schemaF}\n[i1i2i3i4i5i6i7i8]\n[#i8i1i2i3i4i5i6i7i8\n[$i#i812345678\n
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.

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create a non-empty JSON array\n    json j = {1, 2, 3};\n\n    // exception other_error.502\n    try\n    {\n        json::to_bjdata(j, false, true);\n    }\n    catch (const json::other_error& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n}\n

Output:

[json.exception.other_error.502] use_type requires use_size = true\n
"},{"location":"api/basic_json/to_bjdata/#see-also","title":"See also","text":"
  • BJData - the format, its byte layout and how values are mapped
  • Binary formats - overview and comparison of the supported binary formats
  • Binary values - how binary values and subtypes are handled
  • from_bjdata - create a JSON value from an input in BJData format
  • to_cbor - create a CBOR serialization of a JSON value
  • to_msgpack - create a MessagePack serialization of a JSON value
  • to_bson - create a BSON serialization of a JSON value
  • to_ubjson - create a UBJSON serialization of a JSON value
  • to_bon8 - create a BON8 serialization of a JSON value
"},{"location":"api/basic_json/to_bjdata/#version-history","title":"Version history","text":"
  • Added in version 3.11.0.
  • BJData version parameter (for draft3 binary encoding) added in version 3.12.0.
  • Added error_handler parameter in version 3.13.0 unreleased. Its default, keep, writes the bytes of a string or object key that is not valid UTF-8 unchanged, as before; strict (the default if JSON_STRICT_BINARY_UTF8 is enabled) throws type_error.316.
  • Throws type_error.321 for a discarded value since version 3.13.0 unreleased; previously, a discarded value nested in an array or object was silently skipped, producing invalid BJData.
"},{"location":"api/basic_json/to_bon8/","title":"nlohmann::basic_json::to_bon8","text":"
// (1)\nstatic std::vector<std::uint8_t> to_bon8(const basic_json& j);\n\n// (2)\nstatic void to_bon8(const basic_json& j, detail::output_adapter<std::uint8_t> o);\nstatic void to_bon8(const basic_json& j, detail::output_adapter<char> o);\n

Serializes a given JSON value j to a byte vector using the BON8 (Binary Object Notation 8) serialization format. BON8 is a compact binary serialization format that stores strings as UTF-8 without a length prefix.

  1. Returns a byte vector containing the BON8 serialization.
  2. Writes the BON8 serialization to an output adapter.

The exact mapping and its limitations are described on a dedicated page.

"},{"location":"api/basic_json/to_bon8/#parameters","title":"Parameters","text":"j (in) JSON value to serialize o (in) output adapter to write serialization to"},{"location":"api/basic_json/to_bon8/#return-value","title":"Return value","text":"
  1. BON8 serialization as a byte vector
  2. (none)
"},{"location":"api/basic_json/to_bon8/#exception-safety","title":"Exception safety","text":"

Strong guarantee: if an exception is thrown, there are no changes in the JSON value j, which is never modified. With (2), the bytes written before the exception remain in the output adapter.

"},{"location":"api/basic_json/to_bon8/#exceptions","title":"Exceptions","text":"
  • Throws out_of_range.407 if j contains an integer outside the range of int64 (an unsigned integer above 9223372036854775807, or, with a number type wider than 64 bits, any integer beyond int64), which BON8 cannot represent
  • Throws type_error.316 if j contains a string that is not valid UTF-8
  • Throws type_error.321 if j or a value nested in it is discarded; example: \"cannot serialize discarded value to BON8\"
"},{"location":"api/basic_json/to_bon8/#complexity","title":"Complexity","text":"

Linear in the size of the JSON value j.

"},{"location":"api/basic_json/to_bon8/#examples","title":"Examples","text":"Example: serialize a JSON value to BON8

The example shows the serialization of a JSON value to a byte vector in BON8 format.

#include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\nusing namespace nlohmann::literals;\n\nint main()\n{\n    // create a JSON value\n    json j = R\"({\"compact\": true, \"format\": \"BON8\", \"schema\": 0})\"_json;\n\n    // serialize it to BON8\n    std::vector<std::uint8_t> v = json::to_bon8(j);\n\n    // print the vector content\n    for (auto& byte : v)\n    {\n        std::cout << \"0x\" << std::hex << std::setw(2) << std::setfill('0') << static_cast<int>(byte) << \" \";\n    }\n    std::cout << '\\n';\n}\n

Output:

0x89 0x63 0x6f 0x6d 0x70 0x61 0x63 0x74 0xf9 0x66 0x6f 0x72 0x6d 0x61 0x74 0xff 0x42 0x4f 0x4e 0x38 0xff 0x73 0x63 0x68 0x65 0x6d 0x61 0x90 \n
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.

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create a JSON string that is not valid UTF-8\n    std::string invalid_utf8;\n    invalid_utf8.push_back(static_cast<char>(0xFF));\n    json j = invalid_utf8;\n\n    // exception type_error.316\n    try\n    {\n        json::to_bon8(j);\n    }\n    catch (const json::type_error& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n}\n

Output:

[json.exception.type_error.316] invalid UTF-8 byte at index 0: 0xFF\n
"},{"location":"api/basic_json/to_bon8/#see-also","title":"See also","text":"
  • BON8 - the format, its byte layout and how values are mapped
  • Binary formats - overview and comparison of the supported binary formats
  • from_bon8 - create a JSON value from an input in BON8 format
  • to_cbor - create a CBOR serialization of a JSON value
  • to_msgpack - create a MessagePack serialization of a JSON value
  • to_bson - create a BSON serialization of a JSON value
  • to_ubjson - create a UBJSON serialization of a JSON value
  • to_bjdata - create a BJData serialization of a JSON value
"},{"location":"api/basic_json/to_bon8/#version-history","title":"Version history","text":"
  • Added in version 3.13.0 unreleased.
"},{"location":"api/basic_json/to_bson/","title":"nlohmann::basic_json::to_bson","text":"
// (1)\nstatic std::vector<std::uint8_t> to_bson(const basic_json& j,\n                                         const error_handler_t error_handler = error_handler_t::keep);\n\n// (2)\nstatic void to_bson(const basic_json& j, detail::output_adapter<std::uint8_t> o,\n                    const error_handler_t error_handler = error_handler_t::keep);\nstatic void to_bson(const basic_json& j, detail::output_adapter<char> o,\n                    const error_handler_t error_handler = error_handler_t::keep);\n

BSON (Binary JSON) is a binary format in which zero or more ordered key/value pairs are stored as a single entity (a so-called document). The members of an object are written in the order in which iteration visits them.

  1. Returns a byte vector containing the BSON serialization.
  2. Writes the BSON serialization to an output adapter.

The exact mapping and its limitations are described on a dedicated page.

"},{"location":"api/basic_json/to_bson/#parameters","title":"Parameters","text":"j (in) JSON value to serialize o (in) output adapter to write serialization to error_handler (in) how to treat a string or object key in j that is not valid UTF-8; see error_handler_t. The default, keep, writes the ill-formed bytes to the output as is, as every version of to_bson did before this parameter was added; strict throws; replace/ignore sanitize it the same way dump would. If JSON_STRICT_BINARY_UTF8 is enabled, the default is strict instead."},{"location":"api/basic_json/to_bson/#return-value","title":"Return value","text":"
  1. BSON serialization as a byte vector
  2. (none)
"},{"location":"api/basic_json/to_bson/#exception-safety","title":"Exception safety","text":"

Strong guarantee: if an exception is thrown, there are no changes in the JSON value.

"},{"location":"api/basic_json/to_bson/#exceptions","title":"Exceptions","text":"
  • Throws type_error.317 if the top-level type of the JSON value is not an object; example: \"to serialize to BSON, top-level type must be object, but is string\"
  • Throws out_of_range.407 if j contains a signed integer outside the range of int64 or an unsigned integer outside the range of uint64, which is only possible with a number type wider than 64 bits; example: \"integer number 9223372036854775808 cannot be represented by BSON as it does not fit int64\"
  • Throws out_of_range.409 if a key in the JSON object contains a null byte (code point U+0000); example: \"BSON key cannot contain code point U+0000 (at byte 2)\"
  • Throws out_of_range.412 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 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)\"
  • Throws type_error.316 if a string or object key is not valid UTF-8 and error_handler is strict (the default only if JSON_STRICT_BINARY_UTF8 is enabled)
  • Throws type_error.321 if a value nested in j is discarded (the top-level value itself is covered by type_error.317 above, since it must be an object); example: \"cannot serialize discarded value to BSON\"
"},{"location":"api/basic_json/to_bson/#complexity","title":"Complexity","text":"

Linear in the size of the JSON value j. The length prefixes of all nested documents and arrays are computed in one pass before anything is written.

"},{"location":"api/basic_json/to_bson/#examples","title":"Examples","text":"Example: serialize a JSON value to BSON

The example shows the serialization of a JSON value to a byte vector in BSON format.

#include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\nusing namespace nlohmann::literals;\n\nint main()\n{\n    // create a JSON value\n    json j = R\"({\"compact\": true, \"schema\": 0})\"_json;\n\n    // serialize it to BSON\n    std::vector<std::uint8_t> v = json::to_bson(j);\n\n    // print the vector content\n    for (auto& byte : v)\n    {\n        std::cout << \"0x\" << std::hex << std::setw(2) << std::setfill('0') << static_cast<int>(byte) << \" \";\n    }\n    std::cout << '\\n';\n}\n

Output:

0x1b 0x00 0x00 0x00 0x08 0x63 0x6f 0x6d 0x70 0x61 0x63 0x74 0x00 0x01 0x10 0x73 0x63 0x68 0x65 0x6d 0x61 0x00 0x00 0x00 0x00 0x00 0x00 \n
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.

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create a JSON object whose key contains a null byte (U+0000)\n    std::string key = \"ab\";\n    key.push_back('\\0');\n    key.push_back('c');\n    json j = {{key, 1}};\n\n    // exception out_of_range.409\n    try\n    {\n        json::to_bson(j);\n    }\n    catch (const json::out_of_range& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n}\n

Output:

[json.exception.out_of_range.409] BSON key cannot contain code point U+0000 (at byte 2)\n
"},{"location":"api/basic_json/to_bson/#see-also","title":"See also","text":"
  • BSON - the format, its byte layout and how values are mapped
  • Binary formats - overview and comparison of the supported binary formats
  • Binary values - how binary values and subtypes are handled
  • from_bson - create a JSON value from an input in BSON format
  • to_cbor - create a CBOR serialization of a JSON value
  • to_msgpack - create a MessagePack serialization of a JSON value
  • to_ubjson - create a UBJSON serialization of a JSON value
  • to_bjdata - create a BJData serialization of a JSON value
  • to_bon8 - create a BON8 serialization of a JSON value
"},{"location":"api/basic_json/to_bson/#version-history","title":"Version history","text":"
  • Added in version 3.4.0.
  • Throws out_of_range.412 and out_of_range.415 since version 3.13.0 unreleased.
  • Linear in the size of j, and no longer limited by the call stack for deeply nested values, since version 3.13.0 unreleased.
  • out_of_range.415 is now detected before anything is written, like the other exceptions above, since version 3.13.0 unreleased.
  • Throws type_error.321 for a discarded value nested in j since version 3.13.0 unreleased; previously, it was silently skipped, producing a document whose declared size did not match what was actually written.
  • Added error_handler parameter in version 3.13.0 unreleased. Its default, keep, writes the bytes of a string or object key that is not valid UTF-8 unchanged, as before; strict (the default if JSON_STRICT_BINARY_UTF8 is enabled) throws type_error.316 before anything is written.
  • Throws out_of_range.407 for integers that do not fit 64 bits since version 3.13.0 unreleased; previously, integers of a number type wider than 64 bits were silently truncated.
"},{"location":"api/basic_json/to_cbor/","title":"nlohmann::basic_json::to_cbor","text":"
// (1)\nstatic std::vector<std::uint8_t> to_cbor(const basic_json& j,\n                                          const error_handler_t error_handler = error_handler_t::keep);\n\n// (2)\nstatic void to_cbor(const basic_json& j, detail::output_adapter<std::uint8_t> o,\n                     const error_handler_t error_handler = error_handler_t::keep);\nstatic void to_cbor(const basic_json& j, detail::output_adapter<char> o,\n                     const error_handler_t error_handler = error_handler_t::keep);\n

Serializes a given JSON value j to a byte vector using the CBOR (Concise Binary Object Representation) serialization format. CBOR is a binary serialization format that aims to be more compact than JSON itself, yet more efficient to parse.

  1. Returns a byte vector containing the CBOR serialization.
  2. Writes the CBOR serialization to an output adapter.

The exact mapping and its limitations are described on a dedicated page.

"},{"location":"api/basic_json/to_cbor/#parameters","title":"Parameters","text":"j (in) JSON value to serialize o (in) output adapter to write serialization to error_handler (in) how to treat a string or object key in j that is not valid UTF-8; see error_handler_t. The default, keep, writes the ill-formed bytes to the output as is, as every version of to_cbor did before this parameter was added; strict throws; replace/ignore sanitize it the same way dump would. If JSON_STRICT_BINARY_UTF8 is enabled, the default is strict instead."},{"location":"api/basic_json/to_cbor/#return-value","title":"Return value","text":"
  1. CBOR serialization as a byte vector
  2. (none)
"},{"location":"api/basic_json/to_cbor/#exception-safety","title":"Exception safety","text":"

Strong guarantee: if an exception is thrown, there are no changes in the JSON value. Bytes that were already written to the output adapter are not taken back.

"},{"location":"api/basic_json/to_cbor/#exceptions","title":"Exceptions","text":"
  • Throws out_of_range.407 if j contains an integer outside [-2^64, 2^64-1], which is only possible with a number type wider than 64 bits; example: \"integer number 18446744073709551616 cannot be represented by CBOR as it does not fit [-2^64, 2^64-1]\"
  • Throws type_error.316 if a string or object key in j is not valid UTF-8 and error_handler is strict (the default only if JSON_STRICT_BINARY_UTF8 is enabled)
  • Throws type_error.321 if j or a value nested in it is discarded; example: \"cannot serialize discarded value to CBOR\"
"},{"location":"api/basic_json/to_cbor/#complexity","title":"Complexity","text":"

Linear in the size of the JSON value j.

"},{"location":"api/basic_json/to_cbor/#examples","title":"Examples","text":"Example

The example shows the serialization of a JSON value to a byte vector in CBOR format.

#include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\nusing namespace nlohmann::literals;\n\nint main()\n{\n    // create a JSON value\n    json j = R\"({\"compact\": true, \"schema\": 0})\"_json;\n\n    // serialize it to CBOR\n    std::vector<std::uint8_t> v = json::to_cbor(j);\n\n    // print the vector content\n    for (auto& byte : v)\n    {\n        std::cout << \"0x\" << std::hex << std::setw(2) << std::setfill('0') << static_cast<int>(byte) << \" \";\n    }\n    std::cout << '\\n';\n}\n

Output:

0xa2 0x67 0x63 0x6f 0x6d 0x70 0x61 0x63 0x74 0xf5 0x66 0x73 0x63 0x68 0x65 0x6d 0x61 0x00 \n
"},{"location":"api/basic_json/to_cbor/#see-also","title":"See also","text":"
  • CBOR - the format, its byte layout and how values are mapped
  • Binary formats - overview and comparison of the supported binary formats
  • Binary values - how binary values and subtypes are handled
  • from_cbor - create a JSON value from an input in CBOR format
  • to_msgpack - create a MessagePack serialization of a JSON value
  • to_bson - create a BSON serialization of a JSON value
  • to_ubjson - create a UBJSON serialization of a JSON value
  • to_bjdata - create a BJData serialization of a JSON value
  • to_bon8 - create a BON8 serialization of a JSON value
"},{"location":"api/basic_json/to_cbor/#version-history","title":"Version history","text":"
  • Added in version 2.0.9.
  • Compact representation of floating-point numbers added in version 3.8.0.
  • Added error_handler parameter in version 3.13.0 unreleased. Its default, keep, writes the bytes of a string or object key that is not valid UTF-8 unchanged, as before; strict (the default if JSON_STRICT_BINARY_UTF8 is enabled) throws type_error.316.
  • Throws type_error.321 for a discarded value since version 3.13.0 unreleased; previously, a discarded value nested in an array or object was silently skipped, producing invalid CBOR.
  • Throws out_of_range.407 for integers that do not fit 64 bits since version 3.13.0 unreleased; previously, integers of a number type wider than 64 bits were silently truncated.
"},{"location":"api/basic_json/to_msgpack/","title":"nlohmann::basic_json::to_msgpack","text":"
// (1)\nstatic std::vector<std::uint8_t> to_msgpack(const basic_json& j,\n                                            const error_handler_t error_handler = error_handler_t::keep);\n\n// (2)\nstatic void to_msgpack(const basic_json& j, detail::output_adapter<std::uint8_t> o,\n                       const error_handler_t error_handler = error_handler_t::keep);\nstatic void to_msgpack(const basic_json& j, detail::output_adapter<char> o,\n                       const error_handler_t error_handler = error_handler_t::keep);\n

Serializes a given JSON value j to a byte vector using the MessagePack serialization format. MessagePack is a binary serialization format that aims to be more compact than JSON itself, yet more efficient to parse.

  1. Returns a byte vector containing the MessagePack serialization.
  2. Writes the MessagePack serialization to an output adapter.

The exact mapping and its limitations are described on a dedicated page.

"},{"location":"api/basic_json/to_msgpack/#parameters","title":"Parameters","text":"j (in) JSON value to serialize o (in) output adapter to write serialization to error_handler (in) how to treat a string or object key in j that is not valid UTF-8; see error_handler_t. The default, keep, writes the ill-formed bytes to the output as is, as every version of to_msgpack did before this parameter was added and as the MessagePack specification allows; strict throws; replace/ignore sanitize it the same way dump would. Unlike the other binary writers, the default stays keep even if JSON_STRICT_BINARY_UTF8 is enabled."},{"location":"api/basic_json/to_msgpack/#return-value","title":"Return value","text":"
  1. MessagePack serialization as a byte vector
  2. (none)
"},{"location":"api/basic_json/to_msgpack/#exception-safety","title":"Exception safety","text":"

Strong guarantee: if an exception is thrown, there are no changes in the JSON value.

"},{"location":"api/basic_json/to_msgpack/#exceptions","title":"Exceptions","text":"
  • Throws out_of_range.407 if j contains an integer outside [-2^63, 2^64-1], which is only possible with a number type wider than 64 bits; example: \"integer number 18446744073709551616 cannot be represented by MessagePack as it does not fit [-2^63, 2^64-1]\"
  • Throws out_of_range.412 if the length of a string, binary value, array, or object exceeds 4294967295, the maximum MessagePack can store; example: \"MessagePack length 4294967296 exceeds maximum of 4294967295\"
  • Throws out_of_range.415 if the subtype of a binary value exceeds 255, the largest value the library can store in the one-byte MessagePack ext type; example: \"subtype 70000 is too large for the MessagePack ext type (max 255)\"
  • Throws type_error.316 if a string or object key in j is not valid UTF-8 and error_handler is strict
  • Throws type_error.321 if j or a value nested in it is discarded; example: \"cannot serialize discarded value to MessagePack\"
"},{"location":"api/basic_json/to_msgpack/#complexity","title":"Complexity","text":"

Linear in the size of the JSON value j.

"},{"location":"api/basic_json/to_msgpack/#examples","title":"Examples","text":"Example: serialize a JSON value to MessagePack

The example shows the serialization of a JSON value to a byte vector in MessagePack format.

#include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\nusing namespace nlohmann::literals;\n\nint main()\n{\n    // create a JSON value\n    json j = R\"({\"compact\": true, \"schema\": 0})\"_json;\n\n    // serialize it to MessagePack\n    std::vector<std::uint8_t> v = json::to_msgpack(j);\n\n    // print the vector content\n    for (auto& byte : v)\n    {\n        std::cout << \"0x\" << std::hex << std::setw(2) << std::setfill('0') << static_cast<int>(byte) << \" \";\n    }\n    std::cout << '\\n';\n}\n

Output:

0x82 0xa7 0x63 0x6f 0x6d 0x70 0x61 0x63 0x74 0xc3 0xa6 0x73 0x63 0x68 0x65 0x6d 0x61 0x00 \n
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.

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create a JSON value with a binary subtype that exceeds 255\n    json j = json::binary({1, 2, 3}, 300);\n\n    // exception out_of_range.415\n    try\n    {\n        json::to_msgpack(j);\n    }\n    catch (const json::out_of_range& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n}\n

Output:

[json.exception.out_of_range.415] subtype 300 is too large for the MessagePack ext type (max 255)\n
"},{"location":"api/basic_json/to_msgpack/#see-also","title":"See also","text":"
  • MessagePack - the format, its byte layout and how values are mapped
  • Binary formats - overview and comparison of the supported binary formats
  • Binary values - how binary values and subtypes are handled
  • from_msgpack - create a JSON value from an input in MessagePack format
  • to_cbor - create a CBOR serialization of a JSON value
  • to_bson - create a BSON serialization of a JSON value
  • to_ubjson - create a UBJSON serialization of a JSON value
  • to_bjdata - create a BJData serialization of a JSON value
  • to_bon8 - create a BON8 serialization of a JSON value
"},{"location":"api/basic_json/to_msgpack/#version-history","title":"Version history","text":"
  • Added in version 2.0.9.
  • Throws out_of_range.412 and out_of_range.415 since version 3.13.0 unreleased.
  • Added error_handler parameter in version 3.13.0 unreleased. Its default, keep, writes the bytes of a string or object key that is not valid UTF-8 unchanged, as before.
  • Fixed in version 3.13.0 unreleased to serialize number_integer_t/number_unsigned_t pairs of different width correctly; before, integers could be serialized with the wrong value if number_integer_t was narrower than number_unsigned_t.
  • Throws type_error.321 for a discarded value since version 3.13.0 unreleased; previously, a discarded value nested in an array or object was silently skipped, producing invalid MessagePack.
  • Throws out_of_range.407 for integers that do not fit 64 bits since version 3.13.0 unreleased; previously, integers of a number type wider than 64 bits were silently truncated.
"},{"location":"api/basic_json/to_string/","title":"to_string(basic_json)","text":"
template <typename BasicJsonType>\nstd::string to_string(const BasicJsonType& j);\n

This function implements a user-defined to_string for JSON objects.

"},{"location":"api/basic_json/to_string/#template-parameters","title":"Template parameters","text":"BasicJsonType a specialization of basic_json whose string_t is convertible to std::string; for other string types, use dump, which returns a string_t"},{"location":"api/basic_json/to_string/#return-value","title":"Return value","text":"

string containing the serialization of the JSON value

"},{"location":"api/basic_json/to_string/#exception-safety","title":"Exception safety","text":"

Strong guarantee: if an exception is thrown, there are no changes to any JSON value.

"},{"location":"api/basic_json/to_string/#exceptions","title":"Exceptions","text":"

Throws type_error.316 if a string stored inside the JSON value is not UTF-8 encoded

"},{"location":"api/basic_json/to_string/#complexity","title":"Complexity","text":"

Linear.

"},{"location":"api/basic_json/to_string/#possible-implementation","title":"Possible implementation","text":"
template <typename BasicJsonType>\nstd::string to_string(const BasicJsonType& j)\n{\n    return j.dump();\n}\n
"},{"location":"api/basic_json/to_string/#examples","title":"Examples","text":"Example

The following code shows how the library's to_string() function integrates with others, allowing argument-dependent lookup.

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\nusing std::to_string;\n\nint main()\n{\n    // create values\n    json j = {{\"one\", 1}, {\"two\", 2}};\n    int i = 42;\n\n    // use ADL to select best to_string function\n    auto j_str = to_string(j);  // calling nlohmann::to_string\n    auto i_str = to_string(i);  // calling std::to_string\n\n    // serialize without indentation\n    std::cout << j_str << \"\\n\\n\"\n              << i_str << '\\n';\n}\n

Output:

{\"one\":1,\"two\":2}\n\n42\n
"},{"location":"api/basic_json/to_string/#see-also","title":"See also","text":"
  • dump - serialize a JSON value to a string
  • Serialization - the serialization article
"},{"location":"api/basic_json/to_string/#version-history","title":"Version history","text":"

Added in version 3.7.0.

"},{"location":"api/basic_json/to_ubjson/","title":"nlohmann::basic_json::to_ubjson","text":"
// (1)\nstatic std::vector<std::uint8_t> to_ubjson(const basic_json& j,\n                                           const bool use_size = false,\n                                           const bool use_type = false,\n                                           const error_handler_t error_handler = error_handler_t::keep);\n\n// (2)\nstatic void to_ubjson(const basic_json& j, detail::output_adapter<std::uint8_t> o,\n                      const bool use_size = false, const bool use_type = false,\n                      const error_handler_t error_handler = error_handler_t::keep);\nstatic void to_ubjson(const basic_json& j, detail::output_adapter<char> o,\n                      const bool use_size = false, const bool use_type = false,\n                      const error_handler_t error_handler = error_handler_t::keep);\n

Serializes a given JSON value j to a byte vector using the UBJSON (Universal Binary JSON) serialization format. UBJSON aims to be more compact than JSON itself, yet more efficient to parse.

  1. Returns a byte vector containing the UBJSON serialization.
  2. Writes the UBJSON serialization to an output adapter.

The exact mapping and its limitations are described on a dedicated page.

"},{"location":"api/basic_json/to_ubjson/#parameters","title":"Parameters","text":"j (in) JSON value to serialize o (in) output adapter to write serialization to use_size (in) whether to add size annotations to container types; optional, false by default. use_type (in) whether to add type annotations to container types (must be combined with use_size = true); optional, false by default. error_handler (in) how to treat a string or object key in j that is not valid UTF-8; see error_handler_t. The default, keep, writes the ill-formed bytes to the output as is, as every version of to_ubjson did before this parameter was added; strict throws; replace/ignore sanitize it the same way dump would. If JSON_STRICT_BINARY_UTF8 is enabled, the default is strict instead."},{"location":"api/basic_json/to_ubjson/#return-value","title":"Return value","text":"
  1. UBJSON serialization as a byte vector
  2. (none)
"},{"location":"api/basic_json/to_ubjson/#exception-safety","title":"Exception safety","text":"

Strong guarantee: if an exception is thrown, there are no changes in the JSON value.

"},{"location":"api/basic_json/to_ubjson/#exceptions","title":"Exceptions","text":"
  • Throws other_error.502 if use_type is true and use_size is false, and j contains a non-empty array, object, or binary value.
  • Throws type_error.316 if a string or object key in j is not valid UTF-8 and error_handler is strict (the default only if JSON_STRICT_BINARY_UTF8 is enabled)
  • Throws type_error.321 if j or a value nested in it is discarded; example: \"cannot serialize discarded value to UBJSON\"
"},{"location":"api/basic_json/to_ubjson/#complexity","title":"Complexity","text":"

Linear in the size of the JSON value j.

"},{"location":"api/basic_json/to_ubjson/#examples","title":"Examples","text":"Example: serialize a JSON value to UBJSON

The example shows the serialization of a JSON value to a byte vector in UBJSON format.

#include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\nusing namespace nlohmann::literals;\n\n// function to print UBJSON's diagnostic format\nvoid print_byte(uint8_t byte)\n{\n    if (32 < byte and byte < 128)\n    {\n        std::cout << static_cast<char>(byte);\n    }\n    else\n    {\n        std::cout << static_cast<int>(byte);\n    }\n}\n\nint main()\n{\n    // create a JSON value\n    json j = R\"({\"compact\": true, \"schema\": false})\"_json;\n\n    // serialize it to UBJSON\n    std::vector<std::uint8_t> v = json::to_ubjson(j);\n\n    // print the vector content\n    for (auto& byte : v)\n    {\n        print_byte(byte);\n    }\n    std::cout << '\\n';\n\n    // create an array of numbers\n    json array = {1, 2, 3, 4, 5, 6, 7, 8};\n\n    // serialize it to UBJSON using default representation\n    std::vector<std::uint8_t> v_array = json::to_ubjson(array);\n    // serialize it to UBJSON using size optimization\n    std::vector<std::uint8_t> v_array_size = json::to_ubjson(array, true);\n    // serialize it to UBJSON using type optimization\n    std::vector<std::uint8_t> v_array_size_and_type = json::to_ubjson(array, true, true);\n\n    // print the vector contents\n    for (auto& byte : v_array)\n    {\n        print_byte(byte);\n    }\n    std::cout << '\\n';\n\n    for (auto& byte : v_array_size)\n    {\n        print_byte(byte);\n    }\n    std::cout << '\\n';\n\n    for (auto& byte : v_array_size_and_type)\n    {\n        print_byte(byte);\n    }\n    std::cout << '\\n';\n}\n

Output:

{i7compactTi6schemaF}\n[i1i2i3i4i5i6i7i8]\n[#i8i1i2i3i4i5i6i7i8\n[$i#i812345678\n
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.

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create a non-empty JSON array\n    json j = {1, 2, 3};\n\n    // exception other_error.502\n    try\n    {\n        json::to_ubjson(j, false, true);\n    }\n    catch (const json::other_error& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n}\n

Output:

[json.exception.other_error.502] use_type requires use_size = true\n
"},{"location":"api/basic_json/to_ubjson/#see-also","title":"See also","text":"
  • UBJSON - the format, its byte layout and how values are mapped
  • Binary formats - overview and comparison of the supported binary formats
  • Binary values - how binary values and subtypes are handled
  • from_ubjson - create a JSON value from an input in UBJSON format
  • to_cbor - create a CBOR serialization of a JSON value
  • to_msgpack - create a MessagePack serialization of a JSON value
  • to_bson - create a BSON serialization of a JSON value
  • to_bjdata - create a BJData serialization of a JSON value
  • to_bon8 - create a BON8 serialization of a JSON value
"},{"location":"api/basic_json/to_ubjson/#version-history","title":"Version history","text":"
  • Added in version 3.1.0.
  • Added error_handler parameter in version 3.13.0 unreleased. Its default, keep, writes the bytes of a string or object key that is not valid UTF-8 unchanged, as before; strict (the default if JSON_STRICT_BINARY_UTF8 is enabled) throws type_error.316.
  • Throws type_error.321 for a discarded value since version 3.13.0 unreleased; previously, a discarded value nested in an array or object was silently skipped, producing invalid UBJSON.
"},{"location":"api/basic_json/type/","title":"nlohmann::basic_json::type","text":"
constexpr value_t type() const noexcept;\n

Return the type of the JSON value as a value from the value_t enumeration.

"},{"location":"api/basic_json/type/#return-value","title":"Return value","text":"

the type of the JSON value

Value type return value null value_t::null boolean value_t::boolean string value_t::string number (integer) value_t::number_integer number (unsigned integer) value_t::number_unsigned number (floating-point) value_t::number_float object value_t::object array value_t::array binary value_t::binary discarded value_t::discarded"},{"location":"api/basic_json/type/#exception-safety","title":"Exception safety","text":"

No-throw guarantee: this member function never throws exceptions.

"},{"location":"api/basic_json/type/#complexity","title":"Complexity","text":"

Constant.

"},{"location":"api/basic_json/type/#examples","title":"Examples","text":"Example

The following code exemplifies type() for all JSON types.

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create JSON values\n    json j_null;\n    json j_boolean = true;\n    json j_number_integer = -17;\n    json j_number_unsigned = 42u;\n    json j_number_float = 23.42;\n    json j_object = {{\"one\", 1}, {\"two\", 2}};\n    json j_array = {1, 2, 4, 8, 16};\n    json j_string = \"Hello, world\";\n\n    // call type()\n    std::cout << std::boolalpha;\n    std::cout << (j_null.type() == json::value_t::null) << '\\n';\n    std::cout << (j_boolean.type() == json::value_t::boolean) << '\\n';\n    std::cout << (j_number_integer.type() == json::value_t::number_integer) << '\\n';\n    std::cout << (j_number_unsigned.type() == json::value_t::number_unsigned) << '\\n';\n    std::cout << (j_number_float.type() == json::value_t::number_float) << '\\n';\n    std::cout << (j_object.type() == json::value_t::object) << '\\n';\n    std::cout << (j_array.type() == json::value_t::array) << '\\n';\n    std::cout << (j_string.type() == json::value_t::string) << '\\n';\n}\n

Output:

true\ntrue\ntrue\ntrue\ntrue\ntrue\ntrue\ntrue\n
"},{"location":"api/basic_json/type/#see-also","title":"See also","text":"
  • operator value_t - implicit conversion operator equivalent to this named member function
  • type_name - returns the type as a string, for use in error messages
  • value_t - the enumeration of JSON types
  • basic_json_view::type - the same function on a zero-copy view
  • Types - the JSON value types and how they are stored
"},{"location":"api/basic_json/type/#version-history","title":"Version history","text":"
  • Added in version 1.0.0.
  • Added unsigned integer type in version 2.0.0.
  • Added binary type in version 3.8.0.
"},{"location":"api/basic_json/type_error/","title":"nlohmann::basic_json::type_error","text":"
class type_error : public exception;\n

This exception is thrown in case of a type error; that is, a library function is executed on a JSON value whose type does not match the expected semantics.

Exceptions have ids 3xx (see list of type errors).

classDiagram\n  direction LR\n\n    class std_exception [\"std::exception\"] {\n        <<interface>>\n    }\n\n    class json_exception [\"basic_json::exception\"] {\n        +const int id\n        +const char* what() const\n    }\n\n    class json_parse_error [\"basic_json::parse_error\"] {\n        +const std::size_t byte\n    }\n\n    class json_invalid_iterator [\"basic_json::invalid_iterator\"]\n    class json_type_error [\"basic_json::type_error\"]\n    class json_out_of_range [\"basic_json::out_of_range\"]\n    class json_other_error [\"basic_json::other_error\"]\n\n    std_exception <|-- json_exception\n    json_exception <|-- json_parse_error\n    json_exception <|-- json_invalid_iterator\n    json_exception <|-- json_type_error\n    json_exception <|-- json_out_of_range\n    json_exception <|-- json_other_error\n\n    style json_type_error fill:#CCCCFF

Class hierarchy of the library's exceptions; arrows point from a derived class to its base class, and the highlighted box is basic_json::type_error.

"},{"location":"api/basic_json/type_error/#member-functions","title":"Member functions","text":"
  • what - returns explanatory string
"},{"location":"api/basic_json/type_error/#member-variables","title":"Member variables","text":"
  • id - the id of the exception
"},{"location":"api/basic_json/type_error/#examples","title":"Examples","text":"Example

The following code shows how a type_error exception can be caught.

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    try\n    {\n        // calling push_back() on a string value\n        json j = \"string\";\n        j.push_back(\"another string\");\n    }\n    catch (const json::type_error& e)\n    {\n        // output exception information\n        std::cout << \"message: \" << e.what() << '\\n'\n                  << \"exception id: \" << e.id << '\\n';\n    }\n}\n

Output:

message: [json.exception.type_error.308] cannot use push_back() with string\nexception id: 308\n
"},{"location":"api/basic_json/type_error/#see-also","title":"See also","text":"
  • exception - the base class of all exceptions thrown by the library
  • List of type errors - overview of type errors (type_error)
  • parse_error - exceptions indicating a parse error
  • invalid_iterator - exceptions indicating errors with iterators
  • out_of_range - exceptions indicating access out of the defined range
  • other_error - exceptions indicating other library errors
  • Exceptions - all exceptions and their error codes
  • JSON_DIAGNOSTICS - extended exception messages with the path of the failing value
"},{"location":"api/basic_json/type_error/#version-history","title":"Version history","text":"
  • Added in version 3.0.0.
"},{"location":"api/basic_json/type_name/","title":"nlohmann::basic_json::type_name","text":"
const char* type_name() const noexcept;\n

Returns the type name as string to be used in error messages \u2014 usually to indicate that a function was called on a wrong JSON type.

"},{"location":"api/basic_json/type_name/#return-value","title":"Return value","text":"

a string representation of the type (value_t):

Value type return value null \"null\" boolean \"boolean\" string \"string\" number (integer, unsigned integer, floating-point) \"number\" object \"object\" array \"array\" binary \"binary\" discarded \"discarded\" invalid (corrupted value) \"invalid\"

The \\\"invalid\\\" type

The \"invalid\" return value indicates a corrupted JSON value \u2014 this can occur if an enum value falls outside the range of valid value_t values. This is useful for diagnosing data corruption or internal errors.

"},{"location":"api/basic_json/type_name/#exception-safety","title":"Exception safety","text":"

No-throw guarantee: this member function never throws exceptions.

"},{"location":"api/basic_json/type_name/#complexity","title":"Complexity","text":"

Constant.

"},{"location":"api/basic_json/type_name/#examples","title":"Examples","text":"Example

The following code exemplifies type_name() for all JSON types.

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create JSON values\n    json j_null;\n    json j_boolean = true;\n    json j_number_integer = -17;\n    json j_number_unsigned = 42u;\n    json j_number_float = 23.42;\n    json j_object = {{\"one\", 1}, {\"two\", 2}};\n    json j_array = {1, 2, 4, 8, 16};\n    json j_string = \"Hello, world\";\n\n    // call type_name()\n    std::cout << j_null << \" is a \" << j_null.type_name() << '\\n';\n    std::cout << j_boolean << \" is a \" << j_boolean.type_name() << '\\n';\n    std::cout << j_number_integer << \" is a \" << j_number_integer.type_name() << '\\n';\n    std::cout << j_number_unsigned << \" is a \" << j_number_unsigned.type_name() << '\\n';\n    std::cout << j_number_float << \" is a \" << j_number_float.type_name() << '\\n';\n    std::cout << j_object << \" is an \" << j_object.type_name() << '\\n';\n    std::cout << j_array << \" is an \" << j_array.type_name() << '\\n';\n    std::cout << j_string << \" is a \" << j_string.type_name() << '\\n';\n}\n

Output:

null is a null\ntrue is a boolean\n-17 is a number\n42 is a number\n23.42 is a number\n{\"one\":1,\"two\":2} is an object\n[1,2,4,8,16] is an array\n\"Hello, world\" is a string\n
"},{"location":"api/basic_json/type_name/#see-also","title":"See also","text":"
  • type - returns the type of the JSON value
  • value_t - the enumeration of JSON types
  • basic_json_view::type_name - the same function on a zero-copy view
  • Types - the JSON value types and how they are stored
"},{"location":"api/basic_json/type_name/#version-history","title":"Version history","text":"
  • Added in version 1.0.0.
  • Part of the public API version since 2.1.0.
  • Changed return value to const char* and added noexcept in version 3.0.0.
  • Added support for binary type in version 3.8.0.
  • Added \"invalid\" return value for corrupted JSON values in version 3.13.0 unreleased.
"},{"location":"api/basic_json/unflatten/","title":"nlohmann::basic_json::unflatten","text":"
basic_json unflatten() const;\n

The function restores the arbitrary nesting of a JSON value that has been flattened before using the flatten() function. The JSON value must meet certain constraints:

  1. The value must be an object.
  2. The keys must be JSON pointers (see RFC 6901)
  3. The mapped values must be primitive JSON types.
"},{"location":"api/basic_json/unflatten/#return-value","title":"Return value","text":"

the original JSON from a flattened version

"},{"location":"api/basic_json/unflatten/#exception-safety","title":"Exception safety","text":"

Strong exception safety: if an exception occurs, the original value stays intact.

"},{"location":"api/basic_json/unflatten/#exceptions","title":"Exceptions","text":"

The function can throw the following exceptions:

  • Throws type_error.314 if value is not an object
  • Throws type_error.315 if object values are not primitive
  • Throws type_error.313 if a key (JSON pointer) leads to a conflicting nesting; example: \"invalid value to unflatten\"
  • Throws parse_error.106 if an array index in a key begins with '0'; example: \"array index '01' must not begin with '0'\"
  • Throws parse_error.107 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 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 if an array index in a key is not a number; example: \"array index 'one' is not a number\"
  • Throws out_of_range.404 if a level becomes an array (because one of its keys is 0) and another key at that level is empty (as in /a/), is -, or begins with a digit but is not a valid array index (such as 1a); examples: \"unresolved reference token '-'\", \"unresolved reference token ''\"
"},{"location":"api/basic_json/unflatten/#complexity","title":"Complexity","text":"

Linear in the size of the JSON value.

"},{"location":"api/basic_json/unflatten/#notes","title":"Notes","text":"

Empty objects and arrays are flattened by flatten() to null values and cannot be unflattened to their original type.

A flattened array and a flattened object whose keys are array indices are indistinguishable, because both are described by the same JSON pointers. A value is therefore restored as an array if and only if one of its keys is the reference token 0, and as an object otherwise: {\"2\": 1} is restored unchanged, whereas {\"0\": 1} is restored as [1]. This decision does not depend on the order in which the flattened object is iterated.

A third case is an object that has the key 0 next to a key that is not a valid array index: {\"0\": 1, \"b\": 2} is flattened to {\"/0\": 1, \"/b\": 2}, and unflatten treats the level as an array and throws parse_error.109 because b is not a number. (For the keys -, 1a, or the empty key instead of b, it throws out_of_range.404.)

Apart from these three cases, for a JSON value j, the following is always true: j == j.flatten().unflatten().

"},{"location":"api/basic_json/unflatten/#examples","title":"Examples","text":"Example

The following code shows how a flattened JSON object is unflattened into the original nested JSON object.

#include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create JSON value\n    json j_flattened =\n    {\n        {\"/answer/everything\", 42},\n        {\"/happy\", true},\n        {\"/list/0\", 1},\n        {\"/list/1\", 0},\n        {\"/list/2\", 2},\n        {\"/name\", \"Niels\"},\n        {\"/nothing\", nullptr},\n        {\"/object/currency\", \"USD\"},\n        {\"/object/value\", 42.99},\n        {\"/pi\", 3.141}\n    };\n\n    // call unflatten()\n    std::cout << std::setw(4) << j_flattened.unflatten() << '\\n';\n}\n

Output:

{\n    \"answer\": {\n        \"everything\": 42\n    },\n    \"happy\": true,\n    \"list\": [\n        1,\n        0,\n        2\n    ],\n    \"name\": \"Niels\",\n    \"nothing\": null,\n    \"object\": {\n        \"currency\": \"USD\",\n        \"value\": 42.99\n    },\n    \"pi\": 3.141\n}\n
"},{"location":"api/basic_json/unflatten/#see-also","title":"See also","text":"
  • flatten - the reverse function
  • JSON Pointer - the article on JSON Pointer and flattening
"},{"location":"api/basic_json/unflatten/#version-history","title":"Version history","text":"
  • Added in version 2.0.0.
  • Made the array/object decision independent of the object's iteration order in version 3.13.0 unreleased.
  • Throws parse_error.109 instead of out_of_range.404 for a one-character array index that is not a digit (e.g., /x) in version 3.13.0 unreleased, as it already did for longer ones.
"},{"location":"api/basic_json/update/","title":"nlohmann::basic_json::update","text":"
// (1)\nvoid update(const_reference j, bool merge_objects = false);\n\n// (2)\nvoid update(const_iterator first, const_iterator last, bool merge_objects = false);\n
  1. Inserts all values from JSON object j.
  2. Inserts all values from range [first, last)

When merge_objects is false (default), existing keys are overwritten. When merge_objects is true, recursively merges objects with common keys.

If the JSON value is null, it is implicitly converted to an empty object before the values are inserted.

The function is motivated by Python's dict.update function.

"},{"location":"api/basic_json/update/#iterator-invalidation","title":"Iterator invalidation","text":"

For ordered_json, adding a value to an object can yield a reallocation, in which case all iterators (including the end() iterator) and all references to the elements are invalidated.

"},{"location":"api/basic_json/update/#parameters","title":"Parameters","text":"j (in) JSON object to read values from merge_objects (in) when true, keys that exist in both objects and whose value in the source is itself an object are merged recursively; all other values are overwritten as usual (default: false) first (in) the beginning of the range of elements to insert last (in) the end of the range of elements to insert"},{"location":"api/basic_json/update/#exception-safety","title":"Exception safety","text":"

Basic guarantee: if an exception is thrown during the operation, the JSON value may be partially modified.

"},{"location":"api/basic_json/update/#exceptions","title":"Exceptions","text":"
  1. The function can throw the following exceptions:
    • Throws type_error.312 if called on JSON values other than objects; example: \"cannot use update() with string\"
  2. The function can throw the following exceptions:
    • Throws type_error.312 if called on JSON values other than objects; example: \"cannot use update() with string\"
    • Throws invalid_iterator.210 if first and last do not belong to the same JSON value; example: \"iterators do not fit\"
"},{"location":"api/basic_json/update/#complexity","title":"Complexity","text":"
  1. O(N*log(size() + N)), where N is the number of elements to insert.
  2. O(N*log(size() + N)), where N is the number of elements to insert.
"},{"location":"api/basic_json/update/#notes","title":"Notes","text":"

The argument j (or, for overload (2), the range [first, last)) may be *this itself or refer to a value contained in *this (for example, a subobject returned by (*this)[key]); it is read as it was when update() was called, before any modification of *this.

"},{"location":"api/basic_json/update/#examples","title":"Examples","text":"Example: (1) update with another object

The example shows how update() is used.

#include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\nusing namespace nlohmann::literals;\n\nint main()\n{\n    // create two JSON objects\n    json o1 = R\"( {\"color\": \"red\", \"price\": 17.99, \"names\": {\"de\": \"Flugzeug\"}} )\"_json;\n    json o2 = R\"( {\"color\": \"blue\", \"speed\": 100, \"names\": {\"en\": \"plane\"}} )\"_json;\n    json o3 = o1;\n\n    // add all keys from o2 to o1 (updating \"color\", replacing \"names\")\n    o1.update(o2);\n\n    // add all keys from o2 to o1 (updating \"color\", merging \"names\")\n    o3.update(o2, true);\n\n    // output updated object o1 and o3\n    std::cout << std::setw(2) << o1 << '\\n';\n    std::cout << std::setw(2) << o3 << '\\n';\n}\n

Output:

{\n  \"color\": \"blue\",\n  \"names\": {\n    \"en\": \"plane\"\n  },\n  \"price\": 17.99,\n  \"speed\": 100\n}\n{\n  \"color\": \"blue\",\n  \"names\": {\n    \"de\": \"Flugzeug\",\n    \"en\": \"plane\"\n  },\n  \"price\": 17.99,\n  \"speed\": 100\n}\n
Example: (2) update with an iterator range

The example shows how update() is used.

#include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\nusing namespace nlohmann::literals;\n\nint main()\n{\n    // create two JSON objects\n    json o1 = R\"( {\"color\": \"red\", \"price\": 17.99, \"names\": {\"de\": \"Flugzeug\"}} )\"_json;\n    json o2 = R\"( {\"color\": \"blue\", \"speed\": 100, \"names\": {\"en\": \"plane\"}} )\"_json;\n    json o3 = o1;\n\n    // add all keys from o2 to o1 (updating \"color\", replacing \"names\")\n    o1.update(o2.begin(), o2.end());\n\n    // add all keys from o2 to o1 (updating \"color\", merging \"names\")\n    o3.update(o2.begin(), o2.end(), true);\n\n    // output updated object o1 and o3\n    std::cout << std::setw(2) << o1 << '\\n';\n    std::cout << std::setw(2) << o3 << '\\n';\n}\n

Output:

{\n  \"color\": \"blue\",\n  \"names\": {\n    \"en\": \"plane\"\n  },\n  \"price\": 17.99,\n  \"speed\": 100\n}\n{\n  \"color\": \"blue\",\n  \"names\": {\n    \"de\": \"Flugzeug\",\n    \"en\": \"plane\"\n  },\n  \"price\": 17.99,\n  \"speed\": 100\n}\n
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:

{\n    \"color\": \"red\",\n    \"active\": true,\n    \"name\": {\"de\": \"Maus\", \"en\": \"mouse\"}\n}\n

The user may override the default settings selectively:

{\n    \"color\": \"blue\",\n    \"name\": {\"es\": \"rat\u00f3n\"},\n}\n

Then update manages the merging of default settings and user settings:

auto user_settings = json::parse(\"config.json\");\nauto effective_settings = get_default_settings();\neffective_settings.update(user_settings);\n

Now effective_settings contains the default settings, but those keys set by the user are overwritten:

{\n    \"color\": \"blue\",\n    \"active\": true,\n    \"name\": {\"es\": \"rat\u00f3n\"}\n}\n

Note existing keys were just overwritten. To merge objects, merge_objects setting should be set to true:

auto user_settings = json::parse(\"config.json\");\nauto effective_settings = get_default_settings();\neffective_settings.update(user_settings, true);\n
{\n    \"color\": \"blue\",\n    \"active\": true,\n    \"name\": {\"de\": \"Maus\", \"en\": \"mouse\", \"es\": \"rat\u00f3n\"}\n}\n
"},{"location":"api/basic_json/update/#see-also","title":"See also","text":"
  • insert - add values to an array/object
  • merge_patch - applies a JSON Merge Patch
  • Modifying values - the article on modifying values
"},{"location":"api/basic_json/update/#version-history","title":"Version history","text":"
  • Added in version 3.0.0.
  • Added merge_objects parameter in 3.10.5.
  • Fixed use of freed or relocated memory when the argument is *this or refers to a value contained in *this, in version 3.13.0 unreleased.
"},{"location":"api/basic_json/value/","title":"nlohmann::basic_json::value","text":"
// (1)\ntemplate<class ValueType>\nValueType value(const typename object_t::key_type& key,\n                ValueType&& default_value) const;\n\n// (2)\ntemplate<class ValueType, class KeyType>\nValueType value(KeyType&& key,\n                ValueType&& default_value) const;\n\n// (3)\ntemplate<class ValueType>\nValueType value(const json_pointer& ptr,\n                const ValueType& default_value) const;\n

This is equivalent to Python's dict.get(key, default).

  1. Returns either a copy of an object's element at the specified key key or a given default value if no element with key key exists.

    The function is basically equivalent to executing

    try {\n   return at(key);\n} catch(out_of_range) {\n   return default_value;\n}\n

  2. See 1. This overload is only available if KeyType is comparable with typename object_t::key_type and typename object_comparator_t::is_transparent denotes a type.

  3. Returns either a copy of an object's element at the specified JSON pointer ptr or a given default value if no value at ptr exists.

    The function is basically equivalent to executing

    try {\n   return at(ptr);\n} catch(out_of_range) {\n   return default_value;\n}\n
    with one exception: if the JSON value is neither an array nor an object, the function throws type_error.306 before looking at ptr, even for the empty pointer, whereas at returns the value itself for the empty pointer.

Differences to at and operator[]

  • Unlike at, this function does not throw if the given key/ptr was not found.
  • Unlike operator[], 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.

Integer keys

Calling this function with an integer key argument (for example, 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 const char* and, from there, cause undefined behavior when constructing a std::string for the object key. To access an array element with a default value, use at together with a try/catch block, or compare against size instead.

"},{"location":"api/basic_json/value/#template-parameters","title":"Template parameters","text":"KeyType A type for an object key other than json_pointer that is comparable with string_t using object_comparator_t. This can also be a string view (C++17). ValueType type compatible to JSON values, for instance int for JSON integer numbers, bool for JSON booleans, or std::vector types for JSON arrays. Note the type of the expected value at key/ptr and the default value default_value must be compatible."},{"location":"api/basic_json/value/#parameters","title":"Parameters","text":"key (in) key of the element to access default_value (in) the value to return if key/ptr found no value ptr (in) a JSON pointer to the element to access"},{"location":"api/basic_json/value/#return-value","title":"Return value","text":"
  1. copy of the element at key key or default_value if key is not found
  2. copy of the element at key key or default_value if key is not found
  3. copy of the element at JSON Pointer ptr or default_value if no value for ptr is found
"},{"location":"api/basic_json/value/#exception-safety","title":"Exception safety","text":"

Strong guarantee: if an exception is thrown, there are no changes to any JSON value.

"},{"location":"api/basic_json/value/#exceptions","title":"Exceptions","text":"
  1. The function can throw the following exceptions:
    • Throws type_error.302 if default_value does not match the type of the value at key
    • Throws type_error.306 if the JSON value is not an object; in that case, using value() with a key makes no sense.
  2. See 1.
  3. The function can throw the following exceptions:
    • Throws type_error.302 if default_value does not match the type of the value at ptr
    • Throws type_error.306 if the JSON value is not an array or object; in that case, using value() with a JSON pointer makes no sense.
    • Throws parse_error.106 if an array index in the passed JSON pointer ptr begins with '0'.
    • Throws parse_error.109 if an array index in the passed JSON pointer ptr is not a number.
"},{"location":"api/basic_json/value/#complexity","title":"Complexity","text":"
  1. Logarithmic in the size of the container.
  2. Logarithmic in the size of the container.
  3. Logarithmic in the size of the container.
"},{"location":"api/basic_json/value/#notes","title":"Notes","text":"

null members are not missing

The default value is used only if the key (or JSON Pointer) does not exist. A member that exists but is null is converted like any other value, so j.value(\"k\", 0) throws a type_error.302 if \"k\" is null. See Access with default value for alternatives.

Return type

The value function is a template, and the return type of the function is determined by the type of the provided default value unless otherwise specified. This can have unexpected effects. In the example below, we store a 64-bit unsigned integer. We get exactly that value when using operator[]. However, when we call value and provide 0 as default value, then -1 is returned. This occurs, because 0 has type int which overflows when handling the value 18446744073709551615.

To address this issue, either provide a correctly typed default value or use the template parameter to specify the desired return type. Note that this issue occurs even when a value is stored at the provided key, and the default value is not used as the return value.

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    json j = json::parse(R\"({\"uint64\": 18446744073709551615})\");\n\n    std::cout << \"operator[]:                \" << j[\"uint64\"] << '\\n'\n              << \"default value (int):       \" << j.value(\"uint64\", 0) << '\\n'\n              << \"default value (uint64_t):  \" << j.value(\"uint64\", static_cast<std::uint64_t>(0)) << '\\n'\n              << \"explicit return value type: \" << j.value<std::uint64_t>(\"uint64\", 0) << '\\n';\n}\n

Output:

operator[]:                18446744073709551615\ndefault value (int):       -1\ndefault value (uint64_t):  18446744073709551615\nexplicit return value type: 18446744073709551615\n

Deprecation

Overload (3) also accepts a json_pointer 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 for how to update existing code.

"},{"location":"api/basic_json/value/#examples","title":"Examples","text":"Example: (1) access specified object element with default value

The example below shows how object elements can be queried with a default value.

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create a JSON object with different entry types\n    json j =\n    {\n        {\"integer\", 1},\n        {\"floating\", 42.23},\n        {\"string\", \"hello world\"},\n        {\"boolean\", true},\n        {\"object\", {{\"key1\", 1}, {\"key2\", 2}}},\n        {\"array\", {1, 2, 3}}\n    };\n\n    // access existing values\n    int v_integer = j.value(\"integer\", 0);\n    double v_floating = j.value(\"floating\", 47.11);\n\n    // access nonexisting values and rely on default value\n    std::string v_string = j.value(\"nonexisting\", \"oops\");\n    bool v_boolean = j.value(\"nonexisting\", false);\n\n    // output values\n    std::cout << std::boolalpha << v_integer << \" \" << v_floating\n              << \" \" << v_string << \" \" << v_boolean << \"\\n\";\n}\n

Output:

1 42.23 oops false\n
Example: (2) access specified object element using string_view with default value

The example below shows how object elements can be queried with a default value.

#include <iostream>\n#include <string_view>\n#include <nlohmann/json.hpp>\n\nusing namespace std::string_view_literals;\nusing nlohmann::json;\n\nint main()\n{\n    // create a JSON object with different entry types\n    json j =\n    {\n        {\"integer\", 1},\n        {\"floating\", 42.23},\n        {\"string\", \"hello world\"},\n        {\"boolean\", true},\n        {\"object\", {{\"key1\", 1}, {\"key2\", 2}}},\n        {\"array\", {1, 2, 3}}\n    };\n\n    // access existing values\n    int v_integer = j.value(\"integer\"sv, 0);\n    double v_floating = j.value(\"floating\"sv, 47.11);\n\n    // access nonexisting values and rely on default value\n    std::string v_string = j.value(\"nonexisting\"sv, \"oops\");\n    bool v_boolean = j.value(\"nonexisting\"sv, false);\n\n    // output values\n    std::cout << std::boolalpha << v_integer << \" \" << v_floating\n              << \" \" << v_string << \" \" << v_boolean << \"\\n\";\n}\n

Output:

1 42.23 oops false\n
Example: (3) access specified object element via JSON Pointer with default value

The example below shows how object elements can be queried with a default value.

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\nusing namespace nlohmann::literals;\n\nint main()\n{\n    // create a JSON object with different entry types\n    json j =\n    {\n        {\"integer\", 1},\n        {\"floating\", 42.23},\n        {\"string\", \"hello world\"},\n        {\"boolean\", true},\n        {\"object\", {{\"key1\", 1}, {\"key2\", 2}}},\n        {\"array\", {1, 2, 3}}\n    };\n\n    // access existing values\n    int v_integer = j.value(\"/integer\"_json_pointer, 0);\n    double v_floating = j.value(\"/floating\"_json_pointer, 47.11);\n\n    // access nonexisting values and rely on default value\n    std::string v_string = j.value(\"/nonexisting\"_json_pointer, \"oops\");\n    bool v_boolean = j.value(\"/nonexisting\"_json_pointer, false);\n\n    // output values\n    std::cout << std::boolalpha << v_integer << \" \" << v_floating\n              << \" \" << v_string << \" \" << v_boolean << \"\\n\";\n}\n

Output:

1 42.23 oops false\n
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.

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create a JSON object with a string value\n    json j = {{\"name\", \"the good\"}};\n\n    // exception type_error.302\n    try\n    {\n        int v = j.value(\"name\", 0);\n        std::cout << v << '\\n';\n    }\n    catch (const json::type_error& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n\n    // exception type_error.306\n    try\n    {\n        json str = \"I am a string\";\n        auto v = str.value(\"name\", 0);\n        std::cout << v << '\\n';\n    }\n    catch (const json::type_error& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n}\n

Output:

[json.exception.type_error.302] type must be number, but is string\n[json.exception.type_error.306] cannot use value() with string\n
"},{"location":"api/basic_json/value/#see-also","title":"See also","text":"
  • at - access by reference with range checking
  • operator[] - unchecked access by reference
  • basic_json_view::value - the same access on a zero-copy view
  • Access with default value: value - the article on value
  • JSON Pointer - access nested values with a pointer
"},{"location":"api/basic_json/value/#version-history","title":"Version history","text":"
  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 unreleased 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. Support for keys convertible to std::string_view added in version 3.13.0 unreleased, consistently across the lookup functions.
  3. Added in version 2.0.2. Extended to work with arrays in version 3.13.0 unreleased. Throws parse_error.109 instead of returning default_value for a one-character array index that is not a digit (e.g., /x) in version 3.13.0, as it already did for longer ones.
"},{"location":"api/basic_json/value_t/","title":"nlohmann::basic_json::value_t","text":"
enum class value_t : std::uint8_t {\n    null,\n    object,\n    array,\n    string,\n    boolean,\n    number_integer,\n    number_unsigned,\n    number_float,\n    binary,\n    discarded\n};\n

This enumeration collects the different JSON types. It is internally used to distinguish the stored values, and the functions is_null, is_object, is_array, is_string, is_boolean, is_number (with is_number_integer, is_number_unsigned, and is_number_float), is_discarded, is_binary, is_primitive, and is_structured rely on it.

"},{"location":"api/basic_json/value_t/#notes","title":"Notes","text":"

Ordering

The order of types is as follows:

  1. null
  2. boolean
  3. number_integer, number_unsigned, number_float
  4. object
  5. array
  6. string
  7. binary

discarded is unordered.

flowchart LR\n    A[null] --> B[boolean]\n    B --> C[\"number_integer / number_unsigned / number_float\"]\n    C --> D[object]\n    D --> E[array]\n    E --> F[string]\n    F --> G[binary]

Arrows point from a type to the next greater type in the ordering used by operator<.

Types of numbers

There are three enumerators for numbers (number_integer, number_unsigned, and number_float) to distinguish between different types of numbers:

  • number_unsigned_t for unsigned integers
  • number_integer_t for signed integers
  • number_float_t for floating-point numbers or to approximate integers which do not fit into the limits of their respective type

Comparison operators

operator< and operator<=> (since C++20) are overloaded and compare according to the ordering described above. Until C++20 all other relational and equality operators yield results according to the integer value of each enumerator. Since C++20 some compilers consider the rewritten candidates generated from operator<=> during overload resolution, while others do not. For predictable and portable behavior use:

  • operator< or operator<=> when wanting to compare according to the order described above
  • operator== or operator!= when wanting to compare according to each enumerators integer value
"},{"location":"api/basic_json/value_t/#examples","title":"Examples","text":"Example

The following code how type() queries the value_t for all JSON types.

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create JSON values\n    json j_null;\n    json j_boolean = true;\n    json j_number_integer = -17;\n    json j_number_unsigned = 42u;\n    json j_number_float = 23.42;\n    json j_object = {{\"one\", 1}, {\"two\", 2}};\n    json j_array = {1, 2, 4, 8, 16};\n    json j_string = \"Hello, world\";\n\n    // call type()\n    std::cout << std::boolalpha;\n    std::cout << (j_null.type() == json::value_t::null) << '\\n';\n    std::cout << (j_boolean.type() == json::value_t::boolean) << '\\n';\n    std::cout << (j_number_integer.type() == json::value_t::number_integer) << '\\n';\n    std::cout << (j_number_unsigned.type() == json::value_t::number_unsigned) << '\\n';\n    std::cout << (j_number_float.type() == json::value_t::number_float) << '\\n';\n    std::cout << (j_object.type() == json::value_t::object) << '\\n';\n    std::cout << (j_array.type() == json::value_t::array) << '\\n';\n    std::cout << (j_string.type() == json::value_t::string) << '\\n';\n}\n

Output:

true\ntrue\ntrue\ntrue\ntrue\ntrue\ntrue\ntrue\n
"},{"location":"api/basic_json/value_t/#see-also","title":"See also","text":"
  • type - return the type of the JSON value
  • type_name - return the type as string
  • operator value_t - return the type of the JSON value
  • is_primitive - return whether the type is primitive
  • is_structured - return whether the type is structured
  • Types - the JSON value types and how they are stored
"},{"location":"api/basic_json/value_t/#version-history","title":"Version history","text":"
  • Added in version 1.0.0.
  • Added unsigned integer type in version 2.0.0.
  • Added binary type in version 3.8.0.
"},{"location":"api/basic_json/with_t/","title":"nlohmann::basic_json::with_t","text":"

Member alias templates with_object_t, with_array_t, with_string_t, with_boolean_t, with_integers_t, with_float_t, with_allocator_t, with_json_serializer_t, with_binary_t, and with_base_class_t.

template<template<typename, typename, typename...> class ObjectType2>\nusing with_object_t = basic_json<ObjectType2, ArrayType, StringType, BooleanType,\n      NumberIntegerType, NumberUnsignedType, NumberFloatType,\n      AllocatorType, JSONSerializer, BinaryType, CustomBaseClass>;\n\ntemplate<template<typename, typename...> class ArrayType2>\nusing with_array_t = basic_json<ObjectType, ArrayType2, StringType, BooleanType,\n      NumberIntegerType, NumberUnsignedType, NumberFloatType,\n      AllocatorType, JSONSerializer, BinaryType, CustomBaseClass>;\n\ntemplate<class StringType2>\nusing with_string_t = basic_json<ObjectType, ArrayType, StringType2, BooleanType,\n      NumberIntegerType, NumberUnsignedType, NumberFloatType,\n      AllocatorType, JSONSerializer, BinaryType, CustomBaseClass>;\n\ntemplate<class BooleanType2>\nusing with_boolean_t = basic_json<ObjectType, ArrayType, StringType, BooleanType2,\n      NumberIntegerType, NumberUnsignedType, NumberFloatType,\n      AllocatorType, JSONSerializer, BinaryType, CustomBaseClass>;\n\ntemplate<class NumberIntegerType2, class NumberUnsignedType2>\nusing with_integers_t = basic_json<ObjectType, ArrayType, StringType, BooleanType,\n      NumberIntegerType2, NumberUnsignedType2, NumberFloatType,\n      AllocatorType, JSONSerializer, BinaryType, CustomBaseClass>;\n\ntemplate<class NumberFloatType2>\nusing with_float_t = basic_json<ObjectType, ArrayType, StringType, BooleanType,\n      NumberIntegerType, NumberUnsignedType, NumberFloatType2,\n      AllocatorType, JSONSerializer, BinaryType, CustomBaseClass>;\n\ntemplate<template<typename> class AllocatorType2>\nusing with_allocator_t = basic_json<ObjectType, ArrayType, StringType, BooleanType,\n      NumberIntegerType, NumberUnsignedType, NumberFloatType,\n      AllocatorType2, JSONSerializer, BinaryType, CustomBaseClass>;\n\ntemplate<template<typename, typename = void> class JSONSerializer2>\nusing with_json_serializer_t = basic_json<ObjectType, ArrayType, StringType, BooleanType,\n      NumberIntegerType, NumberUnsignedType, NumberFloatType,\n      AllocatorType, JSONSerializer2, BinaryType, CustomBaseClass>;\n\ntemplate<class BinaryType2>\nusing with_binary_t = basic_json<ObjectType, ArrayType, StringType, BooleanType,\n      NumberIntegerType, NumberUnsignedType, NumberFloatType,\n      AllocatorType, JSONSerializer, BinaryType2, CustomBaseClass>;\n\ntemplate<class CustomBaseClass2>\nusing with_base_class_t = basic_json<ObjectType, ArrayType, StringType, BooleanType,\n      NumberIntegerType, NumberUnsignedType, NumberFloatType,\n      AllocatorType, JSONSerializer, BinaryType, CustomBaseClass2>;\n

These member alias templates make it easier to create a basic_json type that is identical to the current type except for one (or, in the case of with_integers_t, two) of its template parameters. Spelling out all 11 template parameters of basic_json just to change a single one is verbose and error-prone; these aliases only require the replacement type(s).

with_object_t<ObjectType2> replaces ObjectType with_array_t<ArrayType2> replaces ArrayType with_string_t<StringType2> replaces StringType with_boolean_t<BooleanType2> replaces BooleanType with_integers_t<NumberIntegerType2, NumberUnsignedType2> replaces both NumberIntegerType and NumberUnsignedType; the two are combined into a single alias because they are usually changed together (for instance, when switching to fixed-width integer types) with_float_t<NumberFloatType2> replaces NumberFloatType with_allocator_t<AllocatorType2> replaces AllocatorType with_json_serializer_t<JSONSerializer2> replaces JSONSerializer with_binary_t<BinaryType2> replaces BinaryType with_base_class_t<CustomBaseClass2> replaces CustomBaseClass; see also json_base_class_t"},{"location":"api/basic_json/with_t/#notes","title":"Notes","text":"

All other template parameters are kept unchanged, so the resulting type still uses, for instance, the same ObjectType unless with_object_t itself is used.

The aliases are members of every basic_json specialization, including ordered_json, and the type they produce is again a basic_json specialization. They can therefore be chained to replace several template parameters at once:

using my_json = nlohmann::json::with_integers_t<int, unsigned int>::with_float_t<float>;\nusing my_ordered_json = nlohmann::ordered_json::with_string_t<std::wstring>;\n

The result is the same type as spelling out all template parameters, so the order of the chained aliases does not matter. For instance, nlohmann::json::with_object_t<nlohmann::ordered_map> is nlohmann::ordered_json.

"},{"location":"api/basic_json/with_t/#examples","title":"Examples","text":"Example

The following code shows how with_object_t can be used to create a JSON type that stores object elements in a std::map and therefore keeps them sorted by key, unlike the default type which preserves insertion order only when nlohmann::ordered_json is used.

#include <iostream>\n#include <map>\n#include <nlohmann/json.hpp>\n\n// a JSON type that stores objects in a std::map (which keeps keys sorted)\n// instead of the default ordered associative container\nusing sorted_json = nlohmann::json::with_object_t<std::map>;\n\nint main()\n{\n    sorted_json j;\n    j[\"c\"] = 1;\n    j[\"a\"] = 2;\n    j[\"b\"] = 3;\n\n    // keys are sorted, because std::map is used to store the object\n    std::cout << j.dump() << '\\n';\n}\n

Output:

{\"a\":2,\"b\":3,\"c\":1}\n
"},{"location":"api/basic_json/with_t/#see-also","title":"See also","text":"
  • basic_json - the template parameters that can be replaced
  • json_base_class_t - the type used for CustomBaseClass
  • Template Parameter Requirements - requirements on the template parameters
"},{"location":"api/basic_json/with_t/#version-history","title":"Version history","text":"
  • Added in version 3.13.0 unreleased.
"},{"location":"api/basic_json/~basic_json/","title":"nlohmann::basic_json::~basic_json","text":"
~basic_json() noexcept;\n

Destroys the JSON value and frees all allocated memory.

"},{"location":"api/basic_json/~basic_json/#exception-safety","title":"Exception safety","text":"

No-throw guarantee: this member function never throws exceptions.

"},{"location":"api/basic_json/~basic_json/#complexity","title":"Complexity","text":"

Linear.

"},{"location":"api/basic_json/~basic_json/#see-also","title":"See also","text":"
  • basic_json - constructs a JSON value
  • clear - clears the content of a JSON value without destroying it
"},{"location":"api/basic_json/~basic_json/#version-history","title":"Version history","text":"
  • Added in version 1.0.0.
"},{"location":"api/basic_json_document/","title":"nlohmann::basic_json_document","text":"

Defined in header <nlohmann/json_view.hpp>

template<typename BasicJsonType, view_mode Mode = view_mode::read_only>\nclass basic_json_document;\n

A parsed JSON text, held as a flat index of its values (16 bytes per value) instead of a tree of BasicJsonType values. Strings and floating-point numbers stay in the source text; integers are converted while parsing, and strings that contain escapes are decoded into one buffer owned by the document. basic_json_view is a read-only handle to one value of a basic_json_document; materialize() turns a subtree into the BasicJsonType value that BasicJsonType::parse() would have produced for it.

A document may borrow the text it was parsed from (the caller's buffer must then outlive the document) or own it (a copy, or an rvalue std::string that was moved in); see owns_source. basic_json_document is move-only: a copy would duplicate the whole index, the decoded-string buffer, and the owned text, and a move is enough in every use we know of. The index, the decoded strings, and the owned text live in one heap block that the document holds through a std::unique_ptr; this is also why views survive a move of the document.

With Mode == view_mode::editable, the document also offers set, push_back, insert, and erase to change values in place, see Edits below. The source text itself is never written; a read-only document (view_mode::read_only, the default) does not carry any of the bookkeeping edits need, and calling any of them on one fails to compile (static_assert).

"},{"location":"api/basic_json_document/#template-parameters","title":"Template parameters","text":"BasicJsonType a specialization of basic_json, for instance json or ordered_json. Only 64-bit number_integer_t/number_unsigned_t types are supported; this is checked with a static_assert. Mode a view_mode: view_mode::editable if the document supports set, push_back, insert, and erase (optional, view_mode::read_only by default). See Edits below."},{"location":"api/basic_json_document/#specializations","title":"Specializations","text":"
  • json_document - read-only documents of the default specialization json
  • ordered_json_document - read-only documents of ordered_json
  • json_editable_document - editable documents of json
  • ordered_json_editable_document - editable documents of ordered_json
"},{"location":"api/basic_json_document/#member-types","title":"Member types","text":"
  • view_type - the type of view returned by root() (basic_json_view<BasicJsonType, Mode>)
  • value_t - the JSON type enumeration, see basic_json::value_t
  • image_check - how load() validates an image (full, bounds, none), see image_check
"},{"location":"api/basic_json_document/#member-functions","title":"Member functions","text":"
  • (constructor)
"},{"location":"api/basic_json_document/#parsing","title":"Parsing","text":"
  • parse (static) - deserialize from a compatible input, borrowing or owning it as appropriate
  • parse_copy (static) - deserialize a copy of a compatible input
  • accept (static) - check whether the input is valid JSON
  • read - (re-)parse into this document, reusing its memory
"},{"location":"api/basic_json_document/#access","title":"Access","text":"
  • root - the view of the root value
  • is_discarded - return whether the last parse failed
  • source - the parsed text
  • owns_source - return whether the document holds its own copy of the text
  • node_count - the number of index entries (values plus object keys)
  • memory_usage - the number of bytes held by the document
  • shrink_to_fit - release unused index capacity
"},{"location":"api/basic_json_document/#images","title":"Images","text":"
  • save - the document as an image that load() reads without parsing
  • load (static) - read an image written by save()
"},{"location":"api/basic_json_document/#edits","title":"Edits","text":"
  • set - replace a value, or set an object member, an array element, or the value a JSON pointer refers to (editable documents only)
  • push_back - append to an array (editable documents only)
  • insert - insert an element into an array before a given position (editable documents only)
  • erase - remove an object member, an array element, or the value a JSON pointer refers to (editable documents only)
"},{"location":"api/basic_json_document/#edits_1","title":"Edits","text":"

An editable document (view_mode::editable) can be changed after parsing, with set, push_back, insert, and erase; json_editable_document and ordered_json_editable_document are the corresponding specializations. A few points apply to every edit:

  • The source text is never written, and the parsed index never moves: every value keeps the node it was parsed into, so views taken before an edit stay valid, including root(). New values (and the element sequences of an edited array/object) go to storage owned by the document, allocated on demand.
  • A view keeps referring to the same value. After set replaces the value a view refers to, that view sees the new value; a view of a value that a later edit replaces or drops keeps showing what it last held. An edit of an array or object, however, invalidates the iterators taken over it (its members may now live in a different sequence), and a string obtained with get_string() stays valid even as further edits happen (earlier buffers of edited text are kept alive, not overwritten).
  • Values are accepted three ways: a basic_json_view of any document (read-only or editable; it is copied, nothing is shared with the source document), a BasicJsonType value, or anything BasicJsonType can be constructed from (numbers, strings, bool, nullptr, containers, ...).
  • dump() writes an edited document with members in document order, new members at the end, and, with number_format::source, keeps the spelling of every number that was not itself edited \u2014 see Editing a document for why this matters.
  • read() discards all edits, shrink_to_fit() does not move the node index once there are edits, and memory_usage() includes the memory edits use. source_offset() of a value introduced by an edit is static_cast<std::size_t>(-1), the same value it reports for a decoded string.
"},{"location":"api/basic_json_document/#see-also","title":"See also","text":"
  • Zero-copy JSON views - guide to documents and views
  • basic_json_view - the non-owning handle to a value in a document
  • json_document - and json_editable_document - the default specializations
  • materialize - build a basic_json value from a view
"},{"location":"api/basic_json_document/#version-history","title":"Version history","text":"
  • Added in version 3.13.0 unreleased.
"},{"location":"api/basic_json_document/accept/","title":"nlohmann::basic_json_document::accept","text":"
template<typename InputType>\nstatic bool accept(InputType&& input,\n                   const bool ignore_comments = false,\n                   const bool ignore_trailing_commas = false);\n

Checks whether the input is valid JSON, accepting and rejecting exactly what BasicJsonType::accept() does, with the same options. Unlike parse(), this function never throws an exception for invalid input, and the returned bool is the only result \u2014 no document is returned.

The result is the same as that of BasicJsonType::accept() by design; the difference is how the check is made. This function runs the document's index builder (and discards the index), while BasicJsonType::accept() runs the SAX parser with a handler that ignores every event. Use this one if you go on to parse the same input with parse() anyway, so that both use the same code; either is fine for a plain yes/no answer.

"},{"location":"api/basic_json_document/accept/#template-parameters","title":"Template parameters","text":"InputType A compatible input; see parse."},{"location":"api/basic_json_document/accept/#parameters","title":"Parameters","text":"input (in) Input to check. ignore_comments (in) whether comments should be ignored and treated like whitespace (true) or yield a parse error (false); (optional, false by default) ignore_trailing_commas (in) whether trailing commas in arrays or objects should be ignored and treated like whitespace (true) or yield a parse error (false); (optional, false by default)"},{"location":"api/basic_json_document/accept/#return-value","title":"Return value","text":"

Whether the input is valid JSON.

"},{"location":"api/basic_json_document/accept/#exception-safety","title":"Exception safety","text":"

Strong guarantee: this function itself never throws for an invalid input; it can only throw what allocating the input's own copy (for inputs that are always read into a buffer) throws.

"},{"location":"api/basic_json_document/accept/#complexity","title":"Complexity","text":"

Linear in the length of the input.

"},{"location":"api/basic_json_document/accept/#notes","title":"Notes","text":"

An integer argument that is not a bool where the flags are expected, such as accept(ptr, len), does not compile; see parse.

"},{"location":"api/basic_json_document/accept/#examples","title":"Examples","text":"Example
#include <iostream>\n#include <nlohmann/json.hpp>\n#include <nlohmann/json_view.hpp>\n\nusing nlohmann::json_document;\n\nint main()\n{\n    std::cout << std::boolalpha;\n\n    // accept() behaves exactly like basic_json::accept(): the same inputs are\n    // accepted or rejected, with the same ignore_comments/ignore_trailing_commas\n    // options\n    std::cout << json_document::accept(R\"({\"a\": 1})\") << '\\n';\n    std::cout << json_document::accept(R\"({\"a\": 1,})\") << '\\n'; // trailing comma: rejected by default\n    std::cout << json_document::accept(R\"({\"a\": 1,})\", false, true) << '\\n'; // ignore_trailing_commas\n\n    std::cout << (json_document::accept(R\"({\"a\": 1})\") == nlohmann::json::accept(R\"({\"a\": 1})\")) << '\\n';\n}\n

Output:

true\nfalse\ntrue\ntrue\n
"},{"location":"api/basic_json_document/accept/#see-also","title":"See also","text":"
  • parse - deserialize from a compatible input
  • BasicJsonType::accept - the corresponding function of basic_json
  • Zero-copy JSON views - how parsing a document differs from, and matches, basic_json::parse
"},{"location":"api/basic_json_document/accept/#version-history","title":"Version history","text":"
  • Added in version 3.13.0 unreleased.
"},{"location":"api/basic_json_document/basic_json_document/","title":"nlohmann::basic_json_document::basic_json_document","text":"
// (1)\nbasic_json_document() = default;\n\n// (2)\nbasic_json_document(basic_json_document&& other) noexcept = default;\n\n// (3)\nbasic_json_document(const basic_json_document&) = delete;\n
  1. Creates an empty (discarded) document: root() returns a discarded view, and is_discarded() is true.
  2. Move constructor. Takes over other's index and, if owned, its text; other is left as an empty document. Views taken from other before the move remain valid, because the index is heap-allocated independently of the basic_json_document object.
  3. basic_json_document is move-only. Copying is disabled because of its cost: a copy would duplicate the whole index, the decoded-string buffer, and the owned text, while a move is enough in every use we know of.
"},{"location":"api/basic_json_document/basic_json_document/#parameters","title":"Parameters","text":"other (in) another document to move the index and text from"},{"location":"api/basic_json_document/basic_json_document/#exception-safety","title":"Exception safety","text":"

No-throw guarantee: the default and move constructors never throw exceptions.

"},{"location":"api/basic_json_document/basic_json_document/#complexity","title":"Complexity","text":"

Constant.

"},{"location":"api/basic_json_document/basic_json_document/#examples","title":"Examples","text":"Example

The example below shows the default constructor and demonstrates that basic_json_document is move-only.

#include <iostream>\n#include <utility>\n#include <nlohmann/json_view.hpp>\n\nusing nlohmann::json_document;\n\nint main()\n{\n    std::cout << std::boolalpha;\n\n    // the default constructor creates an empty (discarded) document\n    json_document empty;\n    std::cout << empty.is_discarded() << '\\n';\n\n    // json_document is move-only: parse() itself returns by value (moved out),\n    // and a document can be moved again, e.g. into a container\n    json_document doc = json_document::parse(R\"({\"a\": 1})\");\n    json_document moved = std::move(doc);\n    std::cout << moved.root().is_object() << '\\n';\n\n    // copying is disabled at compile time:\n    // json_document another = moved; // does not compile\n}\n

Output:

true\ntrue\n
"},{"location":"api/basic_json_document/basic_json_document/#see-also","title":"See also","text":"
  • parse - deserialize from a compatible input
  • is_discarded - return whether the last parse failed
  • Zero-copy JSON views - who owns the source text and for how long
"},{"location":"api/basic_json_document/basic_json_document/#version-history","title":"Version history","text":"
  • Added in version 3.13.0 unreleased.
"},{"location":"api/basic_json_document/erase/","title":"nlohmann::basic_json_document::erase","text":"
// (1)\nstd::size_t erase(view_type object, string_view_t key);\n\n// (2)\ntemplate<typename I>\nvoid erase(view_type array, I idx);\n\n// (3)\nstd::size_t erase(const json_pointer& ptr);\n

Only an editable document (view_mode::editable, e.g. json_editable_document) has erase; calling it on a read-only basic_json_document fails to compile (static_assert).

  1. Removes every member of object whose key is key (see Notes on duplicate keys) and returns how many were removed; 0 if object has no member with this key.
  2. Removes the element at index idx of array, which must already exist (idx < array.size()).
  3. Removes the value the JSON pointer ptr refers to, relative to root(). ptr must not be empty (root() itself cannot be erased), and the parent of the target must already exist. The target is removed as in 1. if the parent is an object (returns the number of removed members, 0 or more) and as in 2. if it is an array (always returns 1).
"},{"location":"api/basic_json_document/erase/#template-parameters","title":"Template parameters","text":"I an integral type other than bool, deduced (overloads taking a bool or a non-integral type for idx do not participate in overload resolution)."},{"location":"api/basic_json_document/erase/#parameters","title":"Parameters","text":"object (in) the object to remove a member of array (in) the array to remove an element of key (in) the key of the member(s) to remove idx (in) the index of the element to remove; a negative value throws (see Exceptions) ptr (in) a JSON pointer to the value to remove, relative to root()"},{"location":"api/basic_json_document/erase/#return-value","title":"Return value","text":"
  1. the number of removed members (0 if object had none with this key)
  2. (nothing)
  3. the number of removed values (0 or more for an object member, always 1 for an array element)
"},{"location":"api/basic_json_document/erase/#exceptions","title":"Exceptions","text":"
  1. Throws type_error.307 if object is not an object \u2014 the same message BasicJsonType::erase throws for the same type.
  2. Throws type_error.307 if array is not an array. Throws out_of_range.401 if idx is negative, or if idx >= array.size().
  3. Throws out_of_range.405 (\"JSON pointer has no parent\") if ptr is empty. Throws what at throws (overload 3) for resolving ptr's parent. For the last reference token itself: if the parent is an array, throws what 2. throws for an index that is out of range, or, for a token that is not a valid array index, parse_error.106 (a leading '0'), parse_error.109 (not a number), out_of_range.410 (too large for size_type), or out_of_range.404 (an empty token); otherwise (an object, or a primitive value the pointer's parent resolves to) throws what 1. throws.

Overloads 1. and 2. also throw invalid_iterator.202 (\"view does not belong to this document\") if object/array is a discarded view or a view of a different document. Overload 3. never throws invalid_iterator.202: it takes no view, and it always starts from this document's own root().

"},{"location":"api/basic_json_document/erase/#complexity","title":"Complexity","text":"
  1. Linear in the number of members of object.
  2. Linear in the number of elements of array at or after idx (they move one slot over).
  3. Linear in the number of reference tokens of ptr and, for each token, in the number of members of the object at that level or the index into the array (as at), plus the complexity of 1. or 2. for the last token.
"},{"location":"api/basic_json_document/erase/#notes","title":"Notes","text":"

Duplicate keys

Overload 1. removes every member with key, not just the first \u2014 unlike set, which assigns the first occurrence and drops the rest. This is why it returns a count rather than a single view: there may be more than one member removed, or none.

Like set and push_back, erase never moves an element's value: a view still referring to a removed member or element keeps showing what it last held (see Edits) \u2014 it just no longer appears when array/object is read, dumped, or iterated. What does change is the container's sequence of links to its elements: removing an element of array (2.) shifts the links to the elements after it by one, as insert does in the other direction. Every iterator already taken over array/object is invalidated by an erase, not only those at or after the removed element, since the container may now use a different sequence.

"},{"location":"api/basic_json_document/erase/#examples","title":"Examples","text":"Example

The example below drops a deprecated field and a decommissioned entry from a configuration document \u2014 using all three overloads \u2014 and shows what stays intact that would not with a plain json/ordered_json value: the order of the fields around the ones removed, and the exact spelling of a number that was never touched.

#include <iostream>\n#include <nlohmann/json_view.hpp>\n\nusing nlohmann::json;\nusing nlohmann::json_editable_document;\nusing nlohmann::json_editable_view;\n\nint main()\n{\n    // a deprecated field is dropped from a configuration file, and a\n    // decommissioned replica is removed from the list -- \"price\" keeps its\n    // trailing zero, and the fields around the removed ones keep their order\n    const std::string text = R\"({\n  \"name\": \"cache\",\n  \"legacy_host\": \"db0\",\n  \"host\": \"db1\",\n  \"price\": 19.90,\n  \"replicas\": [\"db2\", \"db3\", \"db4\"]\n})\";\n\n    json_editable_document doc = json_editable_document::parse(text);\n\n    doc.erase(doc.root(), \"legacy_host\");                                      // (1) an object member\n    doc.erase(doc.root()[\"replicas\"], 1);                                      // (2) an array element (\"db3\")\n    const std::size_t removed = doc.erase(json::json_pointer(\"/replicas/0\"));  // (3) via a JSON pointer\n\n    std::cout << removed << '\\n';\n    std::cout << doc.root().dump(2, ' ', false, json_editable_view::number_format::source) << \"\\n\\n\";\n\n    // the same edits on a plain json value: object_t is a std::map, so\n    // parsing already sorted the keys, and dump() rewrites every number to\n    // its shortest form, even \"price\", which was never touched\n    json plain = json::parse(text);\n    plain.erase(\"legacy_host\");\n    plain[\"replicas\"].erase(1);\n    plain[\"replicas\"].erase(0);\n    std::cout << plain.dump(2) << '\\n';\n}\n

Output:

1\n{\n  \"name\": \"cache\",\n  \"host\": \"db1\",\n  \"price\": 19.90,\n  \"replicas\": [\n    \"db4\"\n  ]\n}\n\n{\n  \"host\": \"db1\",\n  \"name\": \"cache\",\n  \"price\": 19.9,\n  \"replicas\": [\n    \"db4\"\n  ]\n}\n
"},{"location":"api/basic_json_document/erase/#see-also","title":"See also","text":"
  • insert - insert an element into an array
  • set - replace a value, or set an object member, an array element, or the value a JSON pointer refers to
  • push_back - append to an array
  • root - the view of the root value, the starting point of overload 3
  • BasicJsonType::erase - the corresponding function of basic_json
  • Edits - what an edit guarantees, for every overload
  • Zero-copy JSON views - what an edit guarantees and costs
"},{"location":"api/basic_json_document/erase/#version-history","title":"Version history","text":"
  • Added in version 3.13.0 unreleased.
"},{"location":"api/basic_json_document/insert/","title":"nlohmann::basic_json_document::insert","text":"
template<typename I, typename V>\nview_type insert(view_type array, I idx, V&& value);\n

Only an editable document (view_mode::editable, e.g. json_editable_document) has insert; calling it on a read-only basic_json_document fails to compile (static_assert).

Inserts value into array as a new element before position idx, which must not be past the end (idx <= array.size(); idx == array.size() appends, like push_back). Unlike push_back, a null array does not first become an empty array: array must already be an array.

value is accepted three ways: a basic_json_view of any document \u2014 read-only or editable, and it does not have to be array's own document \u2014 which is copied so that nothing is shared with the source document afterward; a BasicJsonType value; or anything BasicJsonType can be constructed from (numbers, strings, bool, nullptr, containers, ...).

"},{"location":"api/basic_json_document/insert/#template-parameters","title":"Template parameters","text":"I an integral type other than bool, deduced (overloads taking a bool or a non-integral type for idx do not participate in overload resolution). V the type of value, deduced; see above for what is accepted."},{"location":"api/basic_json_document/insert/#parameters","title":"Parameters","text":"array (in) the array to insert into idx (in) the position to insert value before; a negative value throws (see Exceptions) value (in) the value to insert"},{"location":"api/basic_json_document/insert/#return-value","title":"Return value","text":"

a view of the new element, now holding value

"},{"location":"api/basic_json_document/insert/#exception-safety","title":"Exception safety","text":"

Basic exception safety: value is fully encoded \u2014 including the checks below \u2014 into storage owned by the document before anything already reachable from root() is touched, so a failure while encoding value (an invalid argument, or std::bad_alloc) leaves the document completely unchanged, other than memory allocated for the encoding that is not reclaimed. A failure of a later allocation \u2014 while array switches from its parsed layout to a growable block, or while that block grows, see Notes \u2014 can still leave array already switched to that layout even though value itself was not inserted.

"},{"location":"api/basic_json_document/insert/#exceptions","title":"Exceptions","text":"

Throws type_error.309 if array is not an array \u2014 the same message BasicJsonType::insert throws for the same type; a null array throws this too (see above). Throws out_of_range.401 if idx is negative, or if idx > array.size(). Throws invalid_iterator.202 (\"view does not belong to this document\") if array is a discarded view or a view of a different document. Throws type_error.302 if value is a discarded view or a discarded BasicJsonType value, and type_error.319 if value is (or contains) a binary value \u2014 BasicJsonType can hold one, but a json_document cannot. Throws type_error.316 if value is (or contains) a string that is not valid UTF-8, with the same message BasicJsonType::dump() gives for that string.

"},{"location":"api/basic_json_document/insert/#complexity","title":"Complexity","text":"

Linear in the number of elements of array at or after idx (they move one slot over), plus time linear in the size of value to encode it into the document's storage (constant for a scalar, linear in the number of nested values for an array or object): like push_back, the elements of array move to a growable block of links the first time it is inserted into (or set/push_back on), and that block grows in amortized constant time; inserting before the end within that block still shifts every later element.

"},{"location":"api/basic_json_document/insert/#notes","title":"Notes","text":"

Like set on a member or an element, insert never moves an existing element's value \u2014 only where array's links to its elements live \u2014 so a view of an existing element of array stays valid across an insert, and keeps referring to the same element even though its index shifts. Any iterator already taken over array is invalidated, since it was walking the old layout. See Edits for what stays valid across an edit in general.

"},{"location":"api/basic_json_document/insert/#examples","title":"Examples","text":"Example

The example below inserts a step into the middle of a deployment plan, without touching the steps that come after it, and shows that a view taken before the insert keeps referring to the same element even though its index shifts \u2014 something a plain json/ordered_json array, or its std::vector-based storage, has no equivalent for.

#include <iostream>\n#include <nlohmann/json_view.hpp>\n\nusing nlohmann::json;\nusing nlohmann::json_editable_document;\nusing nlohmann::json_editable_view;\n\nint main()\n{\n    // a deployment plan -- \"budget\" is written with a trailing zero that has\n    // no effect on its value\n    const std::string text = R\"({\n  \"release\": \"2026.09\",\n  \"steps\": [\"build\", \"test\", \"deploy\"],\n  \"budget\": 19.90\n})\";\n\n    json_editable_document doc = json_editable_document::parse(text);\n\n    const std::size_t deploy_index = 2;\n    const auto deploy = doc.root()[\"steps\"][deploy_index];  // held across the insert\n\n    doc.insert(doc.root()[\"steps\"], deploy_index, \"smoke-test\"); // insert before \"deploy\"\n\n    // the held view still refers to \"deploy\", even though its index moved\n    // from 2 to 3, and nothing else in the document was touched\n    std::cout << deploy.dump() << '\\n';\n    std::cout << doc.root().dump(2, ' ', false, json_editable_view::number_format::source) << \"\\n\\n\";\n\n    // the same edit on a plain json value: an index held from before the\n    // insert now refers to whatever moved into that slot, and dump()\n    // rewrites \"budget\" to its shortest form even though it was never\n    // touched\n    json plain = json::parse(text);\n    plain[\"steps\"].insert(plain[\"steps\"].begin() + static_cast<std::ptrdiff_t>(deploy_index), \"smoke-test\");\n    std::cout << plain[\"steps\"][deploy_index].dump() << '\\n';\n    std::cout << plain.dump(2) << '\\n';\n}\n

Output:

\"deploy\"\n{\n  \"release\": \"2026.09\",\n  \"steps\": [\n    \"build\",\n    \"test\",\n    \"smoke-test\",\n    \"deploy\"\n  ],\n  \"budget\": 19.90\n}\n\n\"smoke-test\"\n{\n  \"budget\": 19.9,\n  \"release\": \"2026.09\",\n  \"steps\": [\n    \"build\",\n    \"test\",\n    \"smoke-test\",\n    \"deploy\"\n  ]\n}\n
"},{"location":"api/basic_json_document/insert/#see-also","title":"See also","text":"
  • push_back - append to an array
  • erase - remove an object member, an array element, or the value a JSON pointer refers to
  • set - replace a value, or set an object member, an array element, or the value a JSON pointer refers to
  • BasicJsonType::insert - the corresponding function of basic_json
  • Edits - what an edit guarantees, for every overload
  • Zero-copy JSON views - what an edit guarantees and costs
"},{"location":"api/basic_json_document/insert/#version-history","title":"Version history","text":"
  • Added in version 3.13.0 unreleased.
"},{"location":"api/basic_json_document/is_discarded/","title":"nlohmann::basic_json_document::is_discarded","text":"
bool is_discarded() const noexcept;\n

Returns whether the document holds no value, either because it was default-constructed or because the last call to parse(), parse_copy(), or read() failed with allow_exceptions set to false.

"},{"location":"api/basic_json_document/is_discarded/#return-value","title":"Return value","text":"

true if the document is discarded, false otherwise.

"},{"location":"api/basic_json_document/is_discarded/#exception-safety","title":"Exception safety","text":"

No-throw guarantee: this function never throws exceptions.

"},{"location":"api/basic_json_document/is_discarded/#complexity","title":"Complexity","text":"

Constant.

"},{"location":"api/basic_json_document/is_discarded/#notes","title":"Notes","text":"

When the document is discarded, root() returns a discarded view (its is_discarded() is also true).

"},{"location":"api/basic_json_document/is_discarded/#examples","title":"Examples","text":"Example
#include <iostream>\n#include <nlohmann/json_view.hpp>\n\nusing nlohmann::json_document;\n\nint main()\n{\n    std::cout << std::boolalpha;\n\n    // with allow_exceptions == false, a parse error produces a discarded\n    // document instead of throwing -- exactly like basic_json::parse()\n    json_document doc = json_document::parse(R\"({\"a\": )\", /* allow_exceptions */ false);\n    std::cout << doc.is_discarded() << '\\n';\n    std::cout << doc.root().is_discarded() << '\\n';\n\n    // a successful parse is never discarded\n    json_document ok = json_document::parse(R\"({\"a\": 1})\", false);\n    std::cout << ok.is_discarded() << '\\n';\n}\n

Output:

true\ntrue\nfalse\n
"},{"location":"api/basic_json_document/is_discarded/#see-also","title":"See also","text":"
  • parse - deserialize from a compatible input
  • basic_json_view::is_discarded - return whether a view is invalid
  • Zero-copy JSON views - how a discarded document arises
"},{"location":"api/basic_json_document/is_discarded/#version-history","title":"Version history","text":"
  • Added in version 3.13.0 unreleased.
"},{"location":"api/basic_json_document/load/","title":"nlohmann::basic_json_document::load","text":"
// (1)\nstatic basic_json_document load(const std::uint8_t* image, std::size_t size,\n                                 const image_check check = image_check::full);\n\n// (2)\nstatic basic_json_document load(const std::vector<std::uint8_t>& image,\n                                 const image_check check = image_check::full);\n\n// (3)\nstatic basic_json_document load(std::vector<std::uint8_t>&& image,\n                                 const image_check check = image_check::full);\n
  1. Reads an image save() wrote, from a pointer and a byte count. The image is borrowed: image must stay alive and unchanged for as long as the returned document, and any view taken from it, is used.
  2. Reads an image from a std::vector. Also borrowed \u2014 equivalent to overload 1 called with image.data() and image.size().
  3. Reads an image, keeping the vector instead of copying it: image is moved into the document (no copy), which then owns it for as long as it needs the text and the decoded strings. owns_source() is true afterward.

In every overload, the node index is copied into storage the document itself owns \u2014 so that it is properly aligned, and, for an editable document, can be edited \u2014 while the text and the decoded strings stay in image. The hash indexes large objects use for lookup are rebuilt, exactly as after parsing.

"},{"location":"api/basic_json_document/load/#parameters","title":"Parameters","text":"image (in) the image save() wrote (overloads 1 and 2), or one to take ownership of (overload 3) size (in) the number of bytes at image (overload 1) check (in) how thoroughly to validate image before trusting it; see image_check below (optional, image_check::full by default)"},{"location":"api/basic_json_document/load/#return-value","title":"Return value","text":"

The document read from the image.

"},{"location":"api/basic_json_document/load/#exception-safety","title":"Exception safety","text":"

Overloads 1 and 2 give the strong guarantee: image is only read, never written, so a thrown exception leaves the caller's buffer untouched.

Overload 3 moves image into the document before validating it, so that a good image is kept without a copy. If loading then fails, the partially built document \u2014 and the vector now inside it \u2014 is discarded along with the exception, and image itself is left empty, not restored to what was passed in. Move a copy in instead, or validate with overload 2 first, if the original vector must survive a failed load.

"},{"location":"api/basic_json_document/load/#exceptions","title":"Exceptions","text":"

Throws parse_error.116 if image is not one save() could have written, or fails the requested check:

message when too short image is nullptr, or size is smaller than the 64-byte header unknown format the header's magic bytes or version do not match, or a reserved header field is not zero sizes out of range the node count, text size, or decoded-string size the header describes does not fit size, or the '\\0' after the text or after the decoded strings is missing the check failed check is not image_check::none, and the image fails it \u2014 see image_check

Example messages

[json.exception.parse_error.116] parse error: invalid json_document image: too short\n
[json.exception.parse_error.116] parse error: invalid json_document image: unknown format\n
[json.exception.parse_error.116] parse error: invalid json_document image: sizes out of range\n
[json.exception.parse_error.116] parse error: invalid json_document image: the check failed\n

"},{"location":"api/basic_json_document/load/#complexity","title":"Complexity","text":"

Linear in the number of nodes, which are always copied into the document. image_check::none does not read the text or the decoded strings. image_check::bounds reads one byte of the text for each float token (its sign, to check the recorded digits against the token's length), and nothing else of the text or the decoded strings.

With image_check::full, linear in the size of the image (the nodes, the text, and the decoded strings), plus sorting the ranges of the strings and of the float tokens (at most one per node): the contents of each distinct range are checked once, however many nodes refer to it.

"},{"location":"api/basic_json_document/load/#notes","title":"Notes","text":"

Little-endian targets only. On a big-endian target, load() does not exist, just like save(): the image format is little-endian, so a call fails to compile.

"},{"location":"api/basic_json_document/load/#image_check","title":"image_check","text":"
using image_check = detail::view::image_check;\n\nenum class image_check\n{\n    full,\n    bounds,\n    none\n};\n

How thoroughly load() validates image before trusting it.

full (the default) Checks everything the parser itself guarantees: structure and bounds; that every string is valid UTF-8 (and, for a string still in the source text, that it contains no quote, backslash, or control character); and that every number token is well-formed and matches the value stored for it. Strings and float tokens may share a range only if the ranges are identical (as nodes that share a value do), and never overlap otherwise. Reading and serializing a checked image is safe and always produces valid JSON, exactly as for a parsed document. This is the right choice for an image from anything you do not fully control \u2014 a file, a cache shared with other processes, a peer on the network. bounds Checks structure and bounds only: that every offset and count in the node index stays inside the image. So load(), root(), element access, and materialize() can never read outside the image, even on a damaged one. It does not guarantee that the image describes valid JSON: a string that a full check would have rejected can make dump() write invalid UTF-8 or invalid JSON, or throw type_error.316, and a number can read back with a value that does not match how it is spelled. An editable document does not take such a string over: set, push_back and insert throw type_error.316 when they copy it from a view of the loaded document, and leave the editable document unchanged. bounds skips scanning the text and the decoded strings, so it fits a cache your own process just wrote and reads straight back, where damage would mean a bug or a hardware fault rather than adversarial input. none Checks nothing. Reading a damaged image is undefined behavior, so use it only for an image you trust as much as your own memory.

Lifetime. Overloads 1 and 2 borrow image: it must stay alive and byte-for-byte unchanged for as long as the returned document, and any view taken from it, is used \u2014 exactly like a document parse() borrowed its input for. Overload 3 avoids this by keeping the vector itself; see owns_source.

Experimental

The image format is versioned but not yet stable, and may change in an incompatible way before it is declared stable; load() already rejects an image written by a different format version with parse_error.116 (\"unknown format\"). Use images to cache a document within one build of the library, or to hand one to another process running the same build on the same (little-endian) machine \u2014 not as a long-term storage format.

"},{"location":"api/basic_json_document/load/#examples","title":"Examples","text":"Caching a document, ownership, and a rejected image

The example below saves a parsed document as an image, checks that load() reproduces the original dump() without parsing, and shows the difference between load(std::move(image)) (owned) and load(image) (borrowed). It then damages one byte of the image and shows image_check::full rejecting it with parse_error.116, while image_check::bounds \u2014 meant for a cache the process already trusts \u2014 still reads it without going out of bounds.

#include <cstdint>\n#include <iostream>\n#include <string>\n#include <vector>\n#include <nlohmann/json_view.hpp>\n\nusing nlohmann::json;\nusing nlohmann::json_document;\nusing image_check = json_document::image_check;\n\nint main()\n{\n    std::cout << std::boolalpha;\n\n    // the image of a parsed document -- as if read back from a cache file or\n    // received from another process running the same build of the library\n    const std::string text = R\"({\"name\": \"cache\", \"note\": \"caf\\u00e9\", \"replicas\": [\"db2\", \"db3\"]})\";\n    const json_document parsed = json_document::parse(text);\n    const std::vector<std::uint8_t> image = parsed.save();\n\n    // (1)/(2) load() needs no parsing, yet dumps exactly what parsing did\n    const json_document borrowed = json_document::load(image);\n    std::cout << (borrowed.root().dump() == parsed.root().dump()) << '\\n';\n    std::cout << borrowed.owns_source() << '\\n'; // borrowed: still points into `image`\n\n    // (3) load(std::move(image)) keeps the vector instead of copying it\n    std::vector<std::uint8_t> to_move = image;\n    const json_document owned = json_document::load(std::move(to_move));\n    std::cout << owned.owns_source() << '\\n';\n\n    // a damaged image -- the last byte of the decoded string \"note\" holds\n    // (an escape sequence, so it was unescaped into the document's own\n    // buffer), flipped, as storage or transport corruption might do\n    std::vector<std::uint8_t> damaged = image;\n    damaged[damaged.size() - 2] = 0xFF;\n\n    // image_check::full inspects strings and numbers, so it catches the damage\n    try\n    {\n        static_cast<void>(json_document::load(damaged, image_check::full));\n    }\n    catch (const json::parse_error& e)\n    {\n        std::cout << e.id << '\\n';\n    }\n\n    // image_check::bounds only checks structure and bounds, so a cache the\n    // process already trusts loads without the extra scan -- reading a value\n    // the damage did not touch is still safe\n    const json_document trusted = json_document::load(damaged, image_check::bounds);\n    std::cout << trusted.root()[\"name\"].get<std::string>() << '\\n';\n}\n

Output:

true\nfalse\ntrue\n116\ncache\n
"},{"location":"api/basic_json_document/load/#see-also","title":"See also","text":"
  • save - write the document as an image
  • owns_source - return whether the document holds its own copy of the text
  • parse - deserialize from JSON text instead of an image
  • Images - why and when to use images
"},{"location":"api/basic_json_document/load/#version-history","title":"Version history","text":"
  • Added in version 3.13.0 unreleased.
"},{"location":"api/basic_json_document/memory_usage/","title":"nlohmann::basic_json_document::memory_usage","text":"
std::size_t memory_usage() const noexcept;\n

Returns the number of bytes held by the document: the node index, the decoded-string buffer (for strings that contain escapes), and, for an owned document, its copy of the source text.

"},{"location":"api/basic_json_document/memory_usage/#return-value","title":"Return value","text":"

The number of bytes the document holds, 0 for a discarded document.

"},{"location":"api/basic_json_document/memory_usage/#exception-safety","title":"Exception safety","text":"

No-throw guarantee: this function never throws exceptions.

"},{"location":"api/basic_json_document/memory_usage/#complexity","title":"Complexity","text":"

Constant.

"},{"location":"api/basic_json_document/memory_usage/#notes","title":"Notes","text":"

The exact value depends on the platform, the allocator, and the library's own layout, and may change between versions; do not rely on it being a specific number, and do not compare it across different builds or platforms. Compare it for the same document over time, or between documents built with the same binary, instead \u2014 for instance to observe the effect of shrink_to_fit().

"},{"location":"api/basic_json_document/memory_usage/#examples","title":"Examples","text":"Example
#include <iostream>\n#include <string>\n#include <nlohmann/json_view.hpp>\n\nusing nlohmann::json_document;\n\nint main()\n{\n    std::cout << std::boolalpha;\n\n    // long enough that copying it needs a real (heap) allocation, so the\n    // comparison below does not depend on the standard library's small\n    // string optimization threshold\n    const std::string text = std::string(200, ' ') + \"[1, 2, 3, 4, 5]\";\n\n    // memory_usage() is not portable across platforms/allocators/compilers, so\n    // compare it relatively instead of printing the raw byte count\n    json_document borrowed = json_document::parse(text);\n    json_document owned = json_document::parse_copy(text);\n\n    // the owned document additionally stores its own copy of the source text\n    std::cout << (owned.memory_usage() > borrowed.memory_usage()) << '\\n';\n\n    // a document with more values needs a larger index\n    json_document small = json_document::parse(std::string(\"[1]\"));\n    json_document large = json_document::parse(std::string(\"[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]\"));\n    std::cout << (large.memory_usage() > small.memory_usage()) << '\\n';\n}\n

Output:

true\ntrue\n
"},{"location":"api/basic_json_document/memory_usage/#see-also","title":"See also","text":"
  • node_count - the number of index entries
  • shrink_to_fit - release unused index capacity
  • Zero-copy JSON views - the flat node index and its memory
"},{"location":"api/basic_json_document/memory_usage/#version-history","title":"Version history","text":"
  • Added in version 3.13.0 unreleased.
"},{"location":"api/basic_json_document/node_count/","title":"nlohmann::basic_json_document::node_count","text":"
std::size_t node_count() const noexcept;\n

Returns the number of entries in the document's flat index.

"},{"location":"api/basic_json_document/node_count/#return-value","title":"Return value","text":"

The number of index entries: one per value (of any type, at any nesting depth) plus one per object key. 0 for a discarded document.

"},{"location":"api/basic_json_document/node_count/#exception-safety","title":"Exception safety","text":"

No-throw guarantee: this function never throws exceptions.

"},{"location":"api/basic_json_document/node_count/#complexity","title":"Complexity","text":"

Constant.

"},{"location":"api/basic_json_document/node_count/#notes","title":"Notes","text":"

Each index entry is 16 bytes, so node_count() * 16 is the size of the index itself (part, but not all, of memory_usage(), which also counts decoded strings and, for an owned document, the text).

"},{"location":"api/basic_json_document/node_count/#examples","title":"Examples","text":"Example
#include <iostream>\n#include <nlohmann/json_view.hpp>\n\nusing nlohmann::json_document;\n\nint main()\n{\n    // node_count() is the size of the flat index: one 16-byte node per value,\n    // plus one per object key (values and keys are all the index stores)\n    json_document scalar = json_document::parse(\"42\");\n    std::cout << scalar.node_count() << '\\n';\n\n    json_document doc = json_document::parse(R\"({\"a\": 1, \"b\": [1, 2]})\");\n    std::cout << doc.node_count() << '\\n';\n}\n

Output:

1\n7\n
"},{"location":"api/basic_json_document/node_count/#see-also","title":"See also","text":"
  • memory_usage - the number of bytes held by the document
  • shrink_to_fit - release unused index capacity
  • Zero-copy JSON views - the flat node index and its memory
"},{"location":"api/basic_json_document/node_count/#version-history","title":"Version history","text":"
  • Added in version 3.13.0 unreleased.
"},{"location":"api/basic_json_document/owns_source/","title":"nlohmann::basic_json_document::owns_source","text":"
bool owns_source() const noexcept;\n

Returns whether the document holds its own copy of the parsed text or is borrowing the caller's buffer.

"},{"location":"api/basic_json_document/owns_source/#return-value","title":"Return value","text":"

true if the document owns the text returned by source(), false if it borrows it (or if the document is discarded).

"},{"location":"api/basic_json_document/owns_source/#exception-safety","title":"Exception safety","text":"

No-throw guarantee: this function never throws exceptions.

"},{"location":"api/basic_json_document/owns_source/#complexity","title":"Complexity","text":"

Constant.

"},{"location":"api/basic_json_document/owns_source/#notes","title":"Notes","text":"

See the ownership table on parse for which inputs are borrowed and which are owned. A borrowed document (owns_source() == false) is only valid while the buffer it was parsed from is still alive.

"},{"location":"api/basic_json_document/owns_source/#examples","title":"Examples","text":"Example
#include <iostream>\n#include <string>\n#include <nlohmann/json_view.hpp>\n\nusing nlohmann::json_document;\n\nint main()\n{\n    std::cout << std::boolalpha;\n\n    std::string text = R\"({\"a\": 1})\";\n\n    // borrowed: the document only points into `text`; `text` must outlive it\n    json_document borrowed = json_document::parse(text);\n    std::cout << borrowed.owns_source() << '\\n';\n\n    // owned: parse_copy() always takes its own copy\n    json_document copied = json_document::parse_copy(text);\n    std::cout << copied.owns_source() << '\\n';\n\n    // owned: an rvalue std::string is moved in, not copied, but still owned\n    json_document moved_in = json_document::parse(std::string(text));\n    std::cout << moved_in.owns_source() << '\\n';\n}\n

Output:

false\ntrue\ntrue\n
"},{"location":"api/basic_json_document/owns_source/#see-also","title":"See also","text":"
  • parse - deserialize from a compatible input
  • parse_copy - deserialize a copy of a compatible input, always owned
  • source - the parsed text
  • Zero-copy JSON views - who owns the source text and for how long
"},{"location":"api/basic_json_document/owns_source/#version-history","title":"Version history","text":"
  • Added in version 3.13.0 unreleased.
"},{"location":"api/basic_json_document/parse/","title":"nlohmann::basic_json_document::parse","text":"
// (1)\ntemplate<typename InputType>\nstatic basic_json_document parse(InputType&& input,\n                                 const bool allow_exceptions = true,\n                                 const bool ignore_comments = false,\n                                 const bool ignore_trailing_commas = false);\n\n// (2)\ntemplate<typename IteratorType>\nstatic basic_json_document parse(IteratorType first, IteratorType last,\n                                 const bool allow_exceptions = true,\n                                 const bool ignore_comments = false,\n                                 const bool ignore_trailing_commas = false);\n
  1. Deserialize from a compatible input, borrowing or owning it depending on its value category and type (see Notes).
  2. Deserialize from a pair of input iterators.

Both overloads accept the same JSON text as BasicJsonType::parse(), with the same ignore_comments/ignore_trailing_commas options, but build a basic_json_document (a flat index into the input) instead of a tree of BasicJsonType values. They accept every input BasicJsonType::parse() takes, and in addition a pointer to a null-terminated wide string (which BasicJsonType::parse() rejects). Contiguous inputs of single-byte characters that stay alive can be borrowed; all others (streams, FILE*, wide characters, which must be converted to UTF-8, and non-contiguous iterators) are read into a copy that the document owns \u2014 see the Notes. Use parse_copy() to get an owned copy of a borrowable input as well.

"},{"location":"api/basic_json_document/parse/#template-parameters","title":"Template parameters","text":"InputType

A compatible input, for instance:

  • a std::string, a std::string_view (C++17), or a C-style array of single-byte characters
  • a pointer to a null-terminated string of single-byte characters (char, signed char, unsigned char, std::uint8_t)
  • a container for which obj.data() and obj.size() give contiguous single-byte access, e.g. std::vector<char> or std::vector<std::uint8_t>
  • an std::istream object
  • a FILE* pointer
  • wide characters (wchar_t, char16_t, char32_t), which are converted to UTF-8: a wide string object (std::wstring, std::u16string, std::u32string), an array (e.g. a wide string literal), or a pointer to a null-terminated wide string
IteratorType an input iterator type, for instance a pair of pointers such as ptr and ptr + len, or a pair of std::string::iterator; the iterators of single-byte characters are borrowed or read like the byte inputs above, those of wide characters are converted to UTF-8

Ill-formed UTF-16 and UTF-32 sequences are rejected: a lone surrogate, a high surrogate that is not followed by its low surrogate, and a code point above U+10FFFF all yield a parse_error.101.

"},{"location":"api/basic_json_document/parse/#parameters","title":"Parameters","text":"input (in) Input to parse from. allow_exceptions (in) whether to throw exceptions in case of a parse error (optional, true by default) ignore_comments (in) whether comments should be ignored and treated like whitespace (true) or yield a parse error (false); (optional, false by default) ignore_trailing_commas (in) whether trailing commas in arrays or objects should be ignored and treated like whitespace (true) or yield a parse error (false); (optional, false by default) first (in) iterator to the start of a character range last (in) iterator to the end of a character range"},{"location":"api/basic_json_document/parse/#return-value","title":"Return value","text":"

The parsed document. If allow_exceptions is false and the input is not valid JSON, the returned document is discarded; see is_discarded.

"},{"location":"api/basic_json_document/parse/#exceptions","title":"Exceptions","text":"

Throws the same exception BasicJsonType::parse() throws for the same input and options \u2014 the same exception id, message, and position \u2014 because on a failing input the library's own parser is run on the same bytes to produce the diagnostic. This replay runs only for a failing input, and costs about a lexing pass up to the error (its SAX handler builds no values); with allow_exceptions set to false, it is skipped and a discarded document is returned instead. Additionally throws out_of_range.416 if the input is 4294967280 bytes (4 GiB minus 16 bytes) or larger, a size BasicJsonType::parse() does not reject.

"},{"location":"api/basic_json_document/parse/#complexity","title":"Complexity","text":"

Linear in the length of the input.

"},{"location":"api/basic_json_document/parse/#notes","title":"Notes","text":"

Ownership. Whether the document borrows input or owns a copy of it depends on its value category and type:

input ownership lvalue byte container (std::string, std::vector<char>, ...), std::string_view, C string, character array borrowed \u2014 input must outlive the document non-const rvalue std::string owned, moved in without a copy other rvalue byte container (including a const rvalue std::string) owned, copied stream, FILE*, wide characters, or anything else read through the general input adapter owned, read into a buffer (a stream is read to its end)

For overload (2), a pair of pointers to single-byte integers (e.g. const char*, std::uint8_t*) is borrowed. From C++20 on, so is any other contiguous iterator over single bytes, such as std::vector<char>::iterator or std::string::const_iterator. Before C++20 these iterators cannot be told apart from other class-type iterators, so their range is read into an owned buffer, as is any non-contiguous range (e.g. of a std::list<char>).

See owns_source to check which happened after a call, and the feature page for the reasoning.

Numbers. As for BasicJsonType::parse(), an integer literal too large for the 64-bit integer type becomes a floating-point value.

No lengths. An integer argument that is not a bool where the flags are expected \u2014 for example parse(ptr, len) \u2014 does not compile (the overload is deleted). Such a call would convert len to allow_exceptions and read ptr as a null-terminated string, past the end of a buffer that has none. To parse a buffer of a given length, pass a pair of pointers: parse(ptr, ptr + len). The same holds for parse_copy, accept, and read.

"},{"location":"api/basic_json_document/parse/#examples","title":"Examples","text":"Example: (1) borrowed vs. owned input, and errors identical to BasicJsonType::parse()
#include <iostream>\n#include <string>\n#include <nlohmann/json.hpp>\n#include <nlohmann/json_view.hpp>\n\nusing nlohmann::json_document;\n\nint main()\n{\n    std::cout << std::boolalpha;\n\n    // an lvalue std::string is BORROWED: the document only stores a pointer\n    // into `text`, so `text` must outlive `borrowed`\n    std::string text = R\"({\"count\": 3})\";\n    json_document borrowed = json_document::parse(text);\n    std::cout << borrowed.owns_source() << '\\n'; // false\n\n    // an rvalue std::string is MOVED into the document -- no copy of the text\n    json_document owned = json_document::parse(std::string(R\"({\"count\": 3})\"));\n    std::cout << owned.owns_source() << '\\n'; // true\n\n    // errors are identical to basic_json::parse: same exception id, message,\n    // and position, because the library parser runs on the same bytes on a\n    // failing input\n    try\n    {\n        static_cast<void>(json_document::parse(R\"({\"count\": )\"));\n    }\n    catch (const nlohmann::json::parse_error& e)\n    {\n        std::cout << e.id << '\\n';\n    }\n}\n

Output:

false\ntrue\n101\n
Example: (2) parse an iterator range (no NUL terminator required)
#include <iostream>\n#include <vector>\n#include <nlohmann/json_view.hpp>\n\nusing nlohmann::json_document;\n\nint main()\n{\n    std::cout << std::boolalpha;\n\n    // a JSON value embedded in a larger, non-null-terminated buffer (e.g. a\n    // slice received over the network)\n    std::vector<char> buffer = {'[', '1', ',', '2', ']', 'j', 'u', 'n', 'k'};\n\n    // a pointer pair is BORROWED, exactly like a byte container lvalue: the\n    // document points into the buffer. (From C++20 on, std::vector<char>\n    // iterators are borrowed as well; before, they are copied.)\n    const char* first = buffer.data();\n    json_document doc = json_document::parse(first, first + 5);\n    std::cout << doc.root().is_array() << ' ' << doc.root().size() << '\\n';\n    std::cout << doc.owns_source() << '\\n'; // false: borrowed\n}\n

Output:

true 2\nfalse\n
"},{"location":"api/basic_json_document/parse/#see-also","title":"See also","text":"
  • parse_copy - deserialize a copy of a compatible input
  • accept - check whether the input is valid JSON
  • read - (re-)parse into this document, reusing its memory
  • owns_source - return whether the document holds its own copy of the text
  • load - read a document from an image instead of parsing JSON text
  • BasicJsonType::parse - the corresponding function of basic_json
"},{"location":"api/basic_json_document/parse/#version-history","title":"Version history","text":"
  • Added in version 3.13.0 unreleased.
  • Ill-formed UTF-16 and UTF-32 input (a lone surrogate, a high surrogate that is not followed by its low surrogate, or a code point above U+10FFFF) is rejected with parse_error.101.
"},{"location":"api/basic_json_document/parse_copy/","title":"nlohmann::basic_json_document::parse_copy","text":"
template<typename InputType>\nstatic basic_json_document parse_copy(InputType&& input,\n                                      const bool allow_exceptions = true,\n                                      const bool ignore_comments = false,\n                                      const bool ignore_trailing_commas = false);\n

Deserialize from a compatible input, always taking the document's own copy of it, regardless of the value category or type of input. Unlike parse(), the returned document never depends on input staying alive.

"},{"location":"api/basic_json_document/parse_copy/#template-parameters","title":"Template parameters","text":"InputType A compatible input; see parse."},{"location":"api/basic_json_document/parse_copy/#parameters","title":"Parameters","text":"input (in) Input to parse from. allow_exceptions (in) whether to throw exceptions in case of a parse error (optional, true by default) ignore_comments (in) whether comments should be ignored and treated like whitespace (true) or yield a parse error (false); (optional, false by default) ignore_trailing_commas (in) whether trailing commas in arrays or objects should be ignored and treated like whitespace (true) or yield a parse error (false); (optional, false by default)"},{"location":"api/basic_json_document/parse_copy/#return-value","title":"Return value","text":"

The parsed document, with owns_source() true. If allow_exceptions is false and the input is not valid JSON, the returned document is discarded; see is_discarded.

"},{"location":"api/basic_json_document/parse_copy/#exceptions","title":"Exceptions","text":"

Same as parse.

"},{"location":"api/basic_json_document/parse_copy/#complexity","title":"Complexity","text":"

Linear in the length of the input.

"},{"location":"api/basic_json_document/parse_copy/#notes","title":"Notes","text":"

parse_copy() accepts and rejects exactly what parse() does, and classifies numbers the same way; it only differs in that the input is always copied rather than sometimes borrowed. Prefer parse() when the input's lifetime already covers the document's, since it avoids the copy for borrowed inputs.

An integer argument that is not a bool where the flags are expected, such as parse_copy(ptr, len), does not compile; see parse.

"},{"location":"api/basic_json_document/parse_copy/#examples","title":"Examples","text":"Example

The example below returns a document from a function whose local buffer would otherwise not outlive it.

#include <iostream>\n#include <nlohmann/json_view.hpp>\n\nusing nlohmann::json_document;\n\njson_document parse_from_temporary_buffer()\n{\n    char buffer[] = R\"({\"a\": 1})\";\n    // parse() would borrow `buffer`, which is about to go out of scope;\n    // parse_copy() takes its own copy instead, so the returned document does\n    // not depend on `buffer` afterward\n    return json_document::parse_copy(buffer);\n}\n\nint main()\n{\n    std::cout << std::boolalpha;\n\n    json_document doc = parse_from_temporary_buffer();\n    std::cout << doc.owns_source() << '\\n';\n    std::cout << doc.root().is_object() << '\\n';\n}\n

Output:

true\ntrue\n
"},{"location":"api/basic_json_document/parse_copy/#see-also","title":"See also","text":"
  • parse - deserialize from a compatible input, borrowing it where possible
  • owns_source - return whether the document holds its own copy of the text
  • Zero-copy JSON views - borrowing or copying the source text
"},{"location":"api/basic_json_document/parse_copy/#version-history","title":"Version history","text":"
  • Added in version 3.13.0 unreleased.
"},{"location":"api/basic_json_document/push_back/","title":"nlohmann::basic_json_document::push_back","text":"
template<typename V>\nview_type push_back(view_type array, V&& value);\n

Appends value as a new last element of array. A null array first becomes an empty array, the same way set turns a null object into an empty object.

value is accepted three ways: a basic_json_view of any document \u2014 read-only or editable, and it does not have to be array's own document \u2014 which is copied so that nothing is shared with the source document afterward; a BasicJsonType value; or anything BasicJsonType can be constructed from (numbers, strings, bool, nullptr, containers, ...).

Only an editable document (view_mode::editable, e.g. json_editable_document) has push_back; calling it on a read-only basic_json_document fails to compile (static_assert).

"},{"location":"api/basic_json_document/push_back/#template-parameters","title":"Template parameters","text":"V the type of value, deduced; see above for what is accepted."},{"location":"api/basic_json_document/push_back/#parameters","title":"Parameters","text":"array (in) the array (or null value) to append to value (in) the value to append"},{"location":"api/basic_json_document/push_back/#return-value","title":"Return value","text":"

a view of the new last element of array, now holding value

"},{"location":"api/basic_json_document/push_back/#exception-safety","title":"Exception safety","text":"

Basic exception safety: value is fully encoded \u2014 including the checks below \u2014 into storage owned by the document before anything already reachable from root() is touched, so a failure while encoding value (an invalid argument, or std::bad_alloc) leaves the document completely unchanged, other than memory allocated for the encoding that is not reclaimed. A failure of a later allocation \u2014 while array switches from its parsed layout to a growable block, or while that block grows, see Notes \u2014 can still leave a partial effect, such as a null array argument already turned into an empty array even though value itself was not appended.

"},{"location":"api/basic_json_document/push_back/#exceptions","title":"Exceptions","text":"

Throws type_error.308 if array is neither an array nor null \u2014 the same message BasicJsonType::push_back throws for the same type. Throws invalid_iterator.202 (\"view does not belong to this document\") if array is a discarded view or a view of a different document. Throws type_error.302 if value is a discarded view or a discarded BasicJsonType value, and type_error.319 if value is (or contains) a binary value \u2014 BasicJsonType can hold one, but a json_document cannot. Throws type_error.316 if value is (or contains) a string that is not valid UTF-8, with the same message BasicJsonType::dump() gives for that string.

"},{"location":"api/basic_json_document/push_back/#complexity","title":"Complexity","text":"

Amortized constant, plus time linear in the size of value to encode it into the document's storage (constant for a scalar, linear in the number of nested values for an array or object): the elements of array move to a growable block of links the first time it is appended to (or set on), and that block itself grows \u2014 doubling its capacity, so the cost of growing it amortizes to constant per element \u2014 only once it runs out of room. See Notes.

"},{"location":"api/basic_json_document/push_back/#notes","title":"Notes","text":"

Like set on a member or an element, push_back never moves an existing element itself \u2014 only where array's links to its elements live \u2014 so a view of an existing element of array stays valid across a push_back, but any iterator already taken over array is invalidated, since it was walking the old layout. See Edits for what stays valid across an edit in general.

"},{"location":"api/basic_json_document/push_back/#examples","title":"Examples","text":"Example

The example below appends records to an array one at a time, as they might arrive from a stream of events, without ever building a BasicJsonType value for the array or for the records already in it, and shows that a view taken from an earlier push_back still refers to the same element once later ones have run.

#include <iostream>\n#include <nlohmann/json_view.hpp>\n\nusing nlohmann::json;\nusing nlohmann::json_editable_document;\n\nint main()\n{\n    // \"events\" starts out null -- the first push_back() turns it into an\n    // array, exactly like set() turns a null object member into an object\n    json_editable_document doc = json_editable_document::parse(R\"({\"source\": \"sensor-1\", \"events\": null})\");\n\n    const auto first = doc.push_back(doc.root()[\"events\"], json{{\"type\", \"start\"}, {\"t\", 0}});\n    for (int t = 1; t <= 3; ++t)\n    {\n        doc.push_back(doc.root()[\"events\"], json{{\"type\", \"tick\"}, {\"t\", t}});\n    }\n\n    // push_back() never moves an existing element: a view taken from an\n    // earlier call still refers to the same element after later ones\n    std::cout << first.dump() << '\\n';\n    std::cout << doc.root()[\"events\"].size() << '\\n';\n    std::cout << doc.root().dump(2) << '\\n';\n}\n

Output:

{\"t\":0,\"type\":\"start\"}\n4\n{\n  \"source\": \"sensor-1\",\n  \"events\": [\n    {\n      \"t\": 0,\n      \"type\": \"start\"\n    },\n    {\n      \"t\": 1,\n      \"type\": \"tick\"\n    },\n    {\n      \"t\": 2,\n      \"type\": \"tick\"\n    },\n    {\n      \"t\": 3,\n      \"type\": \"tick\"\n    }\n  ]\n}\n
"},{"location":"api/basic_json_document/push_back/#see-also","title":"See also","text":"
  • set - replace a value, or set an object member, an array element, or the value a JSON pointer refers to
  • insert - insert an element into an array before a given position
  • erase - remove an object member, an array element, or the value a JSON pointer refers to
  • root - the view of the root value
  • BasicJsonType::push_back - the corresponding function of basic_json
  • Edits - what an edit guarantees, for every overload
  • Zero-copy JSON views - what an edit guarantees and costs
"},{"location":"api/basic_json_document/push_back/#version-history","title":"Version history","text":"
  • Added in version 3.13.0 unreleased.
"},{"location":"api/basic_json_document/read/","title":"nlohmann::basic_json_document::read","text":"
template<typename InputType>\nvoid read(InputType&& input,\n         const bool allow_exceptions = true,\n         const bool ignore_comments = false,\n         const bool ignore_trailing_commas = false);\n

(Re-)parses input into *this, discarding the document's previous value and reusing its memory (the node index, the decoded-string buffer, and, if applicable, the owned copy of the text) rather than allocating a fresh document. parse() is implemented in terms of this function, applied to a default-constructed document.

"},{"location":"api/basic_json_document/read/#template-parameters","title":"Template parameters","text":"InputType A compatible input; see parse."},{"location":"api/basic_json_document/read/#parameters","title":"Parameters","text":"input (in) Input to parse from. allow_exceptions (in) whether to throw exceptions in case of a parse error (optional, true by default) ignore_comments (in) whether comments should be ignored and treated like whitespace (true) or yield a parse error (false); (optional, false by default) ignore_trailing_commas (in) whether trailing commas in arrays or objects should be ignored and treated like whitespace (true) or yield a parse error (false); (optional, false by default)"},{"location":"api/basic_json_document/read/#exceptions","title":"Exceptions","text":"

Same as parse.

"},{"location":"api/basic_json_document/read/#complexity","title":"Complexity","text":"

Linear in the length of the input.

"},{"location":"api/basic_json_document/read/#notes","title":"Notes","text":"

Every view taken from *this before the call \u2014 including the previous root() \u2014 is invalidated, whether or not the new parse succeeds; take fresh views from root() afterward.

input is borrowed or owned by the same rules as parse(); a document can borrow on one call and own on the next, since ownership is decided freshly each time. An input that is copied (see the table in parse()) is written into the document's previous owned copy, reusing its memory; a moved-in std::string replaces it.

Reusing a document matters most for large inputs: the operating system provides the memory of a fresh node index one page at a time, and every page costs a page fault the first time it is written. On x86-64 Linux (4 KiB pages), parsing a 55 MB document into a reused document took about 40 % less time than parsing it into a fresh one. Programs that parse many documents of similar size should therefore keep one document and call read().

An integer argument that is not a bool where the flags are expected, such as read(ptr, len), does not compile; see parse.

"},{"location":"api/basic_json_document/read/#examples","title":"Examples","text":"Example

The example below parses a sequence of messages into the same document, reusing its memory instead of allocating a new document for each one.

#include <iostream>\n#include <string>\n#include <vector>\n#include <nlohmann/json_view.hpp>\n\nusing nlohmann::json_document;\n\nint main()\n{\n    std::cout << std::boolalpha;\n\n    std::vector<std::string> messages =\n    {\n        R\"({\"id\": 1})\", R\"({\"id\": 2, \"tag\": \"x\"})\", R\"({\"id\": 3})\"\n    };\n\n    // parse into the same document over and over: its node index and decode\n    // buffer are reused instead of being freed and reallocated for each message\n    json_document doc;\n    std::size_t total = 0;\n    for (const auto& msg : messages)\n    {\n        doc.read(msg);\n        total += doc.root().size();\n    }\n    std::cout << total << '\\n';\n\n    // read() can also change what kind of input is owned/borrowed between calls\n    doc.read(std::string(R\"({\"owned\": true})\"));\n    std::cout << doc.owns_source() << '\\n';\n}\n

Output:

4\ntrue\n
"},{"location":"api/basic_json_document/read/#see-also","title":"See also","text":"
  • parse - deserialize from a compatible input
  • root - the view of the root value
  • load - read a document from an image instead of parsing JSON text
  • Zero-copy JSON views - reusing a document and what it invalidates
"},{"location":"api/basic_json_document/read/#version-history","title":"Version history","text":"
  • Added in version 3.13.0 unreleased.
"},{"location":"api/basic_json_document/root/","title":"nlohmann::basic_json_document::root","text":"
// (1)\nview_type root() const& noexcept;\n\n// (2)\nview_type root() const&& = delete;\n
  1. Returns a view of the root value of the document.
  2. Deleted: the view of a temporary document would dangle.
"},{"location":"api/basic_json_document/root/#return-value","title":"Return value","text":"

A view_type (i.e. basic_json_view<BasicJsonType>) for the root value, or a discarded view if the document is discarded.

"},{"location":"api/basic_json_document/root/#exception-safety","title":"Exception safety","text":"

No-throw guarantee: this function never throws exceptions.

"},{"location":"api/basic_json_document/root/#complexity","title":"Complexity","text":"

Constant.

"},{"location":"api/basic_json_document/root/#notes","title":"Notes","text":"

Lifetime. A view refers into the document, so the document must outlive it. root() can therefore only be called on a document that has a name (an lvalue); calling it on a temporary does not compile:

auto v = json_document::parse(text).root();  // error: the document is destroyed at the end of the statement\n\nauto doc = json_document::parse(text);       // OK: keep the document alive\nauto v = doc.root();\n

root() is a cheap handle into the document's index, not a copy of anything; call it as often as needed. The returned view is valid under the same conditions as any other view of the document \u2014 see Object inspection \u2014 in particular, it is invalidated by the next read() or shrink_to_fit() on this document. A view can dangle, like a std::string_view; see Ownership and lifetime.

"},{"location":"api/basic_json_document/root/#examples","title":"Examples","text":"Example
#include <iostream>\n#include <nlohmann/json_view.hpp>\n\nusing nlohmann::json_document;\n\nint main()\n{\n    std::cout << std::boolalpha;\n\n    json_document doc = json_document::parse(R\"({\"greeting\": \"hi\"})\");\n    std::cout << doc.root().is_object() << '\\n';\n\n    // root() is a cheap handle, not a copy: repeated calls observe the same value\n    std::cout << (doc.root().type() == doc.root().type()) << '\\n';\n\n    // the root of a failed parse (allow_exceptions == false) is discarded\n    json_document failed = json_document::parse(\"{\", false);\n    std::cout << failed.root().is_discarded() << '\\n';\n}\n

Output:

true\ntrue\ntrue\n
"},{"location":"api/basic_json_document/root/#see-also","title":"See also","text":"
  • is_discarded - return whether the last parse failed
  • materialize - build the BasicJsonType value of a subtree
"},{"location":"api/basic_json_document/root/#version-history","title":"Version history","text":"
  • Added in version 3.13.0 unreleased.
"},{"location":"api/basic_json_document/save/","title":"nlohmann::basic_json_document::save","text":"
std::vector<std::uint8_t> save() const;\n

Writes the document as an image: a byte buffer that load reads back without parsing. The image holds the node index, the source text (plus, for an edited document, the number tokens edits wrote), and the decoded strings (plus the strings edits wrote) \u2014 everything root() needs, with nothing left to parse.

An edited document is written in its current state, with its values in document order, the way the library's own parser would have produced them for that JSON text: a member set added goes at the end, an erased member leaves no trace, and a float that is not finite (NaN or positive/negative infinity) becomes null, the same substitution dump() makes. The same document always saves to the same bytes \u2014 also across BasicJsonType and the view_mode, since the image reflects document order and values only, not which specialization produced them.

"},{"location":"api/basic_json_document/save/#return-value","title":"Return value","text":"

The image, as a std::vector<std::uint8_t>. Pass it, or a pointer to its data together with its size, to load to read the document back.

"},{"location":"api/basic_json_document/save/#exception-safety","title":"Exception safety","text":"

Strong guarantee: save() does not modify *this (it is const), so if it throws, the document is left exactly as it was, and the partially built image is discarded with the exception.

"},{"location":"api/basic_json_document/save/#exceptions","title":"Exceptions","text":"

Throws type_error.320 if the document is discarded \u2014 a default-constructed document, or one a failed parse()/ read() with allow_exceptions == false left discarded.

Throws out_of_range.416 if the node count, the text, or the decoded strings of the image would individually reach 4 GiB \u2014 the same 32-bit offsets parse() and, for edits, set/push_back are already limited to.

Example messages

[json.exception.type_error.320] cannot save a discarded json_document\n
[json.exception.out_of_range.416] images of 4 GiB or more are not supported by json_document\n

"},{"location":"api/basic_json_document/save/#complexity","title":"Complexity","text":"

Linear in the size of the document: the number of nodes, plus the length of the text and the decoded strings that end up in the image.

"},{"location":"api/basic_json_document/save/#notes","title":"Notes","text":"

Format. The image begins with a 64-byte header (the magic bytes \"NJVI\", a version number, the node count, and the sizes of the text and the decoded strings, all little-endian), followed by the nodes (16 bytes each), the text and a '\\0', and the decoded strings and a '\\0'. load checks the header, and the sizes it describes, before reading anything else \u2014 see load's Exceptions.

Experimental

The image format is versioned but not yet stable: it may change in an incompatible way before it is declared stable. Use images to cache a document within one build of the library, or to hand one to another process running the same build on the same (little-endian) machine \u2014 not as a long-term storage format. Keep the original JSON text if you need to read a saved document back with a future library version.

Little-endian targets only. The image is written as raw little-endian bytes, with no byte-swapping. On a big-endian target, save() and load do not exist: a call fails to compile rather than produce bytes a big-endian reader could not interpret correctly.

"},{"location":"api/basic_json_document/save/#examples","title":"Examples","text":"Caching a parsed document as an image

The example below saves a parsed configuration as an image \u2014 the way a service might cache one to answer later requests without parsing the text again \u2014 and confirms that loading it back gives exactly the same result as parsing did, and that saving is deterministic.

#include <cstdint>\n#include <iostream>\n#include <string>\n#include <vector>\n#include <nlohmann/json_view.hpp>\n\nusing nlohmann::json_document;\n\nint main()\n{\n    std::cout << std::boolalpha;\n\n    // a configuration a service parses once and then caches as an image, so\n    // that later requests can load() it instead of parsing the text again\n    const std::string text = R\"({\"name\": \"cache\", \"host\": \"db1\", \"port\": 6379, \"replicas\": [\"db2\", \"db3\"]})\";\n    const json_document config = json_document::parse(text);\n\n    // save() turns the parsed document into a byte buffer: a 64-byte header,\n    // the node index, the source text, and the decoded strings\n    const std::vector<std::uint8_t> image = config.save();\n    std::cout << image.size() << '\\n';\n\n    // the same document always saves to the same bytes\n    std::cout << (image == json_document::parse(text).save()) << '\\n';\n\n    // loading the image back needs no parsing, yet dumps exactly what\n    // parsing the text produced\n    const json_document reloaded = json_document::load(image);\n    std::cout << (reloaded.root().dump() == config.root().dump()) << '\\n';\n}\n

Output:

316\ntrue\ntrue\n
"},{"location":"api/basic_json_document/save/#see-also","title":"See also","text":"
  • load - read an image written by save()
  • owns_source - return whether the document holds its own copy of the text
  • basic_json_view::dump - serialize the document to JSON text instead of an image
  • Images - why and when to use images
"},{"location":"api/basic_json_document/save/#version-history","title":"Version history","text":"
  • Added in version 3.13.0 unreleased.
"},{"location":"api/basic_json_document/set/","title":"nlohmann::basic_json_document::set","text":"
// (1)\ntemplate<typename V>\nview_type set(view_type target, V&& value);\n\n// (2)\ntemplate<typename V>\nview_type set(view_type object, string_view_t key, V&& value);\n\n// (3)\ntemplate<typename I, typename V>\nview_type set(view_type array, I idx, V&& value);\n\n// (4)\ntemplate<typename V>\nview_type set(const json_pointer& ptr, V&& value);\n

Only an editable document (view_mode::editable, e.g. json_editable_document) has set; calling it on a read-only basic_json_document fails to compile (static_assert).

  1. Replaces the value target refers to with value.
  2. Sets the member key of the object object to value: assigns it if object already has a member with this key \u2014 the first one, should the key occur more than once, and the later duplicates are then dropped (see the Notes below) \u2014 or appends a new member at the end otherwise. A null object first becomes an empty object.
  3. Assigns value to the element at index idx of the array array, which must already exist (idx < array.size()).
  4. Sets the value the JSON pointer ptr refers to, relative to root(), to value. The parent of the target must already exist: an object member is set as in 2. (added if it does not exist yet), an array element is assigned as in 3., and a last reference token of \"-\", or equal to the size of the array, appends value instead, exactly as push_back would. A null parent becomes what basic_json::operator[] with a JSON pointer makes of it: an array if the last reference token is \"-\" or consists of digits only (for an index beyond 0, the array is first filled with null values up to that index), an object otherwise. An empty ptr sets root() itself, as in 1.

In every overload, value is accepted three ways: a basic_json_view of any document \u2014 read-only or editable, and it does not have to be target's/object's/array's own document \u2014 which is copied so that nothing is shared with the source document afterward; a BasicJsonType value; or anything BasicJsonType can be constructed from (numbers, strings, bool, nullptr, containers, ...).

"},{"location":"api/basic_json_document/set/#template-parameters","title":"Template parameters","text":"V the type of value, deduced; see above for what is accepted. I an integral type other than bool, deduced (overloads taking a bool or a non-integral type for idx do not participate in overload resolution)."},{"location":"api/basic_json_document/set/#parameters","title":"Parameters","text":"target (in) the value to replace object (in) the object (or null value) whose member to set array (in) the array whose element to assign key (in) the key of the member to set idx (in) the index of the element to assign; a negative value throws (see Exceptions) ptr (in) a JSON pointer to the value to set, relative to root() value (in) the new value"},{"location":"api/basic_json_document/set/#return-value","title":"Return value","text":"
  1. a view of target, now holding value
  2. a view of the member key of object, now holding value
  3. a view of the element idx of array, now holding value
  4. a view of the value ptr refers to, now holding value
"},{"location":"api/basic_json_document/set/#exception-safety","title":"Exception safety","text":"

Basic exception safety: value is fully encoded \u2014 including the checks below \u2014 into storage owned by the document before anything already reachable from root() is touched, so a failure while encoding value (an invalid argument, or std::bad_alloc) leaves the document completely unchanged, other than memory allocated for the encoding that is not reclaimed. A failure of a later allocation \u2014 while an edited array or object switches from its parsed layout to a growable block, see Notes \u2014 can still leave a partial effect, such as a null object/array argument already turned into an empty object/array even though value itself was not linked in. Likewise, a failure of value in 4. leaves a null parent that is set with an index beyond 0 already filled with the null values before the index.

"},{"location":"api/basic_json_document/set/#exceptions","title":"Exceptions","text":"
  1. Throws type_error.302 if value is a discarded view, or a discarded BasicJsonType value (e.g. BasicJsonType(value_t::discarded)) \u2014 an object or array value, of either kind, is fine and is encoded as a whole subtree.
  2. Throws type_error.305 if object is neither an object nor null \u2014 the same message operator[] throws for a string argument on such a value. Throws type_error.316 if key is not valid UTF-8, with the same message BasicJsonType::dump() gives for that string. Also throws what 1. throws for value.
  3. Throws type_error.305 if array is not an array \u2014 the same message operator[] throws for a numeric argument on such a value. Throws out_of_range.401 if idx is negative, or if idx >= array.size(). Also throws what 1. throws for value.
  4. Throws what at throws (overload 3) for resolving ptr's parent, except that a missing object member or an array index equal to the array's size at the very last reference token is not an error there (it becomes a new member or an appended element) instead of out_of_range.403/out_of_range.402. For the last reference token itself: if the parent is an object (or a primitive value, where it throws type_error.305), throws what 2. throws; if the parent is an array, throws what 3. throws for an index that is out of range, or, for a token that is not a valid array index, parse_error.106 (a leading '0'), parse_error.109 (not a number), out_of_range.410 (too large for size_type), or out_of_range.404 (an empty token); the same errors are thrown for a null parent and a token of digits (the parent is not changed then), and out_of_range.401 if the index is 4294967295 or more. Also throws what 1. throws for value.

Every overload also throws type_error.319 if value is (or contains) a binary value \u2014 BasicJsonType can hold one, but a json_document cannot \u2014 and invalid_iterator.202 (\"view does not belong to this document\") if target/object/array is a discarded view or a view of a different document (overloads 1-3 only; overload 4 always starts from this document's own root()).

"},{"location":"api/basic_json_document/set/#complexity","title":"Complexity","text":"
  1. Linear in the size of value (encoding it into the document's storage): constant for a scalar, linear in the number of nested values for an array or object. If target is itself an array or object that spans more than one node in its parent's original, unedited layout, and value is a scalar, replacing it additionally costs time linear in the size of the document, the first time (the parent of target is looked up from root(), and then switches to links) \u2014 see Notes. Once the parent has links, target is replaced in constant time: setting every element of a large array one after the other is linear overall. To avoid the lookup altogether, use 3. (or 2. for an object), which know the parent.
  2. Linear in the number of members of object, to find an existing member with key, plus the complexity of 1. for value.
  3. Constant, plus the complexity of 1. for value.
  4. Linear in the number of reference tokens of ptr and, for each token, in the number of members of the object at that level or the index into the array (as at), plus the complexity of 2. or 3. for the last token; for a null parent and an index, linear in the index.
"},{"location":"api/basic_json_document/set/#notes","title":"Notes","text":"

Duplicate keys

If object already has more than one member with key (2.), the first one is assigned value and every later member with the same key is removed \u2014 so that a lookup, an iteration, and materialize() of object afterward all agree on a single value for key, the same way operator[] already picks the first occurrence of a duplicate key for reading. See the Notes on duplicate keys of operator[].

Setting a member (2.) or an element (3., through 4.) of an array or object whose elements have not been edited before switches it from its parsed layout to a growable block holding links to its elements; a later push_back or set on the same container reuses that block, growing it (amortized constant time) only once it runs out of room. This never moves an element itself \u2014 only where the container's links to its elements live \u2014 so a view of an element stays valid, but any iterator already taken over the container is invalidated, since it was walking the old layout. See Edits for what stays valid across an edit in general.

The same switch happens, for the same reason, when overload 1. replaces a multi-node array/object value with a scalar: the parent's element sequence is what has to switch to links, not target itself, because the parent originally stepped over target's whole subtree by its node count, which no longer applies once target is a one-node scalar.

"},{"location":"api/basic_json_document/set/#examples","title":"Examples","text":"Example: (1)/(2)/(3)/(4) replace a value, set a member, assign an element, set via a JSON pointer

The example below edits a small configuration document \u2014 replacing a value, adding an object member, assigning an array element, and reaching a field through a JSON pointer \u2014 and shows what dump() preserves that is lost once the same edits are made on a BasicJsonType value instead: the order object members were written in, and the exact spelling of a number that was never touched.

#include <iostream>\n#include <nlohmann/json_view.hpp>\n\nusing nlohmann::json;\nusing nlohmann::json_editable_document;\nusing nlohmann::json_editable_view;\n\nint main()\n{\n    // a configuration file, as it might be read from disk -- \"price\" is\n    // written with a trailing zero that has no effect on its value\n    const std::string text = R\"({\n  \"name\": \"cache\",\n  \"host\": \"db1\",\n  \"port\": 6379,\n  \"price\": 19.90,\n  \"replicas\": [\"db2\", \"db3\"],\n  \"timeout\": 30\n})\";\n\n    json_editable_document doc = json_editable_document::parse(text);\n\n    doc.set(doc.root()[\"port\"], 6380);                    // (1) replace a value\n    doc.set(doc.root(), \"region\", \"us-east\");              // (2) add a member\n    doc.set(doc.root()[\"replicas\"], 0, \"db4\");             // (3) assign an element\n    doc.set(json::json_pointer(\"/timeout\"), 45);           // (4) via a JSON pointer\n\n    // members stay in document order (the new one at the end), and a number\n    // that was not itself edited keeps its exact spelling\n    std::cout << doc.root().dump(2, ' ', false, json_editable_view::number_format::source) << \"\\n\\n\";\n\n    // the same edits on a plain json value: object_t is a std::map, so\n    // parsing already sorted the keys, and dump() rewrites every number to\n    // its shortest form, even \"price\", which was never touched\n    json plain = json::parse(text);\n    plain[\"port\"] = 6380;\n    plain[\"region\"] = \"us-east\";\n    plain[\"replicas\"][0] = \"db4\";\n    plain[json::json_pointer(\"/timeout\")] = 45;\n    std::cout << plain.dump(2) << '\\n';\n}\n

Output:

{\n  \"name\": \"cache\",\n  \"host\": \"db1\",\n  \"port\": 6380,\n  \"price\": 19.90,\n  \"replicas\": [\n    \"db4\",\n    \"db3\"\n  ],\n  \"timeout\": 45,\n  \"region\": \"us-east\"\n}\n\n{\n  \"host\": \"db1\",\n  \"name\": \"cache\",\n  \"port\": 6380,\n  \"price\": 19.9,\n  \"region\": \"us-east\",\n  \"replicas\": [\n    \"db4\",\n    \"db3\"\n  ],\n  \"timeout\": 45\n}\n
"},{"location":"api/basic_json_document/set/#see-also","title":"See also","text":"
  • push_back - append to an array
  • insert - insert an element into an array
  • erase - remove an object member, an array element, or the value a JSON pointer refers to
  • root - the view of the root value, the starting point of overload 4
  • basic_json_view::dump - serialize the document, keeping an untouched number's spelling with number_format::source
  • Edits - what an edit guarantees, for every overload
  • Editing a document - why editable documents keep the source text's order and number spelling
"},{"location":"api/basic_json_document/set/#version-history","title":"Version history","text":"
  • Added in version 3.13.0 unreleased.
"},{"location":"api/basic_json_document/shrink_to_fit/","title":"nlohmann::basic_json_document::shrink_to_fit","text":"
void shrink_to_fit();\n

Releases capacity that is no longer needed, both of the node index and of the buffer for decoded strings (strings that contained escape sequences), e.g. after read() replaced a large document with a much smaller one. Like std::vector::shrink_to_fit(), this is a non-binding request: the library may keep more capacity than strictly necessary.

"},{"location":"api/basic_json_document/shrink_to_fit/#exception-safety","title":"Exception safety","text":"

Strong guarantee: if an exception is thrown, there are no changes to the document.

"},{"location":"api/basic_json_document/shrink_to_fit/#exceptions","title":"Exceptions","text":"

May throw std::bad_alloc if the reallocation fails; on exception, the document is unchanged.

"},{"location":"api/basic_json_document/shrink_to_fit/#complexity","title":"Complexity","text":"

Linear in node_count() plus the length of the decoded strings.

"},{"location":"api/basic_json_document/shrink_to_fit/#notes","title":"Notes","text":"

The node index of a small document (an estimate of up to 1024 nodes, which is up to about 4 KiB of minified text) is allocated together with the document's header, so that parsing needs one allocation. That part cannot be released separately: shrink_to_fit() only trims a node index that has its own allocation, and the decoded strings.

Invalidates views

Unlike moving the document, shrink_to_fit() invalidates every view taken from this document before the call, including a previously obtained root(): the node index is moved into a new, smaller allocation, and the old one is freed. Take a fresh view from root() after calling this function.

This is unlike std::vector::shrink_to_fit(), which promises nothing about validity but in practice often leaves iterators alone when it did not need to reallocate; here, an implementation that avoids a reallocation when possible would be an internal optimization only, not a guarantee to rely on.

"},{"location":"api/basic_json_document/shrink_to_fit/#examples","title":"Examples","text":"Example
#include <iostream>\n#include <sstream>\n#include <string>\n#include <nlohmann/json_view.hpp>\n\nusing nlohmann::json_document;\n\nint main()\n{\n    std::cout << std::boolalpha;\n\n    // build a large array (many nodes), then read a small one into the same\n    // document: the index grown for the large input is still allocated\n    std::ostringstream big;\n    big << '[';\n    for (int i = 0; i < 500; ++i)\n    {\n        if (i != 0)\n        {\n            big << ',';\n        }\n        big << i;\n    }\n    big << ']';\n\n    json_document doc;\n    doc.read(big.str());\n    const std::size_t big_nodes = doc.node_count();\n\n    doc.read(std::string(\"[1]\"));\n    std::cout << (doc.node_count() < big_nodes) << '\\n'; // far fewer live nodes now\n    const std::size_t before = doc.memory_usage();\n\n    // shrink_to_fit() moves the index into a block sized for what is actually\n    // used. This INVALIDATES every view taken from this document before the\n    // call (they point into the old, now-freed block) -- take fresh ones from\n    // root() afterward.\n    doc.shrink_to_fit();\n    const std::size_t after = doc.memory_usage();\n    std::cout << (after <= before) << '\\n';\n\n    // a freshly taken view is valid and correct\n    std::cout << doc.root().is_array() << ' ' << doc.root().size() << '\\n';\n}\n

Output:

true\ntrue\ntrue 1\n
"},{"location":"api/basic_json_document/shrink_to_fit/#see-also","title":"See also","text":"
  • node_count - the number of index entries
  • memory_usage - the number of bytes held by the document
  • root - the view of the root value
  • Zero-copy JSON views - what releasing memory invalidates
"},{"location":"api/basic_json_document/shrink_to_fit/#version-history","title":"Version history","text":"
  • Added in version 3.13.0 unreleased.
"},{"location":"api/basic_json_document/source/","title":"nlohmann::basic_json_document::source","text":"
view_type::string_view_t source() const noexcept;\n

Returns the parsed text, whether it is borrowed from the caller or owned by the document.

"},{"location":"api/basic_json_document/source/#return-value","title":"Return value","text":"

A string_view_t (std::string_view on C++17 and newer) over the parsed text, or an empty one if the document is discarded.

"},{"location":"api/basic_json_document/source/#exception-safety","title":"Exception safety","text":"

No-throw guarantee: this function never throws exceptions.

"},{"location":"api/basic_json_document/source/#complexity","title":"Complexity","text":"

Constant.

"},{"location":"api/basic_json_document/source/#notes","title":"Notes","text":"

For a borrowed document, source() points directly into the caller's buffer, so it is only valid while that buffer is; see owns_source.

"},{"location":"api/basic_json_document/source/#examples","title":"Examples","text":"Example
#include <iostream>\n#include <string>\n#include <nlohmann/json_view.hpp>\n\nusing nlohmann::json_document;\n\nint main()\n{\n    std::cout << std::boolalpha;\n\n    std::string text = R\"({\"a\": 1})\";\n    json_document doc = json_document::parse(text);\n\n    // source() is the parsed text, whether borrowed or owned\n    std::cout << (doc.source().size() == text.size()) << '\\n';\n    std::cout << std::string(doc.source().data(), doc.source().size()) << '\\n';\n\n    // for a borrowed document, source() points right into the caller's buffer\n    std::cout << (doc.source().data() == text.data()) << '\\n';\n}\n

Output:

true\n{\"a\": 1}\ntrue\n
"},{"location":"api/basic_json_document/source/#see-also","title":"See also","text":"
  • owns_source - return whether the document holds its own copy of the text
  • source_offset - byte offset of a value in the source text
  • Zero-copy JSON views - who owns the source text and for how long
"},{"location":"api/basic_json_document/source/#version-history","title":"Version history","text":"
  • Added in version 3.13.0 unreleased.
"},{"location":"api/basic_json_view/","title":"nlohmann::basic_json_view","text":"

Defined in header <nlohmann/json_view.hpp>

template<typename BasicJsonType, view_mode Mode = view_mode::read_only>\nclass basic_json_view;\n

A read-only handle to one value of a basic_json_document: two pointers (a pointer to the document and a pointer into its index), trivially copyable. A view is valid as long as

  • the document is alive,
  • the document has not been re-parsed with read() (or parse() into it) or shrunk with shrink_to_fit() since the view was taken, and
  • if the document borrows its source text, that text is still alive and unmodified (floating-point values and unescaped strings are read from it lazily).

Moving the document itself does not invalidate its views: the index is heap-allocated independently of the basic_json_document object.

basic_json_view provides the read-only part of the BasicJsonType interface:

  • the type-inspection functions
  • element access
  • lookup
  • iteration
  • conversion: get<T>(), get_string(), number_token(), and materialize() to build the BasicJsonType value of a subtree on demand
  • comparison: operator== and operator!= compare two views, or a view and a BasicJsonType value, without ever building a BasicJsonType value for a view; no ordering comparison (operator<) is provided

operator[], at, contains, and value also accept a json_pointer. Unlike basic_json, there are no implicit conversion operators (no operator ValueType()), and no get_ptr() or get_ref(); see get.

basic_json_view itself is always read-only \u2014 it never has a set or push_back of its own. A view of an editable document (view_mode::editable) sees every edit made through basic_json_document::set and basic_json_document::push_back: once a value is changed, every view that still refers to it \u2014 including ones taken before the change \u2014 reads the new value. See Edits.

"},{"location":"api/basic_json_view/#template-parameters","title":"Template parameters","text":"BasicJsonType a specialization of basic_json, matching the basic_json_document the view was taken from. Mode a view_mode: whether the view is of an editable document, matching the basic_json_document it was taken from (optional, view_mode::read_only by default). See Edits."},{"location":"api/basic_json_view/#specializations","title":"Specializations","text":"
  • json_view - views of a json_document
  • ordered_json_view - views of an ordered_json_document
  • json_editable_view - views of a json_editable_document
  • ordered_json_editable_view - views of an ordered_json_editable_document
"},{"location":"api/basic_json_view/#member-types","title":"Member types","text":"
  • basic_json_type - BasicJsonType (it also marks the class for is_json_view)
  • value_t - the JSON type enumeration, see basic_json::value_t
  • string_t, number_integer_t, number_unsigned_t, number_float_t, json_pointer - the corresponding member types of BasicJsonType
  • size_type - std::size_t
  • string_view_t - std::string_view on C++17 and newer, a minimal internal substitute otherwise
  • iterator, const_iterator - a forward iterator over the elements of an array or the member values of an object, in document order; both names refer to the same type, since a view is always read-only
  • number_format - how dump() writes numbers
"},{"location":"api/basic_json_view/#member-functions","title":"Member functions","text":"
  • (constructor)
"},{"location":"api/basic_json_view/#object-inspection","title":"Object inspection","text":"
  • type - return the type of the value
  • type_name - return the type as string
  • is_null - return whether the value is null
  • is_boolean - return whether the value is a boolean
  • is_number - return whether the value is a number
  • is_number_integer - return whether the value is an integer number
  • is_number_unsigned - return whether the value is an unsigned integer number
  • is_number_float - return whether the value is a floating-point number
  • is_string - return whether the value is a string
  • is_array - return whether the value is an array
  • is_object - return whether the value is an object
  • is_binary - return whether the value is a binary array (always false)
  • is_primitive - return whether the type is primitive
  • is_structured - return whether the type is structured
  • is_discarded - return whether the view is invalid
"},{"location":"api/basic_json_view/#element-access","title":"Element access","text":"
  • at - access specified element with bounds checking
  • operator[] - access specified element
  • value - access specified element with default value
  • front - access the first element
  • back - access the last element
"},{"location":"api/basic_json_view/#lookup","title":"Lookup","text":"
  • find - find an element in an object
  • count - returns the number of occurrences of a key in an object
  • contains - check the existence of an element in an object
"},{"location":"api/basic_json_view/#iterators","title":"Iterators","text":"
  • begin - returns an iterator to the first element
  • cbegin - returns a const iterator to the first element
  • end - returns an iterator to one past the last element
  • cend - returns a const iterator to one past the last element
  • items - wrapper to access iterator member functions in range-based for
"},{"location":"api/basic_json_view/#capacity","title":"Capacity","text":"
  • size - return the number of elements
  • empty - return whether the value has no elements
"},{"location":"api/basic_json_view/#conversion","title":"Conversion","text":"
  • get - get a value
  • get_to - get a value and write it to a destination
  • get_string - get a string value without a copy
  • number_token - get a number's token text without a copy
  • materialize - build the BasicJsonType value of this subtree
"},{"location":"api/basic_json_view/#comparison","title":"Comparison","text":"
  • operator== - comparison: equal
  • operator!= - comparison: not equal
"},{"location":"api/basic_json_view/#serialization","title":"Serialization","text":"
  • dump - serialize to a JSON-formatted string
  • operator<< - serialize to stream
"},{"location":"api/basic_json_view/#source-access","title":"Source access","text":"
  • source_offset - byte offset of this value in the document's source text
"},{"location":"api/basic_json_view/#see-also","title":"See also","text":"
  • Zero-copy JSON views - guide to documents and views
  • basic_json_document - the document that owns the parsed data
  • json_view - and json_editable_view - the default specializations
  • materialize - build a basic_json value from a view
"},{"location":"api/basic_json_view/#version-history","title":"Version history","text":"
  • Added in version 3.13.0 unreleased.
"},{"location":"api/basic_json_view/at/","title":"nlohmann::basic_json_view::at","text":"
// (1)\nbasic_json_view at(string_view_t key) const;\nbasic_json_view at(const char* key) const;\nbasic_json_view at(const string_t& key) const;\n\n// (2)\nbasic_json_view at(size_type idx) const;\ntemplate<typename IntegerType>\nbasic_json_view at(IntegerType idx) const;\n\n// (3)\nbasic_json_view at(const json_pointer& ptr) const;\n
  1. Returns the value of the object member with key key \u2014 the first one, should the key occur more than once (see Notes on duplicate keys).
  2. Returns the array element at index idx. The template accepts every integer type except bool and std::size_t and forwards to the size_type overload, as for operator[]; a negative idx is out of range.
  3. Returns the value a JSON pointer ptr refers to, starting at this value.
"},{"location":"api/basic_json_view/at/#parameters","title":"Parameters","text":"key (in) object key of the element to access idx (in) index of the element to access ptr (in) JSON pointer to the element to access"},{"location":"api/basic_json_view/at/#return-value","title":"Return value","text":"
  1. the value of the first member with key key
  2. the element at index idx
  3. the value ptr resolves to, starting at this value
"},{"location":"api/basic_json_view/at/#exception-safety","title":"Exception safety","text":"

Strong guarantee: there are no changes to the view or the document it refers to.

"},{"location":"api/basic_json_view/at/#exceptions","title":"Exceptions","text":"
  1. The function can throw the following exceptions, both with the same message as the corresponding call to BasicJsonType::at:
    • Throws type_error.304 if the value is not an object.
    • Throws out_of_range.403 if no member has key key.
  2. The function can throw the following exceptions, both with the same message as the corresponding call to BasicJsonType::at:
    • Throws type_error.304 if the value is not an array.
    • Throws out_of_range.401 if idx >= size().
  3. The function can throw the following exceptions, all with the same message as the corresponding call to BasicJsonType::at:
    • Throws parse_error.106 if an array index in ptr begins with '0'.
    • Throws parse_error.109 if an array index in ptr is not a number.
    • Throws out_of_range.401 if an array index in ptr is out of range.
    • Throws out_of_range.402 if a reference token is \"-\" at an array \u2014 at never inserts an element, so \"-\" is always invalid.
    • Throws out_of_range.403 if a reference token names an object member that does not exist.
    • Throws out_of_range.404 if ptr cannot be resolved because a reference token is used on a primitive value.

None of these exceptions carry a JSON_DIAGNOSTICS path: the view has no BasicJsonType value to point at, so the exception is created without one, even if BasicJsonType was built with JSON_DIAGNOSTICS enabled.

"},{"location":"api/basic_json_view/at/#complexity","title":"Complexity","text":"
  1. Linear in the number of members: as for ordered_json, members are compared one after another, in document order, stopping at the first match. Each comparison first checks the key's length \u2014 already known from the index, without reading the key bytes \u2014 before comparing its content. Objects with 128 or more members get a hash index of their keys while parsing, so that a lookup in them takes constant time on average.
  2. Linear in idx: elements are skipped one at a time from the first one, since they are not a fixed size in the index (unlike BasicJsonType's array, which is random-access). Constant if no element of the array is an array or object, since the elements are then adjacent in the index.
  3. Linear in the number of reference tokens of ptr and, for each token, in the number of members of the object at that level (as 1.) or the index into the array (as 2.).
"},{"location":"api/basic_json_view/at/#notes","title":"Notes","text":"

Duplicate keys: the first member wins

If the source text repeats a key, this resolves to the first member with it, not to the last one that materialize() and parse() keep. See the Notes on duplicate keys of operator[] and Duplicate keys for the reasons and for how to get the last value.

Unlike operator[], which returns a discarded view for a missing key or an out-of-range index, at always throws \u2014 exactly as BasicJsonType::at does, and with the same messages, so existing error handling written against BasicJsonType::at keeps working unchanged when switched to a view. This also holds for overload 3: unlike operator[] with a JSON pointer, which returns a discarded view for a missing key or an out-of-range index, at throws for those too (out_of_range.403/out_of_range.401).

"},{"location":"api/basic_json_view/at/#examples","title":"Examples","text":"Example: (1)/(2) access specified element with bounds checking

The example below reads required fields out of a service configuration with at, and shows that the exceptions it throws \u2014 for a wrong type and for a missing key \u2014 carry the same messages BasicJsonType::at would produce for the same JSON text.

#include <iostream>\n#include <nlohmann/json_view.hpp>\n\nusing nlohmann::json_document;\nusing nlohmann::json_view;\n\nint main()\n{\n    // required fields of a service configuration -- at() reports a missing\n    // or wrong-typed field with the very same exception basic_json::at()\n    // would throw for the equivalent nlohmann::json value, so error\n    // handling written against basic_json::at() keeps working unchanged\n    json_document config = json_document::parse(R\"({\"name\": \"cache\", \"port\": \"6379\"})\");\n    const json_view service = config.root();\n\n    std::cout << service.at(\"port\").materialize().dump() << '\\n';\n\n    try\n    {\n        // \"port\" is a string, not an array\n        static_cast<void>(service.at(\"port\").at(0));\n    }\n    catch (const nlohmann::json::type_error& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n\n    try\n    {\n        static_cast<void>(service.at(\"timeout\"));\n    }\n    catch (const nlohmann::json::out_of_range& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n}\n

Output:

\"6379\"\n[json.exception.type_error.304] cannot use at() with string\n[json.exception.out_of_range.403] key 'timeout' not found\n
Example: (3) access specified element via JSON pointer with bounds checking

The example below shows that at with a JSON pointer throws exactly the exceptions, with exactly the messages, that BasicJsonType::at throws for the same pointer and the same document.

#include <iostream>\n#include <nlohmann/json_view.hpp>\n\nusing nlohmann::json_document;\nusing json_pointer = nlohmann::json::json_pointer;\n\nint main()\n{\n    json_document doc = json_document::parse(R\"({\"region\": \"eu\", \"servers\": [\"eu-1\", \"eu-2\"]})\");\n    const auto root = doc.root();\n\n    std::cout << root.at(json_pointer(\"/servers/1\")).materialize().dump() << '\\n';\n\n    // at() throws for every resolution failure -- with the very same\n    // message json::at(ptr) would throw for the same pointer and the same\n    // document\n    try\n    {\n        static_cast<void>(root.at(json_pointer(\"/servers/5\")));\n    }\n    catch (const nlohmann::json::out_of_range& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n\n    try\n    {\n        static_cast<void>(root.at(json_pointer(\"/missing\")));\n    }\n    catch (const nlohmann::json::out_of_range& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n}\n

Output:

\"eu-2\"\n[json.exception.out_of_range.401] array index 5 is out of range\n[json.exception.out_of_range.403] key 'missing' not found\n
"},{"location":"api/basic_json_view/at/#see-also","title":"See also","text":"
  • operator[] - access specified element (returns a discarded view instead of throwing)
  • front, back - access the first or last element
  • BasicJsonType::at - the corresponding function of basic_json
  • json_pointer - JSON pointer type used by overload 3
"},{"location":"api/basic_json_view/at/#version-history","title":"Version history","text":"
  • Added in version 3.13.0 unreleased.
"},{"location":"api/basic_json_view/back/","title":"nlohmann::basic_json_view::back","text":"
basic_json_view back() const;\n

Returns the last element of an array, the last member value of an object, or the value itself if it is primitive (as for BasicJsonType::back(), a primitive value is a range of one element).

"},{"location":"api/basic_json_view/back/#return-value","title":"Return value","text":"

The last element or member value. For a primitive value (number, string, boolean), the value itself.

"},{"location":"api/basic_json_view/back/#exception-safety","title":"Exception safety","text":"

Strong guarantee: there are no changes to the view or the document it refers to.

"},{"location":"api/basic_json_view/back/#exceptions","title":"Exceptions","text":"

Throws invalid_iterator.214 if the view is null or discarded, or if it is an empty array or object.

This exception does not carry a JSON_DIAGNOSTICS path: the view has no BasicJsonType value to point at, so the exception is created without one, even if BasicJsonType was built with JSON_DIAGNOSTICS enabled.

"},{"location":"api/basic_json_view/back/#complexity","title":"Complexity","text":"

Linear in the size of the array or object: unlike front(), which only ever looks at the first element, back() has to walk every element to find where they end, since elements are not a fixed size in the index. Constant if no element of the array is an array or object, since the elements are then adjacent in the index.

"},{"location":"api/basic_json_view/back/#notes","title":"Notes","text":"

Unlike BasicJsonType::back(), which has undefined behavior for an empty array or object, back() throws invalid_iterator.214 for an empty array, an empty object, a null value, or a discarded view.

"},{"location":"api/basic_json_view/back/#examples","title":"Examples","text":"Example

The example below reads only the final status of a build log with back(). Even though back() is linear in the number of events (unlike front(), which is constant), it still avoids building a BasicJsonType value for the events that are not needed.

#include <iostream>\n#include <nlohmann/json_view.hpp>\n\nusing nlohmann::json_document;\n\nint main()\n{\n    // the same build log; back() reads only the final status. It is linear\n    // in the number of events (unlike front(), which is constant), but\n    // still far less work than materializing the whole array\n    json_document log = json_document::parse(R\"([\"queued\", \"started\", \"compiling\", \"linking\", \"done\"])\");\n    std::cout << log.root().back().materialize().dump() << '\\n';\n\n    // an empty log -- back() throws instead of the undefined behavior\n    // basic_json::back() has for an empty array\n    json_document empty_log = json_document::parse(\"[]\");\n    try\n    {\n        static_cast<void>(empty_log.root().back());\n    }\n    catch (const nlohmann::json::invalid_iterator& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n}\n

Output:

\"done\"\n[json.exception.invalid_iterator.214] cannot get value\n
"},{"location":"api/basic_json_view/back/#see-also","title":"See also","text":"
  • front - access the first element
  • BasicJsonType::back - the corresponding function of basic_json
"},{"location":"api/basic_json_view/back/#version-history","title":"Version history","text":"
  • Added in version 3.13.0 unreleased.
"},{"location":"api/basic_json_view/basic_json_view/","title":"nlohmann::basic_json_view::basic_json_view","text":"
// (1)\nbasic_json_view() noexcept = default;\n\n// (2) only for Mode == view_mode::editable\nbasic_json_view(const basic_json_view<BasicJsonType, view_mode::read_only>& other) noexcept;\n
  1. Creates an invalid (discarded) view: type() is value_t::discarded and is_discarded() is true.
  2. Converts a view of a read-only document into a view of an editable document (implicitly), so that a function taking a json_editable_view accepts both. The result is a view of the same value of the same read-only document. See view_mode for why there is no conversion the other way.
"},{"location":"api/basic_json_view/basic_json_view/#parameters","title":"Parameters","text":"other (in) a view of a read-only document with the same BasicJsonType

Apart from these, a view is obtained from a basic_json_document, via root() or by navigating into a container with operator[], at, front, back, find, or iteration.

"},{"location":"api/basic_json_view/basic_json_view/#exception-safety","title":"Exception safety","text":"

No-throw guarantee: these constructors never throw exceptions.

"},{"location":"api/basic_json_view/basic_json_view/#complexity","title":"Complexity","text":"

Constant.

"},{"location":"api/basic_json_view/basic_json_view/#notes","title":"Notes","text":"

basic_json_view is trivially copyable (it holds two pointers), so a default-constructed view can be used as a placeholder for \"no value yet\" and later be assigned a real view.

"},{"location":"api/basic_json_view/basic_json_view/#examples","title":"Examples","text":"Example

The example below shows the default constructor and that a basic_json_view is a small, copyable handle.

#include <iostream>\n#include <nlohmann/json_view.hpp>\n\nint main()\n{\n    std::cout << std::boolalpha;\n\n    // the default constructor is the only public one: it creates an invalid\n    // (discarded) view, useful as a \"no value yet\" placeholder\n    nlohmann::json_view v;\n    std::cout << v.is_discarded() << '\\n';\n\n    // views are trivially copyable handles (two pointers); the document owns\n    // the actual data\n    nlohmann::json_view copy = v;\n    std::cout << copy.is_discarded() << '\\n';\n}\n

Output:

true\ntrue\n
"},{"location":"api/basic_json_view/basic_json_view/#see-also","title":"See also","text":"
  • is_discarded - return whether the view is invalid
  • root - the view of a document's root value
  • view_mode - whether a document and its views can be edited
  • Zero-copy JSON views - how long a view stays valid
"},{"location":"api/basic_json_view/basic_json_view/#version-history","title":"Version history","text":"
  • Added in version 3.13.0 unreleased.
"},{"location":"api/basic_json_view/begin/","title":"nlohmann::basic_json_view::begin","text":"
iterator begin() const noexcept;\n

Returns an iterator to the first element of an array, or the first member value of an object, in document order \u2014 the order the values appear in the source text, not sorted by key. A primitive value iterates as a range of one element (itself), and a null value or a discarded view iterates as an empty range.

"},{"location":"api/basic_json_view/begin/#return-value","title":"Return value","text":"

Iterator to the first element.

"},{"location":"api/basic_json_view/begin/#exception-safety","title":"Exception safety","text":"

No-throw guarantee: this function never throws exceptions.

"},{"location":"api/basic_json_view/begin/#complexity","title":"Complexity","text":"

Constant.

"},{"location":"api/basic_json_view/begin/#notes","title":"Notes","text":"

For an object, iteration visits every member, including all occurrences of a duplicate key \u2014 unlike operator[], at, find, and contains, which all resolve to the first member with a given key. See the Notes on duplicate keys of operator[].

Because objects are iterated in document order rather than sorted by key, the order seen here can differ from what iterating the materialize()d BasicJsonType value would produce: a basic_json object (std::map-backed by default) sorts its keys, while a view does not.

An ordered_json value also keeps document order, but it keeps only one entry per key: as parse() does, it keeps the last value, at the position of the key's first occurrence. The view, in contrast, visits every member, including the duplicates.

"},{"location":"api/basic_json_view/begin/#examples","title":"Examples","text":"Example

The example below iterates a log record's members with begin()/end() and prints them in the order they were written. Materializing the record into a BasicJsonType object and iterating that would instead print the members sorted by key.

#include <iostream>\n#include <nlohmann/json_view.hpp>\n\nusing nlohmann::json_document;\n\nint main()\n{\n    // a log record: the fields matter in the order they were written, e.g.\n    // to reproduce the record as it was logged. A nlohmann::json object\n    // sorts its keys, so materializing and iterating it would instead print\n    // them alphabetically (\"level\", \"message\", \"time\")\n    json_document record = json_document::parse(R\"({\"time\": \"10:00:01\", \"level\": \"info\", \"message\": \"started\"})\");\n\n    for (auto it = record.root().begin(); it != record.root().end(); ++it)\n    {\n        std::cout << it.key() << '=' << it->materialize().dump() << '\\n';\n    }\n}\n

Output:

time=\"10:00:01\"\nlevel=\"info\"\nmessage=\"started\"\n
"},{"location":"api/basic_json_view/begin/#see-also","title":"See also","text":"
  • end - returns an iterator to one past the last element
  • cbegin - returns a const iterator to the first element
  • items - access iterator member functions in range-based for
  • BasicJsonType::begin - the corresponding function of basic_json
"},{"location":"api/basic_json_view/begin/#version-history","title":"Version history","text":"
  • Added in version 3.13.0 unreleased.
"},{"location":"api/basic_json_view/cbegin/","title":"nlohmann::basic_json_view::cbegin","text":"
iterator cbegin() const noexcept;\n

Returns an iterator to the first element, in document order. Equivalent to begin(): a view is always read-only, so const_iterator and iterator are the same type, and cbegin() exists only so that generic code that expects a cbegin()/cend() pair works with a view too.

"},{"location":"api/basic_json_view/cbegin/#return-value","title":"Return value","text":"

Iterator to the first element; identical to what begin() returns.

"},{"location":"api/basic_json_view/cbegin/#exception-safety","title":"Exception safety","text":"

No-throw guarantee: this function never throws exceptions.

"},{"location":"api/basic_json_view/cbegin/#complexity","title":"Complexity","text":"

Constant.

"},{"location":"api/basic_json_view/cbegin/#examples","title":"Examples","text":"Example

The example below sums many measurements with std::accumulate, using cbegin()/cend() as the range \u2014 the same way it would for any standard container \u2014 without ever materializing the whole array into a BasicJsonType value.

#include <iostream>\n#include <numeric>\n#include <nlohmann/json_view.hpp>\n\nusing nlohmann::json_document;\nusing nlohmann::json_view;\n\nint main()\n{\n    // sum many measurements with std::accumulate; cbegin()/cend() (identical\n    // to begin()/end() here -- the view is always read-only) let the view be\n    // used with standard algorithms without ever materializing the whole\n    // array into a nlohmann::json value\n    json_document measurements = json_document::parse(\"[3, 1, 4, 1, 5, 9, 2, 6]\");\n    const auto values = measurements.root();\n\n    const int sum = std::accumulate(values.cbegin(), values.cend(), 0,\n                                    [](int total, const json_view & v)\n    {\n        return total + v.materialize().get<int>();\n    });\n\n    std::cout << sum << '\\n';\n}\n

Output:

31\n
"},{"location":"api/basic_json_view/cbegin/#see-also","title":"See also","text":"
  • begin - returns an iterator to the first element
  • cend - returns a const iterator to one past the last element
  • BasicJsonType::cbegin - the corresponding function of basic_json
"},{"location":"api/basic_json_view/cbegin/#version-history","title":"Version history","text":"
  • Added in version 3.13.0 unreleased.
"},{"location":"api/basic_json_view/cend/","title":"nlohmann::basic_json_view::cend","text":"
iterator cend() const noexcept;\n

Returns an iterator to one past the last element, in document order. Equivalent to end(): a view is always read-only, so const_iterator and iterator are the same type, and cend() exists only so that generic code that expects a cbegin()/cend() pair works with a view too.

"},{"location":"api/basic_json_view/cend/#return-value","title":"Return value","text":"

Iterator one past the last element; identical to what end() returns.

"},{"location":"api/basic_json_view/cend/#exception-safety","title":"Exception safety","text":"

No-throw guarantee: this function never throws exceptions.

"},{"location":"api/basic_json_view/cend/#complexity","title":"Complexity","text":"

Constant.

"},{"location":"api/basic_json_view/cend/#examples","title":"Examples","text":"Example

The example below checks that every record of a batch is an object with std::all_of, using cbegin()/cend() as the range \u2014 the same way it would for any standard container \u2014 before materializing any record of the batch.

#include <algorithm>\n#include <iostream>\n#include <nlohmann/json_view.hpp>\n\nusing nlohmann::json_document;\nusing nlohmann::json_view;\n\nint main()\n{\n    // check that every element of a (possibly large) batch is an object,\n    // before materializing any of them -- cbegin()/cend() (identical to\n    // begin()/end() here) work as the range for std::all_of like they would\n    // for any standard container\n    json_document batch = json_document::parse(R\"([{\"id\": 1}, {\"id\": 2}, {\"id\": 3}])\");\n    const auto records = batch.root();\n\n    const bool all_objects = std::all_of(records.cbegin(), records.cend(),\n                                         [](const json_view & v)\n    {\n        return v.is_object();\n    });\n\n    std::cout << std::boolalpha << all_objects << '\\n';\n}\n

Output:

true\n
"},{"location":"api/basic_json_view/cend/#see-also","title":"See also","text":"
  • end - returns an iterator to one past the last element
  • cbegin - returns a const iterator to the first element
  • BasicJsonType::cend - the corresponding function of basic_json
"},{"location":"api/basic_json_view/cend/#version-history","title":"Version history","text":"
  • Added in version 3.13.0 unreleased.
"},{"location":"api/basic_json_view/contains/","title":"nlohmann::basic_json_view::contains","text":"
// (1)\nbool contains(string_view_t key) const;\nbool contains(const char* key) const;\nbool contains(const string_t& key) const;\n\n// (2)\nbool contains(const json_pointer& ptr) const;\n
  1. Checks whether the value is an object with a member with key key.
  2. Checks whether a JSON pointer ptr can be resolved, starting at this value.
"},{"location":"api/basic_json_view/contains/#parameters","title":"Parameters","text":"key (in) key value to check its existence ptr (in) JSON pointer to check its existence"},{"location":"api/basic_json_view/contains/#return-value","title":"Return value","text":"
  1. true if the value is an object and has a member with key key, false otherwise
  2. true if ptr can be resolved to a value starting at this view, false otherwise
"},{"location":"api/basic_json_view/contains/#exception-safety","title":"Exception safety","text":"

No-throw guarantee: this function never throws exceptions.

"},{"location":"api/basic_json_view/contains/#complexity","title":"Complexity","text":"
  1. Linear in the number of members: as for ordered_json, members are compared one after another, in document order, stopping at the first match. Each comparison first checks the key's length \u2014 already known from the index, without reading the key bytes \u2014 before comparing its content. Objects with 128 or more members get a hash index of their keys while parsing, so that a lookup in them takes constant time on average.
  2. Linear in the number of reference tokens of ptr and, for each token, in the number of members of the object at that level or the index into the array \u2014 as for operator[] and at with a JSON pointer.
"},{"location":"api/basic_json_view/contains/#notes","title":"Notes","text":"

Duplicate keys: the first member wins

If the source text repeats a key, this resolves to the first member with it, not to the last one that materialize() and parse() keep. See the Notes on duplicate keys of operator[] and Duplicate keys for the reasons and for how to get the last value.

Overload 1 always returns false when the value is not an object \u2014 including a discarded view.

Postconditions

If v.contains(key) returns true, then v[key] is not discarded and v.at(key) does not throw. If v.contains(ptr) returns true, then v[ptr] is not discarded and v.at(ptr) does not throw.

Overload 2 never throws

Unlike BasicJsonType::contains(const json_pointer&), which can throw for certain malformed pointers (for instance an empty array-index reference token), overload 2 never throws: a missing key, an out-of-range or malformed array index, a \"-\" index, or a reference token used on a primitive all simply make it return false.

"},{"location":"api/basic_json_view/contains/#examples","title":"Examples","text":"Example: (1) check with key

The example below counts how many of a batch of records carry an optional retry_of field, using contains() to check without ever materializing a single record of the batch.

#include <iostream>\n#include <nlohmann/json_view.hpp>\n\nusing nlohmann::json_document;\n\nint main()\n{\n    // count how many of many incoming records carry an optional \"retry_of\"\n    // field -- contains() only walks the flat index, so scanning a large\n    // batch like this never builds a single nlohmann::json value\n    json_document batch = json_document::parse(R\"(\n      [\n        {\"id\": 1},\n        {\"id\": 2, \"retry_of\": 1},\n        {\"id\": 3},\n        {\"id\": 4, \"retry_of\": 3}\n      ]\n    )\");\n\n    const auto records = batch.root();\n    std::size_t retries = 0;\n    for (std::size_t i = 0; i < records.size(); ++i)\n    {\n        if (records[i].contains(\"retry_of\"))\n        {\n            ++retries;\n        }\n    }\n    std::cout << retries << \" of \" << records.size() << \" records are retries\\n\";\n}\n

Output:

2 of 4 records are retries\n
Example: (2) check with JSON pointer

The example below checks an optional, nested field with a JSON pointer, and shows two pointers that contains() resolves to false without throwing.

#include <iostream>\n#include <nlohmann/json_view.hpp>\n\nusing nlohmann::json_document;\nusing json_pointer = nlohmann::json::json_pointer;\n\nint main()\n{\n    // \"retry_of\" is only present on some records, nested a level down\n    // inside \"meta\"\n    json_document batch = json_document::parse(R\"(\n      [\n        {\"id\": 1, \"meta\": {}},\n        {\"id\": 2, \"meta\": {\"retry_of\": 1}}\n      ]\n    )\");\n\n    const auto records = batch.root();\n    const json_pointer retry_of(\"/meta/retry_of\");\n    for (std::size_t i = 0; i < records.size(); ++i)\n    {\n        const auto record = records[i];\n        if (record.contains(retry_of))\n        {\n            std::cout << \"record \" << i << \" is a retry of \" << record[retry_of].get<int>() << '\\n';\n        }\n        else\n        {\n            std::cout << \"record \" << i << \" is original\\n\";\n        }\n    }\n\n    // contains() with a JSON pointer never throws -- not even for a\n    // pointer that indexes into a primitive (\"/0/id/x\") or uses a\n    // malformed array index (\"/01\"), either of which would need a\n    // try/catch with json::contains(ptr)\n    std::cout << std::boolalpha << records.contains(json_pointer(\"/0/id/x\")) << '\\n';\n    std::cout << std::boolalpha << records.contains(json_pointer(\"/01\")) << '\\n';\n}\n

Output:

record 0 is original\nrecord 1 is a retry of 1\nfalse\nfalse\n
"},{"location":"api/basic_json_view/contains/#see-also","title":"See also","text":"
  • find - find a value in an object
  • count - returns the number of occurrences of a key
  • at, operator[] - resolve a JSON pointer and throw, or return a discarded view
  • BasicJsonType::contains - the corresponding function of basic_json
"},{"location":"api/basic_json_view/contains/#version-history","title":"Version history","text":"
  • Added in version 3.13.0 unreleased.
"},{"location":"api/basic_json_view/count/","title":"nlohmann::basic_json_view::count","text":"
size_type count(string_view_t key) const;\nsize_type count(const char* key) const;\nsize_type count(const string_t& key) const;\n

Returns the number of members with key key if the value is an object, 0 otherwise. Members with a repeated key are all counted.

"},{"location":"api/basic_json_view/count/#parameters","title":"Parameters","text":"key (in) key value of the element to count"},{"location":"api/basic_json_view/count/#return-value","title":"Return value","text":"

the number of members of the object with key key (duplicates included), or 0 if the value is not an object or has no such member.

"},{"location":"api/basic_json_view/count/#exception-safety","title":"Exception safety","text":"

No-throw guarantee: this function never throws exceptions.

"},{"location":"api/basic_json_view/count/#complexity","title":"Complexity","text":"

Linear in the number of members: unlike the lookup functions, count() does not stop at the first match, because it has to count every member with the key. Members are compared one after another, in document order. Each comparison first checks the key's length \u2014 already known from the index, without reading the key bytes \u2014 before comparing its content. The hash index of the keys of objects with 128 or more members does not help here, since every member is visited.

"},{"location":"api/basic_json_view/count/#notes","title":"Notes","text":"

This method always returns 0 when the value is not an object \u2014 including a discarded view.

If the source text repeats a key, count() returns more than 1 for it, even though the materialized value (like the result of parse()) would have only one member with that key. Hence count(key) > 1 detects duplicate keys. This is unlike the lookup functions (operator[], at, find, contains), which resolve to the first member; see the Notes on duplicate keys of operator[].

"},{"location":"api/basic_json_view/count/#examples","title":"Examples","text":"Example

The example below validates that every transaction of a batch carries exactly one amount field, using count() before deciding whether to materialize a transaction at all. It reports a transaction with no amount field and one with a duplicated amount field.

#include <iostream>\n#include <nlohmann/json_view.hpp>\n\nusing nlohmann::json_document;\n\nint main()\n{\n    // validate that every transaction of a batch carries exactly one\n    // \"amount\" field before materializing any of them into a nlohmann::json\n    // value -- count() counts every member with the key\n    json_document batch = json_document::parse(R\"(\n      [\n        {\"id\": 1, \"amount\": 9.99},\n        {\"id\": 2},\n        {\"id\": 3, \"amount\": 5.00, \"amount\": 500.00}\n      ]\n    )\");\n\n    const auto transactions = batch.root();\n    for (std::size_t i = 0; i < transactions.size(); ++i)\n    {\n        const auto transaction = transactions[i];\n        const auto amounts = transaction.count(\"amount\");\n        if (amounts != 1)\n        {\n            std::cout << \"transaction \" << i << \" has \" << amounts << \" \\\"amount\\\" fields\\n\";\n            continue;\n        }\n        std::cout << \"transaction \" << i << \": \" << transaction[\"amount\"].materialize().dump() << '\\n';\n    }\n}\n

Output:

transaction 0: 9.99\ntransaction 1 has 0 \"amount\" fields\ntransaction 2 has 2 \"amount\" fields\n
"},{"location":"api/basic_json_view/count/#see-also","title":"See also","text":"
  • find - find a value in an object
  • contains - checks whether a key exists
  • BasicJsonType::count - the corresponding function of basic_json
"},{"location":"api/basic_json_view/count/#version-history","title":"Version history","text":"
  • Added in version 3.13.0 unreleased.
"},{"location":"api/basic_json_view/dump/","title":"nlohmann::basic_json_view::dump","text":"
string_t dump(const int indent = -1,\n              const char indent_char = ' ',\n              const bool ensure_ascii = false,\n              const number_format numbers = number_format::shortest) const;\n

Serializes this value (and its subtree) directly from the flat index, without ever building a BasicJsonType value first. With the default numbers == number_format::shortest, the result is the same string BasicJsonType::dump would produce for the value BasicJsonType::parse() builds from the same source text, called with the same indent, indent_char, and ensure_ascii \u2014 except that members of an object appear in document order rather than sorted by key, and every occurrence of a repeated key is written rather than only the last one (see Notes on duplicate keys). For a json_view (whose BasicJsonType is not ordered), this means dump() can print an object's members in a different order than materialize().dump() of the same subtree.

"},{"location":"api/basic_json_view/dump/#parameters","title":"Parameters","text":"indent (in) If indent is nonnegative, array elements and object members are pretty-printed with that indent level. An indent level of 0 only inserts newlines. -1 (the default) selects the most compact representation. indent_char (in) The character used for indentation if indent is greater than 0. The default is (space). ensure_ascii (in) If ensure_ascii is true, all non-ASCII characters in the output are escaped with \\uXXXX sequences, and the result consists of ASCII characters only. numbers (in) how to write numbers, see number_format: shortest (the default) writes them the way BasicJsonType::dump would; source copies every number exactly as it appears in the source text."},{"location":"api/basic_json_view/dump/#return-value","title":"Return value","text":"

string containing the serialization of this value, or \"<discarded>\" if the view is discarded.

"},{"location":"api/basic_json_view/dump/#exception-safety","title":"Exception safety","text":"

Strong exception safety: if an exception is thrown, there are no changes to the view or the document it refers to.

"},{"location":"api/basic_json_view/dump/#exceptions","title":"Exceptions","text":"

May throw std::bad_alloc if allocating the output string fails. Unlike BasicJsonType::dump, there is no error_handler parameter and no type_error.316: the view only ever holds text the parser already validated as UTF-8, so there is nothing to replace or ignore.

"},{"location":"api/basic_json_view/dump/#complexity","title":"Complexity","text":"

Linear in the size of the output text.

"},{"location":"api/basic_json_view/dump/#notes","title":"Notes","text":"

The walk over the subtree is iterative, so the nesting depth it can write is limited by available memory only, not by the call stack \u2014 as for materialize().

Strings are escaped by the same rules as BasicJsonType::dump.

With numbers == number_format::shortest, floats are written with the library's shortest round-trip conversion, exactly as BasicJsonType::dump would (e.g. 1.5, 100.0, 1e+100), and integers are copied from the source text \u2014 already canonical in JSON, so this matches their shortest form too \u2014 except that -0 is written as 0, the way BasicJsonType::parse() reads it.

number_format::source copies every number exactly as written in the source text instead, with no exception for -0 \u2014 1.50, 1E2, -0.0, -0, or all digits of an integer literal with more digits than any number type holds (such a literal is itself classified as a float, see What is different) \u2014 something BasicJsonType cannot do, since parsing already reduces every number to its parsed value.

"},{"location":"api/basic_json_view/dump/#examples","title":"Examples","text":"Example

The example below forwards a single record out of a larger batch, and re-serializes a configuration file, both without ever building a BasicJsonType value for the surrounding array or for the parts of it that were not needed. It also shows that materialize().dump() of the configuration sorts its keys, where dump() on the view keeps the order they appear in the source text.

#include <iostream>\n#include <nlohmann/json_view.hpp>\n\nusing nlohmann::json_document;\nusing nlohmann::json_view;\n\nint main()\n{\n    // a large batch of sensor readings -- forward just the one that changed,\n    // without ever building a basic_json value for the batch or for the\n    // readings that are not needed\n    const json_document batch = json_document::parse(R\"(\n      [{\"id\": 1, \"temp\": 21.5}, {\"id\": 2, \"temp\": 87.3}, {\"id\": 3, \"temp\": 21.7}]\n    )\");\n    const json_view readings = batch.root();\n    std::cout << readings[1].dump() << '\\n';\n\n    // a configuration file -- dump() on the view keeps the member order of\n    // the source text; a json value's object_t is std::map, so\n    // materialize().dump() of the very same view sorts the keys instead\n    const json_document config = json_document::parse(\n                                     R\"({\"name\": \"cache\", \"host\": \"db1\", \"port\": 6379, \"timeout\": 30})\");\n    std::cout << config.root().dump(2) << \"\\n\\n\";\n    std::cout << config.root().materialize().dump(2) << '\\n';\n}\n

Output:

{\"id\":2,\"temp\":87.3}\n{\n  \"name\": \"cache\",\n  \"host\": \"db1\",\n  \"port\": 6379,\n  \"timeout\": 30\n}\n\n{\n  \"host\": \"db1\",\n  \"name\": \"cache\",\n  \"port\": 6379,\n  \"timeout\": 30\n}\n
"},{"location":"api/basic_json_view/dump/#see-also","title":"See also","text":"
  • number_format - how dump() writes numbers
  • operator<< - serialize this value to a stream
  • materialize - build a BasicJsonType value, e.g. to use BasicJsonType::dump's error_handler
  • BasicJsonType::dump - the corresponding function of basic_json
  • Zero-copy JSON views - writing a view back without building a tree
"},{"location":"api/basic_json_view/dump/#version-history","title":"Version history","text":"
  • Added in version 3.13.0 unreleased.
"},{"location":"api/basic_json_view/empty/","title":"nlohmann::basic_json_view::empty","text":"
bool empty() const noexcept;\n

Checks whether size() is 0, as BasicJsonType::empty() would for the same value.

"},{"location":"api/basic_json_view/empty/#return-value","title":"Return value","text":"

The return value depends on the type and is defined as follows:

Value type return value null true discarded true boolean false string false number false object object_t::empty() array array_t::empty()"},{"location":"api/basic_json_view/empty/#exception-safety","title":"Exception safety","text":"

No-throw guarantee: this function never throws exceptions.

"},{"location":"api/basic_json_view/empty/#complexity","title":"Complexity","text":"

Constant.

"},{"location":"api/basic_json_view/empty/#notes","title":"Notes","text":"

As for BasicJsonType::empty(), this does not return whether a string value is empty \u2014 it is false for any string, regardless of its length.

"},{"location":"api/basic_json_view/empty/#examples","title":"Examples","text":"Example

The example below uses size() and empty() to decide whether a parsed message is worth acting on, without materializing it into a BasicJsonType value.

#include <iostream>\n#include <nlohmann/json_view.hpp>\n\nusing nlohmann::json_document;\n\nint main()\n{\n    std::cout << std::boolalpha;\n\n    // decide whether a batch is worth processing before building any\n    // nlohmann::json value for it\n    json_document batch = json_document::parse(R\"([1, 2, 3, 4, 5])\");\n    json_document empty_batch = json_document::parse(\"[]\");\n\n    std::cout << batch.root().empty() << ' ' << batch.root().size() << '\\n';\n    std::cout << empty_batch.root().empty() << ' ' << empty_batch.root().size() << '\\n';\n\n    // as for basic_json: null has size 0, every other scalar has size 1\n    json_document n = json_document::parse(\"null\");\n    json_document s = json_document::parse(R\"(\"hi\")\");\n    std::cout << n.root().size() << ' ' << s.root().size() << '\\n';\n}\n

Output:

false 5\ntrue 0\n0 1\n
"},{"location":"api/basic_json_view/empty/#see-also","title":"See also","text":"
  • size - return the number of elements
  • BasicJsonType::empty - the corresponding function of basic_json
"},{"location":"api/basic_json_view/empty/#version-history","title":"Version history","text":"
  • Added in version 3.13.0 unreleased.
"},{"location":"api/basic_json_view/end/","title":"nlohmann::basic_json_view::end","text":"
iterator end() const noexcept;\n

Returns an iterator to one past the last element of an array, one past the last member value of an object, in document order \u2014 see begin(). A primitive value iterates as a range of one element (itself), and a null value or a discarded view iterates as an empty range (begin() == end()).

"},{"location":"api/basic_json_view/end/#return-value","title":"Return value","text":"

Iterator one past the last element.

"},{"location":"api/basic_json_view/end/#exception-safety","title":"Exception safety","text":"

No-throw guarantee: this function never throws exceptions.

"},{"location":"api/basic_json_view/end/#complexity","title":"Complexity","text":"

Constant.

"},{"location":"api/basic_json_view/end/#notes","title":"Notes","text":"

iterator is a forward iterator: unlike BasicJsonType::iterator, it cannot be decremented, so there is no way to reach the last element by stepping back from end(). Use back() instead.

"},{"location":"api/basic_json_view/end/#examples","title":"Examples","text":"Example

The example below scans a (possibly large) array of readings for the first one over a threshold, stopping the loop at end() as soon as one is found. Only the matching reading, if any, is ever materialized.

#include <iostream>\n#include <nlohmann/json_view.hpp>\n\nusing nlohmann::json_document;\n\nint main()\n{\n    // scan a (possibly large) array of readings for the first one over a\n    // threshold; the loop stops at end() as soon as one is found, and only\n    // the matching reading is ever materialized\n    json_document readings = json_document::parse(\"[12, 18, 25, 31, 9]\");\n    const auto values = readings.root();\n\n    auto it = values.begin();\n    for (; it != values.end(); ++it)\n    {\n        if (it->materialize().get<int>() > 20)\n        {\n            break;\n        }\n    }\n\n    if (it != values.end())\n    {\n        std::cout << \"first reading over 20: \" << it->materialize().dump() << '\\n';\n    }\n}\n

Output:

first reading over 20: 25\n
"},{"location":"api/basic_json_view/end/#see-also","title":"See also","text":"
  • begin - returns an iterator to the first element
  • cend - returns a const iterator to one past the last element
  • BasicJsonType::end - the corresponding function of basic_json
"},{"location":"api/basic_json_view/end/#version-history","title":"Version history","text":"
  • Added in version 3.13.0 unreleased.
"},{"location":"api/basic_json_view/find/","title":"nlohmann::basic_json_view::find","text":"
iterator find(string_view_t key) const;\niterator find(const char* key) const;\niterator find(const string_t& key) const;\n

Finds a member with key key \u2014 the first one, should the key occur more than once (see Notes on duplicate keys). If the value is not an object, or no member has this key, end() is returned.

"},{"location":"api/basic_json_view/find/#parameters","title":"Parameters","text":"key (in) key value of the element to search for"},{"location":"api/basic_json_view/find/#return-value","title":"Return value","text":"

An iterator to the member with key key, or end() if there is none or the value is not an object.

"},{"location":"api/basic_json_view/find/#exception-safety","title":"Exception safety","text":"

No-throw guarantee: this function never throws exceptions.

"},{"location":"api/basic_json_view/find/#complexity","title":"Complexity","text":"

Linear in the number of members: as for ordered_json, members are compared one after another, in document order, stopping at the first match. Each comparison first checks the key's length \u2014 already known from the index, without reading the key bytes \u2014 before comparing its content. Objects with 128 or more members get a hash index of their keys while parsing, so that a lookup in them takes constant time on average.

"},{"location":"api/basic_json_view/find/#notes","title":"Notes","text":"

Duplicate keys: the first member wins

If the source text repeats a key, this resolves to the first member with it, not to the last one that materialize() and parse() keep. See the Notes on duplicate keys of operator[] and Duplicate keys for the reasons and for how to get the last value.

Unlike BasicJsonType::find, which always returns end() for a non-object type, this also does so for a discarded view \u2014 there is no separate \"invalid\" iterator to return.

"},{"location":"api/basic_json_view/find/#examples","title":"Examples","text":"Example

The example below scans a batch of events for those that carry an optional user_id field, using find() instead of operator[] (which would throw for the events that are not objects at all) or contains() followed by a second lookup. Events without a match are never materialized.

#include <iostream>\n#include <nlohmann/json_view.hpp>\n\nusing nlohmann::json_document;\n\nint main()\n{\n    // a batch of incoming events; only some carry a \"user_id\" -- find()\n    // locates it without throwing for the events that turn out to not be\n    // objects, and without materializing an event that does not match\n    json_document batch = json_document::parse(R\"(\n      [\n        {\"type\": \"click\", \"user_id\": 42},\n        {\"type\": \"ping\"},\n        {\"type\": \"click\", \"user_id\": 7}\n      ]\n    )\");\n\n    const auto events = batch.root();\n    for (std::size_t i = 0; i < events.size(); ++i)\n    {\n        const auto event = events[i];\n        const auto it = event.find(\"user_id\");\n        if (it != event.end())\n        {\n            std::cout << \"user \" << it->materialize().dump() << '\\n';\n        }\n    }\n}\n

Output:

user 42\nuser 7\n
"},{"location":"api/basic_json_view/find/#see-also","title":"See also","text":"
  • count - returns the number of occurrences of a key
  • contains - checks whether a key exists
  • BasicJsonType::find - the corresponding function of basic_json
"},{"location":"api/basic_json_view/find/#version-history","title":"Version history","text":"
  • Added in version 3.13.0 unreleased.
"},{"location":"api/basic_json_view/front/","title":"nlohmann::basic_json_view::front","text":"
basic_json_view front() const;\n

Returns the first element of an array, the first member value of an object, or the value itself if it is primitive (as for BasicJsonType::front(), a primitive value is a range of one element).

"},{"location":"api/basic_json_view/front/#return-value","title":"Return value","text":"

The first element or member value. For a primitive value (number, string, boolean), the value itself.

"},{"location":"api/basic_json_view/front/#exception-safety","title":"Exception safety","text":"

Strong guarantee: there are no changes to the view or the document it refers to.

"},{"location":"api/basic_json_view/front/#exceptions","title":"Exceptions","text":"

Throws invalid_iterator.214 if the view is null or discarded, or if it is an empty array or object.

This exception does not carry a JSON_DIAGNOSTICS path: the view has no BasicJsonType value to point at, so the exception is created without one, even if BasicJsonType was built with JSON_DIAGNOSTICS enabled.

"},{"location":"api/basic_json_view/front/#complexity","title":"Complexity","text":"

Constant.

"},{"location":"api/basic_json_view/front/#notes","title":"Notes","text":"

Unlike BasicJsonType::front(), which has undefined behavior for an empty array or object, front() throws invalid_iterator.214 for an empty array, an empty object, a null value, or a discarded view.

"},{"location":"api/basic_json_view/front/#examples","title":"Examples","text":"Example

The example below reads only the earliest entry of a build log with front(), without materializing the rest of the (possibly long) log.

#include <iostream>\n#include <nlohmann/json_view.hpp>\n\nusing nlohmann::json_document;\n\nint main()\n{\n    // the build log of a running job; front() reads just the earliest event\n    // without materializing the (possibly long) rest of the log\n    json_document log = json_document::parse(R\"([\"queued\", \"started\", \"compiling\", \"linking\", \"done\"])\");\n    std::cout << log.root().front().materialize().dump() << '\\n';\n\n    // an empty log -- front() throws instead of the undefined behavior\n    // basic_json::front() has for an empty array\n    json_document empty_log = json_document::parse(\"[]\");\n    try\n    {\n        static_cast<void>(empty_log.root().front());\n    }\n    catch (const nlohmann::json::invalid_iterator& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n}\n

Output:

\"queued\"\n[json.exception.invalid_iterator.214] cannot get value\n
"},{"location":"api/basic_json_view/front/#see-also","title":"See also","text":"
  • back - access the last element
  • BasicJsonType::front - the corresponding function of basic_json
"},{"location":"api/basic_json_view/front/#version-history","title":"Version history","text":"
  • Added in version 3.13.0 unreleased.
"},{"location":"api/basic_json_view/get/","title":"nlohmann::basic_json_view::get","text":"
template<typename T>\nT get() const;\n

Converts the value to T.

For the types below, the conversion works directly on the flat index \u2014 no BasicJsonType value is built for it:

  • bool
  • arithmetic types other than bool (for a boolean, 0/1, exactly as for BasicJsonType::get<T>())
  • std::nullptr_t
  • std::basic_string<char, Traits, Alloc> (including string_t) \u2014 a copy of the string
  • string_view_t \u2014 no copy: the returned view points into the document's source() text, or, for a string that contains escape sequences, into the document's own buffer of decoded strings (see get_string())
  • BasicJsonType \u2014 equivalent to materialize()
  • basic_json_view \u2014 returns *this
  • std::vector<U, A> of the types above \u2014 from an array, element by element, each converted with get<U>(); std::vector<basic_json_view> keeps a view of every element instead of a value
  • std::map<K, basic_json_view, C, A> and std::unordered_map<K, basic_json_view, H, E, A>, if K is constructible from a (const char*, std::size_t) pair \u2014 views of the members of an object; with a repeated key, the view of the last member is kept, as BasicJsonType::parse() keeps its value

A default-constructible T whose from_json() accepts views reads the view directly as well, without building a BasicJsonType value. This covers the library's own conversions of the standard library types \u2014 all other std::vectors, std::map/std::unordered_map (also with other key types), std::list, std::deque, std::set, std::forward_list, std::valarray, std::array, C arrays, std::pair, std::tuple, std::optional, enumerations, std::filesystem::path, ... -- which give the same values as materialize().get<T>() (from an object, a repeated key keeps the last value, as BasicJsonType::parse() does), as well as the types of the NLOHMANN_DEFINE_TYPE_* and NLOHMANN_DEFINE_DERIVED_TYPE_* macros and the enumerations of NLOHMANN_JSON_SERIALIZE_ENUM, and any from_json() constrained to accept views, e.g. with is_json_view. A from_json() that also accepts types that are no JSON values at all, such as the unconstrained template<typename BasicJsonType> void from_json(const BasicJsonType&,T&) of arbitrary type conversions, is not called with a view: it may use BasicJsonType functions a view does not have. See Writing generic code.

Duplicate keys

Such a from_json() looks members up in the view, where a repeated key finds the first member, while materialize().get<T>() sees the last one, as BasicJsonType::parse() keeps it: for {\"x\":1,\"x\":2}, get<point>() reads x == 1. See Duplicate keys.

Every other T \u2014 user types whose from_json() is written for BasicJsonType only, types without a default constructor, std::tuples holding references, ... \u2014 is converted by materialize().get<T>(): the subtree is built into a real BasicJsonType value first (as BasicJsonType::parse() would), and converted from there exactly as BasicJsonType::get<T>() would convert it.

"},{"location":"api/basic_json_view/get/#template-parameters","title":"Template parameters","text":"T the type to convert the value to"},{"location":"api/basic_json_view/get/#return-value","title":"Return value","text":"

the value, converted to T

"},{"location":"api/basic_json_view/get/#exception-safety","title":"Exception safety","text":"

Strong guarantee: there are no changes to the view or the document it refers to.

"},{"location":"api/basic_json_view/get/#exceptions","title":"Exceptions","text":"
  • For the directly-converted types listed above (other than BasicJsonType and basic_json_view, which never throw): throws type_error.302 if the value's type does not match T \u2014 the same exception, with the same message, that BasicJsonType::get<T>() throws for the same JSON type and T.
  • For std::vector<U, A>: throws type_error.302 if the value is not an array; otherwise, whatever converting an element to U throws.
  • For std::map/std::unordered_map of views: throws type_error.302 if the value is not an object.
  • For a T whose from_json() reads the view: whatever that from_json() throws; for the library's conversions and the macros, the same exceptions with the same messages as BasicJsonType::get<T>() of the same value.
  • For every other T: whatever materialize().get<T>() throws \u2014 typically type_error.302, or whatever a user-provided from_json() throws.

None of the exceptions thrown directly by this function or by a from_json() that reads the view (the first four bullets above) carry a JSON_DIAGNOSTICS path: the view has no BasicJsonType value to point at. An exception thrown while converting through materialize() (the last bullet) is different: it is thrown by a real BasicJsonType value, so it does carry a JSON_DIAGNOSTICS path if BasicJsonType was built with it enabled. That path is relative to the root of the view's subtree, because materialize() builds only the subtree (with parent pointers): it is empty if the failing value is the subtree's root itself, and it never is the path within the whole document.

"},{"location":"api/basic_json_view/get/#complexity","title":"Complexity","text":"
  • bool, arithmetic types, std::nullptr_t, string_view_t, basic_json_view: constant.
  • std::basic_string<char, Traits, Alloc>: constant, plus one allocation and a copy of the string's bytes.
  • BasicJsonType: linear in the size of the subtree, see materialize().
  • std::vector<U, A>: linear in the number of elements, times the complexity of converting one element to U.
  • std::map/std::unordered_map: linear in the number of members for walking them, plus the container's own insertion cost per member (logarithmic for std::map, amortized constant for std::unordered_map), times the complexity of converting one member to the mapped type.
  • a T whose from_json() reads the view: the cost of that from_json(); for the macros, linear in the number of members times the cost of a lookup, plus the cost of converting the members.
  • every other T: the cost of materialize() and of destroying the BasicJsonType value afterwards, plus that of BasicJsonType::get<T>().
"},{"location":"api/basic_json_view/get/#notes","title":"Notes","text":"

Floating-point values

A floating-point T is converted from the same digits the lexer would see during BasicJsonType::parse(), using the same conversion, so the result is bit-for-bit identical to BasicJsonType::parse(text).get<T>() for the same source text.

Duplicate keys

std::map/std::unordered_map conversions keep the last value of a repeated key, like materialize() and BasicJsonType::parse() do. This is the opposite of operator[]/at/find/contains, which resolve to the first occurrence (see the Notes on duplicate keys).

No pointers, references, or implicit conversion

Unlike BasicJsonType, basic_json_view has no stored value anywhere to hand out a pointer or a reference to, so it provides neither get_ptr(), get_ref(), nor operator ValueType(). get_string() (equivalently, get<string_view_t>()) is the zero-copy alternative for strings.

"},{"location":"api/basic_json_view/get/#examples","title":"Examples","text":"Example

The example below reads typed fields straight into C++ variables, collects a view of every array element with get<std::vector<basic_json_view>>() instead of a value, and converts a nested object into a user type through its from_json() \u2014 which runs on a BasicJsonType value materialize() builds for just that one member.

#include <iostream>\n#include <nlohmann/json_view.hpp>\n#include <string>\n#include <vector>\n\nusing nlohmann::json_document;\nusing nlohmann::json_view;\n\n// address has no direct conversion in get<T>(), so get<address>() falls back\n// to materialize().get<address>() -- a real nlohmann::json value is built\n// for just this one member, and its own from_json() runs on that\nstruct address\n{\n    std::string city;\n    int zip = 0;\n};\n\nvoid from_json(const nlohmann::json& j, address& a)\n{\n    j.at(\"city\").get_to(a.city);\n    j.at(\"zip\").get_to(a.zip);\n}\n\nint main()\n{\n    json_document doc = json_document::parse(R\"(\n      {\n        \"name\": \"Alice\",\n        \"active\": true,\n        \"orders\": [1, 2, 3],\n        \"address\": {\"city\": \"Berlin\", \"zip\": 10115}\n      }\n    )\");\n    const json_view customer = doc.root();\n\n    // read typed fields straight into C++ variables -- none of these build\n    // a nlohmann::json value\n    const std::string name = customer[\"name\"].get<std::string>();\n    const bool active = customer[\"active\"].get<bool>();\n    std::cout << name << (active ? \" (active)\" : \" (inactive)\") << '\\n';\n\n    // std::vector<json_view> keeps views of the array elements instead of\n    // copies of their values\n    bool first = true;\n    for (const json_view order : customer[\"orders\"].get<std::vector<json_view>>())\n    {\n        std::cout << (first ? \"\" : \" \") << order.get<int>();\n        first = false;\n    }\n    std::cout << '\\n';\n\n    // everything else goes through materialize()\n    const address a = customer[\"address\"].get<address>();\n    std::cout << a.city << ' ' << a.zip << '\\n';\n}\n

Output:

Alice (active)\n1 2 3\nBerlin 10115\n
"},{"location":"api/basic_json_view/get/#see-also","title":"See also","text":"
  • get_to - convert and write into a passed value
  • get_string - the string, without a copy
  • number_token - a number's token text, without a copy
  • materialize - build the BasicJsonType value of this subtree
  • BasicJsonType::get - the corresponding function of basic_json
  • Zero-copy JSON views - which conversions avoid building a basic_json value
"},{"location":"api/basic_json_view/get/#version-history","title":"Version history","text":"
  • Added in version 3.13.0 unreleased.
"},{"location":"api/basic_json_view/get_string/","title":"nlohmann::basic_json_view::get_string","text":"
string_view_t get_string() const;\n

Returns the string value as a string_view_t, without copying it.

"},{"location":"api/basic_json_view/get_string/#return-value","title":"Return value","text":"

The string, as a string_view_t that points either into the document's source() text (a string with no escape sequences), or into the document's own buffer of decoded strings (a string that contains escape sequences, such as \"\\n\" or \"\\u00e9\", which had to be decoded once when the document was parsed).

"},{"location":"api/basic_json_view/get_string/#exception-safety","title":"Exception safety","text":"

Strong guarantee: there are no changes to the view or the document it refers to.

"},{"location":"api/basic_json_view/get_string/#exceptions","title":"Exceptions","text":"

Throws type_error.302 if the value is not a string; example: \"type must be string, but is array\".

This exception does not carry a JSON_DIAGNOSTICS path: the view has no BasicJsonType value to point at, so the exception is created without one, even if BasicJsonType was built with JSON_DIAGNOSTICS enabled.

"},{"location":"api/basic_json_view/get_string/#complexity","title":"Complexity","text":"

Constant.

"},{"location":"api/basic_json_view/get_string/#notes","title":"Notes","text":"

basic_json_view has no BasicJsonType value stored anywhere, so unlike BasicJsonType, it has no get_ref() to hand out a reference to a stored string_t. get_string() (equivalently, get<string_view_t>()) is the zero-copy alternative: BasicJsonType::get_ref<const string_t&>() is its closest counterpart, except that it returns a view instead of a reference to a value that must already exist.

get_string() borrows the string: nothing is copied, whereas get<std::string>() copies it. For a borrowed document, the returned string_view_t is valid as long as the caller's buffer; for an owned one, as long as the document.

The returned string_view_t is valid exactly as long as the view that produced it \u2014 see the validity rules of basic_json_view \u2014 and, for a string with no escapes, for as long as the document's source text, which for a borrowed document must remain valid and unmodified for as long as the document exists, since floating-point values and unescaped strings are read from the source lazily.

"},{"location":"api/basic_json_view/get_string/#examples","title":"Examples","text":"Example

The example below pulls one field out of a JSON text that stands in for a large API response, and shows that no std::string was allocated for it: the returned view still points inside the original buffer. A field that contains an escape sequence cannot point into the original text \u2014 it was decoded once into the document's own buffer instead \u2014 but still avoids a per-field allocation.

#include <iostream>\n#include <nlohmann/json_view.hpp>\n#include <string>\n\nusing nlohmann::json_document;\nusing nlohmann::json_view;\n\nint main()\n{\n    // a \"large response\" stand-in: only the \"id\" field is ever read out of it\n    const std::string text =\n        R\"({\"id\": \"8f14e45f-ceea-467e-bb92-963f5e3c7a08\", \"note\": \"created via API\\n\", \"payload\": \"...\"})\";\n    const json_document doc = json_document::parse(text);\n    const json_view response = doc.root();\n\n    const json_view::string_view_t id = response[\"id\"].get_string();\n    std::cout << id << '\\n';\n\n    // no std::string was allocated for \"id\": its bytes still live inside\n    // the original buffer, so id's data lies inside [text.data(),\n    // text.data() + text.size())\n    const bool id_in_source = id.data() >= text.data() && id.data() + id.size() <= text.data() + text.size();\n    std::cout << std::boolalpha << id_in_source << '\\n';\n\n    // \"note\" contains an escape sequence ('\\n'), so it was decoded once\n    // into the document's own buffer -- get_string() still avoids a copy\n    // into a new std::string, but the bytes no longer live inside \"text\"\n    const json_view::string_view_t note = response[\"note\"].get_string();\n    const bool note_in_source = note.data() >= text.data() && note.data() + note.size() <= text.data() + text.size();\n    std::cout << std::boolalpha << note_in_source << '\\n';\n}\n

Output:

8f14e45f-ceea-467e-bb92-963f5e3c7a08\ntrue\nfalse\n
"},{"location":"api/basic_json_view/get_string/#see-also","title":"See also","text":"
  • get - convert the value to a given type (get<string_view_t>() is equivalent to this function)
  • number_token - a number's token text, without a copy
  • BasicJsonType::get_ref - the closest counterpart of basic_json
  • Zero-copy JSON views - borrowing strings instead of copying them
"},{"location":"api/basic_json_view/get_string/#version-history","title":"Version history","text":"
  • Added in version 3.13.0 unreleased.
"},{"location":"api/basic_json_view/get_to/","title":"nlohmann::basic_json_view::get_to","text":"
template<typename T>\nT& get_to(T& v) const;\n

Converts the value to T and stores it in v, in one of three ways:

  • For the types that get<T>() converts directly \u2014 arithmetic types, bool, std::nullptr_t, string_view_t, std::basic_string, BasicJsonType, basic_json_view, vectors of these, and maps of views \u2014 v is assigned: v = get<T>().
  • For a type whose from_json() accepts views (see get<T>()), that from_json() is called with the view and the existing v, without building a BasicJsonType value.
  • For every other type, the subtree is built into a BasicJsonType value and materialize().get_to(v) is called, i.e. from_json() is invoked with the existing v, exactly as BasicJsonType::get_to() does.
"},{"location":"api/basic_json_view/get_to/#template-parameters","title":"Template parameters","text":"T the type to convert the value to"},{"location":"api/basic_json_view/get_to/#parameters","title":"Parameters","text":"v (out) the variable to store the converted value in"},{"location":"api/basic_json_view/get_to/#return-value","title":"Return value","text":"

v, allowing calls to chain

"},{"location":"api/basic_json_view/get_to/#exception-safety","title":"Exception safety","text":"
  • For the directly converted types: strong exception safety. If an exception is thrown, v is not modified.
  • For every other type: as for BasicJsonType::get_to(). materialize() throws before v is touched, but a from_json() that throws may leave v partly modified.
"},{"location":"api/basic_json_view/get_to/#exceptions","title":"Exceptions","text":"
  • For the directly converted types: whatever get<T>() throws for the same value and T.
  • For every other type: whatever materialize() and BasicJsonType::get_to() throw.
"},{"location":"api/basic_json_view/get_to/#complexity","title":"Complexity","text":"
  • For the directly converted types: whatever get<T>() has for the same T.
  • For every other type: that of materialize(), plus that of BasicJsonType::get_to().
"},{"location":"api/basic_json_view/get_to/#notes","title":"Notes","text":"

The difference between the two ways matters for a from_json() that sets only the fields present in the JSON: since it runs on the existing v, the other fields of v keep their values, whereas assigning get<T>() would replace them with those of a default-constructed T.

"},{"location":"api/basic_json_view/get_to/#examples","title":"Examples","text":"Example

The example below reads several fields of a service configuration directly into existing variables, then uses the returned reference to fold the host/port pair into a single string in the same expression.

#include <iostream>\n#include <nlohmann/json_view.hpp>\n#include <string>\n\nusing nlohmann::json_document;\nusing nlohmann::json_view;\n\nint main()\n{\n    json_document doc = json_document::parse(R\"({\"host\": \"db.example.com\", \"port\": 5432, \"ssl\": true})\");\n    const json_view config = doc.root();\n\n    // get_to() writes directly into existing variables -- handy for filling\n    // in the members of a struct one field at a time, without an\n    // intermediate value from get<T>() for each one\n    std::string host;\n    int port = 0;\n    bool ssl = false;\n    config[\"host\"].get_to(host);\n    config[\"port\"].get_to(port);\n    config[\"ssl\"].get_to(ssl);\n    std::cout << host << ':' << port << (ssl ? \" (tls)\" : \"\") << '\\n';\n\n    // the return value is a reference to the argument, so a call can be\n    // used directly in a larger expression\n    std::string other_host;\n    std::cout << config[\"host\"].get_to(other_host).size() << '\\n';\n}\n

Output:

db.example.com:5432 (tls)\n14\n
"},{"location":"api/basic_json_view/get_to/#see-also","title":"See also","text":"
  • get - convert the value to a given type
  • BasicJsonType::get_to - the corresponding function of basic_json
  • Zero-copy JSON views - which conversions avoid building a basic_json value
"},{"location":"api/basic_json_view/get_to/#version-history","title":"Version history","text":"
  • Added in version 3.13.0 unreleased.
"},{"location":"api/basic_json_view/is_array/","title":"nlohmann::basic_json_view::is_array","text":"
bool is_array() const noexcept;\n

This function returns true if and only if the value is an array.

"},{"location":"api/basic_json_view/is_array/#return-value","title":"Return value","text":"

true if the type is an array, false otherwise.

"},{"location":"api/basic_json_view/is_array/#exception-safety","title":"Exception safety","text":"

No-throw guarantee: this function never throws exceptions.

"},{"location":"api/basic_json_view/is_array/#complexity","title":"Complexity","text":"

Constant.

"},{"location":"api/basic_json_view/is_array/#examples","title":"Examples","text":"Example

The example below classifies several parsed documents by the type of their root value, without materializing any of them into a BasicJsonType value.

#include <iostream>\n#include <nlohmann/json_view.hpp>\n\nusing nlohmann::json_document;\n\nint main()\n{\n    std::cout << std::boolalpha;\n\n    // several incoming messages, one json_document per message. type() and\n    // is_*() only look at the flat index built by parse(); no nlohmann::json\n    // tree exists yet, and none is built unless materialize() is called\n    json_document d_null = json_document::parse(\"null\");\n    json_document d_bool = json_document::parse(\"true\");\n    json_document d_int = json_document::parse(\"-42\");\n    json_document d_unsigned = json_document::parse(\"42\");\n    json_document d_float = json_document::parse(\"4.2\");\n    json_document d_string = json_document::parse(R\"(\"hi\")\");\n    json_document d_array = json_document::parse(\"[1, 2, 3]\");\n    json_document d_object = json_document::parse(R\"({\"a\": 1})\");\n\n    std::cout << d_null.root().is_null() << '\\n';\n    std::cout << d_bool.root().is_boolean() << '\\n';\n    std::cout << d_int.root().is_number() << ' ' << d_int.root().is_number_integer() << '\\n';\n    std::cout << d_unsigned.root().is_number_unsigned() << '\\n';\n    std::cout << d_float.root().is_number_float() << '\\n';\n    std::cout << d_string.root().is_string() << '\\n';\n    std::cout << d_array.root().is_array() << ' ' << d_array.root().is_structured() << '\\n';\n    std::cout << d_object.root().is_object() << ' ' << d_object.root().is_primitive() << '\\n';\n\n    // JSON text can never produce a binary value: is_binary() is always false\n    std::cout << d_array.root().is_binary() << '\\n';\n\n    // a default-constructed view, and the root of a document that failed to\n    // parse without exceptions, are both discarded\n    nlohmann::json_view invalid;\n    json_document failed = json_document::parse(\"not json\", /* allow_exceptions */ false);\n    std::cout << invalid.is_discarded() << '\\n';\n    std::cout << failed.root().is_discarded() << '\\n';\n\n    // type() returns the same value_t enumeration as basic_json::type()\n    std::cout << (d_object.root().type() == nlohmann::json::value_t::object) << '\\n';\n}\n

Output:

true\ntrue\ntrue true\ntrue\ntrue\ntrue\ntrue true\ntrue false\nfalse\ntrue\ntrue\ntrue\n
"},{"location":"api/basic_json_view/is_array/#see-also","title":"See also","text":"
  • is_structured - return whether the type is structured
  • size - the number of elements
  • empty - whether there are no elements
  • BasicJsonType::is_array - the corresponding function of basic_json
"},{"location":"api/basic_json_view/is_array/#version-history","title":"Version history","text":"
  • Added in version 3.13.0 unreleased.
"},{"location":"api/basic_json_view/is_binary/","title":"nlohmann::basic_json_view::is_binary","text":"
bool is_binary() const noexcept;\n

This function always returns false: a document is only ever parsed from JSON text, never from CBOR or the other binary formats, and a JSON text has no binary values, so a view can never refer to one. The function exists for interface parity with BasicJsonType::is_binary.

"},{"location":"api/basic_json_view/is_binary/#return-value","title":"Return value","text":"

false, always.

"},{"location":"api/basic_json_view/is_binary/#exception-safety","title":"Exception safety","text":"

No-throw guarantee: this function never throws exceptions.

"},{"location":"api/basic_json_view/is_binary/#complexity","title":"Complexity","text":"

Constant.

"},{"location":"api/basic_json_view/is_binary/#examples","title":"Examples","text":"Example

The example below classifies several parsed documents by the type of their root value, without materializing any of them into a BasicJsonType value.

#include <iostream>\n#include <nlohmann/json_view.hpp>\n\nusing nlohmann::json_document;\n\nint main()\n{\n    std::cout << std::boolalpha;\n\n    // several incoming messages, one json_document per message. type() and\n    // is_*() only look at the flat index built by parse(); no nlohmann::json\n    // tree exists yet, and none is built unless materialize() is called\n    json_document d_null = json_document::parse(\"null\");\n    json_document d_bool = json_document::parse(\"true\");\n    json_document d_int = json_document::parse(\"-42\");\n    json_document d_unsigned = json_document::parse(\"42\");\n    json_document d_float = json_document::parse(\"4.2\");\n    json_document d_string = json_document::parse(R\"(\"hi\")\");\n    json_document d_array = json_document::parse(\"[1, 2, 3]\");\n    json_document d_object = json_document::parse(R\"({\"a\": 1})\");\n\n    std::cout << d_null.root().is_null() << '\\n';\n    std::cout << d_bool.root().is_boolean() << '\\n';\n    std::cout << d_int.root().is_number() << ' ' << d_int.root().is_number_integer() << '\\n';\n    std::cout << d_unsigned.root().is_number_unsigned() << '\\n';\n    std::cout << d_float.root().is_number_float() << '\\n';\n    std::cout << d_string.root().is_string() << '\\n';\n    std::cout << d_array.root().is_array() << ' ' << d_array.root().is_structured() << '\\n';\n    std::cout << d_object.root().is_object() << ' ' << d_object.root().is_primitive() << '\\n';\n\n    // JSON text can never produce a binary value: is_binary() is always false\n    std::cout << d_array.root().is_binary() << '\\n';\n\n    // a default-constructed view, and the root of a document that failed to\n    // parse without exceptions, are both discarded\n    nlohmann::json_view invalid;\n    json_document failed = json_document::parse(\"not json\", /* allow_exceptions */ false);\n    std::cout << invalid.is_discarded() << '\\n';\n    std::cout << failed.root().is_discarded() << '\\n';\n\n    // type() returns the same value_t enumeration as basic_json::type()\n    std::cout << (d_object.root().type() == nlohmann::json::value_t::object) << '\\n';\n}\n

Output:

true\ntrue\ntrue true\ntrue\ntrue\ntrue\ntrue true\ntrue false\nfalse\ntrue\ntrue\ntrue\n
"},{"location":"api/basic_json_view/is_binary/#see-also","title":"See also","text":"
  • type - return the type of the value
  • BasicJsonType::is_binary - the corresponding function of basic_json
"},{"location":"api/basic_json_view/is_binary/#version-history","title":"Version history","text":"
  • Added in version 3.13.0 unreleased.
"},{"location":"api/basic_json_view/is_boolean/","title":"nlohmann::basic_json_view::is_boolean","text":"
bool is_boolean() const noexcept;\n

This function returns true if and only if the value is a boolean.

"},{"location":"api/basic_json_view/is_boolean/#return-value","title":"Return value","text":"

true if the type is a boolean, false otherwise.

"},{"location":"api/basic_json_view/is_boolean/#exception-safety","title":"Exception safety","text":"

No-throw guarantee: this function never throws exceptions.

"},{"location":"api/basic_json_view/is_boolean/#complexity","title":"Complexity","text":"

Constant.

"},{"location":"api/basic_json_view/is_boolean/#examples","title":"Examples","text":"Example

The example below classifies several parsed documents by the type of their root value, without materializing any of them into a BasicJsonType value.

#include <iostream>\n#include <nlohmann/json_view.hpp>\n\nusing nlohmann::json_document;\n\nint main()\n{\n    std::cout << std::boolalpha;\n\n    // several incoming messages, one json_document per message. type() and\n    // is_*() only look at the flat index built by parse(); no nlohmann::json\n    // tree exists yet, and none is built unless materialize() is called\n    json_document d_null = json_document::parse(\"null\");\n    json_document d_bool = json_document::parse(\"true\");\n    json_document d_int = json_document::parse(\"-42\");\n    json_document d_unsigned = json_document::parse(\"42\");\n    json_document d_float = json_document::parse(\"4.2\");\n    json_document d_string = json_document::parse(R\"(\"hi\")\");\n    json_document d_array = json_document::parse(\"[1, 2, 3]\");\n    json_document d_object = json_document::parse(R\"({\"a\": 1})\");\n\n    std::cout << d_null.root().is_null() << '\\n';\n    std::cout << d_bool.root().is_boolean() << '\\n';\n    std::cout << d_int.root().is_number() << ' ' << d_int.root().is_number_integer() << '\\n';\n    std::cout << d_unsigned.root().is_number_unsigned() << '\\n';\n    std::cout << d_float.root().is_number_float() << '\\n';\n    std::cout << d_string.root().is_string() << '\\n';\n    std::cout << d_array.root().is_array() << ' ' << d_array.root().is_structured() << '\\n';\n    std::cout << d_object.root().is_object() << ' ' << d_object.root().is_primitive() << '\\n';\n\n    // JSON text can never produce a binary value: is_binary() is always false\n    std::cout << d_array.root().is_binary() << '\\n';\n\n    // a default-constructed view, and the root of a document that failed to\n    // parse without exceptions, are both discarded\n    nlohmann::json_view invalid;\n    json_document failed = json_document::parse(\"not json\", /* allow_exceptions */ false);\n    std::cout << invalid.is_discarded() << '\\n';\n    std::cout << failed.root().is_discarded() << '\\n';\n\n    // type() returns the same value_t enumeration as basic_json::type()\n    std::cout << (d_object.root().type() == nlohmann::json::value_t::object) << '\\n';\n}\n

Output:

true\ntrue\ntrue true\ntrue\ntrue\ntrue\ntrue true\ntrue false\nfalse\ntrue\ntrue\ntrue\n
"},{"location":"api/basic_json_view/is_boolean/#see-also","title":"See also","text":"
  • type - return the type of the value
  • BasicJsonType::is_boolean - the corresponding function of basic_json
"},{"location":"api/basic_json_view/is_boolean/#version-history","title":"Version history","text":"
  • Added in version 3.13.0 unreleased.
"},{"location":"api/basic_json_view/is_discarded/","title":"nlohmann::basic_json_view::is_discarded","text":"
bool is_discarded() const noexcept;\n

Returns whether this view is invalid, i.e. does not refer to a value. This is the case for a default-constructed view (see (constructor)), and for root() of a document that is itself discarded \u2014 in particular, the root of a failed parse() with allow_exceptions set to false.

A discarded view is also what operator[] returns for a missing key, an index out of range, or a JSON pointer that cannot be resolved, and for any access on a view that is itself discarded (so a chain such as v[\"a\"][\"b\"] is safe). at throws instead.

"},{"location":"api/basic_json_view/is_discarded/#return-value","title":"Return value","text":"

true if the view or its document is discarded, false otherwise.

"},{"location":"api/basic_json_view/is_discarded/#exception-safety","title":"Exception safety","text":"

No-throw guarantee: this function never throws exceptions.

"},{"location":"api/basic_json_view/is_discarded/#complexity","title":"Complexity","text":"

Constant.

"},{"location":"api/basic_json_view/is_discarded/#notes","title":"Notes","text":"

A basic_json_view is not convertible to bool: such a conversion would mean \"refers to a value\", whereas basic_json converts to the bool it holds, so the same code would silently behave differently. Test !v.is_discarded() explicitly.

"},{"location":"api/basic_json_view/is_discarded/#examples","title":"Examples","text":"Example

The example below classifies several parsed documents by the type of their root value, without materializing any of them into a BasicJsonType value.

#include <iostream>\n#include <nlohmann/json_view.hpp>\n\nusing nlohmann::json_document;\n\nint main()\n{\n    std::cout << std::boolalpha;\n\n    // several incoming messages, one json_document per message. type() and\n    // is_*() only look at the flat index built by parse(); no nlohmann::json\n    // tree exists yet, and none is built unless materialize() is called\n    json_document d_null = json_document::parse(\"null\");\n    json_document d_bool = json_document::parse(\"true\");\n    json_document d_int = json_document::parse(\"-42\");\n    json_document d_unsigned = json_document::parse(\"42\");\n    json_document d_float = json_document::parse(\"4.2\");\n    json_document d_string = json_document::parse(R\"(\"hi\")\");\n    json_document d_array = json_document::parse(\"[1, 2, 3]\");\n    json_document d_object = json_document::parse(R\"({\"a\": 1})\");\n\n    std::cout << d_null.root().is_null() << '\\n';\n    std::cout << d_bool.root().is_boolean() << '\\n';\n    std::cout << d_int.root().is_number() << ' ' << d_int.root().is_number_integer() << '\\n';\n    std::cout << d_unsigned.root().is_number_unsigned() << '\\n';\n    std::cout << d_float.root().is_number_float() << '\\n';\n    std::cout << d_string.root().is_string() << '\\n';\n    std::cout << d_array.root().is_array() << ' ' << d_array.root().is_structured() << '\\n';\n    std::cout << d_object.root().is_object() << ' ' << d_object.root().is_primitive() << '\\n';\n\n    // JSON text can never produce a binary value: is_binary() is always false\n    std::cout << d_array.root().is_binary() << '\\n';\n\n    // a default-constructed view, and the root of a document that failed to\n    // parse without exceptions, are both discarded\n    nlohmann::json_view invalid;\n    json_document failed = json_document::parse(\"not json\", /* allow_exceptions */ false);\n    std::cout << invalid.is_discarded() << '\\n';\n    std::cout << failed.root().is_discarded() << '\\n';\n\n    // type() returns the same value_t enumeration as basic_json::type()\n    std::cout << (d_object.root().type() == nlohmann::json::value_t::object) << '\\n';\n}\n

Output:

true\ntrue\ntrue true\ntrue\ntrue\ntrue\ntrue true\ntrue false\nfalse\ntrue\ntrue\ntrue\n
"},{"location":"api/basic_json_view/is_discarded/#see-also","title":"See also","text":"
  • operator[] - access specified element; yields a discarded view where an element is missing
  • (constructor) - the default constructor creates a discarded view
  • basic_json_document::is_discarded - return whether the last parse failed
  • BasicJsonType::is_discarded - the corresponding function of basic_json
  • Zero-copy JSON views - how views differ from basic_json
"},{"location":"api/basic_json_view/is_discarded/#version-history","title":"Version history","text":"
  • Added in version 3.13.0 unreleased.
"},{"location":"api/basic_json_view/is_null/","title":"nlohmann::basic_json_view::is_null","text":"
bool is_null() const noexcept;\n

This function returns true if and only if the value is null.

"},{"location":"api/basic_json_view/is_null/#return-value","title":"Return value","text":"

true if the type is null, false otherwise.

"},{"location":"api/basic_json_view/is_null/#exception-safety","title":"Exception safety","text":"

No-throw guarantee: this function never throws exceptions.

"},{"location":"api/basic_json_view/is_null/#complexity","title":"Complexity","text":"

Constant.

"},{"location":"api/basic_json_view/is_null/#examples","title":"Examples","text":"Example

The example below classifies several parsed documents by the type of their root value, without materializing any of them into a BasicJsonType value.

#include <iostream>\n#include <nlohmann/json_view.hpp>\n\nusing nlohmann::json_document;\n\nint main()\n{\n    std::cout << std::boolalpha;\n\n    // several incoming messages, one json_document per message. type() and\n    // is_*() only look at the flat index built by parse(); no nlohmann::json\n    // tree exists yet, and none is built unless materialize() is called\n    json_document d_null = json_document::parse(\"null\");\n    json_document d_bool = json_document::parse(\"true\");\n    json_document d_int = json_document::parse(\"-42\");\n    json_document d_unsigned = json_document::parse(\"42\");\n    json_document d_float = json_document::parse(\"4.2\");\n    json_document d_string = json_document::parse(R\"(\"hi\")\");\n    json_document d_array = json_document::parse(\"[1, 2, 3]\");\n    json_document d_object = json_document::parse(R\"({\"a\": 1})\");\n\n    std::cout << d_null.root().is_null() << '\\n';\n    std::cout << d_bool.root().is_boolean() << '\\n';\n    std::cout << d_int.root().is_number() << ' ' << d_int.root().is_number_integer() << '\\n';\n    std::cout << d_unsigned.root().is_number_unsigned() << '\\n';\n    std::cout << d_float.root().is_number_float() << '\\n';\n    std::cout << d_string.root().is_string() << '\\n';\n    std::cout << d_array.root().is_array() << ' ' << d_array.root().is_structured() << '\\n';\n    std::cout << d_object.root().is_object() << ' ' << d_object.root().is_primitive() << '\\n';\n\n    // JSON text can never produce a binary value: is_binary() is always false\n    std::cout << d_array.root().is_binary() << '\\n';\n\n    // a default-constructed view, and the root of a document that failed to\n    // parse without exceptions, are both discarded\n    nlohmann::json_view invalid;\n    json_document failed = json_document::parse(\"not json\", /* allow_exceptions */ false);\n    std::cout << invalid.is_discarded() << '\\n';\n    std::cout << failed.root().is_discarded() << '\\n';\n\n    // type() returns the same value_t enumeration as basic_json::type()\n    std::cout << (d_object.root().type() == nlohmann::json::value_t::object) << '\\n';\n}\n

Output:

true\ntrue\ntrue true\ntrue\ntrue\ntrue\ntrue true\ntrue false\nfalse\ntrue\ntrue\ntrue\n
"},{"location":"api/basic_json_view/is_null/#see-also","title":"See also","text":"
  • type - return the type of the value
  • BasicJsonType::is_null - the corresponding function of basic_json
"},{"location":"api/basic_json_view/is_null/#version-history","title":"Version history","text":"
  • Added in version 3.13.0 unreleased.
"},{"location":"api/basic_json_view/is_number/","title":"nlohmann::basic_json_view::is_number","text":"
bool is_number() const noexcept;\n

This function returns true if and only if the value is a number, i.e. an integer, unsigned integer, or floating-point value. It is defined as is_number_integer() || is_number_float().

"},{"location":"api/basic_json_view/is_number/#return-value","title":"Return value","text":"

true if the type is a number, false otherwise.

"},{"location":"api/basic_json_view/is_number/#exception-safety","title":"Exception safety","text":"

No-throw guarantee: this function never throws exceptions.

"},{"location":"api/basic_json_view/is_number/#complexity","title":"Complexity","text":"

Constant.

"},{"location":"api/basic_json_view/is_number/#examples","title":"Examples","text":"Example

The example below classifies several parsed documents by the type of their root value, without materializing any of them into a BasicJsonType value.

#include <iostream>\n#include <nlohmann/json_view.hpp>\n\nusing nlohmann::json_document;\n\nint main()\n{\n    std::cout << std::boolalpha;\n\n    // several incoming messages, one json_document per message. type() and\n    // is_*() only look at the flat index built by parse(); no nlohmann::json\n    // tree exists yet, and none is built unless materialize() is called\n    json_document d_null = json_document::parse(\"null\");\n    json_document d_bool = json_document::parse(\"true\");\n    json_document d_int = json_document::parse(\"-42\");\n    json_document d_unsigned = json_document::parse(\"42\");\n    json_document d_float = json_document::parse(\"4.2\");\n    json_document d_string = json_document::parse(R\"(\"hi\")\");\n    json_document d_array = json_document::parse(\"[1, 2, 3]\");\n    json_document d_object = json_document::parse(R\"({\"a\": 1})\");\n\n    std::cout << d_null.root().is_null() << '\\n';\n    std::cout << d_bool.root().is_boolean() << '\\n';\n    std::cout << d_int.root().is_number() << ' ' << d_int.root().is_number_integer() << '\\n';\n    std::cout << d_unsigned.root().is_number_unsigned() << '\\n';\n    std::cout << d_float.root().is_number_float() << '\\n';\n    std::cout << d_string.root().is_string() << '\\n';\n    std::cout << d_array.root().is_array() << ' ' << d_array.root().is_structured() << '\\n';\n    std::cout << d_object.root().is_object() << ' ' << d_object.root().is_primitive() << '\\n';\n\n    // JSON text can never produce a binary value: is_binary() is always false\n    std::cout << d_array.root().is_binary() << '\\n';\n\n    // a default-constructed view, and the root of a document that failed to\n    // parse without exceptions, are both discarded\n    nlohmann::json_view invalid;\n    json_document failed = json_document::parse(\"not json\", /* allow_exceptions */ false);\n    std::cout << invalid.is_discarded() << '\\n';\n    std::cout << failed.root().is_discarded() << '\\n';\n\n    // type() returns the same value_t enumeration as basic_json::type()\n    std::cout << (d_object.root().type() == nlohmann::json::value_t::object) << '\\n';\n}\n

Output:

true\ntrue\ntrue true\ntrue\ntrue\ntrue\ntrue true\ntrue false\nfalse\ntrue\ntrue\ntrue\n
"},{"location":"api/basic_json_view/is_number/#see-also","title":"See also","text":"
  • is_number_integer - return whether the value is an integer or unsigned integer number
  • is_number_unsigned - return whether the value is an unsigned integer number
  • is_number_float - return whether the value is a floating-point number
  • BasicJsonType::is_number - the corresponding function of basic_json
"},{"location":"api/basic_json_view/is_number/#version-history","title":"Version history","text":"
  • Added in version 3.13.0 unreleased.
"},{"location":"api/basic_json_view/is_number_float/","title":"nlohmann::basic_json_view::is_number_float","text":"
bool is_number_float() const noexcept;\n

This function returns true if and only if the value is a floating-point number.

"},{"location":"api/basic_json_view/is_number_float/#return-value","title":"Return value","text":"

true if the type is value_t::number_float, false otherwise.

"},{"location":"api/basic_json_view/is_number_float/#exception-safety","title":"Exception safety","text":"

No-throw guarantee: this function never throws exceptions.

"},{"location":"api/basic_json_view/is_number_float/#complexity","title":"Complexity","text":"

Constant.

"},{"location":"api/basic_json_view/is_number_float/#notes","title":"Notes","text":"

As for BasicJsonType::parse, an integer literal that does not fit into the 64-bit integer type is classified as a floating-point number, so is_number_float() can be true even for an integer-looking token in the source text.

"},{"location":"api/basic_json_view/is_number_float/#examples","title":"Examples","text":"Example

The example below classifies several parsed documents by the type of their root value, without materializing any of them into a BasicJsonType value.

#include <iostream>\n#include <nlohmann/json_view.hpp>\n\nusing nlohmann::json_document;\n\nint main()\n{\n    std::cout << std::boolalpha;\n\n    // several incoming messages, one json_document per message. type() and\n    // is_*() only look at the flat index built by parse(); no nlohmann::json\n    // tree exists yet, and none is built unless materialize() is called\n    json_document d_null = json_document::parse(\"null\");\n    json_document d_bool = json_document::parse(\"true\");\n    json_document d_int = json_document::parse(\"-42\");\n    json_document d_unsigned = json_document::parse(\"42\");\n    json_document d_float = json_document::parse(\"4.2\");\n    json_document d_string = json_document::parse(R\"(\"hi\")\");\n    json_document d_array = json_document::parse(\"[1, 2, 3]\");\n    json_document d_object = json_document::parse(R\"({\"a\": 1})\");\n\n    std::cout << d_null.root().is_null() << '\\n';\n    std::cout << d_bool.root().is_boolean() << '\\n';\n    std::cout << d_int.root().is_number() << ' ' << d_int.root().is_number_integer() << '\\n';\n    std::cout << d_unsigned.root().is_number_unsigned() << '\\n';\n    std::cout << d_float.root().is_number_float() << '\\n';\n    std::cout << d_string.root().is_string() << '\\n';\n    std::cout << d_array.root().is_array() << ' ' << d_array.root().is_structured() << '\\n';\n    std::cout << d_object.root().is_object() << ' ' << d_object.root().is_primitive() << '\\n';\n\n    // JSON text can never produce a binary value: is_binary() is always false\n    std::cout << d_array.root().is_binary() << '\\n';\n\n    // a default-constructed view, and the root of a document that failed to\n    // parse without exceptions, are both discarded\n    nlohmann::json_view invalid;\n    json_document failed = json_document::parse(\"not json\", /* allow_exceptions */ false);\n    std::cout << invalid.is_discarded() << '\\n';\n    std::cout << failed.root().is_discarded() << '\\n';\n\n    // type() returns the same value_t enumeration as basic_json::type()\n    std::cout << (d_object.root().type() == nlohmann::json::value_t::object) << '\\n';\n}\n

Output:

true\ntrue\ntrue true\ntrue\ntrue\ntrue\ntrue true\ntrue false\nfalse\ntrue\ntrue\ntrue\n
"},{"location":"api/basic_json_view/is_number_float/#see-also","title":"See also","text":"
  • is_number - return whether the value is a number
  • BasicJsonType::is_number_float - the corresponding function of basic_json
"},{"location":"api/basic_json_view/is_number_float/#version-history","title":"Version history","text":"
  • Added in version 3.13.0 unreleased.
"},{"location":"api/basic_json_view/is_number_integer/","title":"nlohmann::basic_json_view::is_number_integer","text":"
bool is_number_integer() const noexcept;\n

This function returns true if and only if the value is an integer or unsigned integer number.

"},{"location":"api/basic_json_view/is_number_integer/#return-value","title":"Return value","text":"

true if the type is value_t::number_integer or value_t::number_unsigned, false otherwise.

"},{"location":"api/basic_json_view/is_number_integer/#exception-safety","title":"Exception safety","text":"

No-throw guarantee: this function never throws exceptions.

"},{"location":"api/basic_json_view/is_number_integer/#complexity","title":"Complexity","text":"

Constant.

"},{"location":"api/basic_json_view/is_number_integer/#notes","title":"Notes","text":"

As for BasicJsonType::is_number_integer, this includes unsigned integer values; use is_number_unsigned to test for those specifically.

"},{"location":"api/basic_json_view/is_number_integer/#examples","title":"Examples","text":"Example

The example below classifies several parsed documents by the type of their root value, without materializing any of them into a BasicJsonType value.

#include <iostream>\n#include <nlohmann/json_view.hpp>\n\nusing nlohmann::json_document;\n\nint main()\n{\n    std::cout << std::boolalpha;\n\n    // several incoming messages, one json_document per message. type() and\n    // is_*() only look at the flat index built by parse(); no nlohmann::json\n    // tree exists yet, and none is built unless materialize() is called\n    json_document d_null = json_document::parse(\"null\");\n    json_document d_bool = json_document::parse(\"true\");\n    json_document d_int = json_document::parse(\"-42\");\n    json_document d_unsigned = json_document::parse(\"42\");\n    json_document d_float = json_document::parse(\"4.2\");\n    json_document d_string = json_document::parse(R\"(\"hi\")\");\n    json_document d_array = json_document::parse(\"[1, 2, 3]\");\n    json_document d_object = json_document::parse(R\"({\"a\": 1})\");\n\n    std::cout << d_null.root().is_null() << '\\n';\n    std::cout << d_bool.root().is_boolean() << '\\n';\n    std::cout << d_int.root().is_number() << ' ' << d_int.root().is_number_integer() << '\\n';\n    std::cout << d_unsigned.root().is_number_unsigned() << '\\n';\n    std::cout << d_float.root().is_number_float() << '\\n';\n    std::cout << d_string.root().is_string() << '\\n';\n    std::cout << d_array.root().is_array() << ' ' << d_array.root().is_structured() << '\\n';\n    std::cout << d_object.root().is_object() << ' ' << d_object.root().is_primitive() << '\\n';\n\n    // JSON text can never produce a binary value: is_binary() is always false\n    std::cout << d_array.root().is_binary() << '\\n';\n\n    // a default-constructed view, and the root of a document that failed to\n    // parse without exceptions, are both discarded\n    nlohmann::json_view invalid;\n    json_document failed = json_document::parse(\"not json\", /* allow_exceptions */ false);\n    std::cout << invalid.is_discarded() << '\\n';\n    std::cout << failed.root().is_discarded() << '\\n';\n\n    // type() returns the same value_t enumeration as basic_json::type()\n    std::cout << (d_object.root().type() == nlohmann::json::value_t::object) << '\\n';\n}\n

Output:

true\ntrue\ntrue true\ntrue\ntrue\ntrue\ntrue true\ntrue false\nfalse\ntrue\ntrue\ntrue\n
"},{"location":"api/basic_json_view/is_number_integer/#see-also","title":"See also","text":"
  • is_number - return whether the value is a number
  • is_number_unsigned - return whether the value is an unsigned integer number
  • BasicJsonType::is_number_integer - the corresponding function of basic_json
"},{"location":"api/basic_json_view/is_number_integer/#version-history","title":"Version history","text":"
  • Added in version 3.13.0 unreleased.
"},{"location":"api/basic_json_view/is_number_unsigned/","title":"nlohmann::basic_json_view::is_number_unsigned","text":"
bool is_number_unsigned() const noexcept;\n

This function returns true if and only if the value is an unsigned integer number.

"},{"location":"api/basic_json_view/is_number_unsigned/#return-value","title":"Return value","text":"

true if the type is value_t::number_unsigned, false otherwise.

"},{"location":"api/basic_json_view/is_number_unsigned/#exception-safety","title":"Exception safety","text":"

No-throw guarantee: this function never throws exceptions.

"},{"location":"api/basic_json_view/is_number_unsigned/#complexity","title":"Complexity","text":"

Constant.

"},{"location":"api/basic_json_view/is_number_unsigned/#examples","title":"Examples","text":"Example

The example below classifies several parsed documents by the type of their root value, without materializing any of them into a BasicJsonType value.

#include <iostream>\n#include <nlohmann/json_view.hpp>\n\nusing nlohmann::json_document;\n\nint main()\n{\n    std::cout << std::boolalpha;\n\n    // several incoming messages, one json_document per message. type() and\n    // is_*() only look at the flat index built by parse(); no nlohmann::json\n    // tree exists yet, and none is built unless materialize() is called\n    json_document d_null = json_document::parse(\"null\");\n    json_document d_bool = json_document::parse(\"true\");\n    json_document d_int = json_document::parse(\"-42\");\n    json_document d_unsigned = json_document::parse(\"42\");\n    json_document d_float = json_document::parse(\"4.2\");\n    json_document d_string = json_document::parse(R\"(\"hi\")\");\n    json_document d_array = json_document::parse(\"[1, 2, 3]\");\n    json_document d_object = json_document::parse(R\"({\"a\": 1})\");\n\n    std::cout << d_null.root().is_null() << '\\n';\n    std::cout << d_bool.root().is_boolean() << '\\n';\n    std::cout << d_int.root().is_number() << ' ' << d_int.root().is_number_integer() << '\\n';\n    std::cout << d_unsigned.root().is_number_unsigned() << '\\n';\n    std::cout << d_float.root().is_number_float() << '\\n';\n    std::cout << d_string.root().is_string() << '\\n';\n    std::cout << d_array.root().is_array() << ' ' << d_array.root().is_structured() << '\\n';\n    std::cout << d_object.root().is_object() << ' ' << d_object.root().is_primitive() << '\\n';\n\n    // JSON text can never produce a binary value: is_binary() is always false\n    std::cout << d_array.root().is_binary() << '\\n';\n\n    // a default-constructed view, and the root of a document that failed to\n    // parse without exceptions, are both discarded\n    nlohmann::json_view invalid;\n    json_document failed = json_document::parse(\"not json\", /* allow_exceptions */ false);\n    std::cout << invalid.is_discarded() << '\\n';\n    std::cout << failed.root().is_discarded() << '\\n';\n\n    // type() returns the same value_t enumeration as basic_json::type()\n    std::cout << (d_object.root().type() == nlohmann::json::value_t::object) << '\\n';\n}\n

Output:

true\ntrue\ntrue true\ntrue\ntrue\ntrue\ntrue true\ntrue false\nfalse\ntrue\ntrue\ntrue\n
"},{"location":"api/basic_json_view/is_number_unsigned/#see-also","title":"See also","text":"
  • is_number_integer - return whether the value is an integer or unsigned integer number
  • BasicJsonType::is_number_unsigned - the corresponding function of basic_json
"},{"location":"api/basic_json_view/is_number_unsigned/#version-history","title":"Version history","text":"
  • Added in version 3.13.0 unreleased.
"},{"location":"api/basic_json_view/is_object/","title":"nlohmann::basic_json_view::is_object","text":"
bool is_object() const noexcept;\n

This function returns true if and only if the value is an object.

"},{"location":"api/basic_json_view/is_object/#return-value","title":"Return value","text":"

true if the type is an object, false otherwise.

"},{"location":"api/basic_json_view/is_object/#exception-safety","title":"Exception safety","text":"

No-throw guarantee: this function never throws exceptions.

"},{"location":"api/basic_json_view/is_object/#complexity","title":"Complexity","text":"

Constant.

"},{"location":"api/basic_json_view/is_object/#examples","title":"Examples","text":"Example

The example below classifies several parsed documents by the type of their root value, without materializing any of them into a BasicJsonType value.

#include <iostream>\n#include <nlohmann/json_view.hpp>\n\nusing nlohmann::json_document;\n\nint main()\n{\n    std::cout << std::boolalpha;\n\n    // several incoming messages, one json_document per message. type() and\n    // is_*() only look at the flat index built by parse(); no nlohmann::json\n    // tree exists yet, and none is built unless materialize() is called\n    json_document d_null = json_document::parse(\"null\");\n    json_document d_bool = json_document::parse(\"true\");\n    json_document d_int = json_document::parse(\"-42\");\n    json_document d_unsigned = json_document::parse(\"42\");\n    json_document d_float = json_document::parse(\"4.2\");\n    json_document d_string = json_document::parse(R\"(\"hi\")\");\n    json_document d_array = json_document::parse(\"[1, 2, 3]\");\n    json_document d_object = json_document::parse(R\"({\"a\": 1})\");\n\n    std::cout << d_null.root().is_null() << '\\n';\n    std::cout << d_bool.root().is_boolean() << '\\n';\n    std::cout << d_int.root().is_number() << ' ' << d_int.root().is_number_integer() << '\\n';\n    std::cout << d_unsigned.root().is_number_unsigned() << '\\n';\n    std::cout << d_float.root().is_number_float() << '\\n';\n    std::cout << d_string.root().is_string() << '\\n';\n    std::cout << d_array.root().is_array() << ' ' << d_array.root().is_structured() << '\\n';\n    std::cout << d_object.root().is_object() << ' ' << d_object.root().is_primitive() << '\\n';\n\n    // JSON text can never produce a binary value: is_binary() is always false\n    std::cout << d_array.root().is_binary() << '\\n';\n\n    // a default-constructed view, and the root of a document that failed to\n    // parse without exceptions, are both discarded\n    nlohmann::json_view invalid;\n    json_document failed = json_document::parse(\"not json\", /* allow_exceptions */ false);\n    std::cout << invalid.is_discarded() << '\\n';\n    std::cout << failed.root().is_discarded() << '\\n';\n\n    // type() returns the same value_t enumeration as basic_json::type()\n    std::cout << (d_object.root().type() == nlohmann::json::value_t::object) << '\\n';\n}\n

Output:

true\ntrue\ntrue true\ntrue\ntrue\ntrue\ntrue true\ntrue false\nfalse\ntrue\ntrue\ntrue\n
"},{"location":"api/basic_json_view/is_object/#see-also","title":"See also","text":"
  • is_structured - return whether the type is structured
  • size - the number of elements
  • empty - whether there are no elements
  • BasicJsonType::is_object - the corresponding function of basic_json
"},{"location":"api/basic_json_view/is_object/#version-history","title":"Version history","text":"
  • Added in version 3.13.0 unreleased.
"},{"location":"api/basic_json_view/is_primitive/","title":"nlohmann::basic_json_view::is_primitive","text":"
bool is_primitive() const noexcept;\n

This function returns true if and only if the value is primitive, i.e. null, a boolean, a number, or a string. It is defined as is_null() || is_string() || is_boolean() || is_number().

"},{"location":"api/basic_json_view/is_primitive/#return-value","title":"Return value","text":"

true if the type is primitive, false otherwise.

"},{"location":"api/basic_json_view/is_primitive/#exception-safety","title":"Exception safety","text":"

No-throw guarantee: this function never throws exceptions.

"},{"location":"api/basic_json_view/is_primitive/#complexity","title":"Complexity","text":"

Constant.

"},{"location":"api/basic_json_view/is_primitive/#examples","title":"Examples","text":"Example

The example below classifies several parsed documents by the type of their root value, without materializing any of them into a BasicJsonType value.

#include <iostream>\n#include <nlohmann/json_view.hpp>\n\nusing nlohmann::json_document;\n\nint main()\n{\n    std::cout << std::boolalpha;\n\n    // several incoming messages, one json_document per message. type() and\n    // is_*() only look at the flat index built by parse(); no nlohmann::json\n    // tree exists yet, and none is built unless materialize() is called\n    json_document d_null = json_document::parse(\"null\");\n    json_document d_bool = json_document::parse(\"true\");\n    json_document d_int = json_document::parse(\"-42\");\n    json_document d_unsigned = json_document::parse(\"42\");\n    json_document d_float = json_document::parse(\"4.2\");\n    json_document d_string = json_document::parse(R\"(\"hi\")\");\n    json_document d_array = json_document::parse(\"[1, 2, 3]\");\n    json_document d_object = json_document::parse(R\"({\"a\": 1})\");\n\n    std::cout << d_null.root().is_null() << '\\n';\n    std::cout << d_bool.root().is_boolean() << '\\n';\n    std::cout << d_int.root().is_number() << ' ' << d_int.root().is_number_integer() << '\\n';\n    std::cout << d_unsigned.root().is_number_unsigned() << '\\n';\n    std::cout << d_float.root().is_number_float() << '\\n';\n    std::cout << d_string.root().is_string() << '\\n';\n    std::cout << d_array.root().is_array() << ' ' << d_array.root().is_structured() << '\\n';\n    std::cout << d_object.root().is_object() << ' ' << d_object.root().is_primitive() << '\\n';\n\n    // JSON text can never produce a binary value: is_binary() is always false\n    std::cout << d_array.root().is_binary() << '\\n';\n\n    // a default-constructed view, and the root of a document that failed to\n    // parse without exceptions, are both discarded\n    nlohmann::json_view invalid;\n    json_document failed = json_document::parse(\"not json\", /* allow_exceptions */ false);\n    std::cout << invalid.is_discarded() << '\\n';\n    std::cout << failed.root().is_discarded() << '\\n';\n\n    // type() returns the same value_t enumeration as basic_json::type()\n    std::cout << (d_object.root().type() == nlohmann::json::value_t::object) << '\\n';\n}\n

Output:

true\ntrue\ntrue true\ntrue\ntrue\ntrue\ntrue true\ntrue false\nfalse\ntrue\ntrue\ntrue\n
"},{"location":"api/basic_json_view/is_primitive/#see-also","title":"See also","text":"
  • is_structured - return whether the type is structured (the complement of this function, for a non-discarded view)
  • BasicJsonType::is_primitive - the corresponding function of basic_json
"},{"location":"api/basic_json_view/is_primitive/#version-history","title":"Version history","text":"
  • Added in version 3.13.0 unreleased.
"},{"location":"api/basic_json_view/is_string/","title":"nlohmann::basic_json_view::is_string","text":"
bool is_string() const noexcept;\n

This function returns true if and only if the value is a string.

"},{"location":"api/basic_json_view/is_string/#return-value","title":"Return value","text":"

true if the type is a string, false otherwise.

"},{"location":"api/basic_json_view/is_string/#exception-safety","title":"Exception safety","text":"

No-throw guarantee: this function never throws exceptions.

"},{"location":"api/basic_json_view/is_string/#complexity","title":"Complexity","text":"

Constant.

"},{"location":"api/basic_json_view/is_string/#examples","title":"Examples","text":"Example

The example below classifies several parsed documents by the type of their root value, without materializing any of them into a BasicJsonType value.

#include <iostream>\n#include <nlohmann/json_view.hpp>\n\nusing nlohmann::json_document;\n\nint main()\n{\n    std::cout << std::boolalpha;\n\n    // several incoming messages, one json_document per message. type() and\n    // is_*() only look at the flat index built by parse(); no nlohmann::json\n    // tree exists yet, and none is built unless materialize() is called\n    json_document d_null = json_document::parse(\"null\");\n    json_document d_bool = json_document::parse(\"true\");\n    json_document d_int = json_document::parse(\"-42\");\n    json_document d_unsigned = json_document::parse(\"42\");\n    json_document d_float = json_document::parse(\"4.2\");\n    json_document d_string = json_document::parse(R\"(\"hi\")\");\n    json_document d_array = json_document::parse(\"[1, 2, 3]\");\n    json_document d_object = json_document::parse(R\"({\"a\": 1})\");\n\n    std::cout << d_null.root().is_null() << '\\n';\n    std::cout << d_bool.root().is_boolean() << '\\n';\n    std::cout << d_int.root().is_number() << ' ' << d_int.root().is_number_integer() << '\\n';\n    std::cout << d_unsigned.root().is_number_unsigned() << '\\n';\n    std::cout << d_float.root().is_number_float() << '\\n';\n    std::cout << d_string.root().is_string() << '\\n';\n    std::cout << d_array.root().is_array() << ' ' << d_array.root().is_structured() << '\\n';\n    std::cout << d_object.root().is_object() << ' ' << d_object.root().is_primitive() << '\\n';\n\n    // JSON text can never produce a binary value: is_binary() is always false\n    std::cout << d_array.root().is_binary() << '\\n';\n\n    // a default-constructed view, and the root of a document that failed to\n    // parse without exceptions, are both discarded\n    nlohmann::json_view invalid;\n    json_document failed = json_document::parse(\"not json\", /* allow_exceptions */ false);\n    std::cout << invalid.is_discarded() << '\\n';\n    std::cout << failed.root().is_discarded() << '\\n';\n\n    // type() returns the same value_t enumeration as basic_json::type()\n    std::cout << (d_object.root().type() == nlohmann::json::value_t::object) << '\\n';\n}\n

Output:

true\ntrue\ntrue true\ntrue\ntrue\ntrue\ntrue true\ntrue false\nfalse\ntrue\ntrue\ntrue\n
"},{"location":"api/basic_json_view/is_string/#see-also","title":"See also","text":"
  • source_offset - byte offset of this value in the source text, which differs for strings: an escaped string has none
  • BasicJsonType::is_string - the corresponding function of basic_json
"},{"location":"api/basic_json_view/is_string/#version-history","title":"Version history","text":"
  • Added in version 3.13.0 unreleased.
"},{"location":"api/basic_json_view/is_structured/","title":"nlohmann::basic_json_view::is_structured","text":"
bool is_structured() const noexcept;\n

This function returns true if and only if the value is structured, i.e. an array or an object. It is defined as is_array() || is_object().

"},{"location":"api/basic_json_view/is_structured/#return-value","title":"Return value","text":"

true if the type is structured, false otherwise.

"},{"location":"api/basic_json_view/is_structured/#exception-safety","title":"Exception safety","text":"

No-throw guarantee: this function never throws exceptions.

"},{"location":"api/basic_json_view/is_structured/#complexity","title":"Complexity","text":"

Constant.

"},{"location":"api/basic_json_view/is_structured/#examples","title":"Examples","text":"Example

The example below classifies several parsed documents by the type of their root value, without materializing any of them into a BasicJsonType value.

#include <iostream>\n#include <nlohmann/json_view.hpp>\n\nusing nlohmann::json_document;\n\nint main()\n{\n    std::cout << std::boolalpha;\n\n    // several incoming messages, one json_document per message. type() and\n    // is_*() only look at the flat index built by parse(); no nlohmann::json\n    // tree exists yet, and none is built unless materialize() is called\n    json_document d_null = json_document::parse(\"null\");\n    json_document d_bool = json_document::parse(\"true\");\n    json_document d_int = json_document::parse(\"-42\");\n    json_document d_unsigned = json_document::parse(\"42\");\n    json_document d_float = json_document::parse(\"4.2\");\n    json_document d_string = json_document::parse(R\"(\"hi\")\");\n    json_document d_array = json_document::parse(\"[1, 2, 3]\");\n    json_document d_object = json_document::parse(R\"({\"a\": 1})\");\n\n    std::cout << d_null.root().is_null() << '\\n';\n    std::cout << d_bool.root().is_boolean() << '\\n';\n    std::cout << d_int.root().is_number() << ' ' << d_int.root().is_number_integer() << '\\n';\n    std::cout << d_unsigned.root().is_number_unsigned() << '\\n';\n    std::cout << d_float.root().is_number_float() << '\\n';\n    std::cout << d_string.root().is_string() << '\\n';\n    std::cout << d_array.root().is_array() << ' ' << d_array.root().is_structured() << '\\n';\n    std::cout << d_object.root().is_object() << ' ' << d_object.root().is_primitive() << '\\n';\n\n    // JSON text can never produce a binary value: is_binary() is always false\n    std::cout << d_array.root().is_binary() << '\\n';\n\n    // a default-constructed view, and the root of a document that failed to\n    // parse without exceptions, are both discarded\n    nlohmann::json_view invalid;\n    json_document failed = json_document::parse(\"not json\", /* allow_exceptions */ false);\n    std::cout << invalid.is_discarded() << '\\n';\n    std::cout << failed.root().is_discarded() << '\\n';\n\n    // type() returns the same value_t enumeration as basic_json::type()\n    std::cout << (d_object.root().type() == nlohmann::json::value_t::object) << '\\n';\n}\n

Output:

true\ntrue\ntrue true\ntrue\ntrue\ntrue\ntrue true\ntrue false\nfalse\ntrue\ntrue\ntrue\n
"},{"location":"api/basic_json_view/is_structured/#see-also","title":"See also","text":"
  • is_primitive - return whether the type is primitive
  • size, empty - the number of elements, and whether there are none
  • BasicJsonType::is_structured - the corresponding function of basic_json
"},{"location":"api/basic_json_view/is_structured/#version-history","title":"Version history","text":"
  • Added in version 3.13.0 unreleased.
"},{"location":"api/basic_json_view/items/","title":"nlohmann::basic_json_view::items","text":"
/* unspecified */ items() const noexcept;\n

Returns a range of items \u2014 (key, value) pairs \u2014 for use in range-based for loops. An item's key() is a string_view_t (for an array element, its index converted to a string, as for BasicJsonType::items()), and its value() is a basic_json_view of the element.

The returned type is not part of the public API and may change between versions; use a range-based for loop (see the example), or decltype(v.items()) if you need to name it.

for (const auto& item : v.items())\n{\n    std::cout << \"key: \" << item.key() << \", value: \" << item.value() << '\\n';\n}\n

On C++17, item also supports structured bindings:

for (const auto [key, value] : v.items())\n{\n    std::cout << \"key: \" << key << \", value: \" << value << '\\n';\n}\n

Note the const auto (by value), not const auto&: unlike BasicJsonType::items(), whose elements are references into an existing object, a view's item is produced on the fly for each step of the iteration, so there is nothing for a reference to bind to.

"},{"location":"api/basic_json_view/items/#return-value","title":"Return value","text":"

A range whose iterators dereference to an item (with key() and value(), see above) and whose begin()/end() are equivalent to basic_json_view::begin()/end(), in document order.

"},{"location":"api/basic_json_view/items/#exception-safety","title":"Exception safety","text":"

No-throw guarantee: this function never throws exceptions.

"},{"location":"api/basic_json_view/items/#complexity","title":"Complexity","text":"

Constant.

"},{"location":"api/basic_json_view/items/#notes","title":"Notes","text":"

As for begin()/end(), items() visits every member of an object, including all occurrences of a duplicate key \u2014 unlike operator[], at, find, and contains, which resolve to the first member with a given key. See the Notes on duplicate keys of operator[].

Lifetime issues

Unlike BasicJsonType::items() (see #2040), calling items() on a temporary view is safe, for instance for (auto item : v[\"a\"].items()): the returned range holds a copy of the view. What must outlive the loop is the document and, for a borrowed document, the source buffer.

"},{"location":"api/basic_json_view/items/#examples","title":"Examples","text":"Example

The example below shows a settings object whose source text records every update to a key as a duplicate member, in the order they happened. items() walks all of them, so the update history is visible, while operator[] only ever sees the first one and materialize() \u2014 like BasicJsonType::parse() \u2014 keeps only the last.

#include <iostream>\n#include <nlohmann/json_view.hpp>\n\nusing nlohmann::json_document;\n\nint main()\n{\n    // a settings object whose source text records every update to a key as\n    // a duplicate member. items() visits all of them, in document order, so\n    // the update history is visible; operator[] only ever sees the first\n    // one, and materialize() -- like basic_json::parse() -- keeps the last\n    json_document updates = json_document::parse(R\"({\"retries\": 1, \"timeout\": 30, \"retries\": 5})\");\n    const auto settings = updates.root();\n\n    for (const auto& item : settings.items())\n    {\n        std::cout << item.key() << '=' << item.value().materialize().dump() << '\\n';\n    }\n\n    std::cout << \"first \\\"retries\\\" seen by operator[]: \" << settings[\"retries\"].materialize().dump() << '\\n';\n    std::cout << \"last \\\"retries\\\" kept by materialize(): \" << settings.materialize()[\"retries\"].dump() << '\\n';\n}\n

Output:

retries=1\ntimeout=30\nretries=5\nfirst \"retries\" seen by operator[]: 1\nlast \"retries\" kept by materialize(): 5\n
"},{"location":"api/basic_json_view/items/#see-also","title":"See also","text":"
  • begin, end - the iterators items() is built on
  • BasicJsonType::items - the corresponding function of basic_json
"},{"location":"api/basic_json_view/items/#version-history","title":"Version history","text":"
  • Added in version 3.13.0 unreleased.
"},{"location":"api/basic_json_view/materialize/","title":"nlohmann::basic_json_view::materialize","text":"
BasicJsonType materialize() const;\n

Builds the BasicJsonType value of this subtree: the value BasicJsonType::parse() would have produced for the same source text, allocated for the first time by this call.

"},{"location":"api/basic_json_view/materialize/#return-value","title":"Return value","text":"

The BasicJsonType value of this subtree, or a discarded BasicJsonType value (BasicJsonType(value_t::discarded)) if the view is discarded.

"},{"location":"api/basic_json_view/materialize/#exception-safety","title":"Exception safety","text":"

Strong guarantee: there are no changes to the view or the document it refers to (nothing about either is mutated by this function).

"},{"location":"api/basic_json_view/materialize/#exceptions","title":"Exceptions","text":"

May throw std::bad_alloc (via BasicJsonType's allocator) if constructing the result fails.

"},{"location":"api/basic_json_view/materialize/#complexity","title":"Complexity","text":"

Linear in the size of the subtree.

"},{"location":"api/basic_json_view/materialize/#notes","title":"Notes","text":"

materialize() replays the subtree through the same SAX builder BasicJsonType::parse() uses, so the result matches it exactly \u2014 including, for an object, that a repeated key keeps only its last value. The replay is iterative, so it is not limited by the call stack the way a naive recursive conversion would be; the JSON nesting depth is limited only by available memory, as for BasicJsonType::parse() itself.

Unlike parsing with JSON_DIAGNOSTIC_POSITIONS enabled, the values produced by materialize() do not carry source positions. The index has the start offset of every value, but not the end of arrays, objects, and escaped strings, which the positions also need.

Calling materialize() on the same view repeatedly builds a new, independent BasicJsonType value each time; it never caches the result.

"},{"location":"api/basic_json_view/materialize/#examples","title":"Examples","text":"Example

The example below skips messages that are not useful \u2014 a discarded value, or an empty array \u2014 using only is_array() and empty(), and calls materialize() only for the messages that are actually used, so no BasicJsonType value (and none of its per-element allocations) is ever built for the skipped ones.

#include <array>\n#include <iostream>\n#include <nlohmann/json_view.hpp>\n\nusing nlohmann::json_document;\n\nint main()\n{\n    // three incoming messages; skip the ones that are not useful without ever\n    // building a nlohmann::json value for them\n    json_document heartbeat = json_document::parse(\"null\");\n    json_document empty_batch = json_document::parse(\"[]\");\n    json_document batch = json_document::parse(R\"([{\"id\": 1}, {\"id\": 2}, {\"id\": 3}])\");\n    std::array<const json_document*, 3> messages = {{&heartbeat, &empty_batch, &batch}};\n\n    for (const json_document* d : messages)\n    {\n        // is_array()/empty() only look at the flat index: a discarded\n        // heartbeat or an empty batch is never turned into a nlohmann::json\n        // value, so no per-element allocation happens for them\n        if (!d->root().is_array() || d->root().empty())\n        {\n            std::cout << \"skipped\\n\";\n            continue;\n        }\n\n        // materialize() replays the subtree through the same SAX builder\n        // basic_json::parse() uses, so the result is exactly what\n        // basic_json::parse() would have produced for the same text\n        nlohmann::json value = d->root().materialize();\n        std::cout << value.dump() << '\\n';\n    }\n}\n

Output:

skipped\nskipped\n[{\"id\":1},{\"id\":2},{\"id\":3}]\n
"},{"location":"api/basic_json_view/materialize/#see-also","title":"See also","text":"
  • root - the view of a document's root value
  • BasicJsonType::parse - build a BasicJsonType value directly from a JSON text
  • JSON_DIAGNOSTIC_POSITIONS - source positions on parsed values (not produced by materialize())
  • Zero-copy JSON views - when to build a basic_json value from a view
"},{"location":"api/basic_json_view/materialize/#version-history","title":"Version history","text":"
  • Added in version 3.13.0 unreleased.
"},{"location":"api/basic_json_view/number_format/","title":"nlohmann::basic_json_view::number_format","text":"
enum class number_format {\n    shortest,\n    source\n};\n

This enumeration is used in dump to choose how numbers are written. Two values are differentiated:

shortest integers are copied from the source text \u2014 already canonical in JSON \u2014 except that -0 becomes 0, the way BasicJsonType::parse() reads it; floats are written with the library's shortest round-trip conversion, exactly as BasicJsonType::dump() would (e.g. 1.5, 100.0, 1e+100) source every number is copied exactly as it appears in the source text \u2014 1.50, 1E2, -0, all digits of an integer literal with more digits than any number type holds \u2014 something BasicJsonType cannot do, since parsing already reduces every number to its parsed value"},{"location":"api/basic_json_view/number_format/#examples","title":"Examples","text":"Example

The example below writes back a price list received from a supplier: with number_format::shortest (the default), a trailing zero and scientific notation are normalized away and a long account number that overflows every number type is rounded, the same way materialize().dump() (or basic_json::dump()) would; number_format::source keeps every number exactly as it was written in the source text instead.

#include <iostream>\n#include <nlohmann/json_view.hpp>\n\nusing nlohmann::json_document;\nusing nlohmann::json_view;\n\nint main()\n{\n    // a price list received from a supplier feed -- prices and account\n    // numbers must be forwarded exactly, e.g. into an invoice\n    const json_document doc = json_document::parse(R\"(\n      [{\"sku\": \"A1\", \"price\": 19.90, \"account_id\": 12345678901234567890123456},\n       {\"sku\": \"A2\", \"price\": 1E2, \"account_id\": 98765432109876543210987654}]\n    )\");\n    const json_view list = doc.root();\n\n    // number_format::shortest (the default) writes numbers the way\n    // basic_json::dump() would: \"19.90\" becomes \"19.9\", \"1E2\" becomes\n    // \"100.0\", and each account number -- far beyond any 64-bit integer --\n    // is rounded to the nearest double, exactly as materialize().dump()\n    // (or a plain nlohmann::json) would round it\n    std::cout << list.dump() << '\\n';\n\n    // number_format::source copies every number exactly as it was written\n    // in the source text instead -- something basic_json cannot do at all,\n    // since parsing already reduces every number to its parsed value\n    std::cout << list.dump(-1, ' ', false, json_view::number_format::source) << '\\n';\n}\n

Output:

[{\"sku\":\"A1\",\"price\":19.9,\"account_id\":1.2345678901234568e+25},{\"sku\":\"A2\",\"price\":100.0,\"account_id\":9.876543210987655e+25}]\n[{\"sku\":\"A1\",\"price\":19.90,\"account_id\":12345678901234567890123456},{\"sku\":\"A2\",\"price\":1E2,\"account_id\":98765432109876543210987654}]\n
"},{"location":"api/basic_json_view/number_format/#see-also","title":"See also","text":"
  • dump - serialize to a JSON-formatted string
  • number_token - get a single number's token text without dumping the whole value
  • BasicJsonType::error_handler_t - the analogous enumeration for BasicJsonType::dump's decoding-error behavior
  • Zero-copy JSON views - writing numbers as they appeared in the source
"},{"location":"api/basic_json_view/number_format/#version-history","title":"Version history","text":"
  • Added in version 3.13.0 unreleased.
"},{"location":"api/basic_json_view/number_token/","title":"nlohmann::basic_json_view::number_token","text":"
string_view_t number_token() const;\n

Returns the number exactly as it appears in the source text, without parsing or rounding it.

"},{"location":"api/basic_json_view/number_token/#return-value","title":"Return value","text":"

The number's token text, as a string_view_t into the document's source() text \u2014 for example \"1.50\", \"1E2\", \"-0\", or an integer literal with more digits than any number type holds (such as a 30-digit integer, which get<T>() and materialize() can only represent approximately, as a number_float_t).

"},{"location":"api/basic_json_view/number_token/#exception-safety","title":"Exception safety","text":"

Strong guarantee: there are no changes to the view or the document it refers to.

"},{"location":"api/basic_json_view/number_token/#exceptions","title":"Exceptions","text":"

Throws type_error.302 if the value is not a number; example: \"type must be number, but is string\".

This exception does not carry a JSON_DIAGNOSTICS path: the view has no BasicJsonType value to point at, so the exception is created without one, even if BasicJsonType was built with JSON_DIAGNOSTICS enabled.

"},{"location":"api/basic_json_view/number_token/#complexity","title":"Complexity","text":"

Constant.

"},{"location":"api/basic_json_view/number_token/#notes","title":"Notes","text":"

BasicJsonType has no counterpart to this function: once a number is parsed into number_integer_t, number_unsigned_t, or number_float_t, its original textual form (leading zeros aside, which are already rejected by the grammar; trailing zeros in the fraction; the case and sign of the exponent; ...) is gone. number_token() is useful precisely where that form must survive \u2014 a price or an identifier that must be reproduced exactly, or a number too large for any of BasicJsonType's number types to hold without loss.

The returned string_view_t always points into the document's source() text \u2014 numbers are never decoded into the document's separate string buffer \u2014 and is valid exactly as long as that text is, see the validity rules of basic_json_view.

"},{"location":"api/basic_json_view/number_token/#examples","title":"Examples","text":"Example

The example below keeps a price and an order ID exactly as they were written in an incoming order, where converting them with get<T>() would lose information: the price picks up floating-point rounding, and the order ID \u2014 more digits than a 64-bit integer holds \u2014 can only be approximated as a double once materialize()d.

#include <iostream>\n#include <nlohmann/json_view.hpp>\n\nusing nlohmann::json_document;\nusing nlohmann::json_view;\n\nint main()\n{\n    // a price and an order id from an incoming order -- both need to be\n    // reproduced exactly, e.g. for an invoice or an audit log\n    json_document doc = json_document::parse(R\"(\n      {\"price\": 19.90, \"order_id\": 1234567890123456789012345, \"quantity\": 3}\n    )\");\n    const json_view order = doc.root();\n\n    // number_token() returns the number exactly as written in the source\n    std::cout << order[\"price\"].number_token() << '\\n';\n    std::cout << order[\"order_id\"].number_token() << '\\n';\n\n    // get<double>() converts it instead -- the exact source text is gone:\n    // \"19.90\" becomes the double closest to 19.9, printed without the\n    // trailing zero, and the 25-digit order id -- far beyond any 64-bit\n    // integer -- can only be approximated as a double\n    std::cout << order[\"price\"].get<double>() << '\\n';\n    std::cout << order.materialize()[\"order_id\"].dump() << '\\n';\n\n    // an ordinary quantity has nothing to lose either way\n    std::cout << order[\"quantity\"].number_token() << \" == \" << order[\"quantity\"].get<int>() << '\\n';\n}\n

Output:

19.90\n1234567890123456789012345\n19.9\n1.2345678901234568e+24\n3 == 3\n
"},{"location":"api/basic_json_view/number_token/#see-also","title":"See also","text":"
  • get - convert the value to a given type
  • get_string - the string, without a copy
  • BasicJsonType::number_integer_t, number_unsigned_t, number_float_t - the number types get<T>() and materialize() convert into
  • Zero-copy JSON views - reading a number exactly as written
"},{"location":"api/basic_json_view/number_token/#version-history","title":"Version history","text":"
  • Added in version 3.13.0 unreleased.
"},{"location":"api/basic_json_view/operator%5B%5D/","title":"nlohmann::basic_json_view::operator[]","text":"
// (1)\nbasic_json_view operator[](string_view_t key) const;\nbasic_json_view operator[](const char* key) const;\nbasic_json_view operator[](const string_t& key) const;\n\n// (2)\nbasic_json_view operator[](size_type idx) const;\ntemplate<typename IntegerType>\nbasic_json_view operator[](IntegerType idx) const;\n\n// (3)\nbasic_json_view operator[](const json_pointer& ptr) const;\n
  1. Returns the value of the object member with key key \u2014 the first one, should the key occur more than once (see the Notes below) \u2014 or a discarded view if there is no such member.
  2. Returns the array element at index idx, or a discarded view if idx is out of range. The template accepts every integer type except bool and std::size_t (int, unsigned, long, std::int64_t, ...) and forwards to the size_type overload, so that an integer argument is not ambiguous between that overload and 1; a negative idx is out of range.
  3. Returns the value a JSON pointer ptr refers to, starting at this value, or a discarded view wherever resolving it further is not possible without inserting into or extending the document (see Return value and Exceptions below).
"},{"location":"api/basic_json_view/operator%5B%5D/#parameters","title":"Parameters","text":"key (in) object key of the element to access idx (in) index of the element to access ptr (in) JSON pointer to the element to access"},{"location":"api/basic_json_view/operator%5B%5D/#return-value","title":"Return value","text":"
  1. the value of the first member with key key, or a discarded view if no member has this key (or if this view is discarded)
  2. the element at index idx, or a discarded view if idx >= size() or idx is negative (or if this view is discarded)
  3. the value ptr resolves to, starting at this value, or a discarded view (also if this view is discarded) for exactly the reference tokens where the const overload of BasicJsonType::operator[] invokes undefined behavior for the same pointer and the same document: an object member that does not exist, or an array index that is out of range
"},{"location":"api/basic_json_view/operator%5B%5D/#exception-safety","title":"Exception safety","text":"

Strong guarantee: there are no changes to the view or the document it refers to.

"},{"location":"api/basic_json_view/operator%5B%5D/#exceptions","title":"Exceptions","text":"
  1. Throws type_error.305 if the value is not an object and not discarded \u2014 the same exception, with the same message, that the const overload of BasicJsonType::operator[] throws for a string argument on a non-object value.
  2. Throws type_error.305 if the value is not an array and not discarded \u2014 the same exception, with the same message, that the const overload of BasicJsonType::operator[] throws for a numeric argument on a non-array value.
  3. Throws the same exceptions, with the same messages, that the const overload of BasicJsonType::operator[] throws for the same pointer and the same document:
    • out_of_range.402 if a reference token is \"-\" at an array.
    • out_of_range.404 if a reference token cannot be resolved because it is used on a primitive value.
    • parse_error.106 if an array index in ptr begins with '0'.
    • parse_error.109 if an array index in ptr is not a number.

None of these exceptions carry a JSON_DIAGNOSTICS path: the view has no BasicJsonType value to point at, so the exception is created without one, even if BasicJsonType was built with JSON_DIAGNOSTICS enabled.

"},{"location":"api/basic_json_view/operator%5B%5D/#complexity","title":"Complexity","text":"
  1. Linear in the number of members: as for ordered_json, members are compared one after another, in document order, stopping at the first match. Each comparison first checks the key's length \u2014 already known from the index, without reading the key bytes \u2014 before comparing its content, so a key of a different length than key is rejected without touching the source text. Objects with 128 or more members get a hash index of their keys while parsing, so that a lookup in them takes constant time on average.
  2. Linear in idx: elements are skipped one at a time from the first one, since they are not a fixed size in the index (unlike BasicJsonType's array, which is random-access). Constant if no element of the array is an array or object, since the elements are then adjacent in the index.
  3. Linear in the number of reference tokens of ptr and, for each token, in the number of members of the object at that level (as 1.) or the index into the array (as 2.).
"},{"location":"api/basic_json_view/operator%5B%5D/#notes","title":"Notes","text":"

Unlike BasicJsonType::operator[], which is undefined behavior (guarded by a runtime assertion) for a missing key on a const value, this operator returns a safe, testable result for a missing key or an index out of range: a discarded view, which is tested with is_discarded. There is also no non-const overload that inserts a missing key or extends an array \u2014 a view never modifies the document.

Chained access

operator[] on a discarded view returns a discarded view and does not throw, so a chain like v[\"a\"][\"b\"][0] is safe even if \"a\" or \"b\" is missing: the first missing step makes the whole result discarded, which is tested once at the end. Type errors on values that are not discarded still throw: a key on an array or a primitive, or an index on an object or a primitive, is type_error.305 as for BasicJsonType. at still throws for a discarded view, as it does for a missing key.

Duplicate keys: the first member wins

If the source text has an object with a duplicate key, operator[] (and at, find, contains, value, and JSON pointer resolution) all resolve to the first member with that key, because a lookup can stop as soon as it finds a match. This is different from materialize() (and BasicJsonType::parse()), which replay every member in order and so keep the last value for a repeated key, so v[\"a\"] and v.materialize()[\"a\"] can differ. To get the value parse() would give, use materialize() or iterate the members with items() and keep the last match. The key hash index of a larger object (128 members or more) leads to the first member of a key as well. begin()/end() and items() iterate over all members, including duplicates, in document order. See Duplicate keys and size().

JSON pointer resolution

Overload 3 walks ptr one reference token at a time, starting at this value, the same way at and contains do. It only ever returns a discarded view where the const overload of BasicJsonType::operator[] would be undefined behavior for the same pointer \u2014 a missing object member or an out-of-range array index \u2014 and still throws for every other way ptr can fail to resolve. See at for the checked version, which throws in every case instead, and contains for a version that never throws.

"},{"location":"api/basic_json_view/operator%5B%5D/#examples","title":"Examples","text":"Example: (1)/(2) access specified element

The example below reads a couple of fields out of a batch of user records without ever materializing a full BasicJsonType value for the batch. operator[] is used both to look up an optional object member and to index into an array \u2014 in both cases, a missing value comes back as a discarded view that can be tested with a plain if, instead of relying on undefined behavior.

#include <iostream>\n#include <nlohmann/json_view.hpp>\n\nusing nlohmann::json_document;\n\nint main()\n{\n    // two user records from a large API response; only the fields that are\n    // actually read are ever touched, and no nlohmann::json tree is built\n    // for the batch\n    json_document batch = json_document::parse(R\"(\n      [\n        {\"name\": \"Alice\", \"email\": \"alice@example.com\", \"tags\": [\"admin\", \"ops\"]},\n        {\"name\": \"Bob\", \"tags\": []}\n      ]\n    )\");\n\n    const auto users = batch.root();\n    for (std::size_t i = 0; i < users.size(); ++i)\n    {\n        const auto user = users[i];\n        std::cout << user[\"name\"].materialize().dump();\n\n        // operator[] on a missing object key gives a discarded view -- test\n        // it with is_discarded(). The const overload of json::operator[]\n        // would instead be undefined behavior (guarded by an assertion) for\n        // a missing key\n        const auto email = user[\"email\"];\n        if (!email.is_discarded())\n        {\n            std::cout << \" <\" << email.materialize().dump() << \">\";\n        }\n\n        // the same holds for an array index past the end: a discarded view,\n        // not undefined behavior\n        const auto first_tag = user[\"tags\"][0];\n        if (!first_tag.is_discarded())\n        {\n            std::cout << \" #\" << first_tag.materialize().dump();\n        }\n\n        std::cout << '\\n';\n    }\n}\n

Output:

\"Alice\" <\"alice@example.com\"> #\"admin\"\n\"Bob\"\n
Example: (3) access specified element via JSON pointer

The example below reaches straight into one deeply nested field of a large document with a single JSON pointer, without ever building a tree for the rest of it, and shows the discarded-view and throwing outcomes of a pointer that cannot be fully resolved.

#include <iostream>\n#include <nlohmann/json_view.hpp>\n\nusing nlohmann::json_document;\nusing json_pointer = nlohmann::json::json_pointer;\n\nint main()\n{\n    // a larger document; operator[] with a JSON pointer reaches straight to\n    // one deeply nested field, without ever building a tree for the rest\n    json_document doc = json_document::parse(R\"(\n      {\n        \"region\": {\n          \"servers\": [\n            {\"name\": \"eu-1\", \"metrics\": {\"cpu\": 0.42}},\n            {\"name\": \"eu-2\", \"metrics\": {\"cpu\": 0.71}}\n          ]\n        }\n      }\n    )\");\n\n    const auto root = doc.root();\n    std::cout << root[json_pointer(\"/region/servers/1/metrics/cpu\")].materialize().dump() << '\\n';\n\n    // a missing key or an out-of-range index along the path gives a\n    // discarded view, exactly where const json::operator[] would be\n    // undefined behavior for the same pointer\n    const auto missing = root[json_pointer(\"/region/servers/5/metrics/cpu\")];\n    if (!missing.is_discarded())\n    {\n        std::cout << missing.materialize().dump() << '\\n';\n    }\n    else\n    {\n        std::cout << \"no such server\\n\";\n    }\n\n    // indexing into a primitive still throws, as basic_json::operator[]\n    // does for the same pointer\n    try\n    {\n        static_cast<void>(root[json_pointer(\"/region/servers/0/name/x\")]);\n    }\n    catch (const nlohmann::json::out_of_range& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n}\n

Output:

0.71\nno such server\n[json.exception.out_of_range.404] unresolved reference token 'x'\n
"},{"location":"api/basic_json_view/operator%5B%5D/#see-also","title":"See also","text":"
  • at - access specified element with bounds checking (throws instead of returning a discarded view)
  • front, back - access the first or last element
  • find, contains - look up a member without throwing
  • BasicJsonType::operator[] - the corresponding function of basic_json
  • json_pointer - JSON pointer type used by overload 3
"},{"location":"api/basic_json_view/operator%5B%5D/#version-history","title":"Version history","text":"
  • Added in version 3.13.0 unreleased.
"},{"location":"api/basic_json_view/operator_eq/","title":"nlohmann::basic_json_view::operator==","text":"
// (1)\nbool operator==(const basic_json_view& lhs, const basic_json_view& rhs);\n\n// (2)\nbool operator==(const basic_json_view& lhs, const BasicJsonType& rhs);\nbool operator==(const BasicJsonType& lhs, const basic_json_view& rhs);\n
  1. Compares two views for equality: whether the values BasicJsonType::parse() would produce for lhs and rhs are equal, according to BasicJsonType's operator==.
  2. Compares a view and a BasicJsonType value for equality, in either order: whether the value parse() would produce for the view and the other operand are equal, according to BasicJsonType's operator==.

Neither overload builds a BasicJsonType value for a view to do the comparison (see Notes below). Numbers compare by value across their types (1 == 1.0), and an object compares by its members, with duplicate keys resolved exactly as parse() resolves them \u2014 the last value, at the position of the first occurrence of the key. This is not what operator[] and the other lookups return for a duplicate key: they find the first member (see Duplicate keys).

"},{"location":"api/basic_json_view/operator_eq/#parameters","title":"Parameters","text":"lhs (in) first value to consider rhs (in) second value to consider"},{"location":"api/basic_json_view/operator_eq/#return-value","title":"Return value","text":"

whether the values lhs and rhs are equal

"},{"location":"api/basic_json_view/operator_eq/#exception-safety","title":"Exception safety","text":"

Strong exception safety: if an exception is thrown, there are no changes to either operand, or to the document(s) a view refers to.

"},{"location":"api/basic_json_view/operator_eq/#exceptions","title":"Exceptions","text":"

May throw std::bad_alloc. Unlike the other comparison and most other basic_json_view functions, operator== is not noexcept: resolving an object's members needs a temporary array to sort them by key (see Complexity below), and that allocation can fail.

"},{"location":"api/basic_json_view/operator_eq/#complexity","title":"Complexity","text":"

Linear in the size of the compared values: every number, string, array element, and object member is visited at most once, and the walk is iterative, so the nesting depth it can compare is limited by available memory only, not by the call stack (as for materialize()). Resolving an object's members takes an additional O(n log n) in the number of members at that level, since they are sorted by key to detect and resolve duplicates before being compared. Two arrays of different size() are rejected without visiting either one's elements.

"},{"location":"api/basic_json_view/operator_eq/#notes","title":"Notes","text":"

Only a single number, boolean, or null value is ever materialized into a BasicJsonType, to reuse its operator== \u2014 for numbers, so that values written differently in the source text but equal in value (e.g. an integer and a floating-point literal) still compare equal, following the same rules BasicJsonType does for special values such as NaN. Constructing one of these scalars never allocates. Strings are compared directly, without allocating, either from the source text on both sides or, for overload 2, against BasicJsonType's own string. Arrays and objects are never materialized at all; only their elements or members are visited, one pair at a time.

How objects are compared

For a json_view (BasicJsonType::object_t is std::map), members are compared by key, regardless of the order they appear in the source text. For an ordered_json_view (object_t is ordered_map), they are compared in the order they occur, so the very same two objects with their members reordered can compare equal as json_views but not as ordered_json_views. This is exactly how json and ordered_json compare, see \"Comparing different basic_json specializations\".

Discarded views

A discarded view compares the same way a discarded BasicJsonType value does, which is governed by JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON: by default, a discarded view is never equal to anything, not even another discarded view.

No ordering comparison (operator<) is provided for basic_json_view; materialize() is the way to get a BasicJsonType value that supports it.

"},{"location":"api/basic_json_view/operator_eq/#examples","title":"Examples","text":"Example

The example below checks whether a newly received configuration differs from the previous one, and whether a received document matches what a test expects \u2014 directly on views, without ever materializing a BasicJsonType value for either side.

#include <iostream>\n#include <nlohmann/json_view.hpp>\n\nusing nlohmann::json_document;\nusing nlohmann::json;\n\nint main()\n{\n    // two snapshots of a polled configuration endpoint -- compare them\n    // directly as views, without ever building a nlohmann::json value for\n    // either one\n    const json_document previous = json_document::parse(\n                                       R\"({\"name\": \"cache\", \"port\": 6379, \"timeout\": 30})\");\n    const json_document current = json_document::parse(\n                                      R\"({\"port\": 6379.0, \"timeout\": 30, \"name\": \"cache\"})\");\n\n    // same members, reordered, and 6379 written as a float -- operator==\n    // treats them the same way BasicJsonType::operator== would\n    std::cout << std::boolalpha << (previous.root() == current.root()) << '\\n';\n\n    // an actually changed value is detected the same way\n    const json_document changed = json_document::parse(\n                                      R\"({\"name\": \"cache\", \"port\": 6380, \"timeout\": 30})\");\n    std::cout << (previous.root() == changed.root()) << '\\n';\n\n    // comparing a view directly against an expected json value -- handy in a\n    // test, without materializing the received document at all\n    const json expected = {{\"name\", \"cache\"}, {\"port\", 6379}, {\"timeout\", 30}};\n    std::cout << (previous.root() == expected) << '\\n';\n}\n

Output:

true\nfalse\ntrue\n
"},{"location":"api/basic_json_view/operator_eq/#see-also","title":"See also","text":"
  • operator!= - compare for inequality
  • materialize - build a BasicJsonType value, e.g. to keep comparing after the document is gone
  • BasicJsonType::operator== - the corresponding function of basic_json
"},{"location":"api/basic_json_view/operator_eq/#version-history","title":"Version history","text":"
  • Added in version 3.13.0 unreleased.
"},{"location":"api/basic_json_view/operator_ltlt/","title":"nlohmann::basic_json_view::operator<<","text":"
std::ostream& operator<<(std::ostream& o, const basic_json_view& v);\n

Not available when JSON_NO_IO is defined.

Serializes the given view v to the output stream o, using dump \u2014 exactly as operator<<(std::ostream&, const basic_json&) does for a basic_json value.

  • The indentation of the output can be controlled with the member variable width of the output stream o. For instance, using the manipulator std::setw(4) on o sets the indentation level to 4, and the serialization result is the same as calling v.dump(4). A width of 0 or less (the default) selects the most compact representation, as v.dump(-1) does.
  • The indentation character can be controlled with the member variable fill of the output stream o. For instance, the manipulator std::setfill('\\t') sets indentation to use a tab character rather than the default space character.
  • As for basic_json, o's width is reset to 0 after this call, whether or not it was greater than 0 before.

Numbers are always written as v.dump() writes them by default, i.e. as with number_format::shortest; there is no way to select number_format::source through the stream.

"},{"location":"api/basic_json_view/operator_ltlt/#parameters","title":"Parameters","text":"o (in, out) stream to write to v (in) view to serialize"},{"location":"api/basic_json_view/operator_ltlt/#return-value","title":"Return value","text":"

the stream o

"},{"location":"api/basic_json_view/operator_ltlt/#exceptions","title":"Exceptions","text":"

May throw std::bad_alloc, propagated from dump. Unlike operator<<(std::ostream&, const basic_json&), there is no UTF-8 decoding step that could throw type_error.316, and no error_handler to choose between \u2014 see the Exceptions of dump.

"},{"location":"api/basic_json_view/operator_ltlt/#complexity","title":"Complexity","text":"

Linear, as dump.

"},{"location":"api/basic_json_view/operator_ltlt/#examples","title":"Examples","text":"Example

The example below writes one record out of a larger batch straight to a log stream \u2014 compact for a one-line entry, and pretty-printed with std::setw/std::setfill for a readable dump \u2014 without ever building a BasicJsonType value for the record, or for the rest of the batch.

#include <iostream>\n#include <iomanip>\n#include <nlohmann/json_view.hpp>\n\nusing nlohmann::json_document;\nusing nlohmann::json_view;\n\nint main()\n{\n    // one order out of a large incoming batch -- write it straight to a log\n    // stream without ever building a basic_json value for it, or for the\n    // rest of the batch\n    const json_document doc = json_document::parse(R\"(\n      [{\"id\": 1, \"item\": \"cable\"}, {\"id\": 2, \"item\": \"adapter\"}]\n    )\");\n    const json_view orders = doc.root();\n\n    // compact, for a one-line log entry\n    std::cout << orders[1] << '\\n';\n\n    // std::setw sets the indentation level, exactly as for basic_json\n    std::cout << std::setw(2) << orders[1] << \"\\n\\n\";\n\n    // std::setfill changes the indentation character\n    std::cout << std::setw(1) << std::setfill('\\t') << orders[1] << '\\n';\n}\n

Output:

{\"id\":2,\"item\":\"adapter\"}\n{\n  \"id\": 2,\n  \"item\": \"adapter\"\n}\n\n{\n    \"id\": 2,\n    \"item\": \"adapter\"\n}\n
"},{"location":"api/basic_json_view/operator_ltlt/#see-also","title":"See also","text":"
  • dump - serialize to a JSON-formatted string
  • operator<<(std::ostream&) - the corresponding operator for basic_json
  • JSON_NO_IO - switch off functions relying on certain C++ I/O headers
  • Zero-copy JSON views - writing a view back without building a tree
"},{"location":"api/basic_json_view/operator_ltlt/#version-history","title":"Version history","text":"
  • Added in version 3.13.0 unreleased.
"},{"location":"api/basic_json_view/operator_ne/","title":"nlohmann::basic_json_view::operator!=","text":"
// (1)\nbool operator!=(const basic_json_view& lhs, const basic_json_view& rhs);\n\n// (2)\nbool operator!=(const basic_json_view& lhs, const BasicJsonType& rhs);\nbool operator!=(const BasicJsonType& lhs, const basic_json_view& rhs);\n
  1. Compares two views for inequality. Returns !(lhs == rhs), see operator==.
  2. Compares a view and a BasicJsonType value for inequality, in either order. Returns !(lhs == rhs) (or, for the reversed order, !(rhs == lhs)), see operator==.

Since operator!= is defined as the negation of operator==, it follows the same rules for special cases: for instance, since a discarded view is never equal to anything by default (see operator=='s Notes), it is never unequal to anything either \u2014 discarded != discarded is also false, exactly as for a discarded BasicJsonType value.

"},{"location":"api/basic_json_view/operator_ne/#parameters","title":"Parameters","text":"lhs (in) first value to consider rhs (in) second value to consider"},{"location":"api/basic_json_view/operator_ne/#return-value","title":"Return value","text":"

whether the values lhs and rhs are not equal

"},{"location":"api/basic_json_view/operator_ne/#exception-safety","title":"Exception safety","text":"

Strong exception safety: if an exception is thrown, there are no changes to either operand, or to the document(s) a view refers to.

"},{"location":"api/basic_json_view/operator_ne/#exceptions","title":"Exceptions","text":"

May throw std::bad_alloc, propagated from operator==. Unlike most other basic_json_view functions, operator!= is not noexcept.

"},{"location":"api/basic_json_view/operator_ne/#complexity","title":"Complexity","text":"

Linear, as operator==.

"},{"location":"api/basic_json_view/operator_ne/#notes","title":"Notes","text":"

See the Notes of operator== \u2014 in particular for how an object's members are compared (order matters for ordered_json_view but not for json_view) and for how discarded views compare.

No ordering comparison (operator<) is provided for basic_json_view; materialize() is the way to get a BasicJsonType value that supports it.

"},{"location":"api/basic_json_view/operator_ne/#examples","title":"Examples","text":"Example

The example below asserts, as a test would, that a received document differs from an unwanted value, and shows that \u2014 as for json/ordered_json \u2014 reordering an object's members is detected as a difference for an ordered_json_view but not for a json_view.

#include <iostream>\n#include <nlohmann/json_view.hpp>\n\nusing nlohmann::json_document;\nusing nlohmann::ordered_json_document;\nusing nlohmann::json;\n\nint main()\n{\n    // assert, as a test would, that a received document differs from an\n    // unwanted shape -- without ever materializing it into a json value just\n    // to compare\n    const json_document received = json_document::parse(\n                                       R\"({\"status\": \"ok\", \"code\": 200})\");\n    const json unwanted = {{\"status\", \"error\"}, {\"code\", 500}};\n    std::cout << std::boolalpha << (received.root() != unwanted) << '\\n';\n\n    // json (std::map) compares object members regardless of order ...\n    const json_document a = json_document::parse(R\"({\"a\": 1, \"b\": 2})\");\n    const json_document b = json_document::parse(R\"({\"b\": 2, \"a\": 1})\");\n    std::cout << (a.root() != b.root()) << '\\n';\n\n    // ... but ordered_json (ordered_map) compares them in the order they\n    // appear, so the very same reordering is detected as a difference\n    const ordered_json_document oa = ordered_json_document::parse(R\"({\"a\": 1, \"b\": 2})\");\n    const ordered_json_document ob = ordered_json_document::parse(R\"({\"b\": 2, \"a\": 1})\");\n    std::cout << (oa.root() != ob.root()) << '\\n';\n}\n

Output:

true\nfalse\ntrue\n
"},{"location":"api/basic_json_view/operator_ne/#see-also","title":"See also","text":"
  • operator== - compare for equality
  • materialize - build a BasicJsonType value, e.g. to keep comparing after the document is gone
  • BasicJsonType::operator!= - the corresponding function of basic_json
"},{"location":"api/basic_json_view/operator_ne/#version-history","title":"Version history","text":"
  • Added in version 3.13.0 unreleased.
"},{"location":"api/basic_json_view/size/","title":"nlohmann::basic_json_view::size","text":"
size_type size() const noexcept;\n

Returns the number of elements, as BasicJsonType::size() would for the same value.

"},{"location":"api/basic_json_view/size/#return-value","title":"Return value","text":"

The return value depends on the type and is defined as follows:

Value type return value null 0 discarded 0 boolean 1 string 1 number 1 object number of key/value pairs array number of elements"},{"location":"api/basic_json_view/size/#exception-safety","title":"Exception safety","text":"

No-throw guarantee: this function never throws exceptions.

"},{"location":"api/basic_json_view/size/#complexity","title":"Complexity","text":"

Constant: for an object or array, the element count is stored in the index, not counted on demand.

"},{"location":"api/basic_json_view/size/#notes","title":"Notes","text":"

As for BasicJsonType::size(), this does not return the length of a string value \u2014 it is 1 for a string, regardless of its length.

If the source text has an object with a duplicate key, every occurrence counts towards its size() \u2014 unlike materialize() (and BasicJsonType::parse()), which keeps only the last value for a repeated key. This means v.size() can be larger than v.materialize().size(). See the Notes on duplicate keys of operator[] for why lookups and iteration disagree on how many members there are.

"},{"location":"api/basic_json_view/size/#examples","title":"Examples","text":"Example

The example below uses size() and empty() to decide whether a parsed message is worth acting on, without materializing it into a BasicJsonType value.

#include <iostream>\n#include <nlohmann/json_view.hpp>\n\nusing nlohmann::json_document;\n\nint main()\n{\n    std::cout << std::boolalpha;\n\n    // decide whether a batch is worth processing before building any\n    // nlohmann::json value for it\n    json_document batch = json_document::parse(R\"([1, 2, 3, 4, 5])\");\n    json_document empty_batch = json_document::parse(\"[]\");\n\n    std::cout << batch.root().empty() << ' ' << batch.root().size() << '\\n';\n    std::cout << empty_batch.root().empty() << ' ' << empty_batch.root().size() << '\\n';\n\n    // as for basic_json: null has size 0, every other scalar has size 1\n    json_document n = json_document::parse(\"null\");\n    json_document s = json_document::parse(R\"(\"hi\")\");\n    std::cout << n.root().size() << ' ' << s.root().size() << '\\n';\n}\n

Output:

false 5\ntrue 0\n0 1\n
"},{"location":"api/basic_json_view/size/#see-also","title":"See also","text":"
  • empty - return whether the value has no elements
  • BasicJsonType::size - the corresponding function of basic_json
"},{"location":"api/basic_json_view/size/#version-history","title":"Version history","text":"
  • Added in version 3.13.0 unreleased.
"},{"location":"api/basic_json_view/source_offset/","title":"nlohmann::basic_json_view::source_offset","text":"
std::size_t source_offset() const noexcept;\n

Returns the byte offset of this value in the document's source() text, without materializing anything.

"},{"location":"api/basic_json_view/source_offset/#return-value","title":"Return value","text":"
  • For a string with no escapes, a number, true/false/null, an array, or an object: the byte offset of the first byte of the value's token (for a string: the first byte after the opening quote) in source().
  • static_cast<std::size_t>(-1) for a discarded view, and for a string that contains escapes \u2014 such a string was decoded once into the document's own buffer, so there is no single byte range in source() left to point at.
"},{"location":"api/basic_json_view/source_offset/#exception-safety","title":"Exception safety","text":"

No-throw guarantee: this function never throws exceptions.

"},{"location":"api/basic_json_view/source_offset/#complexity","title":"Complexity","text":"

Constant.

"},{"location":"api/basic_json_view/source_offset/#notes","title":"Notes","text":"

This is a raw offset, not a length: the API does not (yet) expose how many bytes the token occupies in the source text, so source_offset() alone is enough to report where a value came from (for an error message, for syntax highlighting, ...) but not to slice its exact text back out of source() for a string, whose token length is not the same as its decoded size().

"},{"location":"api/basic_json_view/source_offset/#examples","title":"Examples","text":"Example
#include <iostream>\n#include <string>\n#include <nlohmann/json_view.hpp>\n\nusing nlohmann::json_document;\n\nint main()\n{\n    std::cout << std::boolalpha;\n\n    // source_offset() points into source(): useful to report *where* in the\n    // original text a value came from (error messages, syntax highlighting,\n    // forwarding a sub-range verbatim, ...) without materializing it\n    json_document doc = json_document::parse(R\"(  123)\");\n    auto v = doc.root();\n    std::cout << v.source_offset() << ' '\n              << std::string(doc.source().data() + v.source_offset(), 3) << '\\n';\n\n    // a string without escapes also stays in the source text\n    json_document plain = json_document::parse(R\"(\"ab\")\");\n    std::cout << plain.source()[plain.root().source_offset()] << '\\n';\n\n    // a string with escapes is decoded once into the document's own buffer, so\n    // there is no single byte range in source() to point at: source_offset()\n    // returns the \"not applicable\" sentinel\n    json_document escaped = json_document::parse(R\"(\"a\\nb\")\");\n    std::cout << (escaped.root().source_offset() == static_cast<std::size_t>(-1)) << '\\n';\n\n    // a discarded view -- default-constructed, or the root of a failed parse\n    // with allow_exceptions == false -- has no offset either\n    json_document failed = json_document::parse(\"not json\", false);\n    std::cout << (failed.root().source_offset() == static_cast<std::size_t>(-1)) << '\\n';\n}\n

Output:

2 123\na\ntrue\ntrue\n
"},{"location":"api/basic_json_view/source_offset/#see-also","title":"See also","text":"
  • source - the parsed text
  • is_string - return whether the value is a string
  • Zero-copy JSON views - images and the source text
"},{"location":"api/basic_json_view/source_offset/#version-history","title":"Version history","text":"
  • Added in version 3.13.0 unreleased.
"},{"location":"api/basic_json_view/type/","title":"nlohmann::basic_json_view::type","text":"
value_t type() const noexcept;\n

Returns the type of the value this view refers to, as a value from the value_t enumeration \u2014 the same enumeration BasicJsonType::type() uses.

"},{"location":"api/basic_json_view/type/#return-value","title":"Return value","text":"

The type of the value; value_t::discarded for a discarded view.

"},{"location":"api/basic_json_view/type/#exception-safety","title":"Exception safety","text":"

No-throw guarantee: this function never throws exceptions.

"},{"location":"api/basic_json_view/type/#complexity","title":"Complexity","text":"

Constant.

"},{"location":"api/basic_json_view/type/#notes","title":"Notes","text":"

Unlike BasicJsonType::type(), this function can never return value_t::binary: a JSON text has no binary values, so type() only distinguishes the eight ordinary JSON value types (plus discarded).

"},{"location":"api/basic_json_view/type/#examples","title":"Examples","text":"Example

The example below classifies several parsed documents by the type of their root value, without materializing any of them into a BasicJsonType value.

#include <iostream>\n#include <nlohmann/json_view.hpp>\n\nusing nlohmann::json_document;\n\nint main()\n{\n    std::cout << std::boolalpha;\n\n    // several incoming messages, one json_document per message. type() and\n    // is_*() only look at the flat index built by parse(); no nlohmann::json\n    // tree exists yet, and none is built unless materialize() is called\n    json_document d_null = json_document::parse(\"null\");\n    json_document d_bool = json_document::parse(\"true\");\n    json_document d_int = json_document::parse(\"-42\");\n    json_document d_unsigned = json_document::parse(\"42\");\n    json_document d_float = json_document::parse(\"4.2\");\n    json_document d_string = json_document::parse(R\"(\"hi\")\");\n    json_document d_array = json_document::parse(\"[1, 2, 3]\");\n    json_document d_object = json_document::parse(R\"({\"a\": 1})\");\n\n    std::cout << d_null.root().is_null() << '\\n';\n    std::cout << d_bool.root().is_boolean() << '\\n';\n    std::cout << d_int.root().is_number() << ' ' << d_int.root().is_number_integer() << '\\n';\n    std::cout << d_unsigned.root().is_number_unsigned() << '\\n';\n    std::cout << d_float.root().is_number_float() << '\\n';\n    std::cout << d_string.root().is_string() << '\\n';\n    std::cout << d_array.root().is_array() << ' ' << d_array.root().is_structured() << '\\n';\n    std::cout << d_object.root().is_object() << ' ' << d_object.root().is_primitive() << '\\n';\n\n    // JSON text can never produce a binary value: is_binary() is always false\n    std::cout << d_array.root().is_binary() << '\\n';\n\n    // a default-constructed view, and the root of a document that failed to\n    // parse without exceptions, are both discarded\n    nlohmann::json_view invalid;\n    json_document failed = json_document::parse(\"not json\", /* allow_exceptions */ false);\n    std::cout << invalid.is_discarded() << '\\n';\n    std::cout << failed.root().is_discarded() << '\\n';\n\n    // type() returns the same value_t enumeration as basic_json::type()\n    std::cout << (d_object.root().type() == nlohmann::json::value_t::object) << '\\n';\n}\n

Output:

true\ntrue\ntrue true\ntrue\ntrue\ntrue\ntrue true\ntrue false\nfalse\ntrue\ntrue\ntrue\n
"},{"location":"api/basic_json_view/type/#see-also","title":"See also","text":"
  • is_null, is_boolean, is_number, is_string, is_array, is_object - type-specific predicates built on type()
  • BasicJsonType::type - the corresponding function of basic_json
"},{"location":"api/basic_json_view/type/#version-history","title":"Version history","text":"
  • Added in version 3.13.0 unreleased.
"},{"location":"api/basic_json_view/type_name/","title":"nlohmann::basic_json_view::type_name","text":"
const char* type_name() const noexcept;\n

Returns the type name as string to be used in error messages \u2014 usually to indicate that a function was called on a wrong JSON type. Identical to BasicJsonType::type_name(), including the extra \"discarded\" return value for a discarded view (BasicJsonType::type_name() produces the same string for a discarded BasicJsonType value).

"},{"location":"api/basic_json_view/type_name/#return-value","title":"Return value","text":"

a string representation of the type (value_t):

Value type return value null \"null\" boolean \"boolean\" string \"string\" number (integer, unsigned integer, floating-point) \"number\" object \"object\" array \"array\" discarded \"discarded\"

type_name() never returns \"binary\", since a JSON text has no binary values (see is_binary()); it also never returns \"invalid\", since a view's kind always comes from a value the parser actually produced.

"},{"location":"api/basic_json_view/type_name/#exception-safety","title":"Exception safety","text":"

No-throw guarantee: this function never throws exceptions.

"},{"location":"api/basic_json_view/type_name/#complexity","title":"Complexity","text":"

Constant.

"},{"location":"api/basic_json_view/type_name/#examples","title":"Examples","text":"Example

The example below reports why some parsed messages were rejected, using only type_name() \u2014 no BasicJsonType value is ever built for the ones that are wrong, and the message text matches what BasicJsonType::type_name() would produce for the same value.

#include <iostream>\n#include <nlohmann/json_view.hpp>\n\nusing nlohmann::json_document;\nusing nlohmann::json_view;\n\nint main()\n{\n    // report why some parsed messages were rejected, using only\n    // type_name() -- no nlohmann::json value is built for the ones that\n    // are wrong\n    json_document good = json_document::parse(R\"({\"id\": 1})\");\n    json_document bad = json_document::parse(\"[1, 2, 3]\");\n    json_document failed = json_document::parse(\"not json\", /* allow_exceptions */ false);\n\n    for (const json_view v :\n            {\n                good.root(), bad.root(), failed.root()\n            })\n    {\n        if (v.is_object())\n        {\n            std::cout << \"ok\\n\";\n        }\n        else\n        {\n            std::cout << \"expected an object, got \" << v.type_name() << '\\n';\n        }\n    }\n}\n

Output:

ok\nexpected an object, got array\nexpected an object, got discarded\n
"},{"location":"api/basic_json_view/type_name/#see-also","title":"See also","text":"
  • type - return the type of the value
  • BasicJsonType::type_name - the corresponding function of basic_json
"},{"location":"api/basic_json_view/type_name/#version-history","title":"Version history","text":"
  • Added in version 3.13.0 unreleased.
"},{"location":"api/basic_json_view/value/","title":"nlohmann::basic_json_view::value","text":"
// (1)\ntemplate<typename T>\nT value(string_view_t key, const T& default_value) const;\nstring_t value(string_view_t key, const char* default_value) const;\n\n// (2)\ntemplate<typename T>\nT value(const json_pointer& ptr, const T& default_value) const;\nstring_t value(const json_pointer& ptr, const char* default_value) const;\n
  1. Returns the value of the object member with key key \u2014 the first one, should the key occur more than once (see Notes on duplicate keys) \u2014 converted to T, or default_value if there is no such member.
  2. Returns the value a JSON pointer ptr refers to, starting at this value, converted to T, or default_value if ptr cannot be resolved.

Both overloads have a dedicated const char* overload, so v.value(key, \"default\") (and the JSON pointer equivalent) deduce string_t, not const char*, for their return type and for the comparison used to pick between key and default_value.

"},{"location":"api/basic_json_view/value/#template-parameters","title":"Template parameters","text":"T the type to convert the found value to; also the type of default_value"},{"location":"api/basic_json_view/value/#parameters","title":"Parameters","text":"key (in) object key of the element to access ptr (in) JSON pointer to the element to access default_value (in) the value to return if key/ptr resolves to no value"},{"location":"api/basic_json_view/value/#return-value","title":"Return value","text":"
  1. the first member with key key, converted to T, or default_value
  2. the value ptr resolves to, converted to T, or default_value
"},{"location":"api/basic_json_view/value/#exception-safety","title":"Exception safety","text":"

Strong guarantee: there are no changes to the view or the document it refers to.

"},{"location":"api/basic_json_view/value/#exceptions","title":"Exceptions","text":"
  1. Throws type_error.306 if the value is not an object \u2014 the same exception, with the same message, that BasicJsonType::value throws for the same call. If a member with key key is found, throws whatever converting it to T throws (typically type_error.302, with the same message BasicJsonType::value throws for the same mismatch); a missing member never throws.
  2. Throws type_error.306 if this value \u2014 not the value ptr resolves to \u2014 is neither an object nor an array. Throws parse_error.106 or parse_error.109 if ptr contains a malformed array index. If ptr resolves to a value, throws whatever converting it to T throws. Every other way ptr can fail to resolve \u2014 a missing key, an out-of-range or \"-\" array index, an unresolvable token on a primitive \u2014 yields default_value instead of throwing, exactly as BasicJsonType::value catches out_of_range and returns default_value.

None of these exceptions carry a JSON_DIAGNOSTICS path: the view has no BasicJsonType value to point at, so the exception is created without one, even if BasicJsonType was built with JSON_DIAGNOSTICS enabled.

"},{"location":"api/basic_json_view/value/#complexity","title":"Complexity","text":"
  1. Linear in the number of members: as for operator[], members are compared one after another, in document order, stopping at the first match. Plus the complexity of converting the found member to T (see get). Objects with 128 or more members get a hash index of their keys while parsing, so that a lookup in them takes constant time on average.
  2. Linear in the number of reference tokens of ptr and, for each token, in the number of members of the object at that level or the index into the array \u2014 as for the operator[] and at overloads that take a JSON pointer. Plus the complexity of converting the resolved value to T.
"},{"location":"api/basic_json_view/value/#notes","title":"Notes","text":"

Duplicate keys: the first member wins

If the source text repeats a key, this resolves to the first member with it, not to the last one that materialize() and parse() keep. See the Notes on duplicate keys of operator[] and Duplicate keys for the reasons and for how to get the last value.

Differences to at and operator[]

Unlike at, this function does not throw if key/ptr resolves to no value. Unlike operator[], it never returns a discarded view \u2014 it always returns a T \u2014 and it is available on any view, since it never needs to insert a missing element the way the non-const BasicJsonType::operator[] would.

Which values can be asked

As for BasicJsonType::value, the key overload (1) requires an object, and the JSON pointer overload (2) an object or an array.

"},{"location":"api/basic_json_view/value/#examples","title":"Examples","text":"Example: (1) access specified object element with default value

The example below reads a couple of optional configuration fields with a default, so that a missing key never needs a try/catch of its own.

#include <iostream>\n#include <nlohmann/json_view.hpp>\n#include <string>\n\nusing nlohmann::json_document;\nusing nlohmann::json_view;\n\nint main()\n{\n    json_document doc = json_document::parse(R\"({\"server\": {\"host\": \"localhost\"}})\");\n    const json_view server = doc.root()[\"server\"];\n\n    // \"port\" is missing -- value() returns the default instead of\n    // throwing, so optional configuration fields never need their own\n    // try/catch\n    std::cout << server.value(\"host\", std::string(\"0.0.0.0\")) << '\\n';\n    std::cout << server.value(\"port\", 8080) << '\\n';\n\n    // a present but wrong-typed default still throws -- value() only\n    // replaces \"not found\", not \"wrong type\", exactly as basic_json::value\n    try\n    {\n        static_cast<void>(server.value(\"host\", 0));\n    }\n    catch (const nlohmann::json::type_error& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n}\n

Output:

localhost\n8080\n[json.exception.type_error.302] type must be number, but is string\n
Example: (2) access specified element via JSON pointer with default value

The example below reads an optional, nested configuration value with a default, given as a JSON pointer.

#include <iostream>\n#include <nlohmann/json_view.hpp>\n\nusing nlohmann::json_document;\nusing nlohmann::json_view;\nusing json_pointer = nlohmann::json::json_pointer;\n\nint main()\n{\n    json_document doc = json_document::parse(R\"({\"server\": {\"host\": \"localhost\", \"limits\": {\"connections\": 100}}})\");\n    const json_view config = doc.root();\n\n    // a nested, optional setting read with a default -- no exception, even\n    // though \"timeout\" is missing several levels down\n    std::cout << config.value(json_pointer(\"/server/limits/connections\"), 10) << '\\n';\n    std::cout << config.value(json_pointer(\"/server/limits/timeout\"), 30) << '\\n';\n\n    // an out-of-range array index also falls back to the default\n    json_document list_doc = json_document::parse(R\"({\"servers\": [\"a\", \"b\"]})\");\n    std::cout << list_doc.root().value(json_pointer(\"/servers/5\"), std::string(\"none\")) << '\\n';\n}\n

Output:

100\n30\nnone\n
"},{"location":"api/basic_json_view/value/#see-also","title":"See also","text":"
  • at - access specified element with bounds checking (throws instead of returning a default value)
  • operator[] - access specified element (returns a discarded view instead of a default value)
  • BasicJsonType::value - the corresponding function of basic_json
"},{"location":"api/basic_json_view/value/#version-history","title":"Version history","text":"
  • Added in version 3.13.0 unreleased.
"},{"location":"api/byte_container_with_subtype/","title":"nlohmann::byte_container_with_subtype","text":"
template<typename BinaryType>\nclass byte_container_with_subtype : public BinaryType;\n

This type extends the template parameter BinaryType provided to basic_json with a subtype used by BSON, CBOR, and MessagePack. This type exists so that the user does not have to specify a type themselves with a specific naming scheme in order to override the binary type.

"},{"location":"api/byte_container_with_subtype/#template-parameters","title":"Template parameters","text":"BinaryType container to store bytes (std::vector<std::uint8_t> by default)"},{"location":"api/byte_container_with_subtype/#member-types","title":"Member types","text":"
  • container_type - the type of the underlying container (BinaryType)
  • subtype_type - the type of the subtype (std::uint64_t)
"},{"location":"api/byte_container_with_subtype/#member-functions","title":"Member functions","text":"
  • (constructor)
  • operator== - comparison: equal
  • operator!= - comparison: not equal
  • set_subtype - sets the binary subtype
  • subtype - return the binary subtype
  • has_subtype - return whether the value has a subtype
  • clear_subtype - clears the binary subtype
"},{"location":"api/byte_container_with_subtype/#see-also","title":"See also","text":"
  • Binary values - how binary values and subtypes are handled
  • binary - create a binary array value
  • get_binary - get a reference to the stored binary value
  • binary_t - type for binary arrays
  • Binary formats - formats that can store binary values
"},{"location":"api/byte_container_with_subtype/#version-history","title":"Version history","text":"
  • Added in version 3.8.0.
  • Changed the type of subtypes to std::uint64_t in 3.10.0.
"},{"location":"api/byte_container_with_subtype/byte_container_with_subtype/","title":"nlohmann::byte_container_with_subtype::byte_container_with_subtype","text":"
// (1)\nbyte_container_with_subtype();\n\n// (2)\nbyte_container_with_subtype(const container_type& container);\nbyte_container_with_subtype(container_type&& container);\n\n// (3)\nbyte_container_with_subtype(const container_type& container, subtype_type subtype);\nbyte_container_with_subtype(container_type&& container, subtype_type subtype);\n
  1. Create an empty binary container without a subtype.
  2. Create a binary container without a subtype.
  3. Create a binary container with a subtype.
"},{"location":"api/byte_container_with_subtype/byte_container_with_subtype/#parameters","title":"Parameters","text":"container (in) binary container subtype (in) subtype"},{"location":"api/byte_container_with_subtype/byte_container_with_subtype/#examples","title":"Examples","text":"Example

The example below demonstrates how byte containers can be created.

#include <iostream>\n#include <nlohmann/json.hpp>\n\n// define a byte container based on std::vector\nusing byte_container_with_subtype = nlohmann::byte_container_with_subtype<std::vector<std::uint8_t>>;\n\nusing nlohmann::json;\n\nint main()\n{\n    // (1) create empty container\n    auto c1 = byte_container_with_subtype();\n\n    std::vector<std::uint8_t> bytes = {{0xca, 0xfe, 0xba, 0xbe}};\n\n    // (2) create container\n    auto c2 = byte_container_with_subtype(bytes);\n\n    // (3) create container with subtype\n    auto c3 = byte_container_with_subtype(bytes, 42);\n\n    std::cout << json(c1) << \"\\n\" << json(c2) << \"\\n\" << json(c3) << '\\n';\n}\n

Output:

{\"bytes\":[],\"subtype\":null}\n{\"bytes\":[202,254,186,190],\"subtype\":null}\n{\"bytes\":[202,254,186,190],\"subtype\":42}\n
"},{"location":"api/byte_container_with_subtype/byte_container_with_subtype/#see-also","title":"See also","text":"
  • set_subtype - sets the binary subtype
  • subtype - return the binary subtype
  • has_subtype - return whether the value has a subtype
  • binary - create a binary JSON value
  • Binary Values - the article on binary values
"},{"location":"api/byte_container_with_subtype/byte_container_with_subtype/#version-history","title":"Version history","text":"

Added in version 3.8.0.

"},{"location":"api/byte_container_with_subtype/clear_subtype/","title":"nlohmann::byte_container_with_subtype::clear_subtype","text":"
void clear_subtype() noexcept;\n

Clears the binary subtype and flags the value as not having a subtype, which has implications for serialization; for instance, MessagePack will prefer the bin family over the ext family.

"},{"location":"api/byte_container_with_subtype/clear_subtype/#exception-safety","title":"Exception safety","text":"

No-throw guarantee: this function never throws exceptions.

"},{"location":"api/byte_container_with_subtype/clear_subtype/#complexity","title":"Complexity","text":"

Constant.

"},{"location":"api/byte_container_with_subtype/clear_subtype/#examples","title":"Examples","text":"Example

The example below demonstrates how clear_subtype can remove subtypes.

#include <iostream>\n#include <nlohmann/json.hpp>\n\n// define a byte container based on std::vector\nusing byte_container_with_subtype = nlohmann::byte_container_with_subtype<std::vector<std::uint8_t>>;\n\nusing nlohmann::json;\n\nint main()\n{\n    std::vector<std::uint8_t> bytes = {{0xca, 0xfe, 0xba, 0xbe}};\n\n    // create container with subtype\n    auto c1 = byte_container_with_subtype(bytes, 42);\n\n    std::cout << \"before calling clear_subtype(): \" << json(c1) << '\\n';\n\n    c1.clear_subtype();\n\n    std::cout << \"after calling clear_subtype(): \" << json(c1) << '\\n';\n}\n

Output:

before calling clear_subtype(): {\"bytes\":[202,254,186,190],\"subtype\":42}\nafter calling clear_subtype(): {\"bytes\":[202,254,186,190],\"subtype\":null}\n
"},{"location":"api/byte_container_with_subtype/clear_subtype/#see-also","title":"See also","text":"
  • Binary values - how binary values and subtypes are handled
  • set_subtype - sets the binary subtype
  • has_subtype - return whether the value has a subtype
  • subtype - return the binary subtype
"},{"location":"api/byte_container_with_subtype/clear_subtype/#version-history","title":"Version history","text":"

Added in version 3.8.0.

"},{"location":"api/byte_container_with_subtype/has_subtype/","title":"nlohmann::byte_container_with_subtype::has_subtype","text":"
constexpr bool has_subtype() const noexcept;\n

Returns whether the value has a subtype.

"},{"location":"api/byte_container_with_subtype/has_subtype/#return-value","title":"Return value","text":"

whether the value has a subtype

"},{"location":"api/byte_container_with_subtype/has_subtype/#exception-safety","title":"Exception safety","text":"

No-throw guarantee: this function never throws exceptions.

"},{"location":"api/byte_container_with_subtype/has_subtype/#complexity","title":"Complexity","text":"

Constant.

"},{"location":"api/byte_container_with_subtype/has_subtype/#examples","title":"Examples","text":"Example

The example below demonstrates how has_subtype can check whether a subtype was set.

#include <iostream>\n#include <nlohmann/json.hpp>\n\n// define a byte container based on std::vector\nusing byte_container_with_subtype = nlohmann::byte_container_with_subtype<std::vector<std::uint8_t>>;\n\nint main()\n{\n    std::vector<std::uint8_t> bytes = {{0xca, 0xfe, 0xba, 0xbe}};\n\n    // create container\n    auto c1 = byte_container_with_subtype(bytes);\n\n    // create container with subtype\n    auto c2 = byte_container_with_subtype(bytes, 42);\n\n    std::cout << std::boolalpha << \"c1.has_subtype() = \" << c1.has_subtype()\n              << \"\\nc2.has_subtype() = \" << c2.has_subtype() << '\\n';\n}\n

Output:

c1.has_subtype() = false\nc2.has_subtype() = true\n
"},{"location":"api/byte_container_with_subtype/has_subtype/#see-also","title":"See also","text":"
  • Binary values - how binary values and subtypes are handled
  • set_subtype - sets the binary subtype
  • clear_subtype - clears the binary subtype
  • subtype - return the binary subtype
"},{"location":"api/byte_container_with_subtype/has_subtype/#version-history","title":"Version history","text":"

Added in version 3.8.0.

"},{"location":"api/byte_container_with_subtype/operator_eq/","title":"nlohmann::byte_container_with_subtype::operator==","text":"
bool operator==(const byte_container_with_subtype& rhs) const;\n

Compares two byte containers for equality by comparing (1) the underlying binary data (the BinaryType base, compared with BinaryType's own operator==) and (2) the subtype information \u2014 both containers must either have no subtype, or have a subtype and the same subtype value.

"},{"location":"api/byte_container_with_subtype/operator_eq/#parameters","title":"Parameters","text":"rhs (in) byte container to compare *this with"},{"location":"api/byte_container_with_subtype/operator_eq/#return-value","title":"Return value","text":"

whether *this and rhs are equal

"},{"location":"api/byte_container_with_subtype/operator_eq/#complexity","title":"Complexity","text":"

Linear in the size of the compared containers.

"},{"location":"api/byte_container_with_subtype/operator_eq/#examples","title":"Examples","text":"Example

The example below demonstrates comparing byte containers with and without subtypes.

#include <iostream>\n#include <nlohmann/json.hpp>\n\n// define a byte container based on std::vector\nusing byte_container_with_subtype = nlohmann::byte_container_with_subtype<std::vector<std::uint8_t>>;\n\nint main()\n{\n    std::vector<std::uint8_t> bytes = {{0xca, 0xfe, 0xba, 0xbe}};\n\n    // create containers without and with a subtype\n    auto c1 = byte_container_with_subtype(bytes);\n    auto c2 = byte_container_with_subtype(bytes);\n    auto c3 = byte_container_with_subtype(bytes, 42);\n    auto c4 = byte_container_with_subtype(bytes, 42);\n    auto c5 = byte_container_with_subtype(bytes, 23);\n\n    std::cout << std::boolalpha\n              << \"c1 == c2: \" << (c1 == c2) << '\\n'\n              << \"c1 == c3: \" << (c1 == c3) << '\\n'\n              << \"c3 == c4: \" << (c3 == c4) << '\\n'\n              << \"c3 == c5: \" << (c3 == c5) << '\\n';\n}\n

Output:

c1 == c2: true\nc1 == c3: false\nc3 == c4: true\nc3 == c5: false\n
"},{"location":"api/byte_container_with_subtype/operator_eq/#see-also","title":"See also","text":"
  • Binary values - how binary values and subtypes are handled
  • operator!= - comparison: not equal
  • has_subtype - return whether the value has a subtype
  • subtype - return the binary subtype
"},{"location":"api/byte_container_with_subtype/operator_eq/#version-history","title":"Version history","text":"
  • Added in version 3.8.0.
"},{"location":"api/byte_container_with_subtype/operator_ne/","title":"nlohmann::byte_container_with_subtype::operator!=","text":"
bool operator!=(const byte_container_with_subtype& rhs) const;\n

Compares two byte containers for inequality. Returns !(rhs == *this); see operator== for the equality semantics.

"},{"location":"api/byte_container_with_subtype/operator_ne/#parameters","title":"Parameters","text":"rhs (in) byte container to compare *this with"},{"location":"api/byte_container_with_subtype/operator_ne/#return-value","title":"Return value","text":"

whether *this and rhs are not equal

"},{"location":"api/byte_container_with_subtype/operator_ne/#complexity","title":"Complexity","text":"

Linear in the size of the compared containers.

"},{"location":"api/byte_container_with_subtype/operator_ne/#examples","title":"Examples","text":"Example

The example below demonstrates comparing byte containers with and without subtypes.

#include <iostream>\n#include <nlohmann/json.hpp>\n\n// define a byte container based on std::vector\nusing byte_container_with_subtype = nlohmann::byte_container_with_subtype<std::vector<std::uint8_t>>;\n\nint main()\n{\n    std::vector<std::uint8_t> bytes = {{0xca, 0xfe, 0xba, 0xbe}};\n\n    // create containers without and with a subtype\n    auto c1 = byte_container_with_subtype(bytes);\n    auto c2 = byte_container_with_subtype(bytes);\n    auto c3 = byte_container_with_subtype(bytes, 42);\n    auto c4 = byte_container_with_subtype(bytes, 42);\n    auto c5 = byte_container_with_subtype(bytes, 23);\n\n    std::cout << std::boolalpha\n              << \"c1 != c2: \" << (c1 != c2) << '\\n'\n              << \"c1 != c3: \" << (c1 != c3) << '\\n'\n              << \"c3 != c4: \" << (c3 != c4) << '\\n'\n              << \"c3 != c5: \" << (c3 != c5) << '\\n';\n}\n

Output:

c1 != c2: false\nc1 != c3: true\nc3 != c4: false\nc3 != c5: true\n
"},{"location":"api/byte_container_with_subtype/operator_ne/#see-also","title":"See also","text":"
  • Binary values - how binary values and subtypes are handled
  • operator== - comparison: equal
  • has_subtype - return whether the value has a subtype
  • subtype - return the binary subtype
"},{"location":"api/byte_container_with_subtype/operator_ne/#version-history","title":"Version history","text":"
  • Added in version 3.8.0.
"},{"location":"api/byte_container_with_subtype/set_subtype/","title":"nlohmann::byte_container_with_subtype::set_subtype","text":"
void set_subtype(subtype_type subtype) noexcept;\n

Sets the binary subtype of the value, also flags a binary JSON value as having a subtype, which has implications for serialization.

"},{"location":"api/byte_container_with_subtype/set_subtype/#parameters","title":"Parameters","text":"subtype (in) subtype to set"},{"location":"api/byte_container_with_subtype/set_subtype/#exception-safety","title":"Exception safety","text":"

No-throw guarantee: this function never throws exceptions.

"},{"location":"api/byte_container_with_subtype/set_subtype/#complexity","title":"Complexity","text":"

Constant.

"},{"location":"api/byte_container_with_subtype/set_subtype/#examples","title":"Examples","text":"Example

The example below demonstrates how a subtype can be set with set_subtype.

#include <iostream>\n#include <nlohmann/json.hpp>\n\n// define a byte container based on std::vector\nusing byte_container_with_subtype = nlohmann::byte_container_with_subtype<std::vector<std::uint8_t>>;\n\nusing nlohmann::json;\n\nint main()\n{\n    std::vector<std::uint8_t> bytes = {{0xca, 0xfe, 0xba, 0xbe}};\n\n    // create container without subtype\n    auto c = byte_container_with_subtype(bytes);\n\n    std::cout << \"before calling set_subtype(42): \" << json(c) << '\\n';\n\n    // set the subtype\n    c.set_subtype(42);\n\n    std::cout << \"after calling set_subtype(42): \" << json(c) << '\\n';\n}\n

Output:

before calling set_subtype(42): {\"bytes\":[202,254,186,190],\"subtype\":null}\nafter calling set_subtype(42): {\"bytes\":[202,254,186,190],\"subtype\":42}\n
"},{"location":"api/byte_container_with_subtype/set_subtype/#see-also","title":"See also","text":"
  • Binary values - how binary values and subtypes are handled
  • subtype - return the binary subtype
  • has_subtype - return whether the value has a subtype
  • clear_subtype - clears the binary subtype
"},{"location":"api/byte_container_with_subtype/set_subtype/#version-history","title":"Version history","text":"

Added in version 3.8.0.

"},{"location":"api/byte_container_with_subtype/subtype/","title":"nlohmann::byte_container_with_subtype::subtype","text":"
constexpr subtype_type subtype() const noexcept;\n

Returns the numerical subtype of the value if it has a subtype. If it does not have a subtype, this function will return subtype_type(-1) as a sentinel value.

"},{"location":"api/byte_container_with_subtype/subtype/#return-value","title":"Return value","text":"

the numerical subtype of the binary value, or subtype_type(-1) if no subtype is set

"},{"location":"api/byte_container_with_subtype/subtype/#exception-safety","title":"Exception safety","text":"

No-throw guarantee: this function never throws exceptions.

"},{"location":"api/byte_container_with_subtype/subtype/#complexity","title":"Complexity","text":"

Constant.

"},{"location":"api/byte_container_with_subtype/subtype/#examples","title":"Examples","text":"Example

The example below demonstrates how the subtype can be retrieved with subtype. Note how subtype_type(-1) is returned for container c1.

#include <iostream>\n#include <nlohmann/json.hpp>\n\n// define a byte container based on std::vector\nusing byte_container_with_subtype = nlohmann::byte_container_with_subtype<std::vector<std::uint8_t>>;\n\nint main()\n{\n    std::vector<std::uint8_t> bytes = {{0xca, 0xfe, 0xba, 0xbe}};\n\n    // create container\n    auto c1 = byte_container_with_subtype(bytes);\n\n    // create container with subtype\n    auto c2 = byte_container_with_subtype(bytes, 42);\n\n    std::cout << \"c1.subtype() = \" << c1.subtype()\n              << \"\\nc2.subtype() = \" << c2.subtype() << '\\n';\n\n    // in case no subtype is set, return special value\n    assert(c1.subtype() == static_cast<byte_container_with_subtype::subtype_type>(-1));\n}\n

Output:

c1.subtype() = 18446744073709551615\nc2.subtype() = 42\n
"},{"location":"api/byte_container_with_subtype/subtype/#see-also","title":"See also","text":"
  • Binary values - how binary values and subtypes are handled
  • set_subtype - sets the binary subtype
  • has_subtype - return whether the value has a subtype
  • clear_subtype - clears the binary subtype
"},{"location":"api/byte_container_with_subtype/subtype/#version-history","title":"Version history","text":"
  • Added in version 3.8.0
  • Fixed return value to properly return subtype_type(-1) as documented in version 3.10.0.
"},{"location":"api/json_pointer/","title":"nlohmann::json_pointer","text":"
template<typename RefStringType>\nclass json_pointer;\n

A JSON pointer defines a string syntax for identifying a specific value within a JSON document. It can be used with functions at and operator[]. Furthermore, JSON pointers are the base for JSON patches.

"},{"location":"api/json_pointer/#template-parameters","title":"Template parameters","text":"RefStringType the string type used for the reference tokens making up the JSON pointer

Deprecation

For backwards compatibility RefStringType may also be a specialization of basic_json in which case string_t will be deduced as basic_json::string_t. This feature is deprecated and may be removed in a future major version.

See the migration guide for how to update existing code.

A JSON pointer is internally a sequence of reference tokens. front, pop_front, and push_front act on the first reference token, whereas back, pop_back, and push_back act on the last one. parent_pointer returns a new JSON pointer with the last reference token removed (like a non-mutating pop_back):

flowchart LR\n    A[\"a\"] --> B[\"b\"] --> C[\"c\"]\n\n    front[\"front() / pop_front() / push_front()\"] -.-> A\n    back[\"back() / pop_back() / push_back()\"] -.-> C\n    parent[\"parent_pointer() returns /a/b\"] -.-> B

Boxes are the reference tokens in order; dotted arrows show which token each member function reads, removes, or adds to.

The diagram shows the reference tokens of the JSON pointer /a/b/c.

"},{"location":"api/json_pointer/#member-types","title":"Member types","text":"
  • string_t - the string type used for the reference tokens
"},{"location":"api/json_pointer/#member-functions","title":"Member functions","text":"
  • (constructor)
  • to_string - return a string representation of the JSON pointer
  • operator string_t - return a string representation of the JSON pointer (deprecated)
  • operator== - compare: equal
  • operator!= - compare: not equal
  • operator<=> - compare: 3-way (C++20)
  • operator/= - append to the end of the JSON pointer
  • operator/ - create JSON Pointer by appending
  • parent_pointer - returns the parent of this JSON pointer
  • pop_back - remove the last reference token
  • back - return last reference token
  • push_back - append an unescaped token at the end of the pointer
  • pop_front - remove the first reference token
  • front - return first reference token
  • push_front - append an unescaped token at the start of the pointer
  • empty - return whether the pointer points to the root document
"},{"location":"api/json_pointer/#literals","title":"Literals","text":"
  • operator\"\"_json_pointer - user-defined string literal for JSON pointers
"},{"location":"api/json_pointer/#see-also","title":"See also","text":"
  • RFC 6901 - specification of JSON Pointer
  • JSON Pointer - the article on JSON Pointer support
  • JSON Patch and Diff - patch paths are JSON pointers
"},{"location":"api/json_pointer/#version-history","title":"Version history","text":"
  • Added in version 2.0.0.
  • Changed template parameter from basic_json to string type in version 3.11.0.
"},{"location":"api/json_pointer/back/","title":"nlohmann::json_pointer::back","text":"
const string_t& back() const;\n

Return the last reference token.

"},{"location":"api/json_pointer/back/#return-value","title":"Return value","text":"

Last reference token.

"},{"location":"api/json_pointer/back/#exception-safety","title":"Exception safety","text":"

Strong exception safety: if an exception occurs, the original value stays intact.

"},{"location":"api/json_pointer/back/#exceptions","title":"Exceptions","text":"

Throws out_of_range.405 if the JSON pointer has no parent.

"},{"location":"api/json_pointer/back/#complexity","title":"Complexity","text":"

Constant.

"},{"location":"api/json_pointer/back/#examples","title":"Examples","text":"Example

The example shows the usage of back.

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // different JSON Pointers\n    json::json_pointer ptr1(\"/foo\");\n    json::json_pointer ptr2(\"/foo/0\");\n\n    // call empty()\n    std::cout << \"last reference token of \\\"\" << ptr1 << \"\\\" is \\\"\" << ptr1.back() << \"\\\"\\n\"\n              << \"last reference token of \\\"\" << ptr2 << \"\\\" is \\\"\" << ptr2.back() << \"\\\"\" << '\\n';\n}\n

Output:

last reference token of \"/foo\" is \"foo\"\nlast reference token of \"/foo/0\" is \"0\"\n
"},{"location":"api/json_pointer/back/#see-also","title":"See also","text":"
  • front - return first reference token
  • pop_back - remove the last reference token
  • push_back - append an unescaped token at the end of the pointer
  • parent_pointer - returns the parent of this JSON pointer
"},{"location":"api/json_pointer/back/#version-history","title":"Version history","text":"
  • Added in version 3.6.0.
  • Changed return type to string_t in version 3.11.0.
"},{"location":"api/json_pointer/empty/","title":"nlohmann::json_pointer::empty","text":"
bool empty() const noexcept;\n

Return whether the pointer points to the root document.

"},{"location":"api/json_pointer/empty/#return-value","title":"Return value","text":"

true iff the JSON pointer points to the root document.

"},{"location":"api/json_pointer/empty/#exception-safety","title":"Exception safety","text":"

No-throw guarantee: this function never throws exceptions.

"},{"location":"api/json_pointer/empty/#complexity","title":"Complexity","text":"

Constant.

"},{"location":"api/json_pointer/empty/#examples","title":"Examples","text":"Example

The example shows the result of empty for different JSON Pointers.

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // different JSON Pointers\n    json::json_pointer ptr0;\n    json::json_pointer ptr1(\"\");\n    json::json_pointer ptr2(\"/foo\");\n    json::json_pointer ptr3(\"/foo/0\");\n\n    // call empty()\n    std::cout << std::boolalpha\n              << \"\\\"\" << ptr0 << \"\\\": \" << ptr0.empty() << '\\n'\n              << \"\\\"\" << ptr1 << \"\\\": \" << ptr1.empty() << '\\n'\n              << \"\\\"\" << ptr2 << \"\\\": \" << ptr2.empty() << '\\n'\n              << \"\\\"\" << ptr3 << \"\\\": \" << ptr3.empty() << '\\n';\n}\n

Output:

\"\": true\n\"\": true\n\"/foo\": false\n\"/foo/0\": false\n
"},{"location":"api/json_pointer/empty/#see-also","title":"See also","text":"
  • front - return first reference token
  • back - return last reference token
  • to_string - return a string representation of the JSON pointer
"},{"location":"api/json_pointer/empty/#version-history","title":"Version history","text":"

Added in version 3.6.0.

"},{"location":"api/json_pointer/front/","title":"nlohmann::json_pointer::front","text":"
const string_t& front() const;\n

Return the first reference token.

"},{"location":"api/json_pointer/front/#return-value","title":"Return value","text":"

First reference token.

"},{"location":"api/json_pointer/front/#exception-safety","title":"Exception safety","text":"

Strong exception safety: if an exception occurs, the original value stays intact.

"},{"location":"api/json_pointer/front/#exceptions","title":"Exceptions","text":"

Throws out_of_range.405 if the JSON pointer has no parent.

"},{"location":"api/json_pointer/front/#complexity","title":"Complexity","text":"

Constant.

"},{"location":"api/json_pointer/front/#examples","title":"Examples","text":"Example

The example shows the usage of front.

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // different JSON Pointers\n    json::json_pointer ptr1(\"/foo\");\n    json::json_pointer ptr2(\"/foo/0\");\n\n    // call empty()\n    std::cout << \"first reference token of \\\"\" << ptr1 << \"\\\" is \\\"\" << ptr1.front() << \"\\\"\\n\"\n              << \"first reference token of \\\"\" << ptr2 << \"\\\" is \\\"\" << ptr2.front() << \"\\\"\" << '\\n';\n}\n

Output:

first reference token of \"/foo\" is \"foo\"\nfirst reference token of \"/foo/0\" is \"foo\"\n
"},{"location":"api/json_pointer/front/#see-also","title":"See also","text":"
  • back - return last reference token
  • pop_front - remove the first reference token
  • push_front - append an unescaped token at the start of the pointer
"},{"location":"api/json_pointer/front/#version-history","title":"Version history","text":"
  • Added in version 3.13.0 unreleased.
"},{"location":"api/json_pointer/json_pointer/","title":"nlohmann::json_pointer::json_pointer","text":"
explicit json_pointer(const string_t& s = \"\");\n

Create a JSON pointer according to the syntax described in Section 3 of RFC6901.

"},{"location":"api/json_pointer/json_pointer/#parameters","title":"Parameters","text":"s (in) string representing the JSON pointer; if omitted, the empty string is assumed which references the whole JSON value"},{"location":"api/json_pointer/json_pointer/#exception-safety","title":"Exception safety","text":"

Strong guarantee: if an exception is thrown, there are no changes to any JSON pointer.

"},{"location":"api/json_pointer/json_pointer/#exceptions","title":"Exceptions","text":"
  • Throws parse_error.107 if the given JSON pointer s is nonempty and does not begin with a slash (/); see example below.
  • Throws parse_error.108 if a tilde (~) in the given JSON pointer s is not followed by 0 (representing ~) or 1 (representing /); see example below.
"},{"location":"api/json_pointer/json_pointer/#complexity","title":"Complexity","text":"

Linear in the length of s.

"},{"location":"api/json_pointer/json_pointer/#examples","title":"Examples","text":"Example

The example shows the construction several valid JSON pointers as well as the exceptional behavior.

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // correct JSON pointers\n    json::json_pointer p1;\n    json::json_pointer p2(\"\");\n    json::json_pointer p3(\"/\");\n    json::json_pointer p4(\"//\");\n    json::json_pointer p5(\"/foo/bar\");\n    json::json_pointer p6(\"/foo/bar/-\");\n    json::json_pointer p7(\"/foo/~0\");\n    json::json_pointer p8(\"/foo/~1\");\n\n    // error: JSON pointer does not begin with a slash\n    try\n    {\n        json::json_pointer p9(\"foo\");\n    }\n    catch (const json::parse_error& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n\n    // error: JSON pointer uses escape symbol ~ not followed by 0 or 1\n    try\n    {\n        json::json_pointer p10(\"/foo/~\");\n    }\n    catch (const json::parse_error& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n\n    // error: JSON pointer uses escape symbol ~ not followed by 0 or 1\n    try\n    {\n        json::json_pointer p11(\"/foo/~3\");\n    }\n    catch (const json::parse_error& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n}\n

Output:

[json.exception.parse_error.107] parse error at byte 1: JSON pointer must be empty or begin with '/' - was: 'foo'\n[json.exception.parse_error.108] parse error: escape character '~' must be followed with '0' or '1'\n[json.exception.parse_error.108] parse error: escape character '~' must be followed with '0' or '1'\n
"},{"location":"api/json_pointer/json_pointer/#see-also","title":"See also","text":"
  • JSON Pointer - the article on JSON Pointer support
  • operator\"\"_json_pointer - user-defined string literal for JSON pointers
"},{"location":"api/json_pointer/json_pointer/#version-history","title":"Version history","text":"
  • Added in version 2.0.0.
  • Changed type of s to string_t in version 3.11.0.
"},{"location":"api/json_pointer/operator_eq/","title":"nlohmann::json_pointer::operator==","text":"
// until C++20\ntemplate<typename RefStringTypeLhs, typename RefStringTypeRhs>\nbool operator==(\n    const json_pointer<RefStringTypeLhs>& lhs,\n    const json_pointer<RefStringTypeRhs>& rhs) noexcept;            // (1)\n\ntemplate<typename RefStringTypeLhs, typename StringType>\nbool operator==(\n    const json_pointer<RefStringTypeLhs>& lhs,\n    const StringType& rhs);                                         // (2)\n\ntemplate<typename RefStringTypeRhs, typename StringType>\nbool operator==(\n    const StringType& lhs,\n    const json_pointer<RefStringTypeRhs>& rhs);                     // (2)\n\n// since C++20\ntemplate<typename RefStringTypeRhs>\nbool operator==(\n    const json_pointer<RefStringTypeRhs>& rhs) const noexcept;      // (1)\n\nbool operator==(const string_t& rhs) const;                         // (2)\n
  1. Compares two JSON pointers for equality by comparing their reference tokens.

  2. Compares a JSON pointer and a string or a string and a JSON pointer for equality by converting the string to a JSON pointer and comparing the JSON pointers according to 1.

"},{"location":"api/json_pointer/operator_eq/#template-parameters","title":"Template parameters","text":"RefStringTypeLhs, RefStringTypeRhs the string type of the left-hand side or right-hand side JSON pointer, respectively StringType the string type derived from the json_pointer operand (json_pointer::string_t)"},{"location":"api/json_pointer/operator_eq/#parameters","title":"Parameters","text":"lhs (in) first value to consider rhs (in) second value to consider"},{"location":"api/json_pointer/operator_eq/#return-value","title":"Return value","text":"

whether the values lhs/*this and rhs are equal

"},{"location":"api/json_pointer/operator_eq/#exception-safety","title":"Exception safety","text":"
  1. No-throw guarantee: this function never throws exceptions.
  2. Strong exception safety: if an exception occurs, the original value stays intact.
"},{"location":"api/json_pointer/operator_eq/#exceptions","title":"Exceptions","text":"
  1. (none)
  2. The function can throw the following exceptions:
  3. Throws parse_error.107 if the given JSON pointer s is nonempty and does not begin with a slash (/); see example below.
  4. Throws parse_error.108 if a tilde (~) in the given JSON pointer s is not followed by 0 (representing ~) or 1 (representing /); see example below.
"},{"location":"api/json_pointer/operator_eq/#complexity","title":"Complexity","text":"

Constant if lhs and rhs differ in the number of reference tokens, otherwise linear in the number of reference tokens.

"},{"location":"api/json_pointer/operator_eq/#notes","title":"Notes","text":"

Deprecation

Overload 2 is deprecated and will be removed in a future major version release.

See the migration guide for how to update existing code.

"},{"location":"api/json_pointer/operator_eq/#examples","title":"Examples","text":"Example: (1) Comparing JSON pointers

The example demonstrates comparing JSON pointers.

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // different JSON pointers\n    json::json_pointer ptr0;\n    json::json_pointer ptr1(\"\");\n    json::json_pointer ptr2(\"/foo\");\n\n    // compare JSON pointers\n    std::cout << std::boolalpha\n              << \"\\\"\" << ptr0 << \"\\\" == \\\"\" << ptr0 << \"\\\": \" << (ptr0 == ptr0) << '\\n'\n              << \"\\\"\" << ptr0 << \"\\\" == \\\"\" << ptr1 << \"\\\": \" << (ptr0 == ptr1) << '\\n'\n              << \"\\\"\" << ptr1 << \"\\\" == \\\"\" << ptr2 << \"\\\": \" << (ptr1 == ptr2) << '\\n'\n              << \"\\\"\" << ptr2 << \"\\\" == \\\"\" << ptr2 << \"\\\": \" << (ptr2 == ptr2) << '\\n';\n}\n

Output:

\"\" == \"\": true\n\"\" == \"\": true\n\"\" == \"/foo\": false\n\"/foo\" == \"/foo\": true\n
Example: (2) Comparing JSON pointers and strings

The example demonstrates comparing JSON pointers and strings, and when doing so may raise an exception.

#include <exception>\n#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // different JSON pointers\n    json::json_pointer ptr0;\n    json::json_pointer ptr1(\"\");\n    json::json_pointer ptr2(\"/foo\");\n\n    // different strings\n    std::string str0(\"\");\n    std::string str1(\"/foo\");\n    std::string str2(\"bar\");\n\n    // compare JSON pointers and strings\n    std::cout << std::boolalpha\n              << \"\\\"\" << ptr0 << \"\\\" == \\\"\" << str0 << \"\\\": \" << (ptr0 == str0) << '\\n'\n              << \"\\\"\" << str0 << \"\\\" == \\\"\" << ptr1 << \"\\\": \" << (str0 == ptr1) << '\\n'\n              << \"\\\"\" << ptr2 << \"\\\" == \\\"\" << str1 << \"\\\": \" << (ptr2 == str1) << '\\n';\n\n    try\n    {\n        std::cout << \"\\\"\" << str2 << \"\\\" == \\\"\" << ptr2 << \"\\\": \" << (str2 == ptr2) << '\\n';\n    }\n    catch (const json::parse_error& ex)\n    {\n        std::cout << ex.what() << '\\n';\n    }\n}\n

Output:

\"\" == \"\": true\n\"\" == \"\": true\n\"/foo\" == \"/foo\": true\n\"bar\" == \"/foo\": [json.exception.parse_error.107] parse error at byte 1: JSON pointer must be empty or begin with '/' - was: 'bar'\n
"},{"location":"api/json_pointer/operator_eq/#see-also","title":"See also","text":"
  • operator!= - compare for inequality
  • operator<=> - comparison: 3-way (C++20)
"},{"location":"api/json_pointer/operator_eq/#version-history","title":"Version history","text":"
  1. Added in version 2.1.0. Added C++20 member functions in version 3.11.2.
  2. Added for backward compatibility and deprecated in version 3.11.2.
"},{"location":"api/json_pointer/operator_ne/","title":"nlohmann::json_pointer::operator!=","text":"
// until C++20\ntemplate<typename RefStringTypeLhs, typename RefStringTypeRhs>\nbool operator!=(\n    const json_pointer<RefStringTypeLhs>& lhs,\n    const json_pointer<RefStringTypeRhs>& rhs) noexcept;  // (1)\n\ntemplate<typename RefStringTypeLhs, typename StringType>\nbool operator!=(\n    const json_pointer<RefStringTypeLhs>& lhs,\n    const StringType& rhs);                               // (2)\n\ntemplate<typename RefStringTypeRhs, typename StringType>\nbool operator!=(\n    const StringType& lhs,\n    const json_pointer<RefStringTypeRhs>& rhs);           // (2)\n
  1. Compares two JSON pointers for inequality by comparing their reference tokens.

  2. Compares a JSON pointer and a string or a string and a JSON pointer for inequality by converting the string to a JSON pointer and comparing the JSON pointers according to 1.

"},{"location":"api/json_pointer/operator_ne/#template-parameters","title":"Template parameters","text":"RefStringTypeLhs, RefStringTypeRhs the string type of the left-hand side or right-hand side JSON pointer, respectively StringType the string type derived from the json_pointer operand (json_pointer::string_t)"},{"location":"api/json_pointer/operator_ne/#parameters","title":"Parameters","text":"lhs (in) first value to consider rhs (in) second value to consider"},{"location":"api/json_pointer/operator_ne/#return-value","title":"Return value","text":"

whether the values lhs/*this and rhs are not equal

"},{"location":"api/json_pointer/operator_ne/#exception-safety","title":"Exception safety","text":"
  1. No-throw guarantee: this function never throws exceptions.
  2. Strong exception safety: if an exception occurs, the original value stays intact.
"},{"location":"api/json_pointer/operator_ne/#exceptions","title":"Exceptions","text":"
  1. (none)
  2. The function can throw the following exceptions:
  3. Throws parse_error.107 if the given JSON pointer s is nonempty and does not begin with a slash (/); see example below.
  4. Throws parse_error.108 if a tilde (~) in the given JSON pointer s is not followed by 0 (representing ~) or 1 (representing /); see example below.
"},{"location":"api/json_pointer/operator_ne/#complexity","title":"Complexity","text":"

Constant if lhs and rhs differ in the number of reference tokens, otherwise linear in the number of reference tokens.

"},{"location":"api/json_pointer/operator_ne/#notes","title":"Notes","text":"

Operator overload resolution

Since C++20 overload resolution will consider the rewritten candidate generated from operator==.

Deprecation

Overload 2 is deprecated and will be removed in a future major version release.

See the migration guide for how to update existing code.

"},{"location":"api/json_pointer/operator_ne/#examples","title":"Examples","text":"Example: (1) Comparing JSON pointers

The example demonstrates comparing JSON pointers.

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // different JSON pointers\n    json::json_pointer ptr0;\n    json::json_pointer ptr1(\"\");\n    json::json_pointer ptr2(\"/foo\");\n\n    // compare JSON pointers\n    std::cout << std::boolalpha\n              << \"\\\"\" << ptr0 << \"\\\" != \\\"\" << ptr0 << \"\\\": \" << (ptr0 != ptr0) << '\\n'\n              << \"\\\"\" << ptr0 << \"\\\" != \\\"\" << ptr1 << \"\\\": \" << (ptr0 != ptr1) << '\\n'\n              << \"\\\"\" << ptr1 << \"\\\" != \\\"\" << ptr2 << \"\\\": \" << (ptr1 != ptr2) << '\\n'\n              << \"\\\"\" << ptr2 << \"\\\" != \\\"\" << ptr2 << \"\\\": \" << (ptr2 != ptr2) << '\\n';\n}\n

Output:

\"\" != \"\": false\n\"\" != \"\": false\n\"\" != \"/foo\": true\n\"/foo\" != \"/foo\": false\n
Example: (2) Comparing JSON pointers and strings

The example demonstrates comparing JSON pointers and strings, and when doing so may raise an exception.

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // different JSON pointers\n    json::json_pointer ptr0;\n    json::json_pointer ptr1(\"\");\n    json::json_pointer ptr2(\"/foo\");\n\n    // different strings\n    std::string str0(\"\");\n    std::string str1(\"/foo\");\n    std::string str2(\"bar\");\n\n    // compare JSON pointers and strings\n    std::cout << std::boolalpha\n              << \"\\\"\" << ptr0 << \"\\\" != \\\"\" << str0 << \"\\\": \" << (ptr0 != str0) << '\\n'\n              << \"\\\"\" << str0 << \"\\\" != \\\"\" << ptr1 << \"\\\": \" << (str0 != ptr1) << '\\n'\n              << \"\\\"\" << ptr2 << \"\\\" != \\\"\" << str1 << \"\\\": \" << (ptr2 != str1) << '\\n';\n\n    try\n    {\n        std::cout << \"\\\"\" << str2 << \"\\\" != \\\"\" << ptr2 << \"\\\": \" << (str2 != ptr2) << '\\n';\n    }\n    catch (const json::parse_error& ex)\n    {\n        std::cout << ex.what() << '\\n';\n    }\n}\n

Output:

\"\" != \"\": false\n\"\" != \"\": false\n\"/foo\" != \"/foo\": false\n\"bar\" != \"/foo\": [json.exception.parse_error.107] parse error at byte 1: JSON pointer must be empty or begin with '/' - was: 'bar'\n
"},{"location":"api/json_pointer/operator_ne/#see-also","title":"See also","text":"
  • operator== - compare for equality
  • operator<=> - comparison: 3-way (C++20)
"},{"location":"api/json_pointer/operator_ne/#version-history","title":"Version history","text":"
  1. Added in version 2.1.0.
  2. Added for backward compatibility and deprecated in version 3.11.2.
"},{"location":"api/json_pointer/operator_slash/","title":"nlohmann::json_pointer::operator/","text":"
// (1)\njson_pointer operator/(const json_pointer& lhs, const json_pointer& rhs);\n\n// (2)\njson_pointer operator/(const json_pointer& lhs, string_t token);\n\n// (3)\njson_pointer operator/(const json_pointer& lhs, std::size_t array_idx);\n
  1. create a new JSON pointer by appending the right JSON pointer at the end of the left JSON pointer
  2. create a new JSON pointer by appending the unescaped token at the end of the JSON pointer
  3. create a new JSON pointer by appending the array-index-token at the end of the JSON pointer
"},{"location":"api/json_pointer/operator_slash/#parameters","title":"Parameters","text":"lhs (in) JSON pointer rhs (in) JSON pointer to append token (in) reference token to append array_idx (in) array index to append"},{"location":"api/json_pointer/operator_slash/#return-value","title":"Return value","text":"
  1. a new JSON pointer with rhs appended to lhs
  2. a new JSON pointer with unescaped token appended to lhs
  3. a new JSON pointer with array_idx appended to lhs
"},{"location":"api/json_pointer/operator_slash/#exception-safety","title":"Exception safety","text":"

Strong guarantee: if an exception is thrown, there are no changes to any JSON pointer. The operands are not modified; a new JSON pointer is built from a copy of lhs.

"},{"location":"api/json_pointer/operator_slash/#complexity","title":"Complexity","text":"
  1. Linear in the length of lhs and rhs.
  2. Linear in the length of lhs.
  3. Linear in the length of lhs.
"},{"location":"api/json_pointer/operator_slash/#examples","title":"Examples","text":"Example

The example shows the usage of operator/.

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create a JSON pointer\n    json::json_pointer ptr(\"/foo\");\n\n    // append a JSON Pointer\n    std::cout << \"\\\"\" << ptr / json::json_pointer(\"/bar/baz\") << \"\\\"\\n\";\n\n    // append a string\n    std::cout << \"\\\"\" << ptr / \"fob\" << \"\\\"\\n\";\n\n    // append an array index\n    std::cout << \"\\\"\" << ptr / 42 << \"\\\"\" << '\\n';\n}\n

Output:

\"/foo/bar/baz\"\n\"/foo/fob\"\n\"/foo/42\"\n
"},{"location":"api/json_pointer/operator_slash/#see-also","title":"See also","text":"
  • operator/= - append to the end of the JSON pointer
  • push_back - append an unescaped token at the end of the pointer
  • JSON Pointer - the article on JSON Pointer support
"},{"location":"api/json_pointer/operator_slash/#version-history","title":"Version history","text":"
  1. Added in version 3.6.0.
  2. Added in version 3.6.0. Changed type of token to string_t in version 3.11.0.
  3. Added in version 3.6.0.
"},{"location":"api/json_pointer/operator_slasheq/","title":"nlohmann::json_pointer::operator/=","text":"
// (1)\njson_pointer& operator/=(const json_pointer& ptr);\n\n// (2)\njson_pointer& operator/=(string_t token);\n\n// (3)\njson_pointer& operator/=(std::size_t array_idx)\n
  1. append another JSON pointer at the end of this JSON pointer
  2. append an unescaped reference token at the end of this JSON pointer
  3. append an array index at the end of this JSON pointer
"},{"location":"api/json_pointer/operator_slasheq/#parameters","title":"Parameters","text":"ptr (in) JSON pointer to append token (in) reference token to append array_idx (in) array index to append"},{"location":"api/json_pointer/operator_slasheq/#return-value","title":"Return value","text":"
  1. JSON pointer with ptr appended
  2. JSON pointer with token appended without escaping token
  3. JSON pointer with array_idx appended
"},{"location":"api/json_pointer/operator_slasheq/#exception-safety","title":"Exception safety","text":"
  1. Basic guarantee: if an exception is thrown (for instance, if copying a reference token fails), the JSON pointer is left in a valid state, but it may contain some of the reference tokens of ptr.
  2. Strong guarantee: if an exception is thrown, there are no changes to the JSON pointer.
  3. Strong guarantee: if an exception is thrown, there are no changes to the JSON pointer.
"},{"location":"api/json_pointer/operator_slasheq/#complexity","title":"Complexity","text":"
  1. Linear in the length of ptr.
  2. Amortized constant.
  3. Amortized constant.
"},{"location":"api/json_pointer/operator_slasheq/#examples","title":"Examples","text":"Example

The example shows the usage of operator/=.

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create a JSON pointer\n    json::json_pointer ptr(\"/foo\");\n    std::cout << \"\\\"\" << ptr << \"\\\"\\n\";\n\n    // append a JSON Pointer\n    ptr /= json::json_pointer(\"/bar/baz\");\n    std::cout << \"\\\"\" << ptr << \"\\\"\\n\";\n\n    // append a string\n    ptr /= \"fob\";\n    std::cout << \"\\\"\" << ptr << \"\\\"\\n\";\n\n    // append an array index\n    ptr /= 42;\n    std::cout << \"\\\"\" << ptr << \"\\\"\" << '\\n';\n}\n

Output:

\"/foo\"\n\"/foo/bar/baz\"\n\"/foo/bar/baz/fob\"\n\"/foo/bar/baz/fob/42\"\n
"},{"location":"api/json_pointer/operator_slasheq/#see-also","title":"See also","text":"
  • operator/ - create JSON Pointer by appending
  • push_back - append an unescaped token at the end of the pointer
  • JSON Pointer - the article on JSON Pointer support
"},{"location":"api/json_pointer/operator_slasheq/#version-history","title":"Version history","text":"
  1. Added in version 3.6.0.
  2. Added in version 3.6.0. Changed type of token to string_t in version 3.11.0.
  3. Added in version 3.6.0.
"},{"location":"api/json_pointer/operator_spaceship/","title":"nlohmann::json_pointer::operator<=>","text":"
// since C++20\ntemplate<typename RefStringTypeRhs>\nstd::strong_ordering operator<=>(const json_pointer<RefStringTypeRhs>& rhs) const noexcept; // *NOPAD*\n

3-way compares two JSON pointers by lexicographically comparing their sequences of reference tokens: corresponding reference tokens are compared with string_t's own operator<=>, and the first pair of tokens that differs determines the result. If all corresponding reference tokens compare equal, the JSON pointer with fewer reference tokens is ordered first.

"},{"location":"api/json_pointer/operator_spaceship/#template-parameters","title":"Template parameters","text":"RefStringTypeRhs the string type of the right-hand side JSON pointer"},{"location":"api/json_pointer/operator_spaceship/#parameters","title":"Parameters","text":"rhs (in) JSON pointer to compare *this with"},{"location":"api/json_pointer/operator_spaceship/#return-value","title":"Return value","text":"

the std::strong_ordering of the 3-way comparison of *this and rhs

"},{"location":"api/json_pointer/operator_spaceship/#exception-safety","title":"Exception safety","text":"

No-throw guarantee: this function never throws exceptions.

"},{"location":"api/json_pointer/operator_spaceship/#complexity","title":"Complexity","text":"

Linear in the number of reference tokens.

"},{"location":"api/json_pointer/operator_spaceship/#notes","title":"Notes","text":"

Ordering enables use as an associative container key

Together with operator==, operator<=> makes json_pointer a LessThanComparable type, so it can be used as the key type of ordered associative containers such as std::map or std::set.

Before C++20

Without C++20's three-way comparison, json_pointer provides a non-member operator< instead, which orders JSON pointers the same way. JSON pointers can therefore be used as keys of ordered associative containers with any supported C++ standard.

"},{"location":"api/json_pointer/operator_spaceship/#examples","title":"Examples","text":"Example

The example demonstrates 3-way comparing JSON pointers.

#include <compare>\n#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nconst char* to_string(const std::strong_ordering& so)\n{\n    if (std::is_lt(so))\n    {\n        return \"less\";\n    }\n    else if (std::is_gt(so))\n    {\n        return \"greater\";\n    }\n    return \"equal\";\n}\n\nint main()\n{\n    // different JSON pointers\n    json::json_pointer ptr1(\"/a/b\");\n    json::json_pointer ptr2(\"/a/c\");\n    json::json_pointer ptr3(\"/a/b/c\");\n    json::json_pointer ptr4(\"/a/b\");\n\n    // 3-way compare JSON pointers\n    std::cout << \"\\\"\" << ptr1 << \"\\\" <=> \\\"\" << ptr2 << \"\\\": \" << to_string(ptr1 <=> ptr2) << '\\n' // *NOPAD*\n              << \"\\\"\" << ptr1 << \"\\\" <=> \\\"\" << ptr3 << \"\\\": \" << to_string(ptr1 <=> ptr3) << '\\n' // *NOPAD*\n              << \"\\\"\" << ptr1 << \"\\\" <=> \\\"\" << ptr4 << \"\\\": \" << to_string(ptr1 <=> ptr4) << std::endl; // *NOPAD*\n}\n

Output:

\"/a/b\" <=> \"/a/c\": less\n\"/a/b\" <=> \"/a/b/c\": less\n\"/a/b\" <=> \"/a/b\": equal\n
"},{"location":"api/json_pointer/operator_spaceship/#see-also","title":"See also","text":"
  • operator== - compare: equal
  • operator!= - compare: not equal
"},{"location":"api/json_pointer/operator_spaceship/#version-history","title":"Version history","text":"
  • Added in version 3.11.2.
"},{"location":"api/json_pointer/operator_string_t/","title":"nlohmann::json_pointer::operator string_t","text":"
operator string_t() const\n

Return a string representation of the JSON pointer.

"},{"location":"api/json_pointer/operator_string_t/#return-value","title":"Return value","text":"

A string representation of the JSON pointer

"},{"location":"api/json_pointer/operator_string_t/#possible-implementation","title":"Possible implementation","text":"
operator string_t() const\n{\n    return to_string();\n}\n
"},{"location":"api/json_pointer/operator_string_t/#notes","title":"Notes","text":"

Deprecation

This function is deprecated in favor of to_string and will be removed in a future major version release.

See the migration guide for how to update existing code.

"},{"location":"api/json_pointer/operator_string_t/#examples","title":"Examples","text":"Example

The example shows how JSON Pointers can be implicitly converted to strings.

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // different JSON Pointers\n    json::json_pointer ptr1(\"/foo/0\");\n    json::json_pointer ptr2(\"/a~1b\");\n\n    // implicit conversion to string\n    std::string s;\n    s += ptr1;\n    s += \"\\n\";\n    s += ptr2;\n\n    std::cout << s << '\\n';\n}\n

Output:

/foo/0\n/a~1b\n
"},{"location":"api/json_pointer/operator_string_t/#see-also","title":"See also","text":"
  • to_string - return a string representation of the JSON pointer
  • string_t - type for strings
"},{"location":"api/json_pointer/operator_string_t/#version-history","title":"Version history","text":"
  • Added in version 2.0.0.
  • Changed type to string_t and deprecated in version 3.11.0.
"},{"location":"api/json_pointer/parent_pointer/","title":"nlohmann::json_pointer::parent_pointer","text":"
json_pointer parent_pointer() const;\n

Returns the parent of this JSON pointer.

"},{"location":"api/json_pointer/parent_pointer/#return-value","title":"Return value","text":"

Parent of this JSON pointer; in case this JSON pointer is the root, the root itself is returned.

"},{"location":"api/json_pointer/parent_pointer/#exception-safety","title":"Exception safety","text":"

Strong exception safety: if an exception occurs, the original value stays intact. The function is not noexcept and allocates a new JSON pointer, so it can throw std::bad_alloc; it throws no library exceptions.

"},{"location":"api/json_pointer/parent_pointer/#complexity","title":"Complexity","text":"

Linear in the length of the JSON pointer.

"},{"location":"api/json_pointer/parent_pointer/#examples","title":"Examples","text":"Example

The example shows the result of parent_pointer for different JSON Pointers.

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // different JSON Pointers\n    json::json_pointer ptr1(\"\");\n    json::json_pointer ptr2(\"/foo\");\n    json::json_pointer ptr3(\"/foo/0\");\n\n    // call parent_pointer()\n    std::cout << std::boolalpha\n              << \"parent of \\\"\" << ptr1 << \"\\\" is \\\"\" << ptr1.parent_pointer() << \"\\\"\\n\"\n              << \"parent of \\\"\" << ptr2 << \"\\\" is \\\"\" << ptr2.parent_pointer() << \"\\\"\\n\"\n              << \"parent of \\\"\" << ptr3 << \"\\\" is \\\"\" << ptr3.parent_pointer() << \"\\\"\" << '\\n';\n}\n

Output:

parent of \"\" is \"\"\nparent of \"/foo\" is \"\"\nparent of \"/foo/0\" is \"/foo\"\n
"},{"location":"api/json_pointer/parent_pointer/#see-also","title":"See also","text":"
  • pop_back - remove the last reference token
  • back - return the last reference token
"},{"location":"api/json_pointer/parent_pointer/#version-history","title":"Version history","text":"

Added in version 3.6.0.

"},{"location":"api/json_pointer/pop_back/","title":"nlohmann::json_pointer::pop_back","text":"
void pop_back();\n

Remove the last reference token.

"},{"location":"api/json_pointer/pop_back/#exception-safety","title":"Exception safety","text":"

Strong exception safety: if an exception occurs, the original value stays intact.

"},{"location":"api/json_pointer/pop_back/#exceptions","title":"Exceptions","text":"

Throws out_of_range.405 if the JSON pointer has no parent.

"},{"location":"api/json_pointer/pop_back/#complexity","title":"Complexity","text":"

Constant.

"},{"location":"api/json_pointer/pop_back/#examples","title":"Examples","text":"Example

The example shows the usage of pop_back.

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create empty JSON Pointer\n    json::json_pointer ptr(\"/foo/bar/baz\");\n    std::cout << \"\\\"\" << ptr << \"\\\"\\n\";\n\n    // call pop_back()\n    ptr.pop_back();\n    std::cout << \"\\\"\" << ptr << \"\\\"\\n\";\n\n    ptr.pop_back();\n    std::cout << \"\\\"\" << ptr << \"\\\"\\n\";\n\n    ptr.pop_back();\n    std::cout << \"\\\"\" << ptr << \"\\\"\\n\";\n}\n

Output:

\"/foo/bar/baz\"\n\"/foo/bar\"\n\"/foo\"\n\"\"\n
"},{"location":"api/json_pointer/pop_back/#see-also","title":"See also","text":"
  • back - return last reference token
  • push_back - append an unescaped token at the end of the pointer
  • parent_pointer - returns the parent of this JSON pointer
"},{"location":"api/json_pointer/pop_back/#version-history","title":"Version history","text":"

Added in version 3.6.0.

"},{"location":"api/json_pointer/pop_front/","title":"nlohmann::json_pointer::pop_front","text":"
void pop_front();\n

Remove the first reference token.

"},{"location":"api/json_pointer/pop_front/#exception-safety","title":"Exception safety","text":"

Strong exception safety: if an exception occurs, the original value stays intact.

"},{"location":"api/json_pointer/pop_front/#exceptions","title":"Exceptions","text":"

Throws out_of_range.405 if the JSON pointer has no parent.

"},{"location":"api/json_pointer/pop_front/#complexity","title":"Complexity","text":"

Linear in the number of reference tokens in the json_pointer.

"},{"location":"api/json_pointer/pop_front/#examples","title":"Examples","text":"Example

The example shows the usage of pop_front.

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create empty JSON Pointer\n    json::json_pointer ptr(\"/foo/bar/baz\");\n    std::cout << \"\\\"\" << ptr << \"\\\"\\n\";\n\n    // call pop_front()\n    ptr.pop_front();\n    std::cout << \"\\\"\" << ptr << \"\\\"\\n\";\n\n    ptr.pop_front();\n    std::cout << \"\\\"\" << ptr << \"\\\"\\n\";\n\n    ptr.pop_front();\n    std::cout << \"\\\"\" << ptr << \"\\\"\\n\";\n}\n

Output:

\"/foo/bar/baz\"\n\"/bar/baz\"\n\"/baz\"\n\"\"\n
"},{"location":"api/json_pointer/pop_front/#see-also","title":"See also","text":"
  • front - return first reference token
  • push_front - append an unescaped token at the start of the pointer
"},{"location":"api/json_pointer/pop_front/#version-history","title":"Version history","text":"
  • Added in version 3.13.0 unreleased.
"},{"location":"api/json_pointer/push_back/","title":"nlohmann::json_pointer::push_back","text":"
void push_back(const string_t& token);\n\nvoid push_back(string_t&& token);\n

Append an unescaped token at the end of the reference pointer.

"},{"location":"api/json_pointer/push_back/#parameters","title":"Parameters","text":"token (in) token to add"},{"location":"api/json_pointer/push_back/#exception-safety","title":"Exception safety","text":"

Strong exception safety: if an exception occurs, the original value stays intact.

"},{"location":"api/json_pointer/push_back/#complexity","title":"Complexity","text":"

Amortized constant.

"},{"location":"api/json_pointer/push_back/#examples","title":"Examples","text":"Example

The example shows the result of push_back for different JSON Pointers.

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create empty JSON Pointer\n    json::json_pointer ptr;\n    std::cout << \"\\\"\" << ptr << \"\\\"\\n\";\n\n    // call push_back()\n    ptr.push_back(\"foo\");\n    std::cout << \"\\\"\" << ptr << \"\\\"\\n\";\n\n    ptr.push_back(\"0\");\n    std::cout << \"\\\"\" << ptr << \"\\\"\\n\";\n\n    ptr.push_back(\"bar\");\n    std::cout << \"\\\"\" << ptr << \"\\\"\\n\";\n}\n

Output:

\"\"\n\"/foo\"\n\"/foo/0\"\n\"/foo/0/bar\"\n
"},{"location":"api/json_pointer/push_back/#see-also","title":"See also","text":"
  • back - return last reference token
  • pop_back - remove the last reference token
  • operator/= - append to the end of the JSON pointer
  • operator/ - create JSON Pointer by appending
"},{"location":"api/json_pointer/push_back/#version-history","title":"Version history","text":"
  • Added in version 3.6.0.
  • Changed type of token to string_t in version 3.11.0.
"},{"location":"api/json_pointer/push_front/","title":"nlohmann::json_pointer::push_front","text":"
void push_front(const string_t& token);\n\nvoid push_front(string_t&& token);\n

Append an unescaped token at the start of the reference pointer.

"},{"location":"api/json_pointer/push_front/#parameters","title":"Parameters","text":"token (in) token to add"},{"location":"api/json_pointer/push_front/#exception-safety","title":"Exception safety","text":"

Basic guarantee: if an exception is thrown (for instance, if copying the reference token fails), the JSON pointer is left in a valid state, but its reference tokens may have changed.

"},{"location":"api/json_pointer/push_front/#complexity","title":"Complexity","text":"

Linear in the number of reference tokens in the json_pointer.

"},{"location":"api/json_pointer/push_front/#examples","title":"Examples","text":"Example

The example shows the result of push_front for different JSON Pointers.

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create empty JSON Pointer\n    json::json_pointer ptr;\n    std::cout << \"\\\"\" << ptr << \"\\\"\\n\";\n\n    // call push_front()\n    ptr.push_front(\"foo\");\n    std::cout << \"\\\"\" << ptr << \"\\\"\\n\";\n\n    ptr.push_front(\"0\");\n    std::cout << \"\\\"\" << ptr << \"\\\"\\n\";\n\n    ptr.push_front(\"bar\");\n    std::cout << \"\\\"\" << ptr << \"\\\"\\n\";\n}\n

Output:

\"\"\n\"/foo\"\n\"/0/foo\"\n\"/bar/0/foo\"\n
"},{"location":"api/json_pointer/push_front/#see-also","title":"See also","text":"
  • front - return first reference token
  • pop_front - remove the first reference token
"},{"location":"api/json_pointer/push_front/#version-history","title":"Version history","text":"
  • Added in version 3.13.0 unreleased.
"},{"location":"api/json_pointer/string_t/","title":"nlohmann::json_pointer::string_t","text":"
using string_t = RefStringType;\n

The string type used for the reference tokens making up the JSON pointer.

See basic_json::string_t for more information.

"},{"location":"api/json_pointer/string_t/#examples","title":"Examples","text":"Example

The example shows the type string_t and its relation to basic_json::string_t.

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    json::json_pointer::string_t s = \"This is a string.\";\n\n    std::cout << s << '\\n';\n\n    std::cout << std::boolalpha << std::is_same<json::json_pointer::string_t, json::string_t>::value << '\\n';\n}\n

Output:

This is a string.\ntrue\n
"},{"location":"api/json_pointer/string_t/#see-also","title":"See also","text":"
  • basic_json::string_t - type used to store JSON strings
  • to_string - return a string representation of the JSON pointer
"},{"location":"api/json_pointer/string_t/#version-history","title":"Version history","text":"
  • Added in version 3.11.0.
"},{"location":"api/json_pointer/to_string/","title":"nlohmann::json_pointer::to_string","text":"
string_t to_string() const;\n

Return a string representation of the JSON pointer.

"},{"location":"api/json_pointer/to_string/#return-value","title":"Return value","text":"

A string representation of the JSON pointer

"},{"location":"api/json_pointer/to_string/#exception-safety","title":"Exception safety","text":"

Strong exception safety: if an exception occurs, the original value stays intact.

"},{"location":"api/json_pointer/to_string/#complexity","title":"Complexity","text":"

Linear in the total length of the reference tokens.

"},{"location":"api/json_pointer/to_string/#notes","title":"Notes","text":"

For each JSON pointer ptr, it holds:

ptr == json_pointer(ptr.to_string());\n
"},{"location":"api/json_pointer/to_string/#examples","title":"Examples","text":"Example

The example shows the result of to_string.

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // different JSON Pointers\n    json::json_pointer ptr1(\"\");\n    json::json_pointer ptr2(\"/foo\");\n    json::json_pointer ptr3(\"/foo/0\");\n    json::json_pointer ptr4(\"/\");\n    json::json_pointer ptr5(\"/a~1b\");\n    json::json_pointer ptr6(\"/c%d\");\n    json::json_pointer ptr7(\"/e^f\");\n    json::json_pointer ptr8(\"/g|h\");\n    json::json_pointer ptr9(\"/i\\\\j\");\n    json::json_pointer ptr10(\"/k\\\"l\");\n    json::json_pointer ptr11(\"/ \");\n    json::json_pointer ptr12(\"/m~0n\");\n\n    std::cout << \"\\\"\" << ptr1.to_string() << \"\\\"\\n\"\n              << \"\\\"\" << ptr2.to_string() << \"\\\"\\n\"\n              << \"\\\"\" << ptr3.to_string() << \"\\\"\\n\"\n              << \"\\\"\" << ptr4.to_string() << \"\\\"\\n\"\n              << \"\\\"\" << ptr5.to_string() << \"\\\"\\n\"\n              << \"\\\"\" << ptr6.to_string() << \"\\\"\\n\"\n              << \"\\\"\" << ptr7.to_string() << \"\\\"\\n\"\n              << \"\\\"\" << ptr8.to_string() << \"\\\"\\n\"\n              << \"\\\"\" << ptr9.to_string() << \"\\\"\\n\"\n              << \"\\\"\" << ptr10.to_string() << \"\\\"\\n\"\n              << \"\\\"\" << ptr11.to_string() << \"\\\"\\n\"\n              << \"\\\"\" << ptr12.to_string() << \"\\\"\" << '\\n';\n}\n

Output:

\"\"\n\"/foo\"\n\"/foo/0\"\n\"/\"\n\"/a~1b\"\n\"/c%d\"\n\"/e^f\"\n\"/g|h\"\n\"/i\\j\"\n\"/k\"l\"\n\"/ \"\n\"/m~0n\"\n
"},{"location":"api/json_pointer/to_string/#see-also","title":"See also","text":"
  • operator string_t - return a string representation of the JSON pointer (deprecated)
  • operator<< - write a JSON pointer to a stream
"},{"location":"api/json_pointer/to_string/#version-history","title":"Version history","text":"
  • Added in version 2.0.0.
  • Changed return type to string_t in version 3.11.0.
"},{"location":"api/json_sax/","title":"nlohmann::json_sax","text":"
template<typename BasicJsonType>\nstruct json_sax;\n

This class describes the SAX interface used by sax_parse. Each function is called in different situations while the input is parsed. The boolean return value informs the parser whether to continue processing the input.

For instance, parsing the JSON text {\"a\": [1, true]} triggers the following callbacks, in order:

sequenceDiagram\n    participant P as Parser\n    participant H as SAX handler\n\n    P->>H: start_object(elements)\n    P->>H: key(\"a\")\n    P->>H: start_array(elements)\n    P->>H: number_unsigned(1)\n    P->>H: boolean(true)\n    P->>H: end_array()\n    P->>H: end_object()

Each arrow is one call from the parser to the SAX handler, from top to bottom in the order the calls happen.

Note elements is passed as std::numeric_limits<std::size_t>::max() (i.e., \"unknown\") for JSON text input; only binary formats such as CBOR or MessagePack may report the actual number of elements in start_object/ start_array. Also note that 1 is reported via number_unsigned rather than number_integer because it has no leading - sign.

"},{"location":"api/json_sax/#template-parameters","title":"Template parameters","text":"BasicJsonType a specialization of basic_json"},{"location":"api/json_sax/#member-types","title":"Member types","text":"
  • number_integer_t - BasicJsonType's type for numbers (integer)
  • number_unsigned_t - BasicJsonType's type for numbers (unsigned)
  • number_float_t - BasicJsonType's type for numbers (floating-point)
  • string_t - BasicJsonType's type for strings
  • binary_t - BasicJsonType's type for binary arrays
"},{"location":"api/json_sax/#member-functions","title":"Member functions","text":"
  • binary (virtual) - a binary value was read
  • boolean (virtual) - a boolean value was read
  • end_array (virtual) - the end of an array was read
  • end_object (virtual) - the end of an object was read
  • key (virtual) - an object key was read
  • null (virtual) - a null value was read
  • number_float (virtual) - a floating-point number was read
  • number_integer (virtual) - an integer number was read
  • number_unsigned (virtual) - an unsigned integer number was read
  • parse_error (virtual) - a parse error occurred
  • start_array (virtual) - the beginning of an array was read
  • start_object (virtual) - the beginning of an object was read
  • string (virtual) - a string value was read
"},{"location":"api/json_sax/#see-also","title":"See also","text":"
  • SAX interface - guide to event-based parsing
  • sax_parse - generate SAX events from an input
  • parse - DOM parsing, with optional parser callbacks
  • Parse exceptions - how parse errors are reported
"},{"location":"api/json_sax/#version-history","title":"Version history","text":"
  • Added in version 3.2.0.
  • Support for binary values (binary_t, binary) added in version 3.8.0.
"},{"location":"api/json_sax/binary/","title":"nlohmann::json_sax::binary","text":"
virtual bool binary(binary_t& val) = 0;\n

A binary value was read.

"},{"location":"api/json_sax/binary/#parameters","title":"Parameters","text":"val (in) binary value"},{"location":"api/json_sax/binary/#return-value","title":"Return value","text":"

Whether parsing should proceed.

"},{"location":"api/json_sax/binary/#notes","title":"Notes","text":"

It is safe to move the passed binary value.

"},{"location":"api/json_sax/binary/#examples","title":"Examples","text":"Example

The example below shows how the SAX interface is used.

#include <iostream>\n#include <iomanip>\n#include <sstream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\n// a simple event consumer that collects string representations of the passed\n// values; note inheriting from json::json_sax_t is not required, but can\n// help not to forget a required function\nclass sax_event_consumer : public json::json_sax_t\n{\n  public:\n    std::vector<std::string> events;\n\n    bool null() override\n    {\n        events.push_back(\"null()\");\n        return true;\n    }\n\n    bool boolean(bool val) override\n    {\n        events.push_back(\"boolean(val=\" + std::string(val ? \"true\" : \"false\") + \")\");\n        return true;\n    }\n\n    bool number_integer(number_integer_t val) override\n    {\n        events.push_back(\"number_integer(val=\" + std::to_string(val) + \")\");\n        return true;\n    }\n\n    bool number_unsigned(number_unsigned_t val) override\n    {\n        events.push_back(\"number_unsigned(val=\" + std::to_string(val) + \")\");\n        return true;\n    }\n\n    bool number_float(number_float_t val, const string_t& s) override\n    {\n        events.push_back(\"number_float(val=\" + std::to_string(val) + \", s=\" + s + \")\");\n        return true;\n    }\n\n    bool string(string_t& val) override\n    {\n        events.push_back(\"string(val=\" + val + \")\");\n        return true;\n    }\n\n    bool start_object(std::size_t elements) override\n    {\n        events.push_back(\"start_object(elements=\" + std::to_string(elements) + \")\");\n        return true;\n    }\n\n    bool end_object() override\n    {\n        events.push_back(\"end_object()\");\n        return true;\n    }\n\n    bool start_array(std::size_t elements) override\n    {\n        events.push_back(\"start_array(elements=\" + std::to_string(elements) + \")\");\n        return true;\n    }\n\n    bool end_array() override\n    {\n        events.push_back(\"end_array()\");\n        return true;\n    }\n\n    bool key(string_t& val) override\n    {\n        events.push_back(\"key(val=\" + val + \")\");\n        return true;\n    }\n\n    bool binary(json::binary_t& val) override\n    {\n        events.push_back(\"binary(val=[...])\");\n        return true;\n    }\n\n    bool parse_error(std::size_t position, const std::string& last_token, const json::exception& ex) override\n    {\n        events.push_back(\"parse_error(position=\" + std::to_string(position) + \", last_token=\" + last_token + \",\\n            ex=\" + std::string(ex.what()) + \")\");\n        return false;\n    }\n};\n\nint main()\n{\n    // CBOR byte string\n    std::vector<std::uint8_t> vec = {{0x44, 0xcA, 0xfe, 0xba, 0xbe}};\n\n    // create a SAX event consumer object\n    sax_event_consumer sec;\n\n    // parse CBOR\n    bool result = json::sax_parse(vec, &sec, json::input_format_t::cbor);\n\n    // output the recorded events\n    for (auto& event : sec.events)\n    {\n        std::cout << event << \"\\n\";\n    }\n\n    // output the result of sax_parse\n    std::cout << \"\\nresult: \" << std::boolalpha << result << '\\n';\n}\n

Output:

binary(val=[...])\n\nresult: true\n
"},{"location":"api/json_sax/binary/#see-also","title":"See also","text":"
  • sax_parse - SAX parser
  • SAX Interface - the SAX interface article
  • Binary Values - the article on binary values
"},{"location":"api/json_sax/binary/#version-history","title":"Version history","text":"
  • Added in version 3.8.0.
"},{"location":"api/json_sax/boolean/","title":"nlohmann::json_sax::boolean","text":"
virtual bool boolean(bool val) = 0;\n

A boolean value was read.

"},{"location":"api/json_sax/boolean/#parameters","title":"Parameters","text":"val (in) boolean value"},{"location":"api/json_sax/boolean/#return-value","title":"Return value","text":"

Whether parsing should proceed.

"},{"location":"api/json_sax/boolean/#examples","title":"Examples","text":"Example

The example below shows how the SAX interface is used.

#include <iostream>\n#include <iomanip>\n#include <sstream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\n// a simple event consumer that collects string representations of the passed\n// values; note inheriting from json::json_sax_t is not required, but can\n// help not to forget a required function\nclass sax_event_consumer : public json::json_sax_t\n{\n  public:\n    std::vector<std::string> events;\n\n    bool null() override\n    {\n        events.push_back(\"null()\");\n        return true;\n    }\n\n    bool boolean(bool val) override\n    {\n        events.push_back(\"boolean(val=\" + std::string(val ? \"true\" : \"false\") + \")\");\n        return true;\n    }\n\n    bool number_integer(number_integer_t val) override\n    {\n        events.push_back(\"number_integer(val=\" + std::to_string(val) + \")\");\n        return true;\n    }\n\n    bool number_unsigned(number_unsigned_t val) override\n    {\n        events.push_back(\"number_unsigned(val=\" + std::to_string(val) + \")\");\n        return true;\n    }\n\n    bool number_float(number_float_t val, const string_t& s) override\n    {\n        events.push_back(\"number_float(val=\" + std::to_string(val) + \", s=\" + s + \")\");\n        return true;\n    }\n\n    bool string(string_t& val) override\n    {\n        events.push_back(\"string(val=\" + val + \")\");\n        return true;\n    }\n\n    bool start_object(std::size_t elements) override\n    {\n        events.push_back(\"start_object(elements=\" + std::to_string(elements) + \")\");\n        return true;\n    }\n\n    bool end_object() override\n    {\n        events.push_back(\"end_object()\");\n        return true;\n    }\n\n    bool start_array(std::size_t elements) override\n    {\n        events.push_back(\"start_array(elements=\" + std::to_string(elements) + \")\");\n        return true;\n    }\n\n    bool end_array() override\n    {\n        events.push_back(\"end_array()\");\n        return true;\n    }\n\n    bool key(string_t& val) override\n    {\n        events.push_back(\"key(val=\" + val + \")\");\n        return true;\n    }\n\n    bool binary(json::binary_t& val) override\n    {\n        events.push_back(\"binary(val=[...])\");\n        return true;\n    }\n\n    bool parse_error(std::size_t position, const std::string& last_token, const json::exception& ex) override\n    {\n        events.push_back(\"parse_error(position=\" + std::to_string(position) + \", last_token=\" + last_token + \",\\n            ex=\" + std::string(ex.what()) + \")\");\n        return false;\n    }\n};\n\nint main()\n{\n    // a JSON text\n    const auto* text = R\"(\n    {\n        \"Image\": {\n            \"Width\":  800,\n            \"Height\": 600,\n            \"Title\":  \"View from 15th Floor\",\n            \"Thumbnail\": {\n                \"Url\":    \"http://www.example.com/image/481989943\",\n                \"Height\": 125,\n                \"Width\":  100\n            },\n            \"Animated\" : false,\n            \"IDs\": [116, 943, 234, -38793],\n            \"DeletionDate\": null,\n            \"Distance\": 12.723374634\n        }\n    }]\n    )\";\n\n    // create a SAX event consumer object\n    sax_event_consumer sec;\n\n    // parse JSON\n    bool result = json::sax_parse(text, &sec);\n\n    // output the recorded events\n    for (auto& event : sec.events)\n    {\n        std::cout << event << \"\\n\";\n    }\n\n    // output the result of sax_parse\n    std::cout << \"\\nresult: \" << std::boolalpha << result << '\\n';\n}\n

Output:

start_object(elements=18446744073709551615)\nkey(val=Image)\nstart_object(elements=18446744073709551615)\nkey(val=Width)\nnumber_unsigned(val=800)\nkey(val=Height)\nnumber_unsigned(val=600)\nkey(val=Title)\nstring(val=View from 15th Floor)\nkey(val=Thumbnail)\nstart_object(elements=18446744073709551615)\nkey(val=Url)\nstring(val=http://www.example.com/image/481989943)\nkey(val=Height)\nnumber_unsigned(val=125)\nkey(val=Width)\nnumber_unsigned(val=100)\nend_object()\nkey(val=Animated)\nboolean(val=false)\nkey(val=IDs)\nstart_array(elements=18446744073709551615)\nnumber_unsigned(val=116)\nnumber_unsigned(val=943)\nnumber_unsigned(val=234)\nnumber_integer(val=-38793)\nend_array()\nkey(val=DeletionDate)\nnull()\nkey(val=Distance)\nnumber_float(val=12.723375, s=12.723374634)\nend_object()\nend_object()\nparse_error(position=460, last_token=12.723374634<U+000A>        }<U+000A>    }],\n            ex=[json.exception.parse_error.101] parse error at line 17, column 6: syntax error while parsing value - unexpected ']'; expected end of input)\n\nresult: false\n
"},{"location":"api/json_sax/boolean/#see-also","title":"See also","text":"
  • sax_parse - SAX parser
  • SAX Interface - the SAX interface article
"},{"location":"api/json_sax/boolean/#version-history","title":"Version history","text":"
  • Added in version 3.2.0.
"},{"location":"api/json_sax/end_array/","title":"nlohmann::json_sax::end_array","text":"
virtual bool end_array() = 0;\n

The end of an array was read.

"},{"location":"api/json_sax/end_array/#return-value","title":"Return value","text":"

Whether parsing should proceed.

"},{"location":"api/json_sax/end_array/#examples","title":"Examples","text":"Example

The example below shows how the SAX interface is used.

#include <iostream>\n#include <iomanip>\n#include <sstream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\n// a simple event consumer that collects string representations of the passed\n// values; note inheriting from json::json_sax_t is not required, but can\n// help not to forget a required function\nclass sax_event_consumer : public json::json_sax_t\n{\n  public:\n    std::vector<std::string> events;\n\n    bool null() override\n    {\n        events.push_back(\"null()\");\n        return true;\n    }\n\n    bool boolean(bool val) override\n    {\n        events.push_back(\"boolean(val=\" + std::string(val ? \"true\" : \"false\") + \")\");\n        return true;\n    }\n\n    bool number_integer(number_integer_t val) override\n    {\n        events.push_back(\"number_integer(val=\" + std::to_string(val) + \")\");\n        return true;\n    }\n\n    bool number_unsigned(number_unsigned_t val) override\n    {\n        events.push_back(\"number_unsigned(val=\" + std::to_string(val) + \")\");\n        return true;\n    }\n\n    bool number_float(number_float_t val, const string_t& s) override\n    {\n        events.push_back(\"number_float(val=\" + std::to_string(val) + \", s=\" + s + \")\");\n        return true;\n    }\n\n    bool string(string_t& val) override\n    {\n        events.push_back(\"string(val=\" + val + \")\");\n        return true;\n    }\n\n    bool start_object(std::size_t elements) override\n    {\n        events.push_back(\"start_object(elements=\" + std::to_string(elements) + \")\");\n        return true;\n    }\n\n    bool end_object() override\n    {\n        events.push_back(\"end_object()\");\n        return true;\n    }\n\n    bool start_array(std::size_t elements) override\n    {\n        events.push_back(\"start_array(elements=\" + std::to_string(elements) + \")\");\n        return true;\n    }\n\n    bool end_array() override\n    {\n        events.push_back(\"end_array()\");\n        return true;\n    }\n\n    bool key(string_t& val) override\n    {\n        events.push_back(\"key(val=\" + val + \")\");\n        return true;\n    }\n\n    bool binary(json::binary_t& val) override\n    {\n        events.push_back(\"binary(val=[...])\");\n        return true;\n    }\n\n    bool parse_error(std::size_t position, const std::string& last_token, const json::exception& ex) override\n    {\n        events.push_back(\"parse_error(position=\" + std::to_string(position) + \", last_token=\" + last_token + \",\\n            ex=\" + std::string(ex.what()) + \")\");\n        return false;\n    }\n};\n\nint main()\n{\n    // a JSON text\n    const auto* text = R\"(\n    {\n        \"Image\": {\n            \"Width\":  800,\n            \"Height\": 600,\n            \"Title\":  \"View from 15th Floor\",\n            \"Thumbnail\": {\n                \"Url\":    \"http://www.example.com/image/481989943\",\n                \"Height\": 125,\n                \"Width\":  100\n            },\n            \"Animated\" : false,\n            \"IDs\": [116, 943, 234, -38793],\n            \"DeletionDate\": null,\n            \"Distance\": 12.723374634\n        }\n    }]\n    )\";\n\n    // create a SAX event consumer object\n    sax_event_consumer sec;\n\n    // parse JSON\n    bool result = json::sax_parse(text, &sec);\n\n    // output the recorded events\n    for (auto& event : sec.events)\n    {\n        std::cout << event << \"\\n\";\n    }\n\n    // output the result of sax_parse\n    std::cout << \"\\nresult: \" << std::boolalpha << result << '\\n';\n}\n

Output:

start_object(elements=18446744073709551615)\nkey(val=Image)\nstart_object(elements=18446744073709551615)\nkey(val=Width)\nnumber_unsigned(val=800)\nkey(val=Height)\nnumber_unsigned(val=600)\nkey(val=Title)\nstring(val=View from 15th Floor)\nkey(val=Thumbnail)\nstart_object(elements=18446744073709551615)\nkey(val=Url)\nstring(val=http://www.example.com/image/481989943)\nkey(val=Height)\nnumber_unsigned(val=125)\nkey(val=Width)\nnumber_unsigned(val=100)\nend_object()\nkey(val=Animated)\nboolean(val=false)\nkey(val=IDs)\nstart_array(elements=18446744073709551615)\nnumber_unsigned(val=116)\nnumber_unsigned(val=943)\nnumber_unsigned(val=234)\nnumber_integer(val=-38793)\nend_array()\nkey(val=DeletionDate)\nnull()\nkey(val=Distance)\nnumber_float(val=12.723375, s=12.723374634)\nend_object()\nend_object()\nparse_error(position=460, last_token=12.723374634<U+000A>        }<U+000A>    }],\n            ex=[json.exception.parse_error.101] parse error at line 17, column 6: syntax error while parsing value - unexpected ']'; expected end of input)\n\nresult: false\n
"},{"location":"api/json_sax/end_array/#see-also","title":"See also","text":"
  • start_array - the beginning of an array was read
  • sax_parse - SAX parser
  • SAX Interface - guide to event-based parsing
"},{"location":"api/json_sax/end_array/#version-history","title":"Version history","text":"
  • Added in version 3.2.0.
"},{"location":"api/json_sax/end_object/","title":"nlohmann::json_sax::end_object","text":"
virtual bool end_object() = 0;\n

The end of an object was read.

"},{"location":"api/json_sax/end_object/#return-value","title":"Return value","text":"

Whether parsing should proceed.

"},{"location":"api/json_sax/end_object/#examples","title":"Examples","text":"Example

The example below shows how the SAX interface is used.

#include <iostream>\n#include <iomanip>\n#include <sstream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\n// a simple event consumer that collects string representations of the passed\n// values; note inheriting from json::json_sax_t is not required, but can\n// help not to forget a required function\nclass sax_event_consumer : public json::json_sax_t\n{\n  public:\n    std::vector<std::string> events;\n\n    bool null() override\n    {\n        events.push_back(\"null()\");\n        return true;\n    }\n\n    bool boolean(bool val) override\n    {\n        events.push_back(\"boolean(val=\" + std::string(val ? \"true\" : \"false\") + \")\");\n        return true;\n    }\n\n    bool number_integer(number_integer_t val) override\n    {\n        events.push_back(\"number_integer(val=\" + std::to_string(val) + \")\");\n        return true;\n    }\n\n    bool number_unsigned(number_unsigned_t val) override\n    {\n        events.push_back(\"number_unsigned(val=\" + std::to_string(val) + \")\");\n        return true;\n    }\n\n    bool number_float(number_float_t val, const string_t& s) override\n    {\n        events.push_back(\"number_float(val=\" + std::to_string(val) + \", s=\" + s + \")\");\n        return true;\n    }\n\n    bool string(string_t& val) override\n    {\n        events.push_back(\"string(val=\" + val + \")\");\n        return true;\n    }\n\n    bool start_object(std::size_t elements) override\n    {\n        events.push_back(\"start_object(elements=\" + std::to_string(elements) + \")\");\n        return true;\n    }\n\n    bool end_object() override\n    {\n        events.push_back(\"end_object()\");\n        return true;\n    }\n\n    bool start_array(std::size_t elements) override\n    {\n        events.push_back(\"start_array(elements=\" + std::to_string(elements) + \")\");\n        return true;\n    }\n\n    bool end_array() override\n    {\n        events.push_back(\"end_array()\");\n        return true;\n    }\n\n    bool key(string_t& val) override\n    {\n        events.push_back(\"key(val=\" + val + \")\");\n        return true;\n    }\n\n    bool binary(json::binary_t& val) override\n    {\n        events.push_back(\"binary(val=[...])\");\n        return true;\n    }\n\n    bool parse_error(std::size_t position, const std::string& last_token, const json::exception& ex) override\n    {\n        events.push_back(\"parse_error(position=\" + std::to_string(position) + \", last_token=\" + last_token + \",\\n            ex=\" + std::string(ex.what()) + \")\");\n        return false;\n    }\n};\n\nint main()\n{\n    // a JSON text\n    const auto* text = R\"(\n    {\n        \"Image\": {\n            \"Width\":  800,\n            \"Height\": 600,\n            \"Title\":  \"View from 15th Floor\",\n            \"Thumbnail\": {\n                \"Url\":    \"http://www.example.com/image/481989943\",\n                \"Height\": 125,\n                \"Width\":  100\n            },\n            \"Animated\" : false,\n            \"IDs\": [116, 943, 234, -38793],\n            \"DeletionDate\": null,\n            \"Distance\": 12.723374634\n        }\n    }]\n    )\";\n\n    // create a SAX event consumer object\n    sax_event_consumer sec;\n\n    // parse JSON\n    bool result = json::sax_parse(text, &sec);\n\n    // output the recorded events\n    for (auto& event : sec.events)\n    {\n        std::cout << event << \"\\n\";\n    }\n\n    // output the result of sax_parse\n    std::cout << \"\\nresult: \" << std::boolalpha << result << '\\n';\n}\n

Output:

start_object(elements=18446744073709551615)\nkey(val=Image)\nstart_object(elements=18446744073709551615)\nkey(val=Width)\nnumber_unsigned(val=800)\nkey(val=Height)\nnumber_unsigned(val=600)\nkey(val=Title)\nstring(val=View from 15th Floor)\nkey(val=Thumbnail)\nstart_object(elements=18446744073709551615)\nkey(val=Url)\nstring(val=http://www.example.com/image/481989943)\nkey(val=Height)\nnumber_unsigned(val=125)\nkey(val=Width)\nnumber_unsigned(val=100)\nend_object()\nkey(val=Animated)\nboolean(val=false)\nkey(val=IDs)\nstart_array(elements=18446744073709551615)\nnumber_unsigned(val=116)\nnumber_unsigned(val=943)\nnumber_unsigned(val=234)\nnumber_integer(val=-38793)\nend_array()\nkey(val=DeletionDate)\nnull()\nkey(val=Distance)\nnumber_float(val=12.723375, s=12.723374634)\nend_object()\nend_object()\nparse_error(position=460, last_token=12.723374634<U+000A>        }<U+000A>    }],\n            ex=[json.exception.parse_error.101] parse error at line 17, column 6: syntax error while parsing value - unexpected ']'; expected end of input)\n\nresult: false\n
"},{"location":"api/json_sax/end_object/#see-also","title":"See also","text":"
  • start_object - the beginning of an object was read
  • key - an object key was read
  • sax_parse - SAX parser
  • SAX Interface - guide to event-based parsing
"},{"location":"api/json_sax/end_object/#version-history","title":"Version history","text":"
  • Added in version 3.2.0.
"},{"location":"api/json_sax/key/","title":"nlohmann::json_sax::key","text":"
virtual bool key(string_t& val) = 0;\n

An object key was read.

"},{"location":"api/json_sax/key/#parameters","title":"Parameters","text":"val (in) object key"},{"location":"api/json_sax/key/#return-value","title":"Return value","text":"

Whether parsing should proceed.

"},{"location":"api/json_sax/key/#notes","title":"Notes","text":"

It is safe to move the passed object key value.

"},{"location":"api/json_sax/key/#examples","title":"Examples","text":"Example

The example below shows how the SAX interface is used.

#include <iostream>\n#include <iomanip>\n#include <sstream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\n// a simple event consumer that collects string representations of the passed\n// values; note inheriting from json::json_sax_t is not required, but can\n// help not to forget a required function\nclass sax_event_consumer : public json::json_sax_t\n{\n  public:\n    std::vector<std::string> events;\n\n    bool null() override\n    {\n        events.push_back(\"null()\");\n        return true;\n    }\n\n    bool boolean(bool val) override\n    {\n        events.push_back(\"boolean(val=\" + std::string(val ? \"true\" : \"false\") + \")\");\n        return true;\n    }\n\n    bool number_integer(number_integer_t val) override\n    {\n        events.push_back(\"number_integer(val=\" + std::to_string(val) + \")\");\n        return true;\n    }\n\n    bool number_unsigned(number_unsigned_t val) override\n    {\n        events.push_back(\"number_unsigned(val=\" + std::to_string(val) + \")\");\n        return true;\n    }\n\n    bool number_float(number_float_t val, const string_t& s) override\n    {\n        events.push_back(\"number_float(val=\" + std::to_string(val) + \", s=\" + s + \")\");\n        return true;\n    }\n\n    bool string(string_t& val) override\n    {\n        events.push_back(\"string(val=\" + val + \")\");\n        return true;\n    }\n\n    bool start_object(std::size_t elements) override\n    {\n        events.push_back(\"start_object(elements=\" + std::to_string(elements) + \")\");\n        return true;\n    }\n\n    bool end_object() override\n    {\n        events.push_back(\"end_object()\");\n        return true;\n    }\n\n    bool start_array(std::size_t elements) override\n    {\n        events.push_back(\"start_array(elements=\" + std::to_string(elements) + \")\");\n        return true;\n    }\n\n    bool end_array() override\n    {\n        events.push_back(\"end_array()\");\n        return true;\n    }\n\n    bool key(string_t& val) override\n    {\n        events.push_back(\"key(val=\" + val + \")\");\n        return true;\n    }\n\n    bool binary(json::binary_t& val) override\n    {\n        events.push_back(\"binary(val=[...])\");\n        return true;\n    }\n\n    bool parse_error(std::size_t position, const std::string& last_token, const json::exception& ex) override\n    {\n        events.push_back(\"parse_error(position=\" + std::to_string(position) + \", last_token=\" + last_token + \",\\n            ex=\" + std::string(ex.what()) + \")\");\n        return false;\n    }\n};\n\nint main()\n{\n    // a JSON text\n    const auto* text = R\"(\n    {\n        \"Image\": {\n            \"Width\":  800,\n            \"Height\": 600,\n            \"Title\":  \"View from 15th Floor\",\n            \"Thumbnail\": {\n                \"Url\":    \"http://www.example.com/image/481989943\",\n                \"Height\": 125,\n                \"Width\":  100\n            },\n            \"Animated\" : false,\n            \"IDs\": [116, 943, 234, -38793],\n            \"DeletionDate\": null,\n            \"Distance\": 12.723374634\n        }\n    }]\n    )\";\n\n    // create a SAX event consumer object\n    sax_event_consumer sec;\n\n    // parse JSON\n    bool result = json::sax_parse(text, &sec);\n\n    // output the recorded events\n    for (auto& event : sec.events)\n    {\n        std::cout << event << \"\\n\";\n    }\n\n    // output the result of sax_parse\n    std::cout << \"\\nresult: \" << std::boolalpha << result << '\\n';\n}\n

Output:

start_object(elements=18446744073709551615)\nkey(val=Image)\nstart_object(elements=18446744073709551615)\nkey(val=Width)\nnumber_unsigned(val=800)\nkey(val=Height)\nnumber_unsigned(val=600)\nkey(val=Title)\nstring(val=View from 15th Floor)\nkey(val=Thumbnail)\nstart_object(elements=18446744073709551615)\nkey(val=Url)\nstring(val=http://www.example.com/image/481989943)\nkey(val=Height)\nnumber_unsigned(val=125)\nkey(val=Width)\nnumber_unsigned(val=100)\nend_object()\nkey(val=Animated)\nboolean(val=false)\nkey(val=IDs)\nstart_array(elements=18446744073709551615)\nnumber_unsigned(val=116)\nnumber_unsigned(val=943)\nnumber_unsigned(val=234)\nnumber_integer(val=-38793)\nend_array()\nkey(val=DeletionDate)\nnull()\nkey(val=Distance)\nnumber_float(val=12.723375, s=12.723374634)\nend_object()\nend_object()\nparse_error(position=460, last_token=12.723374634<U+000A>        }<U+000A>    }],\n            ex=[json.exception.parse_error.101] parse error at line 17, column 6: syntax error while parsing value - unexpected ']'; expected end of input)\n\nresult: false\n
"},{"location":"api/json_sax/key/#see-also","title":"See also","text":"
  • start_object - the beginning of an object was read
  • end_object - the end of an object was read
  • sax_parse - SAX parser
  • SAX Interface - guide to event-based parsing
"},{"location":"api/json_sax/key/#version-history","title":"Version history","text":"
  • Added in version 3.2.0.
"},{"location":"api/json_sax/null/","title":"nlohmann::json_sax::null","text":"
virtual bool null() = 0;\n

A null value was read.

"},{"location":"api/json_sax/null/#return-value","title":"Return value","text":"

Whether parsing should proceed.

"},{"location":"api/json_sax/null/#examples","title":"Examples","text":"Example

The example below shows how the SAX interface is used.

#include <iostream>\n#include <iomanip>\n#include <sstream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\n// a simple event consumer that collects string representations of the passed\n// values; note inheriting from json::json_sax_t is not required, but can\n// help not to forget a required function\nclass sax_event_consumer : public json::json_sax_t\n{\n  public:\n    std::vector<std::string> events;\n\n    bool null() override\n    {\n        events.push_back(\"null()\");\n        return true;\n    }\n\n    bool boolean(bool val) override\n    {\n        events.push_back(\"boolean(val=\" + std::string(val ? \"true\" : \"false\") + \")\");\n        return true;\n    }\n\n    bool number_integer(number_integer_t val) override\n    {\n        events.push_back(\"number_integer(val=\" + std::to_string(val) + \")\");\n        return true;\n    }\n\n    bool number_unsigned(number_unsigned_t val) override\n    {\n        events.push_back(\"number_unsigned(val=\" + std::to_string(val) + \")\");\n        return true;\n    }\n\n    bool number_float(number_float_t val, const string_t& s) override\n    {\n        events.push_back(\"number_float(val=\" + std::to_string(val) + \", s=\" + s + \")\");\n        return true;\n    }\n\n    bool string(string_t& val) override\n    {\n        events.push_back(\"string(val=\" + val + \")\");\n        return true;\n    }\n\n    bool start_object(std::size_t elements) override\n    {\n        events.push_back(\"start_object(elements=\" + std::to_string(elements) + \")\");\n        return true;\n    }\n\n    bool end_object() override\n    {\n        events.push_back(\"end_object()\");\n        return true;\n    }\n\n    bool start_array(std::size_t elements) override\n    {\n        events.push_back(\"start_array(elements=\" + std::to_string(elements) + \")\");\n        return true;\n    }\n\n    bool end_array() override\n    {\n        events.push_back(\"end_array()\");\n        return true;\n    }\n\n    bool key(string_t& val) override\n    {\n        events.push_back(\"key(val=\" + val + \")\");\n        return true;\n    }\n\n    bool binary(json::binary_t& val) override\n    {\n        events.push_back(\"binary(val=[...])\");\n        return true;\n    }\n\n    bool parse_error(std::size_t position, const std::string& last_token, const json::exception& ex) override\n    {\n        events.push_back(\"parse_error(position=\" + std::to_string(position) + \", last_token=\" + last_token + \",\\n            ex=\" + std::string(ex.what()) + \")\");\n        return false;\n    }\n};\n\nint main()\n{\n    // a JSON text\n    const auto* text = R\"(\n    {\n        \"Image\": {\n            \"Width\":  800,\n            \"Height\": 600,\n            \"Title\":  \"View from 15th Floor\",\n            \"Thumbnail\": {\n                \"Url\":    \"http://www.example.com/image/481989943\",\n                \"Height\": 125,\n                \"Width\":  100\n            },\n            \"Animated\" : false,\n            \"IDs\": [116, 943, 234, -38793],\n            \"DeletionDate\": null,\n            \"Distance\": 12.723374634\n        }\n    }]\n    )\";\n\n    // create a SAX event consumer object\n    sax_event_consumer sec;\n\n    // parse JSON\n    bool result = json::sax_parse(text, &sec);\n\n    // output the recorded events\n    for (auto& event : sec.events)\n    {\n        std::cout << event << \"\\n\";\n    }\n\n    // output the result of sax_parse\n    std::cout << \"\\nresult: \" << std::boolalpha << result << '\\n';\n}\n

Output:

start_object(elements=18446744073709551615)\nkey(val=Image)\nstart_object(elements=18446744073709551615)\nkey(val=Width)\nnumber_unsigned(val=800)\nkey(val=Height)\nnumber_unsigned(val=600)\nkey(val=Title)\nstring(val=View from 15th Floor)\nkey(val=Thumbnail)\nstart_object(elements=18446744073709551615)\nkey(val=Url)\nstring(val=http://www.example.com/image/481989943)\nkey(val=Height)\nnumber_unsigned(val=125)\nkey(val=Width)\nnumber_unsigned(val=100)\nend_object()\nkey(val=Animated)\nboolean(val=false)\nkey(val=IDs)\nstart_array(elements=18446744073709551615)\nnumber_unsigned(val=116)\nnumber_unsigned(val=943)\nnumber_unsigned(val=234)\nnumber_integer(val=-38793)\nend_array()\nkey(val=DeletionDate)\nnull()\nkey(val=Distance)\nnumber_float(val=12.723375, s=12.723374634)\nend_object()\nend_object()\nparse_error(position=460, last_token=12.723374634<U+000A>        }<U+000A>    }],\n            ex=[json.exception.parse_error.101] parse error at line 17, column 6: syntax error while parsing value - unexpected ']'; expected end of input)\n\nresult: false\n
"},{"location":"api/json_sax/null/#see-also","title":"See also","text":"
  • sax_parse - SAX parser
  • SAX Interface - the SAX interface article
"},{"location":"api/json_sax/null/#version-history","title":"Version history","text":"
  • Added in version 3.2.0.
"},{"location":"api/json_sax/number_float/","title":"nlohmann::json_sax::number_float","text":"
virtual bool number_float(number_float_t val, const string_t& s) = 0;\n

A floating-point number was read.

"},{"location":"api/json_sax/number_float/#parameters","title":"Parameters","text":"val (in) floating-point value s (in) string representation of the original input"},{"location":"api/json_sax/number_float/#return-value","title":"Return value","text":"

Whether parsing should proceed.

"},{"location":"api/json_sax/number_float/#examples","title":"Examples","text":"Example

The example below shows how the SAX interface is used.

#include <iostream>\n#include <iomanip>\n#include <sstream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\n// a simple event consumer that collects string representations of the passed\n// values; note inheriting from json::json_sax_t is not required, but can\n// help not to forget a required function\nclass sax_event_consumer : public json::json_sax_t\n{\n  public:\n    std::vector<std::string> events;\n\n    bool null() override\n    {\n        events.push_back(\"null()\");\n        return true;\n    }\n\n    bool boolean(bool val) override\n    {\n        events.push_back(\"boolean(val=\" + std::string(val ? \"true\" : \"false\") + \")\");\n        return true;\n    }\n\n    bool number_integer(number_integer_t val) override\n    {\n        events.push_back(\"number_integer(val=\" + std::to_string(val) + \")\");\n        return true;\n    }\n\n    bool number_unsigned(number_unsigned_t val) override\n    {\n        events.push_back(\"number_unsigned(val=\" + std::to_string(val) + \")\");\n        return true;\n    }\n\n    bool number_float(number_float_t val, const string_t& s) override\n    {\n        events.push_back(\"number_float(val=\" + std::to_string(val) + \", s=\" + s + \")\");\n        return true;\n    }\n\n    bool string(string_t& val) override\n    {\n        events.push_back(\"string(val=\" + val + \")\");\n        return true;\n    }\n\n    bool start_object(std::size_t elements) override\n    {\n        events.push_back(\"start_object(elements=\" + std::to_string(elements) + \")\");\n        return true;\n    }\n\n    bool end_object() override\n    {\n        events.push_back(\"end_object()\");\n        return true;\n    }\n\n    bool start_array(std::size_t elements) override\n    {\n        events.push_back(\"start_array(elements=\" + std::to_string(elements) + \")\");\n        return true;\n    }\n\n    bool end_array() override\n    {\n        events.push_back(\"end_array()\");\n        return true;\n    }\n\n    bool key(string_t& val) override\n    {\n        events.push_back(\"key(val=\" + val + \")\");\n        return true;\n    }\n\n    bool binary(json::binary_t& val) override\n    {\n        events.push_back(\"binary(val=[...])\");\n        return true;\n    }\n\n    bool parse_error(std::size_t position, const std::string& last_token, const json::exception& ex) override\n    {\n        events.push_back(\"parse_error(position=\" + std::to_string(position) + \", last_token=\" + last_token + \",\\n            ex=\" + std::string(ex.what()) + \")\");\n        return false;\n    }\n};\n\nint main()\n{\n    // a JSON text\n    const auto* text = R\"(\n    {\n        \"Image\": {\n            \"Width\":  800,\n            \"Height\": 600,\n            \"Title\":  \"View from 15th Floor\",\n            \"Thumbnail\": {\n                \"Url\":    \"http://www.example.com/image/481989943\",\n                \"Height\": 125,\n                \"Width\":  100\n            },\n            \"Animated\" : false,\n            \"IDs\": [116, 943, 234, -38793],\n            \"DeletionDate\": null,\n            \"Distance\": 12.723374634\n        }\n    }]\n    )\";\n\n    // create a SAX event consumer object\n    sax_event_consumer sec;\n\n    // parse JSON\n    bool result = json::sax_parse(text, &sec);\n\n    // output the recorded events\n    for (auto& event : sec.events)\n    {\n        std::cout << event << \"\\n\";\n    }\n\n    // output the result of sax_parse\n    std::cout << \"\\nresult: \" << std::boolalpha << result << '\\n';\n}\n

Output:

start_object(elements=18446744073709551615)\nkey(val=Image)\nstart_object(elements=18446744073709551615)\nkey(val=Width)\nnumber_unsigned(val=800)\nkey(val=Height)\nnumber_unsigned(val=600)\nkey(val=Title)\nstring(val=View from 15th Floor)\nkey(val=Thumbnail)\nstart_object(elements=18446744073709551615)\nkey(val=Url)\nstring(val=http://www.example.com/image/481989943)\nkey(val=Height)\nnumber_unsigned(val=125)\nkey(val=Width)\nnumber_unsigned(val=100)\nend_object()\nkey(val=Animated)\nboolean(val=false)\nkey(val=IDs)\nstart_array(elements=18446744073709551615)\nnumber_unsigned(val=116)\nnumber_unsigned(val=943)\nnumber_unsigned(val=234)\nnumber_integer(val=-38793)\nend_array()\nkey(val=DeletionDate)\nnull()\nkey(val=Distance)\nnumber_float(val=12.723375, s=12.723374634)\nend_object()\nend_object()\nparse_error(position=460, last_token=12.723374634<U+000A>        }<U+000A>    }],\n            ex=[json.exception.parse_error.101] parse error at line 17, column 6: syntax error while parsing value - unexpected ']'; expected end of input)\n\nresult: false\n
"},{"location":"api/json_sax/number_float/#see-also","title":"See also","text":"
  • number_integer - an integer number was read
  • number_unsigned - an unsigned integer number was read
  • sax_parse - SAX parser
  • SAX Interface - guide to event-based parsing
"},{"location":"api/json_sax/number_float/#version-history","title":"Version history","text":"
  • Added in version 3.2.0.
"},{"location":"api/json_sax/number_integer/","title":"nlohmann::json_sax::number_integer","text":"
virtual bool number_integer(number_integer_t val) = 0;\n

An integer number was read.

"},{"location":"api/json_sax/number_integer/#parameters","title":"Parameters","text":"val (in) integer value"},{"location":"api/json_sax/number_integer/#return-value","title":"Return value","text":"

Whether parsing should proceed.

"},{"location":"api/json_sax/number_integer/#examples","title":"Examples","text":"Example

The example below shows how the SAX interface is used.

#include <iostream>\n#include <iomanip>\n#include <sstream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\n// a simple event consumer that collects string representations of the passed\n// values; note inheriting from json::json_sax_t is not required, but can\n// help not to forget a required function\nclass sax_event_consumer : public json::json_sax_t\n{\n  public:\n    std::vector<std::string> events;\n\n    bool null() override\n    {\n        events.push_back(\"null()\");\n        return true;\n    }\n\n    bool boolean(bool val) override\n    {\n        events.push_back(\"boolean(val=\" + std::string(val ? \"true\" : \"false\") + \")\");\n        return true;\n    }\n\n    bool number_integer(number_integer_t val) override\n    {\n        events.push_back(\"number_integer(val=\" + std::to_string(val) + \")\");\n        return true;\n    }\n\n    bool number_unsigned(number_unsigned_t val) override\n    {\n        events.push_back(\"number_unsigned(val=\" + std::to_string(val) + \")\");\n        return true;\n    }\n\n    bool number_float(number_float_t val, const string_t& s) override\n    {\n        events.push_back(\"number_float(val=\" + std::to_string(val) + \", s=\" + s + \")\");\n        return true;\n    }\n\n    bool string(string_t& val) override\n    {\n        events.push_back(\"string(val=\" + val + \")\");\n        return true;\n    }\n\n    bool start_object(std::size_t elements) override\n    {\n        events.push_back(\"start_object(elements=\" + std::to_string(elements) + \")\");\n        return true;\n    }\n\n    bool end_object() override\n    {\n        events.push_back(\"end_object()\");\n        return true;\n    }\n\n    bool start_array(std::size_t elements) override\n    {\n        events.push_back(\"start_array(elements=\" + std::to_string(elements) + \")\");\n        return true;\n    }\n\n    bool end_array() override\n    {\n        events.push_back(\"end_array()\");\n        return true;\n    }\n\n    bool key(string_t& val) override\n    {\n        events.push_back(\"key(val=\" + val + \")\");\n        return true;\n    }\n\n    bool binary(json::binary_t& val) override\n    {\n        events.push_back(\"binary(val=[...])\");\n        return true;\n    }\n\n    bool parse_error(std::size_t position, const std::string& last_token, const json::exception& ex) override\n    {\n        events.push_back(\"parse_error(position=\" + std::to_string(position) + \", last_token=\" + last_token + \",\\n            ex=\" + std::string(ex.what()) + \")\");\n        return false;\n    }\n};\n\nint main()\n{\n    // a JSON text\n    const auto* text = R\"(\n    {\n        \"Image\": {\n            \"Width\":  800,\n            \"Height\": 600,\n            \"Title\":  \"View from 15th Floor\",\n            \"Thumbnail\": {\n                \"Url\":    \"http://www.example.com/image/481989943\",\n                \"Height\": 125,\n                \"Width\":  100\n            },\n            \"Animated\" : false,\n            \"IDs\": [116, 943, 234, -38793],\n            \"DeletionDate\": null,\n            \"Distance\": 12.723374634\n        }\n    }]\n    )\";\n\n    // create a SAX event consumer object\n    sax_event_consumer sec;\n\n    // parse JSON\n    bool result = json::sax_parse(text, &sec);\n\n    // output the recorded events\n    for (auto& event : sec.events)\n    {\n        std::cout << event << \"\\n\";\n    }\n\n    // output the result of sax_parse\n    std::cout << \"\\nresult: \" << std::boolalpha << result << '\\n';\n}\n

Output:

start_object(elements=18446744073709551615)\nkey(val=Image)\nstart_object(elements=18446744073709551615)\nkey(val=Width)\nnumber_unsigned(val=800)\nkey(val=Height)\nnumber_unsigned(val=600)\nkey(val=Title)\nstring(val=View from 15th Floor)\nkey(val=Thumbnail)\nstart_object(elements=18446744073709551615)\nkey(val=Url)\nstring(val=http://www.example.com/image/481989943)\nkey(val=Height)\nnumber_unsigned(val=125)\nkey(val=Width)\nnumber_unsigned(val=100)\nend_object()\nkey(val=Animated)\nboolean(val=false)\nkey(val=IDs)\nstart_array(elements=18446744073709551615)\nnumber_unsigned(val=116)\nnumber_unsigned(val=943)\nnumber_unsigned(val=234)\nnumber_integer(val=-38793)\nend_array()\nkey(val=DeletionDate)\nnull()\nkey(val=Distance)\nnumber_float(val=12.723375, s=12.723374634)\nend_object()\nend_object()\nparse_error(position=460, last_token=12.723374634<U+000A>        }<U+000A>    }],\n            ex=[json.exception.parse_error.101] parse error at line 17, column 6: syntax error while parsing value - unexpected ']'; expected end of input)\n\nresult: false\n
"},{"location":"api/json_sax/number_integer/#see-also","title":"See also","text":"
  • number_unsigned - an unsigned integer number was read
  • number_float - a floating-point number was read
  • sax_parse - SAX parser
  • SAX Interface - guide to event-based parsing
"},{"location":"api/json_sax/number_integer/#version-history","title":"Version history","text":"
  • Added in version 3.2.0.
"},{"location":"api/json_sax/number_unsigned/","title":"nlohmann::json_sax::number_unsigned","text":"
virtual bool number_unsigned(number_unsigned_t val) = 0;\n

An unsigned integer number was read.

"},{"location":"api/json_sax/number_unsigned/#parameters","title":"Parameters","text":"val (in) unsigned integer value"},{"location":"api/json_sax/number_unsigned/#return-value","title":"Return value","text":"

Whether parsing should proceed.

"},{"location":"api/json_sax/number_unsigned/#examples","title":"Examples","text":"Example

The example below shows how the SAX interface is used.

#include <iostream>\n#include <iomanip>\n#include <sstream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\n// a simple event consumer that collects string representations of the passed\n// values; note inheriting from json::json_sax_t is not required, but can\n// help not to forget a required function\nclass sax_event_consumer : public json::json_sax_t\n{\n  public:\n    std::vector<std::string> events;\n\n    bool null() override\n    {\n        events.push_back(\"null()\");\n        return true;\n    }\n\n    bool boolean(bool val) override\n    {\n        events.push_back(\"boolean(val=\" + std::string(val ? \"true\" : \"false\") + \")\");\n        return true;\n    }\n\n    bool number_integer(number_integer_t val) override\n    {\n        events.push_back(\"number_integer(val=\" + std::to_string(val) + \")\");\n        return true;\n    }\n\n    bool number_unsigned(number_unsigned_t val) override\n    {\n        events.push_back(\"number_unsigned(val=\" + std::to_string(val) + \")\");\n        return true;\n    }\n\n    bool number_float(number_float_t val, const string_t& s) override\n    {\n        events.push_back(\"number_float(val=\" + std::to_string(val) + \", s=\" + s + \")\");\n        return true;\n    }\n\n    bool string(string_t& val) override\n    {\n        events.push_back(\"string(val=\" + val + \")\");\n        return true;\n    }\n\n    bool start_object(std::size_t elements) override\n    {\n        events.push_back(\"start_object(elements=\" + std::to_string(elements) + \")\");\n        return true;\n    }\n\n    bool end_object() override\n    {\n        events.push_back(\"end_object()\");\n        return true;\n    }\n\n    bool start_array(std::size_t elements) override\n    {\n        events.push_back(\"start_array(elements=\" + std::to_string(elements) + \")\");\n        return true;\n    }\n\n    bool end_array() override\n    {\n        events.push_back(\"end_array()\");\n        return true;\n    }\n\n    bool key(string_t& val) override\n    {\n        events.push_back(\"key(val=\" + val + \")\");\n        return true;\n    }\n\n    bool binary(json::binary_t& val) override\n    {\n        events.push_back(\"binary(val=[...])\");\n        return true;\n    }\n\n    bool parse_error(std::size_t position, const std::string& last_token, const json::exception& ex) override\n    {\n        events.push_back(\"parse_error(position=\" + std::to_string(position) + \", last_token=\" + last_token + \",\\n            ex=\" + std::string(ex.what()) + \")\");\n        return false;\n    }\n};\n\nint main()\n{\n    // a JSON text\n    const auto* text = R\"(\n    {\n        \"Image\": {\n            \"Width\":  800,\n            \"Height\": 600,\n            \"Title\":  \"View from 15th Floor\",\n            \"Thumbnail\": {\n                \"Url\":    \"http://www.example.com/image/481989943\",\n                \"Height\": 125,\n                \"Width\":  100\n            },\n            \"Animated\" : false,\n            \"IDs\": [116, 943, 234, -38793],\n            \"DeletionDate\": null,\n            \"Distance\": 12.723374634\n        }\n    }]\n    )\";\n\n    // create a SAX event consumer object\n    sax_event_consumer sec;\n\n    // parse JSON\n    bool result = json::sax_parse(text, &sec);\n\n    // output the recorded events\n    for (auto& event : sec.events)\n    {\n        std::cout << event << \"\\n\";\n    }\n\n    // output the result of sax_parse\n    std::cout << \"\\nresult: \" << std::boolalpha << result << '\\n';\n}\n

Output:

start_object(elements=18446744073709551615)\nkey(val=Image)\nstart_object(elements=18446744073709551615)\nkey(val=Width)\nnumber_unsigned(val=800)\nkey(val=Height)\nnumber_unsigned(val=600)\nkey(val=Title)\nstring(val=View from 15th Floor)\nkey(val=Thumbnail)\nstart_object(elements=18446744073709551615)\nkey(val=Url)\nstring(val=http://www.example.com/image/481989943)\nkey(val=Height)\nnumber_unsigned(val=125)\nkey(val=Width)\nnumber_unsigned(val=100)\nend_object()\nkey(val=Animated)\nboolean(val=false)\nkey(val=IDs)\nstart_array(elements=18446744073709551615)\nnumber_unsigned(val=116)\nnumber_unsigned(val=943)\nnumber_unsigned(val=234)\nnumber_integer(val=-38793)\nend_array()\nkey(val=DeletionDate)\nnull()\nkey(val=Distance)\nnumber_float(val=12.723375, s=12.723374634)\nend_object()\nend_object()\nparse_error(position=460, last_token=12.723374634<U+000A>        }<U+000A>    }],\n            ex=[json.exception.parse_error.101] parse error at line 17, column 6: syntax error while parsing value - unexpected ']'; expected end of input)\n\nresult: false\n
"},{"location":"api/json_sax/number_unsigned/#see-also","title":"See also","text":"
  • number_integer - an integer number was read
  • number_float - a floating-point number was read
  • sax_parse - SAX parser
  • SAX Interface - guide to event-based parsing
"},{"location":"api/json_sax/number_unsigned/#version-history","title":"Version history","text":"
  • Added in version 3.2.0.
"},{"location":"api/json_sax/parse_error/","title":"nlohmann::json_sax::parse_error","text":"
virtual bool parse_error(std::size_t position,\n                         const std::string& last_token,\n                         const detail::exception& ex) = 0;\n

A parse error occurred.

"},{"location":"api/json_sax/parse_error/#parameters","title":"Parameters","text":"position (in) the position in the input where the error occurs last_token (in) the last read token ex (in) an exception object describing the error"},{"location":"api/json_sax/parse_error/#return-value","title":"Return value","text":"

Whether parsing should proceed (must return false).

"},{"location":"api/json_sax/parse_error/#examples","title":"Examples","text":"Example

The example below shows how the SAX interface is used.

#include <iostream>\n#include <iomanip>\n#include <sstream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\n// a simple event consumer that collects string representations of the passed\n// values; note inheriting from json::json_sax_t is not required, but can\n// help not to forget a required function\nclass sax_event_consumer : public json::json_sax_t\n{\n  public:\n    std::vector<std::string> events;\n\n    bool null() override\n    {\n        events.push_back(\"null()\");\n        return true;\n    }\n\n    bool boolean(bool val) override\n    {\n        events.push_back(\"boolean(val=\" + std::string(val ? \"true\" : \"false\") + \")\");\n        return true;\n    }\n\n    bool number_integer(number_integer_t val) override\n    {\n        events.push_back(\"number_integer(val=\" + std::to_string(val) + \")\");\n        return true;\n    }\n\n    bool number_unsigned(number_unsigned_t val) override\n    {\n        events.push_back(\"number_unsigned(val=\" + std::to_string(val) + \")\");\n        return true;\n    }\n\n    bool number_float(number_float_t val, const string_t& s) override\n    {\n        events.push_back(\"number_float(val=\" + std::to_string(val) + \", s=\" + s + \")\");\n        return true;\n    }\n\n    bool string(string_t& val) override\n    {\n        events.push_back(\"string(val=\" + val + \")\");\n        return true;\n    }\n\n    bool start_object(std::size_t elements) override\n    {\n        events.push_back(\"start_object(elements=\" + std::to_string(elements) + \")\");\n        return true;\n    }\n\n    bool end_object() override\n    {\n        events.push_back(\"end_object()\");\n        return true;\n    }\n\n    bool start_array(std::size_t elements) override\n    {\n        events.push_back(\"start_array(elements=\" + std::to_string(elements) + \")\");\n        return true;\n    }\n\n    bool end_array() override\n    {\n        events.push_back(\"end_array()\");\n        return true;\n    }\n\n    bool key(string_t& val) override\n    {\n        events.push_back(\"key(val=\" + val + \")\");\n        return true;\n    }\n\n    bool binary(json::binary_t& val) override\n    {\n        events.push_back(\"binary(val=[...])\");\n        return true;\n    }\n\n    bool parse_error(std::size_t position, const std::string& last_token, const json::exception& ex) override\n    {\n        events.push_back(\"parse_error(position=\" + std::to_string(position) + \", last_token=\" + last_token + \",\\n            ex=\" + std::string(ex.what()) + \")\");\n        return false;\n    }\n};\n\nint main()\n{\n    // a JSON text\n    const auto* text = R\"(\n    {\n        \"Image\": {\n            \"Width\":  800,\n            \"Height\": 600,\n            \"Title\":  \"View from 15th Floor\",\n            \"Thumbnail\": {\n                \"Url\":    \"http://www.example.com/image/481989943\",\n                \"Height\": 125,\n                \"Width\":  100\n            },\n            \"Animated\" : false,\n            \"IDs\": [116, 943, 234, -38793],\n            \"DeletionDate\": null,\n            \"Distance\": 12.723374634\n        }\n    }]\n    )\";\n\n    // create a SAX event consumer object\n    sax_event_consumer sec;\n\n    // parse JSON\n    bool result = json::sax_parse(text, &sec);\n\n    // output the recorded events\n    for (auto& event : sec.events)\n    {\n        std::cout << event << \"\\n\";\n    }\n\n    // output the result of sax_parse\n    std::cout << \"\\nresult: \" << std::boolalpha << result << '\\n';\n}\n

Output:

start_object(elements=18446744073709551615)\nkey(val=Image)\nstart_object(elements=18446744073709551615)\nkey(val=Width)\nnumber_unsigned(val=800)\nkey(val=Height)\nnumber_unsigned(val=600)\nkey(val=Title)\nstring(val=View from 15th Floor)\nkey(val=Thumbnail)\nstart_object(elements=18446744073709551615)\nkey(val=Url)\nstring(val=http://www.example.com/image/481989943)\nkey(val=Height)\nnumber_unsigned(val=125)\nkey(val=Width)\nnumber_unsigned(val=100)\nend_object()\nkey(val=Animated)\nboolean(val=false)\nkey(val=IDs)\nstart_array(elements=18446744073709551615)\nnumber_unsigned(val=116)\nnumber_unsigned(val=943)\nnumber_unsigned(val=234)\nnumber_integer(val=-38793)\nend_array()\nkey(val=DeletionDate)\nnull()\nkey(val=Distance)\nnumber_float(val=12.723375, s=12.723374634)\nend_object()\nend_object()\nparse_error(position=460, last_token=12.723374634<U+000A>        }<U+000A>    }],\n            ex=[json.exception.parse_error.101] parse error at line 17, column 6: syntax error while parsing value - unexpected ']'; expected end of input)\n\nresult: false\n
"},{"location":"api/json_sax/parse_error/#see-also","title":"See also","text":"
  • sax_parse - SAX parser
  • Parsing and Exceptions - the article on handling parse errors without exceptions
  • SAX Interface - guide to event-based parsing
"},{"location":"api/json_sax/parse_error/#version-history","title":"Version history","text":"
  • Added in version 3.2.0.
"},{"location":"api/json_sax/start_array/","title":"nlohmann::json_sax::start_array","text":"
virtual bool start_array(std::size_t elements) = 0;\n

The beginning of an array was read.

"},{"location":"api/json_sax/start_array/#parameters","title":"Parameters","text":"elements (in) number of array elements, or std::numeric_limits<std::size_t>::max() if unknown"},{"location":"api/json_sax/start_array/#return-value","title":"Return value","text":"

Whether parsing should proceed.

"},{"location":"api/json_sax/start_array/#notes","title":"Notes","text":"

Binary formats may report the number of elements.

"},{"location":"api/json_sax/start_array/#examples","title":"Examples","text":"Example

The example below shows how the SAX interface is used.

#include <iostream>\n#include <iomanip>\n#include <sstream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\n// a simple event consumer that collects string representations of the passed\n// values; note inheriting from json::json_sax_t is not required, but can\n// help not to forget a required function\nclass sax_event_consumer : public json::json_sax_t\n{\n  public:\n    std::vector<std::string> events;\n\n    bool null() override\n    {\n        events.push_back(\"null()\");\n        return true;\n    }\n\n    bool boolean(bool val) override\n    {\n        events.push_back(\"boolean(val=\" + std::string(val ? \"true\" : \"false\") + \")\");\n        return true;\n    }\n\n    bool number_integer(number_integer_t val) override\n    {\n        events.push_back(\"number_integer(val=\" + std::to_string(val) + \")\");\n        return true;\n    }\n\n    bool number_unsigned(number_unsigned_t val) override\n    {\n        events.push_back(\"number_unsigned(val=\" + std::to_string(val) + \")\");\n        return true;\n    }\n\n    bool number_float(number_float_t val, const string_t& s) override\n    {\n        events.push_back(\"number_float(val=\" + std::to_string(val) + \", s=\" + s + \")\");\n        return true;\n    }\n\n    bool string(string_t& val) override\n    {\n        events.push_back(\"string(val=\" + val + \")\");\n        return true;\n    }\n\n    bool start_object(std::size_t elements) override\n    {\n        events.push_back(\"start_object(elements=\" + std::to_string(elements) + \")\");\n        return true;\n    }\n\n    bool end_object() override\n    {\n        events.push_back(\"end_object()\");\n        return true;\n    }\n\n    bool start_array(std::size_t elements) override\n    {\n        events.push_back(\"start_array(elements=\" + std::to_string(elements) + \")\");\n        return true;\n    }\n\n    bool end_array() override\n    {\n        events.push_back(\"end_array()\");\n        return true;\n    }\n\n    bool key(string_t& val) override\n    {\n        events.push_back(\"key(val=\" + val + \")\");\n        return true;\n    }\n\n    bool binary(json::binary_t& val) override\n    {\n        events.push_back(\"binary(val=[...])\");\n        return true;\n    }\n\n    bool parse_error(std::size_t position, const std::string& last_token, const json::exception& ex) override\n    {\n        events.push_back(\"parse_error(position=\" + std::to_string(position) + \", last_token=\" + last_token + \",\\n            ex=\" + std::string(ex.what()) + \")\");\n        return false;\n    }\n};\n\nint main()\n{\n    // a JSON text\n    const auto* text = R\"(\n    {\n        \"Image\": {\n            \"Width\":  800,\n            \"Height\": 600,\n            \"Title\":  \"View from 15th Floor\",\n            \"Thumbnail\": {\n                \"Url\":    \"http://www.example.com/image/481989943\",\n                \"Height\": 125,\n                \"Width\":  100\n            },\n            \"Animated\" : false,\n            \"IDs\": [116, 943, 234, -38793],\n            \"DeletionDate\": null,\n            \"Distance\": 12.723374634\n        }\n    }]\n    )\";\n\n    // create a SAX event consumer object\n    sax_event_consumer sec;\n\n    // parse JSON\n    bool result = json::sax_parse(text, &sec);\n\n    // output the recorded events\n    for (auto& event : sec.events)\n    {\n        std::cout << event << \"\\n\";\n    }\n\n    // output the result of sax_parse\n    std::cout << \"\\nresult: \" << std::boolalpha << result << '\\n';\n}\n

Output:

start_object(elements=18446744073709551615)\nkey(val=Image)\nstart_object(elements=18446744073709551615)\nkey(val=Width)\nnumber_unsigned(val=800)\nkey(val=Height)\nnumber_unsigned(val=600)\nkey(val=Title)\nstring(val=View from 15th Floor)\nkey(val=Thumbnail)\nstart_object(elements=18446744073709551615)\nkey(val=Url)\nstring(val=http://www.example.com/image/481989943)\nkey(val=Height)\nnumber_unsigned(val=125)\nkey(val=Width)\nnumber_unsigned(val=100)\nend_object()\nkey(val=Animated)\nboolean(val=false)\nkey(val=IDs)\nstart_array(elements=18446744073709551615)\nnumber_unsigned(val=116)\nnumber_unsigned(val=943)\nnumber_unsigned(val=234)\nnumber_integer(val=-38793)\nend_array()\nkey(val=DeletionDate)\nnull()\nkey(val=Distance)\nnumber_float(val=12.723375, s=12.723374634)\nend_object()\nend_object()\nparse_error(position=460, last_token=12.723374634<U+000A>        }<U+000A>    }],\n            ex=[json.exception.parse_error.101] parse error at line 17, column 6: syntax error while parsing value - unexpected ']'; expected end of input)\n\nresult: false\n
"},{"location":"api/json_sax/start_array/#see-also","title":"See also","text":"
  • end_array - the end of an array was read
  • sax_parse - SAX parser
  • SAX Interface - guide to event-based parsing
"},{"location":"api/json_sax/start_array/#version-history","title":"Version history","text":"
  • Added in version 3.2.0.
"},{"location":"api/json_sax/start_object/","title":"nlohmann::json_sax::start_object","text":"
virtual bool start_object(std::size_t elements) = 0;\n

The beginning of an object was read.

"},{"location":"api/json_sax/start_object/#parameters","title":"Parameters","text":"elements (in) number of object elements, or std::numeric_limits<std::size_t>::max() if unknown"},{"location":"api/json_sax/start_object/#return-value","title":"Return value","text":"

Whether parsing should proceed.

"},{"location":"api/json_sax/start_object/#notes","title":"Notes","text":"

Binary formats may report the number of elements.

"},{"location":"api/json_sax/start_object/#examples","title":"Examples","text":"Example

The example below shows how the SAX interface is used.

#include <iostream>\n#include <iomanip>\n#include <sstream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\n// a simple event consumer that collects string representations of the passed\n// values; note inheriting from json::json_sax_t is not required, but can\n// help not to forget a required function\nclass sax_event_consumer : public json::json_sax_t\n{\n  public:\n    std::vector<std::string> events;\n\n    bool null() override\n    {\n        events.push_back(\"null()\");\n        return true;\n    }\n\n    bool boolean(bool val) override\n    {\n        events.push_back(\"boolean(val=\" + std::string(val ? \"true\" : \"false\") + \")\");\n        return true;\n    }\n\n    bool number_integer(number_integer_t val) override\n    {\n        events.push_back(\"number_integer(val=\" + std::to_string(val) + \")\");\n        return true;\n    }\n\n    bool number_unsigned(number_unsigned_t val) override\n    {\n        events.push_back(\"number_unsigned(val=\" + std::to_string(val) + \")\");\n        return true;\n    }\n\n    bool number_float(number_float_t val, const string_t& s) override\n    {\n        events.push_back(\"number_float(val=\" + std::to_string(val) + \", s=\" + s + \")\");\n        return true;\n    }\n\n    bool string(string_t& val) override\n    {\n        events.push_back(\"string(val=\" + val + \")\");\n        return true;\n    }\n\n    bool start_object(std::size_t elements) override\n    {\n        events.push_back(\"start_object(elements=\" + std::to_string(elements) + \")\");\n        return true;\n    }\n\n    bool end_object() override\n    {\n        events.push_back(\"end_object()\");\n        return true;\n    }\n\n    bool start_array(std::size_t elements) override\n    {\n        events.push_back(\"start_array(elements=\" + std::to_string(elements) + \")\");\n        return true;\n    }\n\n    bool end_array() override\n    {\n        events.push_back(\"end_array()\");\n        return true;\n    }\n\n    bool key(string_t& val) override\n    {\n        events.push_back(\"key(val=\" + val + \")\");\n        return true;\n    }\n\n    bool binary(json::binary_t& val) override\n    {\n        events.push_back(\"binary(val=[...])\");\n        return true;\n    }\n\n    bool parse_error(std::size_t position, const std::string& last_token, const json::exception& ex) override\n    {\n        events.push_back(\"parse_error(position=\" + std::to_string(position) + \", last_token=\" + last_token + \",\\n            ex=\" + std::string(ex.what()) + \")\");\n        return false;\n    }\n};\n\nint main()\n{\n    // a JSON text\n    const auto* text = R\"(\n    {\n        \"Image\": {\n            \"Width\":  800,\n            \"Height\": 600,\n            \"Title\":  \"View from 15th Floor\",\n            \"Thumbnail\": {\n                \"Url\":    \"http://www.example.com/image/481989943\",\n                \"Height\": 125,\n                \"Width\":  100\n            },\n            \"Animated\" : false,\n            \"IDs\": [116, 943, 234, -38793],\n            \"DeletionDate\": null,\n            \"Distance\": 12.723374634\n        }\n    }]\n    )\";\n\n    // create a SAX event consumer object\n    sax_event_consumer sec;\n\n    // parse JSON\n    bool result = json::sax_parse(text, &sec);\n\n    // output the recorded events\n    for (auto& event : sec.events)\n    {\n        std::cout << event << \"\\n\";\n    }\n\n    // output the result of sax_parse\n    std::cout << \"\\nresult: \" << std::boolalpha << result << '\\n';\n}\n

Output:

start_object(elements=18446744073709551615)\nkey(val=Image)\nstart_object(elements=18446744073709551615)\nkey(val=Width)\nnumber_unsigned(val=800)\nkey(val=Height)\nnumber_unsigned(val=600)\nkey(val=Title)\nstring(val=View from 15th Floor)\nkey(val=Thumbnail)\nstart_object(elements=18446744073709551615)\nkey(val=Url)\nstring(val=http://www.example.com/image/481989943)\nkey(val=Height)\nnumber_unsigned(val=125)\nkey(val=Width)\nnumber_unsigned(val=100)\nend_object()\nkey(val=Animated)\nboolean(val=false)\nkey(val=IDs)\nstart_array(elements=18446744073709551615)\nnumber_unsigned(val=116)\nnumber_unsigned(val=943)\nnumber_unsigned(val=234)\nnumber_integer(val=-38793)\nend_array()\nkey(val=DeletionDate)\nnull()\nkey(val=Distance)\nnumber_float(val=12.723375, s=12.723374634)\nend_object()\nend_object()\nparse_error(position=460, last_token=12.723374634<U+000A>        }<U+000A>    }],\n            ex=[json.exception.parse_error.101] parse error at line 17, column 6: syntax error while parsing value - unexpected ']'; expected end of input)\n\nresult: false\n
"},{"location":"api/json_sax/start_object/#see-also","title":"See also","text":"
  • end_object - the end of an object was read
  • key - an object key was read
  • sax_parse - SAX parser
  • SAX Interface - guide to event-based parsing
"},{"location":"api/json_sax/start_object/#version-history","title":"Version history","text":"
  • Added in version 3.2.0.
"},{"location":"api/json_sax/string/","title":"nlohmann::json_sax::string","text":"
virtual bool string(string_t& val) = 0;\n

A string value was read.

"},{"location":"api/json_sax/string/#parameters","title":"Parameters","text":"val (in) string value"},{"location":"api/json_sax/string/#return-value","title":"Return value","text":"

Whether parsing should proceed.

"},{"location":"api/json_sax/string/#notes","title":"Notes","text":"

It is safe to move the passed string value.

"},{"location":"api/json_sax/string/#examples","title":"Examples","text":"Example

The example below shows how the SAX interface is used.

#include <iostream>\n#include <iomanip>\n#include <sstream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\n// a simple event consumer that collects string representations of the passed\n// values; note inheriting from json::json_sax_t is not required, but can\n// help not to forget a required function\nclass sax_event_consumer : public json::json_sax_t\n{\n  public:\n    std::vector<std::string> events;\n\n    bool null() override\n    {\n        events.push_back(\"null()\");\n        return true;\n    }\n\n    bool boolean(bool val) override\n    {\n        events.push_back(\"boolean(val=\" + std::string(val ? \"true\" : \"false\") + \")\");\n        return true;\n    }\n\n    bool number_integer(number_integer_t val) override\n    {\n        events.push_back(\"number_integer(val=\" + std::to_string(val) + \")\");\n        return true;\n    }\n\n    bool number_unsigned(number_unsigned_t val) override\n    {\n        events.push_back(\"number_unsigned(val=\" + std::to_string(val) + \")\");\n        return true;\n    }\n\n    bool number_float(number_float_t val, const string_t& s) override\n    {\n        events.push_back(\"number_float(val=\" + std::to_string(val) + \", s=\" + s + \")\");\n        return true;\n    }\n\n    bool string(string_t& val) override\n    {\n        events.push_back(\"string(val=\" + val + \")\");\n        return true;\n    }\n\n    bool start_object(std::size_t elements) override\n    {\n        events.push_back(\"start_object(elements=\" + std::to_string(elements) + \")\");\n        return true;\n    }\n\n    bool end_object() override\n    {\n        events.push_back(\"end_object()\");\n        return true;\n    }\n\n    bool start_array(std::size_t elements) override\n    {\n        events.push_back(\"start_array(elements=\" + std::to_string(elements) + \")\");\n        return true;\n    }\n\n    bool end_array() override\n    {\n        events.push_back(\"end_array()\");\n        return true;\n    }\n\n    bool key(string_t& val) override\n    {\n        events.push_back(\"key(val=\" + val + \")\");\n        return true;\n    }\n\n    bool binary(json::binary_t& val) override\n    {\n        events.push_back(\"binary(val=[...])\");\n        return true;\n    }\n\n    bool parse_error(std::size_t position, const std::string& last_token, const json::exception& ex) override\n    {\n        events.push_back(\"parse_error(position=\" + std::to_string(position) + \", last_token=\" + last_token + \",\\n            ex=\" + std::string(ex.what()) + \")\");\n        return false;\n    }\n};\n\nint main()\n{\n    // a JSON text\n    const auto* text = R\"(\n    {\n        \"Image\": {\n            \"Width\":  800,\n            \"Height\": 600,\n            \"Title\":  \"View from 15th Floor\",\n            \"Thumbnail\": {\n                \"Url\":    \"http://www.example.com/image/481989943\",\n                \"Height\": 125,\n                \"Width\":  100\n            },\n            \"Animated\" : false,\n            \"IDs\": [116, 943, 234, -38793],\n            \"DeletionDate\": null,\n            \"Distance\": 12.723374634\n        }\n    }]\n    )\";\n\n    // create a SAX event consumer object\n    sax_event_consumer sec;\n\n    // parse JSON\n    bool result = json::sax_parse(text, &sec);\n\n    // output the recorded events\n    for (auto& event : sec.events)\n    {\n        std::cout << event << \"\\n\";\n    }\n\n    // output the result of sax_parse\n    std::cout << \"\\nresult: \" << std::boolalpha << result << '\\n';\n}\n

Output:

start_object(elements=18446744073709551615)\nkey(val=Image)\nstart_object(elements=18446744073709551615)\nkey(val=Width)\nnumber_unsigned(val=800)\nkey(val=Height)\nnumber_unsigned(val=600)\nkey(val=Title)\nstring(val=View from 15th Floor)\nkey(val=Thumbnail)\nstart_object(elements=18446744073709551615)\nkey(val=Url)\nstring(val=http://www.example.com/image/481989943)\nkey(val=Height)\nnumber_unsigned(val=125)\nkey(val=Width)\nnumber_unsigned(val=100)\nend_object()\nkey(val=Animated)\nboolean(val=false)\nkey(val=IDs)\nstart_array(elements=18446744073709551615)\nnumber_unsigned(val=116)\nnumber_unsigned(val=943)\nnumber_unsigned(val=234)\nnumber_integer(val=-38793)\nend_array()\nkey(val=DeletionDate)\nnull()\nkey(val=Distance)\nnumber_float(val=12.723375, s=12.723374634)\nend_object()\nend_object()\nparse_error(position=460, last_token=12.723374634<U+000A>        }<U+000A>    }],\n            ex=[json.exception.parse_error.101] parse error at line 17, column 6: syntax error while parsing value - unexpected ']'; expected end of input)\n\nresult: false\n
"},{"location":"api/json_sax/string/#see-also","title":"See also","text":"
  • sax_parse - SAX parser
  • SAX Interface - the SAX interface article
"},{"location":"api/json_sax/string/#version-history","title":"Version history","text":"
  • Added in version 3.2.0.
"},{"location":"api/macros/","title":"Macros","text":"

Some aspects of the library can be configured by defining preprocessor macros before including the json.hpp header. See also the macro overview page.

"},{"location":"api/macros/#runtime-assertions","title":"Runtime assertions","text":"
  • JSON_ASSERT(x) - control behavior of runtime assertions
"},{"location":"api/macros/#exceptions","title":"Exceptions","text":"
  • JSON_CATCH_USER(exception)JSON_THROW_USER(exception)JSON_TRY_USER - control exceptions
  • JSON_DIAGNOSTICS - control extended diagnostics
  • JSON_DIAGNOSTIC_POSITIONS - access positions of elements
  • JSON_NOEXCEPTION - switch off exceptions
"},{"location":"api/macros/#parsing","title":"Parsing","text":"
  • JSON_DISABLE_STREAM_BULK_SCAN - read a std::istream one character at a time instead of scanning its stream buffer in bulk
  • JSON_DISABLE_UNLOCKED_FILE_IO - read a FILE* with std::fgetc instead of locking it once and using the unlocked stdio functions
  • JSON_PRECISE_STREAM_POSITION - opt in to leaving an input stream positioned right after a parsed number
  • JSON_STRICT_BINARY_UTF8 - opt in to checking strings for valid UTF-8 in the CBOR, UBJSON, BJData, and BSON writers
  • JSON_STRICT_NUL_HANDLING - opt in to rejecting a NUL byte in the input instead of treating it as end of input
"},{"location":"api/macros/#language-support","title":"Language support","text":"
  • JSON_HAS_CPP_11JSON_HAS_CPP_14JSON_HAS_CPP_17JSON_HAS_CPP_20 - set supported C++ standard
  • JSON_HAS_FILESYSTEMJSON_HAS_EXPERIMENTAL_FILESYSTEM - control std::filesystem support
  • JSON_HAS_RANGE_VIEW_CONVERSION - control construction from std::ranges views
  • JSON_HAS_RANGES - control std::ranges support
  • JSON_HAS_STATIC_RTTI - control RTTI (run time type information) support
  • JSON_HAS_STD_FORMAT - control std::format/std::formatter support
  • JSON_HAS_THREE_WAY_COMPARISON - control 3-way comparison support
  • JSON_NO_AUTOMATIC_UDLS - do not include the user-defined string literals (UDLs) automatically
  • JSON_NO_IO - switch off functions relying on certain C++ I/O headers
  • JSON_NO_SIMD - use only portable code instead of vector instructions (SSE2, SSSE3, NEON)
  • JSON_NO_THREAD_LOCAL - switch off the use of thread_local storage
  • JSON_SKIP_UNSUPPORTED_COMPILER_CHECK - do not warn about unsupported compilers
  • JSON_USE_GLOBAL_UDLS - place user-defined string literals (UDLs) into the global namespace
  • JSON_USE_SIMDUTF - use the simdutf library to accelerate UTF-8 validation
"},{"location":"api/macros/#library-version","title":"Library version","text":"
  • JSON_SKIP_LIBRARY_VERSION_CHECK - skip library version check
  • NLOHMANN_JSON_VERSION_MAJORNLOHMANN_JSON_VERSION_MINORNLOHMANN_JSON_VERSION_PATCH - library version information
"},{"location":"api/macros/#library-namespace","title":"Library namespace","text":"
  • NLOHMANN_JSON_NAMESPACE - full name of the nlohmann namespace
  • NLOHMANN_JSON_NAMESPACE_BEGINNLOHMANN_JSON_NAMESPACE_END - open and close the library namespace
  • NLOHMANN_JSON_NAMESPACE_NO_VERSION - disable the version component of the inline namespace
"},{"location":"api/macros/#type-conversions","title":"Type conversions","text":"
  • JSON_BRACE_INIT_COPY_SEMANTICS - opt in to copy/move semantics for single-element brace initialization
  • JSON_DISABLE_ENUM_SERIALIZATION - switch off default serialization/deserialization functions for enums
  • JSON_DISABLE_TUPLE_REFERENCE_CONVERSION - switch off conversion from a one-element tuple of a JSON reference
  • JSON_USE_IMPLICIT_CONVERSIONS - control implicit conversions
  • JSON_USE_OBJECTS_FOR_ENUM_KEYED_MAPS - opt in to storing maps with enum keys as objects
"},{"location":"api/macros/#deprecated-functions","title":"Deprecated functions","text":"
  • JSON_DELETE_DEPRECATED_FUNCTIONS - opt in to deleting the deprecated functions ahead of their removal in version 4.0.0
"},{"location":"api/macros/#comparison-behavior","title":"Comparison behavior","text":"
  • JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON - control comparison of discarded values
"},{"location":"api/macros/#serializationdeserialization-macros","title":"Serialization/deserialization macros","text":""},{"location":"api/macros/#enums","title":"Enums","text":"
  • NLOHMANN_JSON_SERIALIZE_ENUM - serialize/deserialize an enum
  • NLOHMANN_JSON_SERIALIZE_ENUM_STRICT - serialize/deserialize an enum with exceptions
"},{"location":"api/macros/#classes-and-structs","title":"Classes and structs","text":"
  • NLOHMANN_DEFINE_TYPE_INTRUSIVE - serialize/deserialize a non-derived class with private members
  • NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT - serialize/deserialize a non-derived class with private members; uses default values
  • NLOHMANN_DEFINE_TYPE_INTRUSIVE_ONLY_SERIALIZE - serialize a non-derived class with private members
  • NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE - serialize/deserialize a non-derived class
  • NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT - serialize/deserialize a non-derived class; uses default values
  • NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE - serialize a non-derived class

  • NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE - serialize/deserialize a derived class with private members

  • NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_WITH_DEFAULT - serialize/deserialize a derived class with private members; uses default values
  • NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_ONLY_SERIALIZE - serialize a derived class with private members
  • NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE - serialize/deserialize a derived class
  • NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_WITH_DEFAULT - serialize/deserialize a derived class; uses default values
  • NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE - serialize a derived class
  • NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_NAMES - serialize/deserialize a non-derived class with private members; uses custom names
  • NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT_WITH_NAMES - serialize/deserialize a non-derived class with private members; uses default values; uses custom names
  • NLOHMANN_DEFINE_TYPE_INTRUSIVE_ONLY_SERIALIZE_WITH_NAMES - serialize a non-derived class with private members; uses custom names
  • NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_NAMES - serialize/deserialize a non-derived class; uses custom names
  • NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT_WITH_NAMES - serialize/deserialize a non-derived class; uses default values; uses custom names
  • NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE_WITH_NAMES - serialize a non-derived class; uses custom names

  • NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_WITH_NAMES - serialize/deserialize a derived class with private members; uses custom names

  • NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_WITH_DEFAULT_WITH_NAMES - serialize/deserialize a derived class with private members; uses default values; uses custom names
  • NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_ONLY_SERIALIZE_WITH_NAMES - serialize a derived class with private members; uses custom names
  • NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_WITH_NAMES - serialize/deserialize a derived class; uses custom names
  • NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_WITH_DEFAULT_WITH_NAMES - serialize/deserialize a derived class; uses default values; uses custom names
  • NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE_WITH_NAMES - serialize a derived class; uses custom names
"},{"location":"api/macros/#see-also","title":"See also","text":"
  • Macros - guide to the supported macros
  • Runtime assertions - assertions guarding against undefined behavior
  • Arbitrary type conversions - using the NLOHMANN_DEFINE_TYPE_* macros
  • Enum conversion - using NLOHMANN_JSON_SERIALIZE_ENUM
  • The nlohmann namespace - how the library's namespace is defined and versioned
  • CMake integration - setting macros from the build system
  • Integration - integrate the library and set macros
  • Modules - macros and C++20 modules
  • Working Without Exceptions - using the library without exceptions
  • Architecture - how the library is put together
"},{"location":"api/macros/json_assert/","title":"JSON_ASSERT","text":"
#define JSON_ASSERT(x) /* value */\n

This macro controls which code is executed for runtime assertions of the library.

"},{"location":"api/macros/json_assert/#parameters","title":"Parameters","text":"x (in) expression of a scalar type"},{"location":"api/macros/json_assert/#default-definition","title":"Default definition","text":"

The default value is assert(x).

#define JSON_ASSERT(x) assert(x)\n

Therefore, assertions can be switched off by defining NDEBUG.

"},{"location":"api/macros/json_assert/#notes","title":"Notes","text":"
  • The library uses numerous assertions to guarantee invariants and to abort in case of otherwise undefined behavior (e.g., when calling operator[] with a missing object key on a const object). See page runtime assertions for more information.
  • Defining the macro to code that does not call std::abort may leave the library in an undefined state.
  • The macro is undefined outside the library.
"},{"location":"api/macros/json_assert/#examples","title":"Examples","text":"Example: default behavior

The following code will trigger an assertion at runtime:

#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    const json j = {{\"key\", \"value\"}};\n    auto v = j[\"missing\"];\n}\n

Output:

Assertion failed: (m_value.object->find(key) != m_value.object->end()), function operator[], file json.hpp, line 2144.\n
Example: user-defined behavior

The assertion reporting can be changed by defining JSON_ASSERT(x) differently.

#include <cstdio>\n#include <cstdlib>\n#define JSON_ASSERT(x) if(!(x)){fprintf(stderr, \"assertion error in %s\\n\", __FUNCTION__); std::abort();}\n\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    const json j = {{\"key\", \"value\"}};\n    auto v = j[\"missing\"];\n}\n

Output:

assertion error in operator[]\n
"},{"location":"api/macros/json_assert/#see-also","title":"See also","text":"
  • Runtime Assertions - overview documentation
  • Supported Macros - guide to all supported macros
"},{"location":"api/macros/json_assert/#version-history","title":"Version history","text":"
  • Added in version 3.9.0.
"},{"location":"api/macros/json_brace_init_copy_semantics/","title":"JSON_BRACE_INIT_COPY_SEMANTICS","text":"
#define JSON_BRACE_INIT_COPY_SEMANTICS /* value */\n

When defined to 1, single-element brace initialization of a basic_json value is treated as a copy/move of the element rather than wrapping it in a single-element array.

"},{"location":"api/macros/json_brace_init_copy_semantics/#default-definition","title":"Default definition","text":"

The default value is 0 (disabled \u2014 existing behavior is preserved).

#define JSON_BRACE_INIT_COPY_SEMANTICS 0\n
"},{"location":"api/macros/json_brace_init_copy_semantics/#notes","title":"Notes","text":"

Background

C++ always prefers the initializer_list constructor over the copy/move constructor for brace initialization. This means that code like

json obj = {{\"key\", \"value\"}};\njson j{obj};\n

creates a single-element array [{\"key\":\"value\"}] instead of a copy of obj. This behavior is compiler-dependent for older compilers (GCC wrapped, Clang did not), but starting from Clang 20, both compilers behave the same way.

Enabling this macro opts into copy/move semantics for this case (see #5074).

Opt-in only

This macro must be defined before including <nlohmann/json.hpp>. Defining it after the include has no effect.

Applies to every single-element list

The macro does not only affect a single JSON value in braces. Any single-element braced list is treated as its element, so it no longer creates a one-element array:

json j1 = {1};       // 1, not [1]\njson j2 = {\"text\"};  // \"text\", not [\"text\"]\njson j3 = {{1, 2}};  // [1,2], not [[1,2]]\n

Code that relies on these producing arrays must use json::array() instead (see below). Lists with more than one element, and a single [string, value] pair written as a braced list, such as {{\"key\", \"value\"}}, which still creates an object, are not affected. This exception is based on how the pair is written, not on the shape of its value: an existing JSON value that happens to be a two-element array with a string as its first element, such as json arr = {\"key\", 42};, is still copied by json j{arr}; rather than turned into an object. The library's own conversions are not affected either: for example, std::tuple<int>{5} still becomes [5].

ABI compatibility

The value of this macro is encoded in the namespace (tag _bics), resulting in distinct symbol names. Translation units compiled with and without it can therefore be linked into the same program without One Definition Rule (ODR) violations, but they cannot exchange instances of library types.

Workaround without the macro

To explicitly create a single-element array without enabling this macro, use json::array():

json j = json::array({obj});  // always creates [obj]\n
"},{"location":"api/macros/json_brace_init_copy_semantics/#examples","title":"Examples","text":"Example: default behavior (macro not defined)

Without the macro, single-element brace initialization wraps the value in an array:

#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    json obj = {{\"key\", \"value\"}};\n\n    json j{obj};\n    // j is [{\"key\":\"value\"}]  -- single-element array, NOT a copy of obj\n}\n
Example: opt-in copy semantics (macro defined to 1)

With the macro, single-element brace initialization copies/moves the value:

#define JSON_BRACE_INIT_COPY_SEMANTICS 1\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    json obj = {{\"key\", \"value\"}};\n\n    json j{obj};\n    // j is {\"key\":\"value\"}  -- copy of obj\n}\n
"},{"location":"api/macros/json_brace_init_copy_semantics/#see-also","title":"See also","text":"
  • FAQ: Brace initialization yields arrays - why brace initialization may create arrays
  • basic_json(initializer_list_t) - the affected constructor
  • Creating JSON values - initializer lists and braces
"},{"location":"api/macros/json_brace_init_copy_semantics/#version-history","title":"Version history","text":"
  • Added in version 3.13.0 unreleased.
  • Planned to become the default (with the macro removed) in version 4.0.0.
"},{"location":"api/macros/json_delete_deprecated_functions/","title":"JSON_DELETE_DEPRECATED_FUNCTIONS","text":"
#define JSON_DELETE_DEPRECATED_FUNCTIONS /* value */\n

When defined to 1, all deprecated functions of the library are declared as deleted (= delete) instead of only being marked as deprecated. Code that still calls one of them no longer compiles. This way, you can find all calls that need to be replaced before version 4.0.0 unreleased removes these functions; the migration guide describes how.

A deleted function, unlike a removed one, still takes part in overload resolution. A call that would select it therefore fails to compile instead of silently selecting another overload. This matters for the deprecated from_*(ptr, len) overloads of from_cbor, from_msgpack, from_ubjson, from_bjdata, from_bon8, and from_bson: without them, a call like from_cbor(ptr, len) would compile, read ptr as a NUL-terminated string, and convert len to the strict parameter.

The macro does not affect the deprecated legacy comparison of discarded values, which is controlled by JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON.

"},{"location":"api/macros/json_delete_deprecated_functions/#default-definition","title":"Default definition","text":"

The default value is 0 (disabled, the deprecated functions can still be called, and the compiler warns about it).

#define JSON_DELETE_DEPRECATED_FUNCTIONS 0\n
"},{"location":"api/macros/json_delete_deprecated_functions/#notes","title":"Notes","text":"

CMake option

The macro can also be set with the CMake option JSON_DeleteDeprecatedFunctions (OFF by default).

Opt-in only

This macro must be defined before including <nlohmann/json.hpp>. Defining it after the include has no effect. Define it for the whole project to avoid different declarations of the same class in different translation units.

ABI compatibility

The macro only turns calls that compile into calls that do not; it does not change the layout or the behavior of any type. Its value is therefore not encoded in the namespace.

"},{"location":"api/macros/json_delete_deprecated_functions/#examples","title":"Examples","text":"Example: default behavior (macro not defined)

Without the macro, the deprecated overload is called, and the compiler warns about it:

#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    const std::vector<std::uint8_t> v = {0x82, 0x01, 0x02};\n    auto j = json::from_cbor(v.data(), v.size());\n    // warning: 'from_cbor' is deprecated: Since 3.8.0; use from_cbor(ptr, ptr + len)\n}\n
Example: deleted deprecated functions (macro defined to 1)

With the macro, the call does not compile:

#define JSON_DELETE_DEPRECATED_FUNCTIONS 1\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    const std::vector<std::uint8_t> v = {0x82, 0x01, 0x02};\n    auto j = json::from_cbor(v.data(), v.size());\n    // error: call to deleted function 'from_cbor'\n}\n
"},{"location":"api/macros/json_delete_deprecated_functions/#see-also","title":"See also","text":"
  • Roadmap: removal of deprecated functions - the deprecated functions and the version they were deprecated in
  • Migration guide: replace deprecated functions - how to replace each deprecated function
  • Supported Macros - guide to all supported macros
  • CMake - the corresponding CMake option
"},{"location":"api/macros/json_delete_deprecated_functions/#version-history","title":"Version history","text":"
  • Added in version 3.13.0 unreleased.
  • Planned to be removed in version 4.0.0, which removes the deprecated functions. The deprecated from_*(ptr, len) overloads stay deleted in version 4.0.0 unreleased.
"},{"location":"api/macros/json_diagnostic_positions/","title":"JSON_DIAGNOSTIC_POSITIONS","text":"
#define JSON_DIAGNOSTIC_POSITIONS /* value */\n

This macro enables position diagnostics for generated JSON objects.

When enabled, two new member functions start_pos() and end_pos() are added to basic_json values. If the value was created by calling theparse function, then these functions allow querying the byte positions of the value in the input it was parsed from. In case the value was constructed by other means, std::string::npos is returned.

start_pos() returns the position of the first character of a given value in the original JSON string, while end_pos() returns the position of the character following the last character. For objects and arrays, the first and last characters correspond to the opening or closing braces/brackets, respectively. For primitive values, the first and last character represents the opening and closing quotes (strings) or the first and last character of the field's numerical or predefined value (true, false, null), respectively.

JSON type return value start_pos() return value end_pos() object position of the opening { position after the closing } array position of the opening [ position after the closing ] string position of the opening \" position after the closing \" number position of the first character position after the last character boolean position of t for true and f for false position after e null position of n position after l

Given the above, end_pos()-start_pos() for a JSON value provides the length of the parsed JSON string for that value, including the opening or closing braces, brackets, or quotes.

Note that enabling this macro increases the size of every JSON value by two std::size_t fields and adds slight runtime overhead to parsing, copying JSON value objects, and the generation of error messages for exceptions. It also causes these values to be reported in those error messages.

"},{"location":"api/macros/json_diagnostic_positions/#default-definition","title":"Default definition","text":"

The default value is 0 (position diagnostics are switched off).

#define JSON_DIAGNOSTIC_POSITIONS 0\n

When the macro is not defined, the library will define it to its default value.

"},{"location":"api/macros/json_diagnostic_positions/#notes","title":"Notes","text":"

CMake option

Diagnostic positions can also be controlled with the CMake option JSON_Diagnostic_Positions (OFF by default) which defines JSON_DIAGNOSTIC_POSITIONS accordingly.

Availability

Diagnostic positions are only available if the value was created by the parse function. The sax_parse function or all other means to create a JSON value do not set the diagnostic positions and start_pos() and end_pos() will only return std::string::npos for these values.

Invalidation

The returned positions are only valid as long as the JSON value is not changed. The positions are not updated when the JSON value is changed.

"},{"location":"api/macros/json_diagnostic_positions/#examples","title":"Examples","text":"Example: retrieving positions
#include <iostream>\n\n#define JSON_DIAGNOSTIC_POSITIONS 1\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    std::string json_string = R\"(\n    {\n        \"address\": {\n            \"street\": \"Fake Street\",\n            \"housenumber\": 1\n        }\n    }\n    )\";\n    json j = json::parse(json_string);\n\n    std::cout << \"Root diagnostic positions: \\n\";\n    std::cout << \"\\tstart_pos: \" << j.start_pos() << '\\n';\n    std::cout << \"\\tend_pos:\" << j.end_pos() << \"\\n\";\n    std::cout << \"Original string: \\n\";\n    std::cout << \"{\\n        \\\"address\\\": {\\n            \\\"street\\\": \\\"Fake Street\\\",\\n            \\\"housenumber\\\": 1\\n        }\\n    }\" << \"\\n\";\n    std::cout << \"Parsed string: \\n\";\n    std::cout << json_string.substr(j.start_pos(), j.end_pos() - j.start_pos()) << \"\\n\\n\";\n\n    std::cout << \"address diagnostic positions: \\n\";\n    std::cout << \"\\tstart_pos:\" << j[\"address\"].start_pos() << '\\n';\n    std::cout << \"\\tend_pos:\" << j[\"address\"].end_pos() << \"\\n\\n\";\n    std::cout << \"Original string: \\n\";\n    std::cout << \"{            \\\"street\\\": \\\"Fake Street\\\",\\n            \\\"housenumber\\\": 1\\n        }\" << \"\\n\";\n    std::cout << \"Parsed string: \\n\";\n    std::cout << json_string.substr(j[\"address\"].start_pos(), j[\"address\"].end_pos() - j[\"address\"].start_pos()) << \"\\n\\n\";\n\n    std::cout << \"street diagnostic positions: \\n\";\n    std::cout << \"\\tstart_pos:\" << j[\"address\"][\"street\"].start_pos() << '\\n';\n    std::cout << \"\\tend_pos:\" << j[\"address\"][\"street\"].end_pos() << \"\\n\\n\";\n    std::cout << \"Original string: \\n\";\n    std::cout << \"\\\"Fake Street\\\"\" << \"\\n\";\n    std::cout << \"Parsed string: \\n\";\n    std::cout << json_string.substr(j[\"address\"][\"street\"].start_pos(), j[\"address\"][\"street\"].end_pos() - j[\"address\"][\"street\"].start_pos()) << \"\\n\\n\";\n\n    std::cout << \"housenumber diagnostic positions: \\n\";\n    std::cout << \"\\tstart_pos:\" << j[\"address\"][\"housenumber\"].start_pos() << '\\n';\n    std::cout << \"\\tend_pos:\" << j[\"address\"][\"housenumber\"].end_pos() << \"\\n\\n\";\n    std::cout << \"Original string: \\n\";\n    std::cout << \"1\" << \"\\n\";\n    std::cout << \"Parsed string: \\n\";\n    std::cout << json_string.substr(j[\"address\"][\"housenumber\"].start_pos(), j[\"address\"][\"housenumber\"].end_pos() - j[\"address\"][\"housenumber\"].start_pos()) << \"\\n\\n\";\n}\n

Output:

Root diagnostic positions: \n    start_pos: 5\n    end_pos:109\nOriginal string: \n{\n        \"address\": {\n            \"street\": \"Fake Street\",\n            \"housenumber\": 1\n        }\n    }\nParsed string: \n{\n        \"address\": {\n            \"street\": \"Fake Street\",\n            \"housenumber\": 1\n        }\n    }\n\naddress diagnostic positions: \n    start_pos:26\n    end_pos:103\n\nOriginal string: \n{            \"street\": \"Fake Street\",\n            \"housenumber\": 1\n        }\nParsed string: \n{\n            \"street\": \"Fake Street\",\n            \"housenumber\": 1\n        }\n\nstreet diagnostic positions: \n    start_pos:50\n    end_pos:63\n\nOriginal string: \n\"Fake Street\"\nParsed string: \n\"Fake Street\"\n\nhousenumber diagnostic positions: \n    start_pos:92\n    end_pos:93\n\nOriginal string: \n1\nParsed string: \n1\n

The output shows the start/end positions of all the objects and fields in the JSON string.

Example: using only diagnostic positions in exceptions
#include <iostream>\n\n#define JSON_DIAGNOSTIC_POSITIONS 1\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\n/* Demonstration of type error exception with diagnostic positions support enabled */\nint main()\n{\n    //Invalid json string - housenumber type must be int instead of string\n    const std::string json_invalid_string = R\"(\n    {\n        \"address\": {\n            \"street\": \"Fake Street\",\n            \"housenumber\": \"1\"\n        }\n    }\n    )\";\n    json j = json::parse(json_invalid_string);\n    try\n    {\n        int housenumber = j[\"address\"][\"housenumber\"];\n        std::cout << housenumber;\n    }\n    catch (const json::exception& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n}\n

Output:

[json.exception.type_error.302] (bytes 92-95) type must be number, but is string\n
The output shows the exception with start/end positions only.\n
Example: using extended diagnostics with positions enabled in exceptions
#include <iostream>\n\n#define JSON_DIAGNOSTICS 1\n#define JSON_DIAGNOSTIC_POSITIONS 1\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\n/* Demonstration of type error exception with diagnostic positions support enabled */\nint main()\n{\n    //Invalid json string - housenumber type must be int instead of string\n    const std::string json_invalid_string = R\"(\n    {\n        \"address\": {\n            \"street\": \"Fake Street\",\n            \"housenumber\": \"1\"\n        }\n    }\n    )\";\n    json j = json::parse(json_invalid_string);\n    try\n    {\n        int housenumber = j[\"address\"][\"housenumber\"];\n        std::cout << housenumber;\n    }\n    catch (const json::exception& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n}\n

Output:

[json.exception.type_error.302] (/address/housenumber) (bytes 92-95) type must be number, but is string\n
The output shows the exception with diagnostic path info and start/end positions.\n
"},{"location":"api/macros/json_diagnostic_positions/#see-also","title":"See also","text":"
  • JSON_Diagnostic_Positions - CMake option to control the macro
  • JSON_DIAGNOSTICS - macro to control extended diagnostics
  • Parsing and Exceptions - handling parse errors and locating them in the input
"},{"location":"api/macros/json_diagnostic_positions/#version-history","title":"Version history","text":"
  • Added in version 3.12.0.
"},{"location":"api/macros/json_diagnostics/","title":"JSON_DIAGNOSTICS","text":"
#define JSON_DIAGNOSTICS /* value */\n

This macro enables extended diagnostics for exception messages. Possible values are 1 to enable or 0 to disable (default).

When enabled, exception messages contain a JSON Pointer to the JSON value that triggered the exception. Note that enabling this macro increases the size of every JSON value by one pointer and adds some runtime overhead.

"},{"location":"api/macros/json_diagnostics/#default-definition","title":"Default definition","text":"

The default value is 0 (extended diagnostics are switched off).

#define JSON_DIAGNOSTICS 0\n

When the macro is not defined, the library will define it to its default value.

"},{"location":"api/macros/json_diagnostics/#notes","title":"Notes","text":"

ABI compatibility

As of version 3.11.0, this macro is no longer required to be defined consistently throughout a codebase to avoid One Definition Rule (ODR) violations, as the value of this macro is encoded in the namespace, resulting in distinct symbol names.

This allows different parts of a codebase to use different versions or configurations of this library without causing improper behavior.

Where possible, it is still recommended that all code define this the same way for maximum interoperability.

CMake option

Diagnostic messages can also be controlled with the CMake option JSON_Diagnostics (OFF by default) which defines JSON_DIAGNOSTICS accordingly. Note this only applies when building the library from source \u2014 see the pre-installed-package caveat on that page.

"},{"location":"api/macros/json_diagnostics/#examples","title":"Examples","text":"Example: default behavior
#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    json j;\n    j[\"address\"][\"street\"] = \"Fake Street\";\n    j[\"address\"][\"housenumber\"] = \"12\";\n\n    try\n    {\n        int housenumber = j[\"address\"][\"housenumber\"];\n    }\n    catch (const json::exception& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n}\n

Output:

[json.exception.type_error.302] type must be number, but is string\n

This exception can be hard to debug if storing the value \"12\" and accessing it is further apart.

Example: extended diagnostic messages
#include <iostream>\n\n# define JSON_DIAGNOSTICS 1\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    json j;\n    j[\"address\"][\"street\"] = \"Fake Street\";\n    j[\"address\"][\"housenumber\"] = \"12\";\n\n    try\n    {\n        int housenumber = j[\"address\"][\"housenumber\"];\n    }\n    catch (const json::exception& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n}\n

Output:

[json.exception.type_error.302] (/address/housenumber) type must be number, but is string\n

Now the exception message contains a JSON Pointer /address/housenumber that indicates which value has the wrong type.

Example: using only diagnostic positions in exceptions
#include <iostream>\n\n#define JSON_DIAGNOSTIC_POSITIONS 1\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\n/* Demonstration of type error exception with diagnostic positions support enabled */\nint main()\n{\n    //Invalid json string - housenumber type must be int instead of string\n    const std::string json_invalid_string = R\"(\n    {\n        \"address\": {\n            \"street\": \"Fake Street\",\n            \"housenumber\": \"1\"\n        }\n    }\n    )\";\n    json j = json::parse(json_invalid_string);\n    try\n    {\n        int housenumber = j[\"address\"][\"housenumber\"];\n        std::cout << housenumber;\n    }\n    catch (const json::exception& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n}\n

Output:

[json.exception.type_error.302] (bytes 92-95) type must be number, but is string\n
The output shows the exception with start/end positions only.

"},{"location":"api/macros/json_diagnostics/#see-also","title":"See also","text":"
  • JSON_Diagnostics - CMake option to control the macro
  • JSON_DIAGNOSTIC_POSITIONS - macro to access positions of elements
  • Supported Macros - guide to all supported macros
  • Exceptions: extended diagnostic messages - how extended diagnostics change the messages
  • Debugging - debugging aids
  • exception - base class of all exceptions thrown by the library
"},{"location":"api/macros/json_diagnostics/#version-history","title":"Version history","text":"
  • Added in version 3.10.0.
  • As of version 3.11.0, the definition is allowed to vary between translation units.
"},{"location":"api/macros/json_disable_enum_serialization/","title":"JSON_DISABLE_ENUM_SERIALIZATION","text":"
#define JSON_DISABLE_ENUM_SERIALIZATION /* value */\n

When defined to 1, default serialization and deserialization functions for enums are excluded and have to be provided by the user, for example, using NLOHMANN_JSON_SERIALIZE_ENUM (see arbitrary type conversions for more details).

Parsing or serializing an enum will result in a compiler error.

This works for both unscoped and scoped enums.

"},{"location":"api/macros/json_disable_enum_serialization/#default-definition","title":"Default definition","text":"

The default value is 0.

#define JSON_DISABLE_ENUM_SERIALIZATION 0\n
"},{"location":"api/macros/json_disable_enum_serialization/#notes","title":"Notes","text":"

CMake option

Enum serialization can also be controlled with the CMake option JSON_DisableEnumSerialization (OFF by default) which defines JSON_DISABLE_ENUM_SERIALIZATION accordingly.

"},{"location":"api/macros/json_disable_enum_serialization/#examples","title":"Examples","text":"Example: Disabled behavior

The code below forces the library not to create default serialization/deserialization functions from_json and to_json, meaning the code below does not compile.

#define JSON_DISABLE_ENUM_SERIALIZATION 1\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nenum class Choice\n{\n    first,\n    second,\n};\n\nint main()\n{\n    // normally invokes to_json serialization function but with JSON_DISABLE_ENUM_SERIALIZATION defined, it does not\n    const json j = Choice::first; \n\n    // normally invokes from_json parse function but with JSON_DISABLE_ENUM_SERIALIZATION defined, it does not\n    Choice ch = j.get<Choice>();\n}\n
Example: Serialize enum macro

The code below forces the library not to create default serialization/deserialization functions from_json and to_json, but uses NLOHMANN_JSON_SERIALIZE_ENUM to parse and serialize the enum.

#define JSON_DISABLE_ENUM_SERIALIZATION 1\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nenum class Choice\n{\n    first,\n    second,\n};\n\nNLOHMANN_JSON_SERIALIZE_ENUM(Choice,\n{\n    { Choice::first, \"first\" },\n    { Choice::second, \"second\" },\n})\n\nint main()\n{\n    // uses user-defined to_json function defined by macro\n    const json j = Choice::first; \n\n    // uses user-defined from_json function defined by macro\n    Choice ch = j.get<Choice>();\n}\n
Example: User-defined serialization/deserialization functions

The code below forces the library not to create default serialization/deserialization functions from_json and to_json, but uses user-defined functions to parse and serialize the enum.

#define JSON_DISABLE_ENUM_SERIALIZATION 1\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nenum class Choice\n{\n    first,\n    second,\n};\n\nvoid from_json(const json& j, Choice& ch)\n{\n    auto value = j.get<std::string>();\n    if (value == \"first\")\n    {\n        ch = Choice::first;\n    }\n    else if (value == \"second\")\n    {\n        ch = Choice::second;\n    }\n}\n\nvoid to_json(json& j, const Choice& ch)\n{\n    if (ch == Choice::first)\n    {\n        j = \"first\";\n    }\n    else if (ch == Choice::second)\n    {\n        j = \"second\";\n    }\n}\n\nint main()\n{\n    // uses user-defined to_json function\n    const json j = Choice::first; \n\n    // uses user-defined from_json function\n    Choice ch = j.get<Choice>();\n}\n
"},{"location":"api/macros/json_disable_enum_serialization/#see-also","title":"See also","text":"
  • JSON_DisableEnumSerialization - CMake option to control the macro
  • NLOHMANN_JSON_SERIALIZE_ENUM - serialize/deserialize an enum
  • Specializing enum conversion - map enums to JSON strings instead of integers
"},{"location":"api/macros/json_disable_enum_serialization/#version-history","title":"Version history","text":"
  • Added in version 3.11.0.
"},{"location":"api/macros/json_disable_stream_bulk_scan/","title":"JSON_DISABLE_STREAM_BULK_SCAN","text":"
#define JSON_DISABLE_STREAM_BULK_SCAN /* value */\n

When defined to 1, parsing from a std::istream reads the input one character at a time through the stream buffer, as in version 3.12.0 and earlier, instead of scanning the characters that the stream buffer already holds in bulk.

The macro is an escape hatch for stream buffers that do not follow the usual contract of std::basic_streambuf (see the requirements on the stream buffer in the notes below). It does not change any result: values, exceptions, and the position of the stream after parsing are the same either way. Only the speed differs.

"},{"location":"api/macros/json_disable_stream_bulk_scan/#default-definition","title":"Default definition","text":"

The default value is 0: streams are scanned in bulk.

#define JSON_DISABLE_STREAM_BULK_SCAN 0\n
"},{"location":"api/macros/json_disable_stream_bulk_scan/#notes","title":"Notes","text":"

How streams are scanned

A std::streambuf keeps the part of the input it has read but not yet handed out in its get area, the range from gptr() to egptr(). A std::filebuf, for instance, reads the file in blocks of a few kilobytes into its get area, and a std::stringbuf exposes its whole string as one get area.

When parsing from a std::istream, the parser scans this get area directly, with the same fast paths that it uses for a std::string: runs of ordinary string characters, numbers, and indentation are recognized several bytes at a time instead of being requested from the stream buffer one character at a time. When the parser reaches the end of the get area, it asks the stream buffer for the next character as before, which makes the stream buffer refill its get area.

The parser only reads characters that it would also have read one at a time, and it advances the stream buffer exactly over the characters it consumes. Nothing is read ahead, buffered elsewhere, or put back. Therefore, the stream is left exactly where it was left before:

  • operator>> and sax_parse with strict = false can still read several values from one stream, and the stream can still be used with other std::istream functions after a value has been read.
  • With JSON_PRECISE_STREAM_POSITION, the stream is still positioned right after a parsed number.
  • Exception messages, including the line, the column, and the last read token, are unchanged.

Performance

Parsing from a std::ifstream or std::istringstream is typically 1.5 to 2 times as fast as before, and reading many small values from one stream with operator>> 1.4 to 4 times as fast. Parsing from a stream is then within about 10 to 20 % of first reading the whole file into a std::string and parsing that.

A stream buffer without a get area (one that only overrides underflow() and uflow() and hands out every character from there) offers nothing to scan in bulk, so it is read one character at a time as before.

Requirements on the stream buffer

The bulk scan relies on the following behavior, which every stream buffer of the standard library and every stream buffer that keeps its input in its get area has:

  • When sgetc() returns a character while gptr() < egptr(), that character is *gptr(); when sbumpc() returns one, it was at gptr() before the call.
  • Characters in the get area are not changed while they are in the get area.
  • underflow() or uflow() either sets up a get area that holds the returned character at gptr() (or at gptr() - 1 after uflow()), or leaves the get area empty.

A stream buffer that returns characters from uflow() while leaving unrelated characters in its get area, or that changes the characters in its get area in place, does not meet these requirements. Define the macro to 1 for such stream buffers.

ABI compatibility

The value of this macro is encoded in the namespace (tag _dsbs), resulting in distinct symbol names. Translation units compiled with and without it can therefore be linked into the same program without One Definition Rule (ODR) violations, but they cannot exchange instances of library types.

Other inputs

Strings, string views, vectors, arrays, and pointer or iterator ranges over contiguous memory are scanned in bulk anyway. Reading from a FILE* is not affected by this macro; see JSON_DISABLE_UNLOCKED_FILE_IO for that input.

"},{"location":"api/macros/json_disable_stream_bulk_scan/#examples","title":"Examples","text":"Example: reading values from a stream (default)

The stream is scanned in bulk, and the values are read one after the other:

#include <iostream>\n#include <sstream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    std::istringstream input(R\"({\"id\": 1} {\"id\": 2} 42 rest)\");\n    json j1, j2, j3;\n    input >> j1 >> j2 >> j3;  // {\"id\":1}, {\"id\":2}, 42\n\n    std::string word;\n    input >> word;            // \"rest\"\n}\n
Example: reading one character at a time (macro defined to 1)

With the macro, the same program reads the stream one character at a time, with the same results:

#define JSON_DISABLE_STREAM_BULK_SCAN 1\n#include <iostream>\n#include <sstream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    std::istringstream input(R\"({\"id\": 1} {\"id\": 2} 42 rest)\");\n    json j1, j2, j3;\n    input >> j1 >> j2 >> j3;  // {\"id\":1}, {\"id\":2}, 42\n\n    std::string word;\n    input >> word;            // \"rest\"\n}\n
"},{"location":"api/macros/json_disable_stream_bulk_scan/#see-also","title":"See also","text":"
  • parse - deserialize from a compatible input
  • operator>> - deserialize from stream
  • sax_parse - generate SAX events
  • JSON_PRECISE_STREAM_POSITION - leave an input stream positioned right after a parsed number
  • JSON_DISABLE_UNLOCKED_FILE_IO - read a FILE* with the locking stdio functions
  • Parsing: input sources and performance - how input sources affect parsing performance
  • Large, Streamed, and Partial Input - chunked, concatenated, and very large input
"},{"location":"api/macros/json_disable_stream_bulk_scan/#version-history","title":"Version history","text":"
  • Added in version 3.13.0 unreleased.
"},{"location":"api/macros/json_disable_tuple_reference_conversion/","title":"JSON_DISABLE_TUPLE_REFERENCE_CONVERSION","text":"
#define JSON_DISABLE_TUPLE_REFERENCE_CONVERSION /* value */\n

When defined to 1, a basic_json value can no longer be constructed from a one-element std::tuple whose element is a reference to that basic_json type, such as std::tuple<json&>, std::tuple<const json&>, or std::tuple<json&&>. These are the tuples created by std::forward_as_tuple(j).

"},{"location":"api/macros/json_disable_tuple_reference_conversion/#default-definition","title":"Default definition","text":"

The default value is 0 (disabled \u2014 existing behavior is preserved).

#define JSON_DISABLE_TUPLE_REFERENCE_CONVERSION 0\n
"},{"location":"api/macros/json_disable_tuple_reference_conversion/#notes","title":"Notes","text":"

Background

By default, basic_json can be constructed from any std::tuple whose elements can be converted to JSON; the result is an array. This includes std::tuple<json&>, which becomes a one-element array.

std::tuple only converts another tuple element by element if its element type cannot be constructed from the whole source tuple. Because json can be constructed from std::tuple<json&>, std::tuple instead converts the whole tuple into a single json value. This has two surprising effects:

json j = true;\n\n// rejected by some standard libraries (e.g., libc++); with others, the\n// reference binds to a temporary that is destroyed right away\nstd::tuple<const json&> t1(std::forward_as_tuple(j));\n\n// compiles, but std::get<0>(t2) is [true], not true\nstd::tuple<json> t2(std::forward_as_tuple(j));\n

Enabling this macro removes the conversion, so both tuples are converted element by element: std::get<0>(t1) refers to j, and std::get<0>(t2) is a copy of j (see #2226).

Opt-in only

This macro must be defined before including <nlohmann/json.hpp>. Defining it after the include has no effect.

Affected conversions

Only one-element tuples holding a reference to the same basic_json type are affected. Constructing a JSON value from them no longer compiles:

json j = true;\njson a = std::forward_as_tuple(j);  // error with the macro enabled\njson b = json::array({j});          // use this instead: [true]\n

Tuples holding a JSON value (std::make_tuple(j)), tuples with more than one element, and tuples holding references to other types (including other basic_json specializations) are converted to arrays as before.

CMake option

This behavior can also be controlled with the CMake option JSON_DisableTupleReferenceConversion (OFF by default) which defines JSON_DISABLE_TUPLE_REFERENCE_CONVERSION accordingly.

"},{"location":"api/macros/json_disable_tuple_reference_conversion/#examples","title":"Examples","text":"Example: default behavior (macro not defined)
#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    json j = true;\n\n    std::tuple<json> t(std::forward_as_tuple(j));\n    // std::get<0>(t) is [true] -- the whole tuple was converted\n}\n
Example: conversion disabled (macro defined to 1)
#define JSON_DISABLE_TUPLE_REFERENCE_CONVERSION 1\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    json j = true;\n\n    std::tuple<json> t(std::forward_as_tuple(j));\n    // std::get<0>(t) is true -- a copy of j\n\n    std::tuple<const json&> r(std::forward_as_tuple(j));\n    // std::get<0>(r) refers to j\n}\n
"},{"location":"api/macros/json_disable_tuple_reference_conversion/#see-also","title":"See also","text":"
  • basic_json(CompatibleType&&) - the affected constructor
  • JSON_DisableTupleReferenceConversion - CMake option to control the macro
  • Converting values - getting values out
  • Arbitrary Type Conversions - converting your own types
"},{"location":"api/macros/json_disable_tuple_reference_conversion/#version-history","title":"Version history","text":"
  • Added in version 3.13.0 unreleased.
  • Planned to become the default (with the macro removed) in version 4.0.0.
"},{"location":"api/macros/json_disable_unlocked_file_io/","title":"JSON_DISABLE_UNLOCKED_FILE_IO","text":"
#define JSON_DISABLE_UNLOCKED_FILE_IO /* value */\n

When defined to 1, parsing from a FILE* reads every character with std::fgetc, as in version 3.12.0 and earlier, instead of locking the file once and reading it with the unlocked stdio functions.

It does not change any result: values, exceptions, and the position of the file after parsing are the same either way. Only the speed and the locking of the file differ (see the notes on locking below).

Builds with MemorySanitizer use std::fgetc automatically, because the inline getc_unlocked of glibc reads the stdio buffer directly, which glibc (not instrumented) filled, and MemorySanitizer would report it as uninitialized.

"},{"location":"api/macros/json_disable_unlocked_file_io/#default-definition","title":"Default definition","text":"

The default value is 0: the file is locked once and read with the unlocked stdio functions where they are available.

#define JSON_DISABLE_UNLOCKED_FILE_IO 0\n
"},{"location":"api/macros/json_disable_unlocked_file_io/#notes","title":"Notes","text":"

Background

The C standard library makes every std::fgetc call thread-safe by locking and unlocking the FILE object. When parsing from a FILE*, the parser reads one character at a time, so this happens for every character of the input.

Instead, the parser locks the file once when parsing starts and unlocks it when parsing ends - also when an exception is thrown - and reads the characters in between without locking:

C library functions glibc (Linux), Apple (macOS, iOS), Android, FreeBSD, NetBSD, OpenBSD, DragonFly BSD flockfile, getc_unlocked, funlockfile (POSIX) Microsoft (MSVC, clang-cl) _lock_file, _fgetc_nolock, _unlock_file others (e.g., musl, MinGW, newlib) std::fgetc, as before

This makes parsing from a FILE* 3 to 4 times as fast with the Apple C library and 1.1 to 1.3 times as fast with glibc, whose locking is cheaper. The binary formats (from_cbor, from_msgpack, ...) read from a FILE* the same way.

Locking

While a value is parsed from a FILE*, the parsing thread holds the file's lock. The lock is recursive, so the parsing thread itself - for instance, a SAX handler or a parser callback - can keep using the file with stdio functions such as std::ftell. Other threads that use the same FILE object wait until the parser is done. Before, they could interleave their reads with the parser's, which made the parsed input unpredictable anyway.

A program in which a SAX handler or parser callback waits for another thread that uses the same FILE object would deadlock. Define the macro to 1 for such programs.

ABI compatibility

The value of this macro is encoded in the namespace (tag _dufio), resulting in distinct symbol names. Translation units compiled with and without it can therefore be linked into the same program without One Definition Rule (ODR) violations, but they cannot exchange instances of library types.

Other inputs

Reading from a std::istream is not affected by this macro; see JSON_DISABLE_STREAM_BULK_SCAN for that input.

"},{"location":"api/macros/json_disable_unlocked_file_io/#examples","title":"Examples","text":"Example: parsing from a FILE* (default)

The file is locked once while it is parsed:

#include <cstdio>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    std::FILE* f = std::fopen(\"example.json\", \"rb\");\n    json j = json::parse(f);  // f is locked until parse() returns\n    std::fclose(f);\n}\n
Example: locking for every character (macro defined to 1)

With the macro, every character is read with std::fgetc, with the same result:

#define JSON_DISABLE_UNLOCKED_FILE_IO 1\n#include <cstdio>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    std::FILE* f = std::fopen(\"example.json\", \"rb\");\n    json j = json::parse(f);  // std::fgetc for every character\n    std::fclose(f);\n}\n
"},{"location":"api/macros/json_disable_unlocked_file_io/#see-also","title":"See also","text":"
  • parse - deserialize from a compatible input
  • sax_parse - generate SAX events
  • JSON_DISABLE_STREAM_BULK_SCAN - read a std::istream one character at a time
  • Parsing: input sources and performance - how input sources affect parsing performance
  • Large, Streamed, and Partial Input - chunked, concatenated, and very large input
"},{"location":"api/macros/json_disable_unlocked_file_io/#version-history","title":"Version history","text":"
  • Added in version 3.13.0 unreleased.
"},{"location":"api/macros/json_has_cpp_11/","title":"JSON_HAS_CPP_11, JSON_HAS_CPP_14, JSON_HAS_CPP_17, JSON_HAS_CPP_20, JSON_HAS_CPP_23, JSON_HAS_CPP_26","text":"
#define JSON_HAS_CPP_11\n#define JSON_HAS_CPP_14\n#define JSON_HAS_CPP_17\n#define JSON_HAS_CPP_20\n#define JSON_HAS_CPP_23\n#define JSON_HAS_CPP_26\n

The library targets C++11, but also supports some features introduced in later C++ versions (e.g., std::string_view support for C++17). For these new features, the library implements some preprocessor checks to determine the C++ standard. By defining any of these symbols, the internal check is overridden and the provided C++ version is unconditionally assumed. This can be helpful for compilers that only implement parts of the standard and would be detected incorrectly.

"},{"location":"api/macros/json_has_cpp_11/#default-definition","title":"Default definition","text":"

The default value is detected based on preprocessor macros such as __cplusplus, _HAS_CXX17, or _MSVC_LANG.

"},{"location":"api/macros/json_has_cpp_11/#notes","title":"Notes","text":"
  • When the C++ standard is detected automatically, JSON_HAS_CPP_11 is always defined. When you override the detection by defining one of these macros manually, the automatic detection is skipped entirely, so you should define all applicable macros (including JSON_HAS_CPP_11) yourself.
  • All macros are undefined outside the library.
"},{"location":"api/macros/json_has_cpp_11/#examples","title":"Examples","text":"Example

The code below forces the library to use the C++14 standard:

#define JSON_HAS_CPP_14 1\n#include <nlohmann/json.hpp>\n\n...\n
"},{"location":"api/macros/json_has_cpp_11/#see-also","title":"See also","text":"
  • JSON_HAS_FILESYSTEM / JSON_HAS_EXPERIMENTAL_FILESYSTEM - control std::filesystem support
  • JSON_HAS_RANGES - control std::ranges support
  • JSON_HAS_THREE_WAY_COMPARISON - control 3-way comparison support
  • JSON_HAS_STD_FORMAT - control std::format/std::formatter support
  • Supported Macros - guide to all supported macros
"},{"location":"api/macros/json_has_cpp_11/#version-history","title":"Version history","text":"
  • Added in version 3.10.0.
  • Added JSON_HAS_CPP_23 in version 3.12.0.
  • Added JSON_HAS_CPP_26 in version 3.13.0 unreleased.
"},{"location":"api/macros/json_has_filesystem/","title":"JSON_HAS_FILESYSTEM / JSON_HAS_EXPERIMENTAL_FILESYSTEM","text":"
#define JSON_HAS_FILESYSTEM /* value */\n#define JSON_HAS_EXPERIMENTAL_FILESYSTEM /* value */\n

When compiling with C++17, the library provides conversions from and to std::filesystem::path. As compiler support for filesystem is limited, the library tries to detect whether <filesystem>/std::filesystem (JSON_HAS_FILESYSTEM) or <experimental/filesystem>/std::experimental::filesystem (JSON_HAS_EXPERIMENTAL_FILESYSTEM) should be used. To override the built-in check, define JSON_HAS_FILESYSTEM or JSON_HAS_EXPERIMENTAL_FILESYSTEM to 1.

"},{"location":"api/macros/json_has_filesystem/#default-definition","title":"Default definition","text":"

The default value is detected based on the preprocessor macros __cpp_lib_filesystem, __cpp_lib_experimental_filesystem, __has_include(<filesystem>), or __has_include(<experimental/filesystem>).

Known compiler/stdlib exclusions

Even when the feature-test macro indicates filesystem support is available, the library disables it on the following broken toolchains:

  • MinGW + GCC 8 \u2014 disabled entirely (broken std::filesystem implementation; MinGW-w64 bug 737)
  • GCC (non-Clang) < 8 \u2014 disabled (no filesystem support)
  • Clang < 7 \u2014 disabled (no filesystem support)
  • MSVC < 19.14 \u2014 disabled (no filesystem support)
  • iOS < 13 \u2014 disabled (no filesystem support)
  • macOS < Catalina (10.15) \u2014 disabled (no filesystem support)

If JSON_HAS_FILESYSTEM or JSON_HAS_EXPERIMENTAL_FILESYSTEM is 0 despite __cpp_lib_filesystem being defined, one of the exclusions above likely applies to your toolchain.

"},{"location":"api/macros/json_has_filesystem/#notes","title":"Notes","text":"
  • Note that older compilers or older versions of libstdc++ also require the library stdc++fs to be linked to for filesystem support.
  • Both macros are undefined outside the library.
"},{"location":"api/macros/json_has_filesystem/#examples","title":"Examples","text":"Example

The code below forces the library to use the header <experimental/filesystem>.

#define JSON_HAS_EXPERIMENTAL_FILESYSTEM 1\n#include <nlohmann/json.hpp>\n\n...\n
"},{"location":"api/macros/json_has_filesystem/#see-also","title":"See also","text":"
  • JSON_HAS_CPP_11 / JSON_HAS_CPP_14 / JSON_HAS_CPP_17 / JSON_HAS_CPP_20 / JSON_HAS_CPP_23 / JSON_HAS_CPP_26 - set supported C++ standard
  • Supported Macros - guide to all supported macros
  • Converting values - conversions of values
"},{"location":"api/macros/json_has_filesystem/#version-history","title":"Version history","text":"
  • Added in version 3.10.5.
"},{"location":"api/macros/json_has_range_view_conversion/","title":"JSON_HAS_RANGE_VIEW_CONVERSION","text":"
#define JSON_HAS_RANGE_VIEW_CONVERSION /* value */\n

This macro indicates whether a JSON array can be constructed directly from a C++20 range view (std::ranges::view), such as the result of std::views::filter or std::views::transform. Possible values are 1 when supported or 0 when unsupported.

"},{"location":"api/macros/json_has_range_view_conversion/#default-definition","title":"Default definition","text":"

The default value is 1 if JSON_HAS_RANGES is 1 and the compiler is not MinGW (that is, __MINGW32__ is not defined), and 0 otherwise.

When the macro is not defined, the library will define it to its default value.

Known compiler/stdlib exclusions

  • MinGW \u2014 disabled, because its std::ranges support is incomplete (issue #4916).
  • All toolchains for which JSON_HAS_RANGES is disabled.
"},{"location":"api/macros/json_has_range_view_conversion/#examples","title":"Examples","text":"Example

The code below forces the library to disable the conversion from range views:

#define JSON_HAS_RANGE_VIEW_CONVERSION 0\n#include <nlohmann/json.hpp>\n\n...\n
"},{"location":"api/macros/json_has_range_view_conversion/#see-also","title":"See also","text":"
  • JSON_HAS_RANGES - control std::ranges support
  • Constructing from a C++20 range view - usage of the feature
"},{"location":"api/macros/json_has_range_view_conversion/#version-history","title":"Version history","text":"
  • Added in version 3.13.0 unreleased.
"},{"location":"api/macros/json_has_ranges/","title":"JSON_HAS_RANGES","text":"
#define JSON_HAS_RANGES /* value */\n

This macro indicates whether the standard library has any support for ranges. Implies support for concepts. Possible values are 1 when supported or 0 when unsupported.

"},{"location":"api/macros/json_has_ranges/#default-definition","title":"Default definition","text":"

The default value is detected based on the preprocessor macro __cpp_lib_ranges.

When the macro is not defined, the library will define it to its default value.

Known compiler/stdlib exclusions

Even when the feature-test macro __cpp_lib_ranges indicates ranges support is available, the library disables it on the following incomplete or broken toolchains:

  • GCC 11.1.0 \u2014 disabled (the shipped <ranges> header has a syntax error; issue #4440)
  • libstdc++ < 11 \u2014 disabled (incomplete C++20 ranges support; issue #4440)
  • Clang < 16 with libstdc++ \u2014 disabled (incomplete ranges support; issue #5161)
  • libc++ < 160000 \u2014 disabled (incomplete C++20 ranges support; issue #4440)
  • nvcc (CUDA) 12.0.x and 12.1.x \u2014 disabled (the enable_borrowed_range variable-template syntax triggers a parse error under these two toolkit versions; fixed in CUDA 12.2; issue #3907)

If JSON_HAS_RANGES is 0 despite __cpp_lib_ranges being defined, one of the exclusions above likely applies to your toolchain.

"},{"location":"api/macros/json_has_ranges/#examples","title":"Examples","text":"Example

The code below forces the library to enable support for ranges:

#define JSON_HAS_RANGES 1\n#include <nlohmann/json.hpp>\n\n...\n
"},{"location":"api/macros/json_has_ranges/#see-also","title":"See also","text":"
  • JSON_HAS_CPP_11 / JSON_HAS_CPP_14 / JSON_HAS_CPP_17 / JSON_HAS_CPP_20 / JSON_HAS_CPP_23 / JSON_HAS_CPP_26 - set supported C++ standard
  • JSON_HAS_RANGE_VIEW_CONVERSION - control construction from std::ranges views
  • JSON_HAS_STD_FORMAT - a similar feature-detection macro, for std::format/std::formatter support
  • Supported Macros - guide to all supported macros
"},{"location":"api/macros/json_has_ranges/#version-history","title":"Version history","text":"
  • Added in version 3.11.0.
  • Added the exclusions for libstdc++ < 11, Clang < 16 with libstdc++, libc++ < 16, and nvcc (CUDA) 12.0.x and 12.1.x in version 3.13.0 unreleased. Before, only GCC 11.1.0 was excluded.
"},{"location":"api/macros/json_has_static_rtti/","title":"JSON_HAS_STATIC_RTTI","text":"
#define JSON_HAS_STATIC_RTTI /* value */\n

This macro indicates whether the standard library has any support for RTTI (run time type information). Possible values are 1 when supported or 0 when unsupported.

"},{"location":"api/macros/json_has_static_rtti/#default-definition","title":"Default definition","text":"

The default value is detected based on the preprocessor macro _HAS_STATIC_RTTI.

When the macro is not defined, the library will define it to its default value.

"},{"location":"api/macros/json_has_static_rtti/#examples","title":"Examples","text":"Example

The code below forces the library to enable support for libraries with RTTI dependence:

#define JSON_HAS_STATIC_RTTI 1\n#include <nlohmann/json.hpp>\n\n...\n
"},{"location":"api/macros/json_has_static_rtti/#see-also","title":"See also","text":"
  • operator ValueType - get a value (implicit); on C++17, this macro controls whether std::any is excluded from its candidate types
  • Supported Macros - guide to all supported macros
  • Converting values - conversions of values
"},{"location":"api/macros/json_has_static_rtti/#version-history","title":"Version history","text":"
  • Added in version 3.11.3.
"},{"location":"api/macros/json_has_std_format/","title":"JSON_HAS_STD_FORMAT","text":"
#define JSON_HAS_STD_FORMAT /* value */\n

This macro indicates whether the standard library has support for std::format/std::formatter (that is, the <format> header). Possible values are 1 when supported or 0 when unsupported.

"},{"location":"api/macros/json_has_std_format/#default-definition","title":"Default definition","text":"

The default value is detected based on the preprocessor macros JSON_HAS_CPP_20 and __cpp_lib_format.

When the macro is not defined, the library will define it to its default value.

"},{"location":"api/macros/json_has_std_format/#notes","title":"Notes","text":"

Enabled functionality

When this macro evaluates to 1, the library provides a std::formatter<basic_json> specialization so JSON values can be used directly with std::format.

"},{"location":"api/macros/json_has_std_format/#examples","title":"Examples","text":"Example

The code below forces the library to disable support for std::format, even if the standard library would otherwise support it:

#define JSON_HAS_STD_FORMAT 0\n#include <nlohmann/json.hpp>\n\n...\n
"},{"location":"api/macros/json_has_std_format/#see-also","title":"See also","text":"
  • std::formatter<basic_json> - format JSON values with std::format
  • Supported Macros - guide to all supported macros
  • Serialization - serialize values to text
"},{"location":"api/macros/json_has_std_format/#version-history","title":"Version history","text":"
  • Added in version 3.13.0 unreleased.
"},{"location":"api/macros/json_has_three_way_comparison/","title":"JSON_HAS_THREE_WAY_COMPARISON","text":"
#define JSON_HAS_THREE_WAY_COMPARISON /* value */\n

This macro indicates whether the compiler and standard library support 3-way comparison. Possible values are 1 when supported or 0 when unsupported.

"},{"location":"api/macros/json_has_three_way_comparison/#default-definition","title":"Default definition","text":"

The default value is detected based on the preprocessor macros __cpp_impl_three_way_comparison and __cpp_lib_three_way_comparison.

When the macro is not defined, the library will define it to its default value.

"},{"location":"api/macros/json_has_three_way_comparison/#examples","title":"Examples","text":"Example

The code below forces the library to use 3-way comparison:

#define JSON_HAS_THREE_WAY_COMPARISON 1\n#include <nlohmann/json.hpp>\n\n...\n
"},{"location":"api/macros/json_has_three_way_comparison/#see-also","title":"See also","text":"
  • operator<=> - 3-way compare JSON values
  • operator== - compare JSON pointers for equality
"},{"location":"api/macros/json_has_three_way_comparison/#version-history","title":"Version history","text":"
  • Added in version 3.11.0.
"},{"location":"api/macros/json_no_automatic_udls/","title":"JSON_NO_AUTOMATIC_UDLS","text":"
#define JSON_NO_AUTOMATIC_UDLS\n

When defined, <nlohmann/json.hpp> does not include <nlohmann/json_literals.hpp>, so the user-defined string literals operator\"\"_json and operator\"\"_json_pointer are not declared. Include <nlohmann/json_literals.hpp> in the files that use them.

The literals are ordinary inline functions whose bodies call the parser, so every translation unit that includes them instantiates the parser \u2014 even if it never parses anything itself. Defining JSON_NO_AUTOMATIC_UDLS for a whole project avoids this cost in translation units that do not parse (e.g., ones that only define types and conversions or pass json values around) and reduces their compile time.

"},{"location":"api/macros/json_no_automatic_udls/#default-definition","title":"Default definition","text":"

By default, JSON_NO_AUTOMATIC_UDLS is not defined, and <nlohmann/json.hpp> includes <nlohmann/json_literals.hpp>.

#undef JSON_NO_AUTOMATIC_UDLS\n
"},{"location":"api/macros/json_no_automatic_udls/#notes","title":"Notes","text":"

Header <nlohmann/json_literals.hpp>

The header includes <nlohmann/json.hpp> itself and places the literals according to JSON_USE_GLOBAL_UDLS. It is part of the multi-header sources (include/nlohmann) and of the single-header sources (single_include/nlohmann), next to json.hpp.

C++ modules

The nlohmann.json module always exports the literals, regardless of this macro.

"},{"location":"api/macros/json_no_automatic_udls/#examples","title":"Examples","text":"Example

The code below includes the library without the literals and adds them in a single translation unit.

// compiled with -DJSON_NO_AUTOMATIC_UDLS for the whole project\n\n// this file uses the literals, so it includes them explicitly\n// (the header includes <nlohmann/json.hpp> itself)\n#include <nlohmann/json_literals.hpp>\n\nint main()\n{\n    auto j = R\"({\"foo\": 42})\"_json;\n    return j.at(\"/foo\"_json_pointer) == 42 ? 0 : 1;\n}\n

Without the include of <nlohmann/json_literals.hpp>, the code would fail to compile.

"},{"location":"api/macros/json_no_automatic_udls/#see-also","title":"See also","text":"
  • operator\"\"_json - user-defined string literal for JSON values
  • operator\"\"_json_pointer - user-defined string literal for JSON pointers
  • JSON_USE_GLOBAL_UDLS - place user-defined string literals (UDLs) into the global namespace
  • Compile times - options to reduce compile times
  • Creating JSON values - the article on creating JSON values
"},{"location":"api/macros/json_no_automatic_udls/#version-history","title":"Version history","text":"
  • Added in version 3.13.0 unreleased.
"},{"location":"api/macros/json_no_io/","title":"JSON_NO_IO","text":"
#define JSON_NO_IO\n

When defined, headers <cstdio>, <ios>, <iosfwd>, <istream>, and <ostream> are not included and parse functions relying on these headers are excluded. This is relevant for environments where these I/O functions are disallowed for security reasons (e.g., Intel Software Guard Extensions (SGX)).

"},{"location":"api/macros/json_no_io/#default-definition","title":"Default definition","text":"

By default, JSON_NO_IO is not defined.

#undef JSON_NO_IO\n
"},{"location":"api/macros/json_no_io/#examples","title":"Examples","text":"Example

The code below forces the library not to use the headers <cstdio>, <ios>, <iosfwd>, <istream>, and <ostream>.

#define JSON_NO_IO 1\n#include <nlohmann/json.hpp>\n\n...\n
"},{"location":"api/macros/json_no_io/#see-also","title":"See also","text":"
  • operator<< - serialize to stream
  • operator>> - deserialize from stream
  • Serialization - pretty-printing, UTF-8 handling, and number output
  • Parsing - overview of the parsing functions
"},{"location":"api/macros/json_no_io/#version-history","title":"Version history","text":"
  • Added in version 3.10.0.
"},{"location":"api/macros/json_no_simd/","title":"JSON_NO_SIMD","text":"
#define JSON_NO_SIMD\n

When defined, the library uses only portable C++ code where it would otherwise use vector instructions: when scanning strings during parsing, and when writing floating-point numbers during serialization. This includes the parser of basic_json_document (<nlohmann/json_view.hpp>).

The macro is an escape hatch, for example for toolchains that cannot compile the vector code, for sanitizers or analyzers that do not understand it, or to compare the speed of both variants. It does not change any result: values, exceptions, and error positions are the same either way. Only the speed differs.

"},{"location":"api/macros/json_no_simd/#default-definition","title":"Default definition","text":"

By default, JSON_NO_SIMD is not defined, and vector instructions are used where the target has them.

#undef JSON_NO_SIMD\n
"},{"location":"api/macros/json_no_simd/#notes","title":"Notes","text":"

Which instructions are used

  • x86-64: SSE2, which every x86-64 CPU has, finds the end of runs of plain string characters 16 bytes at a time and writes the digits of floating-point numbers. The UTF-8 check of non-ASCII text needs SSSE3, which is not part of x86-64: it is compiled for SSSE3 with a function attribute and used when the CPU has SSSE3 (every x86-64 CPU since about 2011), else the portable check. Code compiled for SSSE3 anyway (e.g., with -mssse3 or -march=native) skips this check of the CPU. 32-bit x86 uses SSE2 for strings when the compiler targets it.
  • AArch64: NEON, which every 64-bit Arm CPU has, checks UTF-8 text and long runs of plain string characters 16 bytes at a time, and writes the digits of floating-point numbers. With MSVC, only the floating-point digits use NEON.
  • Other targets: portable code only.

Strings are only scanned this way for contiguous input and for the characters a std::istream holds in its stream buffer (see JSON_DISABLE_STREAM_BULK_SCAN); other inputs are read one character at a time.

Interaction with JSON_USE_SIMDUTF

With JSON_USE_SIMDUTF, runs of string characters are first validated by simdutf; the code described here is used for what simdutf does not accept, so that errors are reported at the same position. JSON_NO_SIMD does not affect simdutf.

ABI compatibility

The macro selects between two definitions of the library's internal scanning and formatting functions. Whether it is defined is encoded in the namespace (tag _ns), resulting in distinct symbol names. Translation units compiled with and without it can therefore be linked into the same program without One Definition Rule (ODR) violations, but they cannot exchange instances of library types.

"},{"location":"api/macros/json_no_simd/#examples","title":"Examples","text":"Example: switching off vector instructions

The program parses and serializes the same values with and without the macro:

#define JSON_NO_SIMD\n#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    const json j = json::parse(R\"({\"name\": \"\u65e5\u672c\u8a9e text\", \"pi\": 3.141592653589793})\");\n    std::cout << j.dump() << '\\n';  // {\"name\":\"\u65e5\u672c\u8a9e text\",\"pi\":3.141592653589793}\n}\n
"},{"location":"api/macros/json_no_simd/#see-also","title":"See also","text":"
  • parse - deserialize from a compatible input
  • dump - serialization
  • JSON_USE_SIMDUTF - use the simdutf library to accelerate UTF-8 validation
  • JSON_DISABLE_STREAM_BULK_SCAN - read a std::istream one character at a time
  • Parsing: input sources and performance - how input sources affect parsing performance
  • Serialization - pretty-printing, UTF-8 handling, and number output
  • Zero-copy JSON views - the zero-copy view, whose parser the macro also affects
"},{"location":"api/macros/json_no_simd/#version-history","title":"Version history","text":"
  • Added in version 3.13.0 unreleased.
"},{"location":"api/macros/json_no_thread_local/","title":"JSON_NO_THREAD_LOCAL","text":"
#define JSON_NO_THREAD_LOCAL\n

When defined, the library does not use thread_local storage. This is relevant for the few environments whose toolchain does not support it.

Copying a value and comparing two values both descend into the first levels by letting the containers copy or compare themselves, and finish whatever is nested deeper than that without the call stack, so that neither can exhaust the stack however deeply the values are nested. Each counts the levels it has descended into in a thread_local variable, as a counter shared between threads would be raced.

Without those counters, no descent can be bounded safely, so objects and arrays are copied and compared without the call stack right away. Both keep working exactly as they do otherwise - the same values come out, the same comparisons hold, and deeply nested values are handled just as safely - but both are slower, because the containers no longer copy or compare themselves. Copying the benchmark documents takes 9% (canada.json) to 34% (twitter.json) longer, and comparing two equal ones 10% (citm_catalog.json) to 90% (canada.json) longer.

"},{"location":"api/macros/json_no_thread_local/#default-definition","title":"Default definition","text":"

By default, JSON_NO_THREAD_LOCAL is not defined.

#undef JSON_NO_THREAD_LOCAL\n

The library defines it by itself for Clang targeting MinGW, which does not survive the thread_local storage: copying a value segfaults there, with both old and current Clang versions, while GCC targeting MinGW is unaffected. Copying and comparing fall back to working without the call stack there, as they do whenever the macro is defined.

"},{"location":"api/macros/json_no_thread_local/#examples","title":"Examples","text":"Example

The code below forces the library not to use thread_local storage.

#define JSON_NO_THREAD_LOCAL 1\n#include <nlohmann/json.hpp>\n\n...\n
"},{"location":"api/macros/json_no_thread_local/#see-also","title":"See also","text":"
  • FAQ: Thread safety - thread-safety guarantees of the library
  • Supported Macros - guide to all supported macros
"},{"location":"api/macros/json_no_thread_local/#version-history","title":"Version history","text":"
  • Added in version 3.13.0 unreleased.
"},{"location":"api/macros/json_noexception/","title":"JSON_NOEXCEPTION","text":"
#define JSON_NOEXCEPTION\n

Exceptions can be switched off by defining the symbol JSON_NOEXCEPTION. When defining JSON_NOEXCEPTION, try is replaced by if (true), catch is replaced by if (false), and throw is replaced by std::abort().

The same effect is achieved by setting the compiler flag -fno-exceptions.

"},{"location":"api/macros/json_noexception/#default-definition","title":"Default definition","text":"

By default, the macro is not defined.

#undef JSON_NOEXCEPTION\n
"},{"location":"api/macros/json_noexception/#notes","title":"Notes","text":"

The explanatory what() string of exceptions is not available for MSVC if exceptions are disabled, see #2824.

"},{"location":"api/macros/json_noexception/#examples","title":"Examples","text":"Example

The code below switches off exceptions in the library.

#define JSON_NOEXCEPTION 1\n#include <nlohmann/json.hpp>\n\n...\n
"},{"location":"api/macros/json_noexception/#see-also","title":"See also","text":"
  • Switch off exceptions - more information how to switch off exceptions
  • Supported Macros - guide to all supported macros
  • Working Without Exceptions - using the library without exceptions
  • Exceptions - all exceptions and their error codes
  • exception - base class of all exceptions thrown by the library
"},{"location":"api/macros/json_noexception/#version-history","title":"Version history","text":"

Added in version 2.1.0.

"},{"location":"api/macros/json_precise_stream_position/","title":"JSON_PRECISE_STREAM_POSITION","text":"
#define JSON_PRECISE_STREAM_POSITION /* value */\n

When defined to 1, operator>> and sax_parse with strict = false leave a std::istream positioned right after the parsed value for every value type. By default, the character that terminates a number is consumed as well.

The macro only affects reading from a std::istream when the rest of the stream is not required to be consumed. parse, accept, and all other inputs (strings, iterators, containers, FILE*) are never affected.

"},{"location":"api/macros/json_precise_stream_position/#default-definition","title":"Default definition","text":"

The default value is 0 (disabled \u2014 existing behavior is preserved).

#define JSON_PRECISE_STREAM_POSITION 0\n
"},{"location":"api/macros/json_precise_stream_position/#notes","title":"Notes","text":"

Background

A number is the only JSON value whose end can be detected solely by reading the character that follows it. By default, that character is consumed and not put back, so the stream is left one byte too far after a number, and only after a number:

std::istringstream input(\"1true\");\njson j;\ninput >> j;  // j == 1, but the stream now starts at \"rue\"\n

With this macro, the character is only looked at and left in the stream, so the stream starts at true. This does not require the stream buffer to support putting a character back.

This was not changed unconditionally, because code can depend on the consumed character, even unknowingly (see #5340). Both of the following work by default only because the character after each number is swallowed, and behave differently with this macro:

std::istringstream input(\"1,2,3\");\njson j1, j2, j3;\ninput >> j1 >> j2 >> j3;  // default: 1, 2, 3\n                          // with the macro: throws parse_error.101 at the ','\n
std::istringstream input(\"42\\nfoo\");\njson j;\nstd::string line;\ninput >> j;\nstd::getline(input, line);  // default: \"foo\"\n                            // with the macro: \"\" (like after reading an int with >>)\n

In both cases, the behavior with the macro is what you already get today when the value is not a number: \"a\",\"b\" fails at the ,, and std::getline after {} returns an empty string. This macro offers an opt-in path to the consistent behavior ahead of version 4.0.0, where it is planned to become the default.

Opt-in only

This macro must be defined before including <nlohmann/json.hpp>. Defining it after the include has no effect.

ABI compatibility

The value of this macro is encoded in the namespace (tag _psp), resulting in distinct symbol names. Translation units compiled with and without it can therefore be linked into the same program without One Definition Rule (ODR) violations, but they cannot exchange instances of library types.

Bulk scanning

The parser scans the characters in the stream buffer in bulk (see JSON_DISABLE_STREAM_BULK_SCAN), but it never reads ahead. The stream is left at the same position with and without bulk scanning, in both modes of this macro.

Workaround without the macro

Separate the values in the stream with whitespace. The character consumed after a number is then the separator, and whitespace before the next value is skipped anyway.

"},{"location":"api/macros/json_precise_stream_position/#examples","title":"Examples","text":"Example: default behavior (macro not defined)

Without the macro, the character after a number is consumed:

#include <iostream>\n#include <sstream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    std::istringstream input(\"1true\");\n    json j1, j2;\n    input >> j1;  // j1 == 1\n    input >> j2;  // throws parse_error.101: the stream now starts at \"rue\"\n}\n
Example: opt-in precise stream position (macro defined to 1)

With the macro, the stream is positioned right after the number:

#define JSON_PRECISE_STREAM_POSITION 1\n#include <iostream>\n#include <sstream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    std::istringstream input(\"1true\");\n    json j1, j2;\n    input >> j1;  // j1 == 1\n    input >> j2;  // j2 == true\n}\n
"},{"location":"api/macros/json_precise_stream_position/#see-also","title":"See also","text":"
  • operator>> - deserialize from stream
  • sax_parse - generate SAX events
  • Large, Streamed, and Partial Input - chunked, concatenated, and very large input
"},{"location":"api/macros/json_precise_stream_position/#version-history","title":"Version history","text":"
  • Added in version 3.13.0 unreleased.
  • Planned to become the default (with the macro removed) in version 4.0.0.
"},{"location":"api/macros/json_skip_library_version_check/","title":"JSON_SKIP_LIBRARY_VERSION_CHECK","text":"
#define JSON_SKIP_LIBRARY_VERSION_CHECK\n

When defined, the library will not create a compiler warning when a different version of the library was already included.

"},{"location":"api/macros/json_skip_library_version_check/#default-definition","title":"Default definition","text":"

By default, the macro is not defined.

#undef JSON_SKIP_LIBRARY_VERSION_CHECK\n
"},{"location":"api/macros/json_skip_library_version_check/#notes","title":"Notes","text":"

ABI compatibility

Mixing different library versions in the same code can be a problem as the different versions may not be ABI compatible.

"},{"location":"api/macros/json_skip_library_version_check/#examples","title":"Examples","text":"Example: switch off the version check

The code below switches off the warning about including a different version of the library.

#define JSON_SKIP_LIBRARY_VERSION_CHECK 1\n#include <nlohmann/json.hpp>\n\n...\n
Example: warning about a different library version

The following warning will be shown in case a different version of the library was already included:

Already included a different version of the library!\n
"},{"location":"api/macros/json_skip_library_version_check/#see-also","title":"See also","text":"
  • NLOHMANN_JSON_VERSION_MAJOR / NLOHMANN_JSON_VERSION_MINOR / NLOHMANN_JSON_VERSION_PATCH - library version information
  • Supported Macros - guide to all supported macros
  • Integration - integrate the library
"},{"location":"api/macros/json_skip_library_version_check/#version-history","title":"Version history","text":"
  • Added in version 3.11.0.
"},{"location":"api/macros/json_skip_unsupported_compiler_check/","title":"JSON_SKIP_UNSUPPORTED_COMPILER_CHECK","text":"
#define JSON_SKIP_UNSUPPORTED_COMPILER_CHECK\n

When defined, the library will not create a compile error when a known unsupported compiler is detected. This allows using the library with compilers that do not fully support C++11 and may only work if unsupported features are not used.

"},{"location":"api/macros/json_skip_unsupported_compiler_check/#default-definition","title":"Default definition","text":"

By default, the macro is not defined.

#undef JSON_SKIP_UNSUPPORTED_COMPILER_CHECK\n
"},{"location":"api/macros/json_skip_unsupported_compiler_check/#examples","title":"Examples","text":"Example

The code below switches off the check whether the compiler is supported.

#define JSON_SKIP_UNSUPPORTED_COMPILER_CHECK 1\n#include <nlohmann/json.hpp>\n\n...\n
"},{"location":"api/macros/json_skip_unsupported_compiler_check/#see-also","title":"See also","text":"
  • JSON_HAS_CPP_11 / JSON_HAS_CPP_14 / JSON_HAS_CPP_17 / JSON_HAS_CPP_20 / JSON_HAS_CPP_23 / JSON_HAS_CPP_26 - set supported C++ standard
  • Supported Macros - guide to all supported macros
  • Integration - integrate the library
"},{"location":"api/macros/json_skip_unsupported_compiler_check/#version-history","title":"Version history","text":"
  • Added in version 3.2.0.
"},{"location":"api/macros/json_strict_binary_utf8/","title":"JSON_STRICT_BINARY_UTF8","text":"
#define JSON_STRICT_BINARY_UTF8 /* value */\n

When defined to 1, the error_handler parameter of the binary writers to_cbor, to_ubjson, to_bjdata, and to_bson defaults to error_handler_t::strict instead of error_handler_t::keep. These writers then check every string value and object key for valid UTF-8 and throw type_error.316 for ill-formed UTF-8, like dump does. Without it, they write the bytes unchanged. An error_handler passed explicitly always takes precedence.

The macro does not affect:

  • to_msgpack: the MessagePack specification allows a str value to contain bytes that are not valid UTF-8, so its error_handler always defaults to keep.
  • to_bon8: BON8 always checks, because the UTF-8 lead bytes mark where a string ends.
  • The binary readers (from_cbor, from_msgpack, from_ubjson, from_bjdata, from_bson): none of these formats requires a decoder to reject ill-formed UTF-8, so by default they return the bytes unchanged (error_handler_t::keep), independent of this macro. Pass an error_handler argument explicitly to validate or sanitize the strings they read.
  • from_bon8: BON8 always validates, because the UTF-8 lead bytes mark where a string ends.
"},{"location":"api/macros/json_strict_binary_utf8/#default-definition","title":"Default definition","text":"

The default value is 0 (disabled, the behavior of version 3.12.0 and earlier is preserved).

#define JSON_STRICT_BINARY_UTF8 0\n
"},{"location":"api/macros/json_strict_binary_utf8/#notes","title":"Notes","text":"

Background

CBOR, UBJSON, BJData, and BSON all require strings to be UTF-8. Up to version 3.12.0, the writers did not check this, so they could produce output that other decoders reject. Checking by default would break code that stores other encodings (for instance ISO 8859-1) in a string and only ever writes it to a binary format. You can pass error_handler_t::strict to each call, or use this macro to check by default ahead of version 4.0.0, where strict is planned to become the default (see #5529 and #5651).

Opt-in only

This macro must be defined before including <nlohmann/json.hpp>. Defining it after the include has no effect.

ABI compatibility

The value of this macro is encoded in the namespace (tag _sbu8), resulting in distinct symbol names. Translation units compiled with and without it can therefore be linked into the same program without One Definition Rule (ODR) violations, but they cannot exchange instances of library types.

"},{"location":"api/macros/json_strict_binary_utf8/#examples","title":"Examples","text":"Example: default behavior (macro not defined)

Without the macro, the bytes are written unchanged:

#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    auto v = json::to_cbor(json(\"\\xFF\"));\n    // v is {0x61, 0xFF}\n}\n
Example: opt-in check (macro defined to 1)

With the macro, ill-formed UTF-8 is rejected:

#define JSON_STRICT_BINARY_UTF8 1\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    auto v = json::to_cbor(json(\"\\xFF\"));\n    // throws type_error.316: invalid UTF-8 byte at index 0: 0xFF\n}\n
"},{"location":"api/macros/json_strict_binary_utf8/#see-also","title":"See also","text":"
  • Binary formats - overview of the supported binary formats
  • from_cbor - also affected when parsing CBOR strings
  • to_cbor - create a CBOR serialization of a JSON value
  • to_ubjson - create a UBJSON serialization of a JSON value
  • to_bjdata - create a BJData serialization of a JSON value
  • to_bson - create a BSON serialization of a JSON value
  • error_handler_t - how dump treats ill-formed UTF-8
"},{"location":"api/macros/json_strict_binary_utf8/#version-history","title":"Version history","text":"
  • Added in version 3.13.0 unreleased.
  • Planned to become the default (with the macro removed) in version 4.0.0.
"},{"location":"api/macros/json_strict_nul_handling/","title":"JSON_STRICT_NUL_HANDLING","text":"
#define JSON_STRICT_NUL_HANDLING /* value */\n

When defined to 1, a '\\0' (NUL) byte in JSON text input is rejected with parse_error.101, like any other unexpected byte, instead of being silently treated as end of input.

The macro only affects the JSON text parser (parse, accept, sax_parse, and operator>>). There are three cases where a NUL byte is still not rejected:

  • The binary formats (from_bjdata, from_bon8, from_bson, from_cbor, from_msgpack, from_ubjson) are never affected: there, 0x00 is ordinary data.
  • A bare const char* pointer has no length of its own, so its length is still determined with strlen(). The first NUL byte therefore still marks the end of the input, and nothing after it is read.
  • One trailing '\\0' at the end of a char, wchar_t, char16_t, char32_t, or (C++20) char8_t array (e.g., a string literal) is trimmed; see the warning below.
"},{"location":"api/macros/json_strict_nul_handling/#default-definition","title":"Default definition","text":"

The default value is 0 (disabled \u2014 existing behavior is preserved).

#define JSON_STRICT_NUL_HANDLING 0\n
"},{"location":"api/macros/json_strict_nul_handling/#notes","title":"Notes","text":"

Background

By default, a '\\0' byte anywhere in the input is treated the same as the real end of the input, rather than as an ordinary (and, outside of a string, invalid) byte. Everything from that byte onward is silently ignored, without a parse error - including further, otherwise well-formed JSON:

json::parse(std::string(\"123\") + '\\0');          // == 123, no error\njson::parse(std::string(\"123\") + '\\0' + \"true\"); // == 123, the \"true\" is silently ignored too\n

This falls out of the same convention used when no explicit input length is given at all: parsing from a const char* already stops at the first NUL byte via strlen(), since a bare pointer has no length of its own. The library applies that same NUL-terminated-C-string convention uniformly, rather than only when a length is genuinely unavailable - so a std::string, iterator range, or container whose content happens to include a NUL byte is affected the same way a raw const char* would be (see the FAQ entry for a fuller explanation).

This was not fixed unconditionally, because doing so is backwards-incompatible for any caller who happens to depend on the current behavior - even unknowingly, for instance because their input already contains trailing padding they never noticed was being discarded (see #5530). This macro instead offers an opt-in path to the corrected behavior ahead of version 4.0.0, where it is planned to become the default.

Opt-in only

This macro must be defined before including <nlohmann/json.hpp>. Defining it after the include has no effect.

Enabling it also changes how an array of a text-literal element type (char, wchar_t, char16_t, char32_t, or, since C++20, char8_t - including a string literal, e.g. json::parse(\"123\") or json::parse(L\"123\")) is read: such an array normally carries a trailing '\\0' contributed by the compiler, not by the source text. With this macro enabled, that one trailing element is trimmed if present so that parsing a string literal keeps working, for any of these character types; every other element in the array - including any '\\0' that is not the very last element - is read as real data and rejected like any other unexpected byte. Arrays of any other element type (unsigned char, std::uint8_t, ...), as used for CBOR or MessagePack, are never affected by this trimming; their full extent - including a genuine trailing 0x00 - is always preserved, in both states of this macro.

ABI compatibility

The value of this macro is encoded in the namespace (tag _snul), resulting in distinct symbol names. Translation units compiled with and without it can therefore be linked into the same program without One Definition Rule (ODR) violations, but they cannot exchange instances of library types.

Workaround without the macro

To reject a NUL byte without enabling this macro, trim your input yourself before calling parse():

s.resize(s.find('\\0')); // drop everything from the first NUL onward, if any\njson::parse(s);\n
"},{"location":"api/macros/json_strict_nul_handling/#examples","title":"Examples","text":"Example: default behavior (macro not defined)

Without the macro, a NUL byte silently ends parsing at that point:

#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    json j = json::parse(std::string(\"123\") + '\\0' + \"true\");\n    // j is 123 -- the '\\0' and everything after it is silently ignored\n}\n
Example: opt-in strict handling (macro defined to 1)

With the macro, a NUL byte is rejected like any other unexpected byte:

#define JSON_STRICT_NUL_HANDLING 1\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    json j = json::parse(std::string(\"123\") + '\\0' + \"true\");\n    // throws parse_error.101 -- the NUL byte is now invalid input,\n    // exactly like any other unexpected trailing byte\n\n    json ok = json::parse(\"123\");\n    // ok is 123 -- parsing from a string literal still works\n}\n
"},{"location":"api/macros/json_strict_nul_handling/#see-also","title":"See also","text":"
  • JSON_StrictNulHandling - CMake option to control the macro
  • FAQ: NUL bytes in the input - how NUL bytes in the input are handled
  • parse - deserialize from a compatible input
  • accept - check if the input is valid JSON
  • operator>> - deserialize from stream
  • Parsing Untrusted Input - limits and checks for input you do not control
"},{"location":"api/macros/json_strict_nul_handling/#version-history","title":"Version history","text":"
  • Added in version 3.13.0 unreleased.
  • Planned to become the default (with the macro removed) in version 4.0.0.
"},{"location":"api/macros/json_throw_user/","title":"JSON_CATCH_USER, JSON_THROW_USER, JSON_TRY_USER","text":"
// (1)\n#define JSON_CATCH_USER(exception) /* value */\n// (2)\n#define JSON_THROW_USER(exception) /* value */\n// (3)\n#define JSON_TRY_USER /* value */\n

Controls how exceptions are handled by the library.

  1. This macro overrides catch calls inside the library. The argument is the type of the exception to catch. The library uses it in a single place: to swallow any exception escaping the parent-pointer check that JSON_DIAGNOSTICS adds to the class invariant. The places where the library catches its own json::out_of_range exceptions use JSON_INTERNAL_CATCH instead, which JSON_CATCH_USER also overrides unless JSON_INTERNAL_CATCH_USER is defined. The macro is always followed by a scope.
  2. This macro overrides throw calls inside the library. The argument is the exception to be thrown. Note that JSON_THROW_USER should leave the current scope (e.g., by throwing or aborting), as continuing after it may yield undefined behavior.
  3. This macro overrides try calls inside the library. It has no arguments and is always followed by a scope.
"},{"location":"api/macros/json_throw_user/#parameters","title":"Parameters","text":"exception (in) an exception type"},{"location":"api/macros/json_throw_user/#default-definition","title":"Default definition","text":"

By default, the macros map to their respective C++ keywords:

#define JSON_CATCH_USER(exception) catch(exception)\n#define JSON_THROW_USER(exception) throw exception\n#define JSON_TRY_USER              try\n

When exceptions are switched off, the try block is executed unconditionally, and throwing exceptions is replaced by calling std::abort to make reaching the throw branch abort the process.

#define JSON_THROW_USER(exception) std::abort()\n#define JSON_TRY_USER              if (true)\n#define JSON_CATCH_USER(exception) if (false)\n
"},{"location":"api/macros/json_throw_user/#examples","title":"Examples","text":"Example

The code below switches off exceptions and creates a log entry with a detailed error message in case of errors.

#include <iostream>\n\n#define JSON_TRY_USER if(true)\n#define JSON_CATCH_USER(exception) if(false)\n#define JSON_THROW_USER(exception)                           \\\n    {std::clog << \"Error in \" << __FILE__ << \":\" << __LINE__ \\\n               << \" (function \" << __FUNCTION__ << \") - \"    \\\n               << (exception).what() << std::endl;           \\\n     std::abort();}\n\n#include <nlohmann/json.hpp>\n
"},{"location":"api/macros/json_throw_user/#see-also","title":"See also","text":"
  • Switch off exceptions - more information how to switch off exceptions
  • JSON_NOEXCEPTION - switch off exceptions
  • Supported Macros - guide to all supported macros
  • Working Without Exceptions - using the library without exceptions
  • exception - base class of all exceptions thrown by the library
"},{"location":"api/macros/json_throw_user/#version-history","title":"Version history","text":"
  • Added in version 3.1.0.
"},{"location":"api/macros/json_use_global_udls/","title":"JSON_USE_GLOBAL_UDLS","text":"
#define JSON_USE_GLOBAL_UDLS /* value */\n

When defined to 1, the user-defined string literals (UDLs) are placed into the global namespace instead of nlohmann::literals::json_literals.

"},{"location":"api/macros/json_use_global_udls/#default-definition","title":"Default definition","text":"

The default value is 1.

#define JSON_USE_GLOBAL_UDLS 1\n

When the macro is not defined, the library behaves as if it were defined to its default value.

"},{"location":"api/macros/json_use_global_udls/#notes","title":"Notes","text":"

Future behavior change

The user-defined string literals will be removed from the global namespace in the next major release of the library.

To prepare existing code, define JSON_USE_GLOBAL_UDLS to 0 and bring the string literals into scope where needed. Refer to any of the string literals for details.

See the migration guide for how to update existing code.

CMake option

The placement of user-defined string literals can also be controlled with the CMake option JSON_GlobalUDLs (ON by default) which defines JSON_USE_GLOBAL_UDLS accordingly.

Leaving out the literals

If JSON_NO_AUTOMATIC_UDLS is defined, the literals are only declared where <nlohmann/json_literals.hpp> is included; this macro then applies to that header.

"},{"location":"api/macros/json_use_global_udls/#examples","title":"Examples","text":"Example: Default behavior

The code below shows the default behavior using the _json UDL.

#include <nlohmann/json.hpp>\n\n#include <iostream>\n\nint main()\n{\n    auto j = \"42\"_json;\n\n    std::cout << j << std::endl;\n}\n

Output:

42\n
Example: Namespaced UDLs

The code below shows how UDLs need to be brought into scope before using _json when JSON_USE_GLOBAL_UDLS is defined to 0.

#define JSON_USE_GLOBAL_UDLS 0\n#include <nlohmann/json.hpp>\n\n#include <iostream>\n\nint main()\n{\n    // auto j = \"42\"_json; // This line would fail to compile,\n                           // because the UDLs are not in the global namespace\n\n    // Bring the UDLs into scope\n    using namespace nlohmann::json_literals;\n\n    auto j = \"42\"_json;\n\n    std::cout << j << std::endl;\n}\n

Output:

42\n
"},{"location":"api/macros/json_use_global_udls/#see-also","title":"See also","text":"
  • operator\"\"_json - user-defined string literal for JSON values
  • operator\"\"_json_pointer - user-defined string literal for JSON pointers
  • JSON_NO_AUTOMATIC_UDLS - do not include the user-defined string literals automatically
  • JSON_GlobalUDLs - CMake option to control the macro
  • Creating JSON values - the article on creating JSON values
"},{"location":"api/macros/json_use_global_udls/#version-history","title":"Version history","text":"
  • Added in version 3.11.0.
"},{"location":"api/macros/json_use_implicit_conversions/","title":"JSON_USE_IMPLICIT_CONVERSIONS","text":"
#define JSON_USE_IMPLICIT_CONVERSIONS /* value */\n

When defined to 0, implicit conversions are switched off. By default, implicit conversions are switched on. The value directly affects operator ValueType and the converting constructor from a basic_json specialization with a different string type (overload 4).

"},{"location":"api/macros/json_use_implicit_conversions/#default-definition","title":"Default definition","text":"

By default, implicit conversions are enabled.

#define JSON_USE_IMPLICIT_CONVERSIONS 1\n
"},{"location":"api/macros/json_use_implicit_conversions/#notes","title":"Notes","text":"

Future behavior change

Implicit conversions will be switched off by default in the next major release of the library.

You can prepare existing code by already defining JSON_USE_IMPLICIT_CONVERSIONS to 0 and replace any implicit conversions with calls to get.

See the migration guide for how to update existing code.

Automatic migration

The community-maintained clang-tidy check modernize-nlohmann-json-explicit-conversions rewrites implicit conversions into explicit calls to get; for example, int i = j; becomes int i = j.get<int>();. The check is not part of clang-tidy itself, and it does not catch every case (for example, constructing a std::optional from a JSON value), so review the result. See discussion #4610 for how to build and use it.

CMake option

Implicit conversions can also be controlled with the CMake option JSON_ImplicitConversions (ON by default) which defines JSON_USE_IMPLICIT_CONVERSIONS accordingly.

"},{"location":"api/macros/json_use_implicit_conversions/#examples","title":"Examples","text":"Example: implicit and explicit conversions

This is an example for an implicit conversion:

json j = \"Hello, world!\";\nstd::string s = j;\n

When JSON_USE_IMPLICIT_CONVERSIONS is defined to 0, the code above does no longer compile. Instead, it must be written like this:

json j = \"Hello, world!\";\nauto s = j.get<std::string>();\n
Example: conversion between basic_json specializations

A basic_json specialization with a different string type is also no longer converted implicitly when JSON_USE_IMPLICIT_CONVERSIONS is defined to 0:

using wjson = nlohmann::json::with_string_t<std::wstring>;\n\nvoid load(const nlohmann::json& j);\n\nwjson wj = /* ... */;\nload(wj);                            // error: no implicit conversion\nload(nlohmann::json(wj));            // OK: explicit conversion\nload(wj.get<nlohmann::json>());      // OK: explicit conversion\n

Specializations that share the same string type, such as json and ordered_json, remain implicitly convertible.

"},{"location":"api/macros/json_use_implicit_conversions/#see-also","title":"See also","text":"
  • operator ValueType - get a value (implicit)
  • get - get a value (explicit)
  • JSON_ImplicitConversions - CMake option to control the macro
  • Converting values - implicit conversions and how to disable them
"},{"location":"api/macros/json_use_implicit_conversions/#version-history","title":"Version history","text":"
  • Added in version 3.9.0.
  • Also affects the conversion between basic_json specializations with different string types since version 3.13.0 unreleased.
"},{"location":"api/macros/json_use_legacy_discarded_value_comparison/","title":"JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON","text":"
#define JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON /* value */\n

This macro enables the (incorrect) legacy comparison behavior of discarded JSON values. Possible values are 1 to enable or 0 to disable (default).

When enabled, comparisons involving at least one discarded JSON value yield results as follows:

Operator Result == false != true < false <= true >= true > false

Otherwise, comparisons involving at least one discarded JSON value yield false, except for !=, which is the negation of == and yields true.

"},{"location":"api/macros/json_use_legacy_discarded_value_comparison/#default-definition","title":"Default definition","text":"

The default value is 0.

#define JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON 0\n

When the macro is not defined, the library will define it to its default value.

"},{"location":"api/macros/json_use_legacy_discarded_value_comparison/#notes","title":"Notes","text":"

Inconsistent behavior in C++20 and beyond

When targeting C++20 or above, enabling the legacy comparison behavior is strongly discouraged.

  • The 3-way comparison operator (<=>) will always give the correct result (std::partial_ordering::unordered) regardless of the value of JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON.
  • Overloads for the equality and relational operators emulate the legacy behavior.

Code outside your control may use either 3-way comparison or the equality and relational operators, resulting in inconsistent and unpredictable behavior.

See operator<=> for more information on 3-way comparison.

Deprecation

The legacy comparison behavior is deprecated and may be removed in a future major version release.

New code should not depend on it and existing code should try to remove or rewrite expressions relying on it.

See the migration guide for how to update existing code.

CMake option

Legacy comparison can also be controlled with the CMake option JSON_LegacyDiscardedValueComparison (OFF by default) which defines JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON accordingly.

"},{"location":"api/macros/json_use_legacy_discarded_value_comparison/#examples","title":"Examples","text":"Example

The code below switches on the legacy discarded value comparison behavior in the library.

#define JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON 1\n#include <nlohmann/json.hpp>\n\n...\n
"},{"location":"api/macros/json_use_legacy_discarded_value_comparison/#see-also","title":"See also","text":"
  • JSON_LegacyDiscardedValueComparison - CMake option to control the macro
"},{"location":"api/macros/json_use_legacy_discarded_value_comparison/#version-history","title":"Version history","text":"
  • Added in version 3.11.0.
  • Fixed in version 3.13.0 unreleased so <= and >= also emulate the legacy behavior in C++20 when the JSON value is the right-hand operand of a scalar comparison; before, only the 3-way-comparison-rewritten candidate was found, which yielded false instead of true.
"},{"location":"api/macros/json_use_objects_for_enum_keyed_maps/","title":"JSON_USE_OBJECTS_FOR_ENUM_KEYED_MAPS","text":"
#define JSON_USE_OBJECTS_FOR_ENUM_KEYED_MAPS /* value */\n

When defined to 1, maps whose keys are enums (such as std::map<E, T> or std::unordered_map<E, T>) are stored as JSON objects, using the enum's own conversion for the keys. By default, they are stored as arrays of [key, value] pairs.

"},{"location":"api/macros/json_use_objects_for_enum_keyed_maps/#default-definition","title":"Default definition","text":"

The default value is 0 (disabled \u2014 existing behavior is preserved).

#define JSON_USE_OBJECTS_FOR_ENUM_KEYED_MAPS 0\n
"},{"location":"api/macros/json_use_objects_for_enum_keyed_maps/#notes","title":"Notes","text":"

Background

JSON object keys are strings, so a map is only stored as an object if its keys can be converted to a string type. Enums are not, even if NLOHMANN_JSON_SERIALIZE_ENUM maps them to strings, so a map with enum keys becomes an array of [key, value] pairs:

[[\"stopped\", \"aa\"], [\"completed\", \"bb\"]]\n

With this macro, the same map becomes an object (see #4378):

{\"completed\": \"bb\", \"stopped\": \"aa\"}\n

Maps with non-unique keys

Maps that allow duplicate keys, such as std::multimap<E, T> or std::unordered_multimap<E, T>, are not affected by the macro and are still stored as arrays of [key, value] pairs, as an object cannot hold duplicate keys.

Reading

Reading is not affected by the macro: a map with enum keys can always be read from both an array of pairs and an object. For the latter, each key is converted to the enum with its from_json function, e.g., the one defined by NLOHMANN_JSON_SERIALIZE_ENUM. Data written without the macro can therefore still be read after enabling it.

Keys must serialize to distinct strings

Each key is converted with the enum's to_json function. If a key is not converted to a string (for instance, an enum without NLOHMANN_JSON_SERIALIZE_ENUM, which is stored as an integer, or an enumerator mapped to nullptr), type_error.302 is thrown. If two keys are converted to the same string (for instance, because NLOHMANN_JSON_SERIALIZE_ENUM maps an unlisted enumerator to the first entry), type_error.318 is thrown. In both cases, the target value is not changed.

Opt-in only

This macro must be defined before including <nlohmann/json.hpp>. Defining it after the include has no effect.

ABI compatibility

The value of this macro is encoded in the namespace (tag _ekmo), resulting in distinct symbol names. Translation units compiled with and without it can therefore be linked into the same program without One Definition Rule (ODR) violations, but they cannot exchange instances of library types.

"},{"location":"api/macros/json_use_objects_for_enum_keyed_maps/#examples","title":"Examples","text":"Example: default behavior (macro not defined)

Without the macro, a map with enum keys is stored as an array of pairs:

#include <map>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nenum TaskState { TS_STOPPED, TS_RUNNING, TS_COMPLETED };\n\nNLOHMANN_JSON_SERIALIZE_ENUM(TaskState, {\n    {TS_STOPPED, \"stopped\"},\n    {TS_RUNNING, \"running\"},\n    {TS_COMPLETED, \"completed\"},\n})\n\nint main()\n{\n    std::map<TaskState, std::string> m = {{TS_STOPPED, \"aa\"}, {TS_COMPLETED, \"bb\"}};\n\n    json j = m;\n    // j is [[\"stopped\",\"aa\"],[\"completed\",\"bb\"]]\n}\n
Example: objects for enum-keyed maps (macro defined to 1)

With the macro, the same map is stored as an object:

#define JSON_USE_OBJECTS_FOR_ENUM_KEYED_MAPS 1\n#include <map>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nenum TaskState { TS_STOPPED, TS_RUNNING, TS_COMPLETED };\n\nNLOHMANN_JSON_SERIALIZE_ENUM(TaskState, {\n    {TS_STOPPED, \"stopped\"},\n    {TS_RUNNING, \"running\"},\n    {TS_COMPLETED, \"completed\"},\n})\n\nint main()\n{\n    std::map<TaskState, std::string> m = {{TS_STOPPED, \"aa\"}, {TS_COMPLETED, \"bb\"}};\n\n    json j = m;\n    // j is {\"completed\":\"bb\",\"stopped\":\"aa\"}\n\n    auto m2 = j.get<std::map<TaskState, std::string>>();\n    // m2 == m\n}\n
"},{"location":"api/macros/json_use_objects_for_enum_keyed_maps/#see-also","title":"See also","text":"
  • Specializing enum conversion - serializing enums as JSON strings
  • NLOHMANN_JSON_SERIALIZE_ENUM - serialize/deserialize an enum
  • NLOHMANN_JSON_SERIALIZE_ENUM_STRICT - serialize/deserialize an enum with exceptions
"},{"location":"api/macros/json_use_objects_for_enum_keyed_maps/#version-history","title":"Version history","text":"
  • Added in version 3.13.0 unreleased.
"},{"location":"api/macros/json_use_simdutf/","title":"JSON_USE_SIMDUTF","text":"
#define JSON_USE_SIMDUTF\n

When defined, the parser validates the UTF-8 content of JSON strings that come from a contiguous byte input (std::string, std::vector<char>/<std::uint8_t>, string literals, const char* ranges, \u2026) using the simdutf library instead of the built-in validator (which uses SSSE3 or NEON where available, see JSON_NO_SIMD). On text with many non-ASCII characters (e.g. CJK or emoji) this can validate faster, depending on the CPU.

This is an opt-in external dependency. The library itself remains header-only and its behavior is unchanged: the same input is accepted or rejected either way, and every parse error is reported at the same position with the same message (simdutf is only used to fast-path valid runs; anything it flags falls back to the scalar path so the exact diagnostic is preserved). A std::istream uses simdutf for the characters its stream buffer holds (see JSON_DISABLE_STREAM_BULK_SCAN); other streaming inputs (FILE*, wide strings, user-defined adapters) always use the scalar path.

When JSON_USE_SIMDUTF is defined you must make the simdutf.h header available on the include path and link the simdutf library. When it is not defined, no simdutf header is included and there is no dependency.

Requires C++17

simdutf requires C++17 and its header rejects older standards with an #error. The backend is therefore only compiled in from C++17 on. In C++11 and C++14 the macro has no effect and the scalar validator is used, which accepts and rejects exactly the same input \u2014 only throughput differs. Setting the macro project-wide is therefore safe even when some translation units are built with an older standard.

Define consistently

The macro selects between two definitions of the same inline validation function. It must therefore be defined identically for every translation unit that includes the library; mixing translation units that define it with ones that do not is an ODR violation. Prefer setting it as a compile definition on the target rather than with #define in individual source files.

"},{"location":"api/macros/json_use_simdutf/#default-definition","title":"Default definition","text":"

By default, JSON_USE_SIMDUTF is not defined and the portable C++11 scalar validator is used.

#undef JSON_USE_SIMDUTF\n
"},{"location":"api/macros/json_use_simdutf/#examples","title":"Examples","text":"Example

The code below enables the simdutf backend for UTF-8 validation.

#define JSON_USE_SIMDUTF 1\n#include <nlohmann/json.hpp>\n\n...\n

The project must also link against simdutf, e.g. with CMake:

target_compile_definitions(your_target PRIVATE JSON_USE_SIMDUTF)\ntarget_link_libraries(your_target PRIVATE simdutf::simdutf)\n

Testing this configuration

The unit tests can be built against the simdutf backend with the CMake option JSON_TestSimdutf (OFF by default), which fetches simdutf and defines JSON_USE_SIMDUTF for every test target. The ci_test_simdutf target runs the whole test suite in that configuration.

"},{"location":"api/macros/json_use_simdutf/#see-also","title":"See also","text":"
  • JSON_TestSimdutf - CMake option to build the unit tests against the simdutf backend
  • Parsing - overview of the parsing functions
  • Serialization - pretty-printing, UTF-8 handling, and number output
"},{"location":"api/macros/json_use_simdutf/#version-history","title":"Version history","text":"
  • Added in version 3.13.0 unreleased.
"},{"location":"api/macros/nlohmann_define_derived_type/","title":"NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE, NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_WITH_DEFAULT, NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_ONLY_SERIALIZE, NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE, NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_WITH_DEFAULT, NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE","text":"NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE, NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_WITH_DEFAULT, NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_ONLY_SERIALIZE, NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE, NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_WITH_DEFAULT, NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE
// (1)\n#define NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE(type, base_type, member...)\n// (2)\n#define NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_WITH_DEFAULT(type, base_type, member...)\n// (3)\n#define NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_ONLY_SERIALIZE(type, base_type, member...)\n\n// (4)\n#define NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE(type, base_type, member...)\n// (5)\n#define NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_WITH_DEFAULT(type, base_type, member...)\n// (6)\n#define NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE(type, base_type, member...)\n

These macros can be used to simplify the serialization/deserialization of derived types if you want to use a JSON object as serialization and want to use the member variable names as object keys in that object.

  • Macros 1, 2, and 3 are to be defined inside the class/struct to create code for. Like NLOHMANN_DEFINE_TYPE_INTRUSIVE, they can access private members.
  • Macros 4, 5, and 6 are to be defined outside the class/struct to create code for, but inside its namespace. Like NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE, they cannot access private members.

The first parameter is the name of the derived class/struct, the second parameter is the name of the base class/struct and all remaining parameters name the members. The base type must be already serializable/deserializable.

  • Macros 1 and 4 will use at during deserialization and will throw out_of_range.403 if a key is missing in the JSON object.
  • Macros 2 and 5 will use value during deserialization and fall back to the default value for the respective type of the member variable if a key in the JSON object is missing. The generated from_json() function default constructs an object and uses its values as the defaults when calling the value function.

Summary:

Need access to private members Need only serialization Allow missing values when de-serializing macro NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_WITH_DEFAULT NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_ONLY_SERIALIZE NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_WITH_DEFAULT NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE"},{"location":"api/macros/nlohmann_define_derived_type/#parameters","title":"Parameters","text":"type (in) name of the type (class, struct) to serialize/deserialize base_type (in) name of the base type (class, struct) type is derived from member (in) name of the member variable to serialize/deserialize; up to 63 members can be given as a comma-separated list, which may also be empty"},{"location":"api/macros/nlohmann_define_derived_type/#default-definition","title":"Default definition","text":"

Macros 1 and 2 add two friend functions to the class which take care of the serialization and deserialization:

template<typename BasicJsonType>\nfriend void to_json(BasicJsonType&, const type&);\ntemplate<typename BasicJsonType>\nfriend void from_json(const BasicJsonType&, type&);\n

Macros 4 and 5 add two functions to the namespace which take care of the serialization and deserialization:

template<typename BasicJsonType>\nvoid to_json(BasicJsonType&, const type&);\ntemplate<typename BasicJsonType>\nvoid from_json(const BasicJsonType&, type&);\n

Macros 3 and 6 add one function to the namespace, which takes care of the serialization only:

template<typename BasicJsonType>\nvoid to_json(BasicJsonType&, const type&);\n

In first two cases, they call the to_json/from_json functions of the base type before serializing/deserializing the members of the derived type:

class A { /* ... */ };\nclass B : public A { /* ... */ };\n\ntemplate<typename BasicJsonType>\nvoid to_json(BasicJsonType& j, const B& b) {\n    nlohmann::to_json(j, static_cast<const A&>(b));\n    // ...\n}\n\ntemplate<typename BasicJsonType>\nvoid from_json(const BasicJsonType& j, B& b) {\n    nlohmann::from_json(j, static_cast<A&>(b));\n    // ...\n}\n

In the third case, only to_json will be called:

class A { /* ... */ };\nclass B : public A { /* ... */ };\n\ntemplate<typename BasicJsonType>\nvoid to_json(BasicJsonType& j, const B& b) {\n    nlohmann::to_json(j, static_cast<const A&>(b));\n    // ...\n}\n
"},{"location":"api/macros/nlohmann_define_derived_type/#notes","title":"Notes","text":"

Prerequisites

  • Macros 1, 2, and 3 have the same prerequisites of NLOHMANN_DEFINE_TYPE_INTRUSIVE.
  • Macros 4, 5, and 6 have the same prerequisites of NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE.
  • Serialization/deserialization of base types must be defined.

Derived types without own members

The member list may be empty. The macro then generates a to_json/from_json pair that only delegates to the base type, so type serializes exactly like base_type:

struct derived : base\n{\n    NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE(derived, base)\n};\n

The WITH_NAMES variants do not support this.

Implementation limits

See Implementation limits for NLOHMANN_DEFINE_TYPE_INTRUSIVE and NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE, respectively.

Views

The generated from_json() also reads the views of json_documents (<nlohmann/json_view.hpp>): get<T>() on a view looks the members up in the view, without building a json value first. The base part is read from the view as well if the base's from_json() accepts views, and from materialize() otherwise.

"},{"location":"api/macros/nlohmann_define_derived_type/#examples","title":"Examples","text":"Example: (1) NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE

Consider the following complete example:

#include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nclass A\n{\n  private:\n    double Aa = 0.0;\n    double Ab = 0.0;\n\n  public:\n    A() = default;\n    A(double a, double b) : Aa(a), Ab(b) {}\n    NLOHMANN_DEFINE_TYPE_INTRUSIVE(A, Aa, Ab)\n};\n\nclass B : public A\n{\n  private:\n    int Ba = 0;\n    int Bb = 0;\n\n  public:\n    B() = default;\n    B(int a, int b, double aa, double ab) : A(aa, ab), Ba(a), Bb(b) {}\n    NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE(B, A, Ba, Bb)\n};\n\nint main()\n{\n    B example(23, 42, 3.142, 1.777);\n    json example_json = example;\n\n    std::cout << std::setw(4) << example_json << '\\n';\n}\n

Output:

{\n    \"Aa\": 3.142,\n    \"Ab\": 1.777,\n    \"Ba\": 23,\n    \"Bb\": 42\n}\n

Notes:

  • A and B are default-constructible. This is a requirement for using the macro.
  • A has private members and is not a derived class. Hence, macro NLOHMANN_DEFINE_TYPE_INTRUSIVE is used.
  • As B is a derived class, NLOHMANN_DEFINE_TYPE_INTRUSIVE is not applicable, but NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE must be used.
  • The macro NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE is used inside the class use as NLOHMANN_DEFINE_TYPE_INTRUSIVE.
"},{"location":"api/macros/nlohmann_define_derived_type/#see-also","title":"See also","text":"
  • NLOHMANN_DEFINE_TYPE_INTRUSIVE / NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT / NLOHMANN_DEFINE_TYPE_INTRUSIVE_ONLY_SERIALIZE - similar macros that can be defined inside a non-derived type
  • NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE / NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT / NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE - similar macros that can be defined outside a non-derived type
  • Arbitrary Type Conversions - overview of the supported conversions
  • Recipes for Common Types - class hierarchies
"},{"location":"api/macros/nlohmann_define_derived_type/#version-history","title":"Version history","text":"
  1. Added in version 3.12.0.
  2. Added in version 3.12.0.
  3. Added in version 3.12.0.
  4. Added in version 3.12.0.
  5. Added in version 3.12.0.
  6. Added in version 3.12.0.

All six macros were changed to allow an empty member list in version 3.13.0 unreleased.

The generated from_json() reads the views of json_documents since version 3.13.0 unreleased.

"},{"location":"api/macros/nlohmann_define_type_intrusive/","title":"NLOHMANN_DEFINE_TYPE_INTRUSIVE, NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT, NLOHMANN_DEFINE_TYPE_INTRUSIVE_ONLY_SERIALIZE","text":"
#define NLOHMANN_DEFINE_TYPE_INTRUSIVE(type, member...)              // (1)\n#define NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(type, member...) // (2)\n#define NLOHMANN_DEFINE_TYPE_INTRUSIVE_ONLY_SERIALIZE(type, member...) // (3)\n

These macros can be used to simplify the serialization/deserialization of types if you want to use a JSON object as serialization and want to use the member variable names as object keys in that object. The macro is to be defined inside the class/struct to create code for. Unlike NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE, it can access private members. The first parameter is the name of the class/struct, and all remaining parameters name the members.

  1. Will use at during deserialization and will throw out_of_range.403 if a key is missing in the JSON object.
  2. Will use value during deserialization and fall back to the default value for the respective type of the member variable if a key in the JSON object is missing. The generated from_json() function default constructs an object and uses its values as the defaults when calling the value function.
  3. Only defines the serialization. Useful in cases when the type does not have a default constructor and only serialization is required.

Summary:

Need access to private members Need only serialization Allow missing values when de-serializing macro NLOHMANN_DEFINE_TYPE_INTRUSIVE NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT NLOHMANN_DEFINE_TYPE_INTRUSIVE_ONLY_SERIALIZE"},{"location":"api/macros/nlohmann_define_type_intrusive/#parameters","title":"Parameters","text":"type (in) name of the type (class, struct) to serialize/deserialize member (in) name of the member variable to serialize/deserialize; up to 63 members can be given as a comma-separated list, which may also be empty"},{"location":"api/macros/nlohmann_define_type_intrusive/#default-definition","title":"Default definition","text":"

The macros add two friend functions to the class which take care of the serialization and deserialization:

template<typename BasicJsonType>\nfriend void to_json(BasicJsonType&, const type&);\ntemplate<typename BasicJsonType>\nfriend void from_json(const BasicJsonType&, type&); // except (3)\n

See the examples below for the concrete generated code.

"},{"location":"api/macros/nlohmann_define_type_intrusive/#notes","title":"Notes","text":"

Prerequisites

  1. The type type must be default constructible (except (3)). See How can I use get() for non-default constructible/non-copyable types? for how to overcome this limitation.
  2. The macro must be used inside the type (class/struct).

Types without members

The member list may be empty. The macro then generates a to_json that produces an empty JSON object {}, and a from_json that reads no members:

struct marker\n{\n    NLOHMANN_DEFINE_TYPE_INTRUSIVE(marker)\n};\n

The WITH_NAMES variants do not support this.

Implementation limits

  • The current implementation is limited to at most 63 member variables. If you want to serialize/deserialize types with more than 63 member variables, you need to define the to_json/from_json functions manually.
  • These macros always produce object-style (named-key) JSON, one key per member. There is no macro variant that serializes a struct's members positionally into a JSON array; for that, write to_json/from_json by hand, building/reading a json::array() of the members in order.

Views

The generated from_json() also reads the views of json_documents (<nlohmann/json_view.hpp>): get<T>() on a view looks the members up in the view, without building a json value first.

"},{"location":"api/macros/nlohmann_define_type_intrusive/#examples","title":"Examples","text":"Example: (1) NLOHMANN_DEFINE_TYPE_INTRUSIVE

Consider the following complete example:

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\nusing namespace nlohmann::literals;\n\nnamespace ns\n{\nclass person\n{\n  private:\n    std::string name = \"John Doe\";\n    std::string address = \"123 Fake St\";\n    int age = -1;\n\n  public:\n    person() = default;\n    person(std::string name_, std::string address_, int age_)\n        : name(std::move(name_)), address(std::move(address_)), age(age_)\n    {}\n\n    NLOHMANN_DEFINE_TYPE_INTRUSIVE(person, name, address, age)\n};\n} // namespace ns\n\nint main()\n{\n    ns::person p = {\"Ned Flanders\", \"744 Evergreen Terrace\", 60};\n\n    // serialization: person -> json\n    json j = p;\n    std::cout << \"serialization: \" << j << '\\n';\n\n    // deserialization: json -> person\n    json j2 = R\"({\"address\": \"742 Evergreen Terrace\", \"age\": 40, \"name\": \"Homer Simpson\"})\"_json;\n    auto p2 = j2.get<ns::person>();\n\n    // incomplete deserialization:\n    json j3 = R\"({\"address\": \"742 Evergreen Terrace\", \"name\": \"Maggie Simpson\"})\"_json;\n    try\n    {\n        auto p3 = j3.get<ns::person>();\n    }\n    catch (const json::exception& e)\n    {\n        std::cout << \"deserialization failed: \" << e.what() << '\\n';\n    }\n}\n

Output:

serialization: {\"address\":\"744 Evergreen Terrace\",\"age\":60,\"name\":\"Ned Flanders\"}\ndeserialization failed: [json.exception.out_of_range.403] key 'age' not found\n

Notes:

  • ns::person is default-constructible. This is a requirement for using the macro.
  • ns::person has private member variables. This makes NLOHMANN_DEFINE_TYPE_INTRUSIVE applicable, but not NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE.
  • The macro NLOHMANN_DEFINE_TYPE_INTRUSIVE is used inside the class.
  • A missing key \"age\" in the deserialization yields an exception. To fall back to the default value, NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT can be used.

The macro is equivalent to:

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\nusing namespace nlohmann::literals;\n\nnamespace ns\n{\nclass person\n{\n  private:\n    std::string name = \"John Doe\";\n    std::string address = \"123 Fake St\";\n    int age = -1;\n\n  public:\n    person() = default;\n    person(std::string name_, std::string address_, int age_)\n        : name(std::move(name_)), address(std::move(address_)), age(age_)\n    {}\n\n    template<typename BasicJsonType>\n    friend void to_json(BasicJsonType& nlohmann_json_j, const person& nlohmann_json_t)\n    {\n        nlohmann_json_j[\"name\"] = nlohmann_json_t.name;\n        nlohmann_json_j[\"address\"] = nlohmann_json_t.address;\n        nlohmann_json_j[\"age\"] = nlohmann_json_t.age;\n    }\n\n    template<typename BasicJsonType>\n    friend void from_json(const BasicJsonType& nlohmann_json_j, person& nlohmann_json_t)\n    {\n        nlohmann_json_t.name = nlohmann_json_j.at(\"name\");\n        nlohmann_json_t.address = nlohmann_json_j.at(\"address\");\n        nlohmann_json_t.age = nlohmann_json_j.at(\"age\");\n    }\n};\n} // namespace ns\n\nint main()\n{\n    ns::person p = {\"Ned Flanders\", \"744 Evergreen Terrace\", 60};\n\n    // serialization: person -> json\n    json j = p;\n    std::cout << \"serialization: \" << j << '\\n';\n\n    // deserialization: json -> person\n    json j2 = R\"({\"address\": \"742 Evergreen Terrace\", \"age\": 40, \"name\": \"Homer Simpson\"})\"_json;\n    auto p2 = j2.get<ns::person>();\n\n    // incomplete deserialization:\n    json j3 = R\"({\"address\": \"742 Evergreen Terrace\", \"name\": \"Maggie Simpson\"})\"_json;\n    try\n    {\n        auto p3 = j3.get<ns::person>();\n    }\n    catch (const json::exception& e)\n    {\n        std::cout << \"deserialization failed: \" << e.what() << '\\n';\n    }\n}\n
Example: (2) NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT

Consider the following complete example:

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\nusing namespace nlohmann::literals;\n\nnamespace ns\n{\nclass person\n{\n  private:\n    std::string name = \"John Doe\";\n    std::string address = \"123 Fake St\";\n    int age = -1;\n\n  public:\n    person() = default;\n    person(std::string name_, std::string address_, int age_)\n        : name(std::move(name_)), address(std::move(address_)), age(age_)\n    {}\n\n    NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(person, name, address, age)\n};\n} // namespace ns\n\nint main()\n{\n    ns::person p = {\"Ned Flanders\", \"744 Evergreen Terrace\", 60};\n\n    // serialization: person -> json\n    json j = p;\n    std::cout << \"serialization: \" << j << '\\n';\n\n    // deserialization: json -> person\n    json j2 = R\"({\"address\": \"742 Evergreen Terrace\", \"age\": 40, \"name\": \"Homer Simpson\"})\"_json;\n    auto p2 = j2.get<ns::person>();\n\n    // incomplete deserialization:\n    json j3 = R\"({\"address\": \"742 Evergreen Terrace\", \"name\": \"Maggie Simpson\"})\"_json;\n    auto p3 = j3.get<ns::person>();\n    std::cout << \"roundtrip: \" << json(p3) << '\\n';\n}\n

Output:

serialization: {\"address\":\"744 Evergreen Terrace\",\"age\":60,\"name\":\"Ned Flanders\"}\nroundtrip: {\"address\":\"742 Evergreen Terrace\",\"age\":-1,\"name\":\"Maggie Simpson\"}\n

Notes:

  • ns::person is default-constructible. This is a requirement for using the macro.
  • ns::person has private member variables. This makes NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT applicable, but not NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT.
  • The macro NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT is used inside the class.
  • A missing key \"age\" in the deserialization does not yield an exception. Instead, the default value -1 is used.

The macro is equivalent to:

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\nusing namespace nlohmann::literals;\n\nnamespace ns\n{\nclass person\n{\n  private:\n    std::string name = \"John Doe\";\n    std::string address = \"123 Fake St\";\n    int age = -1;\n\n  public:\n    person() = default;\n    person(std::string name_, std::string address_, int age_)\n        : name(std::move(name_)), address(std::move(address_)), age(age_)\n    {}\n\n    template<typename BasicJsonType>\n    friend void to_json(BasicJsonType& nlohmann_json_j, const person& nlohmann_json_t)\n    {\n        nlohmann_json_j[\"name\"] = nlohmann_json_t.name;\n        nlohmann_json_j[\"address\"] = nlohmann_json_t.address;\n        nlohmann_json_j[\"age\"] = nlohmann_json_t.age;\n    }\n\n    template<typename BasicJsonType>\n    friend void from_json(const BasicJsonType& nlohmann_json_j, person& nlohmann_json_t)\n    {\n        person nlohmann_json_default_obj;\n        nlohmann_json_t.name = nlohmann_json_j.value(\"name\", nlohmann_json_default_obj.name);\n        nlohmann_json_t.address = nlohmann_json_j.value(\"address\", nlohmann_json_default_obj.address);\n        nlohmann_json_t.age = nlohmann_json_j.value(\"age\", nlohmann_json_default_obj.age);\n    }\n};\n} // namespace ns\n\nint main()\n{\n    ns::person p = {\"Ned Flanders\", \"744 Evergreen Terrace\", 60};\n\n    // serialization: person -> json\n    json j = p;\n    std::cout << \"serialization: \" << j << '\\n';\n\n    // deserialization: json -> person\n    json j2 = R\"({\"address\": \"742 Evergreen Terrace\", \"age\": 40, \"name\": \"Homer Simpson\"})\"_json;\n    auto p2 = j2.get<ns::person>();\n\n    // incomplete deserialization:\n    json j3 = R\"({\"address\": \"742 Evergreen Terrace\", \"name\": \"Maggie Simpson\"})\"_json;\n    auto p3 = j3.get<ns::person>();\n    std::cout << \"roundtrip: \" << json(p3) << '\\n';\n}\n

Note how a default-initialized person object is used in the from_json to fill missing values.

Example: (3) NLOHMANN_DEFINE_TYPE_INTRUSIVE_ONLY_SERIALIZE

Consider the following complete example:

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\nusing namespace nlohmann::literals;\n\nnamespace ns\n{\nclass person\n{\n  private:\n    std::string name = \"John Doe\";\n    std::string address = \"123 Fake St\";\n    int age = -1;\n\n  public:\n    // No default constructor\n    person(std::string name_, std::string address_, int age_)\n        : name(std::move(name_)), address(std::move(address_)), age(age_)\n    {}\n\n    NLOHMANN_DEFINE_TYPE_INTRUSIVE(person, name, address, age)\n};\n} // namespace ns\n\nint main()\n{\n    ns::person p = {\"Ned Flanders\", \"744 Evergreen Terrace\", 60};\n\n    // serialization: person -> json\n    json j = p;\n    std::cout << \"serialization: \" << j << '\\n';\n}\n

Output:

serialization: {\"address\":\"744 Evergreen Terrace\",\"age\":60,\"name\":\"Ned Flanders\"}\n

Notes:

  • ns::person is non-default-constructible. This allows this macro to be used instead of NLOHMANN_DEFINE_TYPE_INTRUSIVE and NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT.
  • ns::person has private member variables. This makes NLOHMANN_DEFINE_TYPE_INTRUSIVE_ONLY_SERIALIZE applicable, but not NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE.
  • The macro NLOHMANN_DEFINE_TYPE_INTRUSIVE_ONLY_SERIALIZE is used inside the class.

The macro is equivalent to:

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\nusing namespace nlohmann::literals;\n\nnamespace ns\n{\nclass person\n{\n  private:\n    std::string name = \"John Doe\";\n    std::string address = \"123 Fake St\";\n    int age = -1;\n\n  public:\n    // No default constructor\n    person(std::string name_, std::string address_, int age_)\n        : name(std::move(name_)), address(std::move(address_)), age(age_)\n    {}\n\n    template<typename BasicJsonType>\n    friend void to_json(BasicJsonType& nlohmann_json_j, const person& nlohmann_json_t)\n    {\n        nlohmann_json_j[\"name\"] = nlohmann_json_t.name;\n        nlohmann_json_j[\"address\"] = nlohmann_json_t.address;\n        nlohmann_json_j[\"age\"] = nlohmann_json_t.age;\n    }\n};\n} // namespace ns\n\nint main()\n{\n    ns::person p = {\"Ned Flanders\", \"744 Evergreen Terrace\", 60};\n\n    // serialization: person -> json\n    json j = p;\n    std::cout << \"serialization: \" << j << '\\n';\n}\n
"},{"location":"api/macros/nlohmann_define_type_intrusive/#see-also","title":"See also","text":"
  • NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE / NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT / NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE - a similar macro that can be defined outside the type
  • NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE / NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_WITH_DEFAULT / NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_ONLY_SERIALIZE / NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE / NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_WITH_DEFAULT / NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE - similar macros for derived types
  • Arbitrary Type Conversions - overview of the supported conversions
"},{"location":"api/macros/nlohmann_define_type_intrusive/#version-history","title":"Version history","text":"
  1. Added in version 3.9.0.
  2. Added in version 3.11.0.
  3. Added in version 3.11.3.

All three macros were changed to work with any basic_json specialization (not only nlohmann::json) in version 3.12.0, and to allow an empty member list in version 3.13.0 unreleased.

The generated from_json() reads the views of json_documents since version 3.13.0 unreleased.

"},{"location":"api/macros/nlohmann_define_type_non_intrusive/","title":"NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE, NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT, NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE","text":"
#define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(type, member...)              // (1)\n#define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT(type, member...) // (2)\n#define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE(type, member...) // (3)\n

These macros can be used to simplify the serialization/deserialization of types if you want to use a JSON object as serialization and want to use the member variable names as object keys in that object. The macro is to be defined outside the class/struct to create code for, but inside its namespace. Unlike NLOHMANN_DEFINE_TYPE_INTRUSIVE, it cannot access private members. The first parameter is the name of the class/struct, and all remaining parameters name the members.

  1. Will use at during deserialization and will throw out_of_range.403 if a key is missing in the JSON object.
  2. Will use value during deserialization and fall back to the default value for the respective type of the member variable if a key in the JSON object is missing. The generated from_json() function default constructs an object and uses its values as the defaults when calling the value function.
  3. Only defines the serialization. Useful in cases when the type does not have a default constructor and only serialization is required.

Summary:

Need access to private members Need only serialization Allow missing values when de-serializing macro NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE"},{"location":"api/macros/nlohmann_define_type_non_intrusive/#parameters","title":"Parameters","text":"type (in) name of the type (class, struct) to serialize/deserialize member (in) name of the (public) member variable to serialize/deserialize; up to 63 members can be given as a comma-separated list, which may also be empty"},{"location":"api/macros/nlohmann_define_type_non_intrusive/#default-definition","title":"Default definition","text":"

The macros add two functions to the namespace which take care of the serialization and deserialization:

template<typename BasicJsonType>\nvoid to_json(BasicJsonType&, const type&);\ntemplate<typename BasicJsonType>\nvoid from_json(const BasicJsonType&, type&); // except (3)\n

See the examples below for the concrete generated code.

"},{"location":"api/macros/nlohmann_define_type_non_intrusive/#notes","title":"Notes","text":"

Prerequisites

  1. The type type must be default constructible (except (3). See How can I use get() for non-default constructible/non-copyable types? for how to overcome this limitation.
  2. The macro must be used outside the type (class/struct).
  3. The passed members must be public.

Types without members

The member list may be empty. The macro then generates a to_json that produces an empty JSON object {}, and a from_json that reads no members:

struct marker {};\nNLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(marker)\n

The WITH_NAMES variants do not support this.

Implementation limits

  • The current implementation is limited to at most 63 member variables. If you want to serialize/deserialize types with more than 63 member variables, you need to define the to_json/from_json functions manually.
  • These macros always produce object-style (named-key) JSON, one key per member. There is no macro variant that serializes a struct's members positionally into a JSON array; for that, write to_json/from_json by hand, building/reading a json::array() of the members in order.

Views

The generated from_json() also reads the views of json_documents (<nlohmann/json_view.hpp>): get<T>() on a view looks the members up in the view, without building a json value first.

"},{"location":"api/macros/nlohmann_define_type_non_intrusive/#examples","title":"Examples","text":"Example: (1) NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE

Consider the following complete example:

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\nusing namespace nlohmann::literals;\n\nnamespace ns\n{\nstruct person\n{\n    std::string name;\n    std::string address;\n    int age;\n};\n\nNLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(person, name, address, age)\n} // namespace ns\n\nint main()\n{\n    ns::person p = {\"Ned Flanders\", \"744 Evergreen Terrace\", 60};\n\n    // serialization: person -> json\n    json j = p;\n    std::cout << \"serialization: \" << j << '\\n';\n\n    // deserialization: json -> person\n    json j2 = R\"({\"address\": \"742 Evergreen Terrace\", \"age\": 40, \"name\": \"Homer Simpson\"})\"_json;\n    auto p2 = j2.get<ns::person>();\n\n    // incomplete deserialization:\n    json j3 = R\"({\"address\": \"742 Evergreen Terrace\", \"name\": \"Maggie Simpson\"})\"_json;\n    try\n    {\n        auto p3 = j3.get<ns::person>();\n    }\n    catch (const json::exception& e)\n    {\n        std::cout << \"deserialization failed: \" << e.what() << '\\n';\n    }\n}\n

Output:

serialization: {\"address\":\"744 Evergreen Terrace\",\"age\":60,\"name\":\"Ned Flanders\"}\ndeserialization failed: [json.exception.out_of_range.403] key 'age' not found\n

Notes:

  • ns::person is default-constructible. This is a requirement for using the macro.
  • ns::person has only public member variables. This makes NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE applicable.
  • The macro NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE is used outside the class, but inside its namespace ns.
  • A missing key \"age\" in the deserialization yields an exception. To fall back to the default value, NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT can be used.

The macro is equivalent to:

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\nusing namespace nlohmann::literals;\n\nnamespace ns\n{\nstruct person\n{\n    std::string name;\n    std::string address;\n    int age;\n};\n\ntemplate<typename BasicJsonType>\nvoid to_json(BasicJsonType& nlohmann_json_j, const person& nlohmann_json_t)\n{\n    nlohmann_json_j[\"name\"] = nlohmann_json_t.name;\n    nlohmann_json_j[\"address\"] = nlohmann_json_t.address;\n    nlohmann_json_j[\"age\"] = nlohmann_json_t.age;\n}\n\ntemplate<typename BasicJsonType>\nvoid from_json(const BasicJsonType& nlohmann_json_j, person& nlohmann_json_t)\n{\n    nlohmann_json_t.name = nlohmann_json_j.at(\"name\");\n    nlohmann_json_t.address = nlohmann_json_j.at(\"address\");\n    nlohmann_json_t.age = nlohmann_json_j.at(\"age\");\n}\n} // namespace ns\n\nint main()\n{\n    ns::person p = {\"Ned Flanders\", \"744 Evergreen Terrace\", 60};\n\n    // serialization: person -> json\n    json j = p;\n    std::cout << \"serialization: \" << j << '\\n';\n\n    // deserialization: json -> person\n    json j2 = R\"({\"address\": \"742 Evergreen Terrace\", \"age\": 40, \"name\": \"Homer Simpson\"})\"_json;\n    auto p2 = j2.get<ns::person>();\n\n    // incomplete deserialization:\n    json j3 = R\"({\"address\": \"742 Evergreen Terrace\", \"name\": \"Maggie Simpson\"})\"_json;\n    try\n    {\n        auto p3 = j3.get<ns::person>();\n    }\n    catch (const json::exception& e)\n    {\n        std::cout << \"deserialization failed: \" << e.what() << '\\n';\n    }\n}\n
Example: (2) NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT

Consider the following complete example:

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\nusing namespace nlohmann::literals;\n\nnamespace ns\n{\nstruct person\n{\n    std::string name = \"John Doe\";\n    std::string address = \"123 Fake St\";\n    int age = -1;\n\n    person() = default;\n    person(std::string name_, std::string address_, int age_)\n        : name(std::move(name_)), address(std::move(address_)), age(age_)\n    {}\n};\n\nNLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT(person, name, address, age)\n} // namespace ns\n\nint main()\n{\n    ns::person p = {\"Ned Flanders\", \"744 Evergreen Terrace\", 60};\n\n    // serialization: person -> json\n    json j = p;\n    std::cout << \"serialization: \" << j << '\\n';\n\n    // deserialization: json -> person\n    json j2 = R\"({\"address\": \"742 Evergreen Terrace\", \"age\": 40, \"name\": \"Homer Simpson\"})\"_json;\n    auto p2 = j2.get<ns::person>();\n\n    // incomplete deserialization:\n    json j3 = R\"({\"address\": \"742 Evergreen Terrace\", \"name\": \"Maggie Simpson\"})\"_json;\n    auto p3 = j3.get<ns::person>();\n    std::cout << \"roundtrip: \" << json(p3) << '\\n';\n}\n

Output:

serialization: {\"address\":\"744 Evergreen Terrace\",\"age\":60,\"name\":\"Ned Flanders\"}\nroundtrip: {\"address\":\"742 Evergreen Terrace\",\"age\":-1,\"name\":\"Maggie Simpson\"}\n

Notes:

  • ns::person is default-constructible. This is a requirement for using the macro.
  • ns::person has only public member variables. This makes NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT applicable.
  • The macro NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT is used outside the class, but inside its namespace ns.
  • A missing key \"age\" in the deserialization does not yield an exception. Instead, the default value -1 is used.

The macro is equivalent to:

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\nusing namespace nlohmann::literals;\n\nnamespace ns\n{\nstruct person\n{\n    std::string name = \"John Doe\";\n    std::string address = \"123 Fake St\";\n    int age = -1;\n\n    person() = default;\n    person(std::string name_, std::string address_, int age_)\n        : name(std::move(name_)), address(std::move(address_)), age(age_)\n    {}\n};\n\ntemplate<typename BasicJsonType>\nvoid to_json(BasicJsonType& nlohmann_json_j, const person& nlohmann_json_t)\n{\n    nlohmann_json_j[\"name\"] = nlohmann_json_t.name;\n    nlohmann_json_j[\"address\"] = nlohmann_json_t.address;\n    nlohmann_json_j[\"age\"] = nlohmann_json_t.age;\n}\n\ntemplate<typename BasicJsonType>\nvoid from_json(const BasicJsonType& nlohmann_json_j, person& nlohmann_json_t)\n{\n    person nlohmann_json_default_obj;\n    nlohmann_json_t.name = nlohmann_json_j.value(\"name\", nlohmann_json_default_obj.name);\n    nlohmann_json_t.address = nlohmann_json_j.value(\"address\", nlohmann_json_default_obj.address);\n    nlohmann_json_t.age = nlohmann_json_j.value(\"age\", nlohmann_json_default_obj.age);\n}\n} // namespace ns\n\nint main()\n{\n    ns::person p = {\"Ned Flanders\", \"744 Evergreen Terrace\", 60};\n\n    // serialization: person -> json\n    json j = p;\n    std::cout << \"serialization: \" << j << '\\n';\n\n    // deserialization: json -> person\n    json j2 = R\"({\"address\": \"742 Evergreen Terrace\", \"age\": 40, \"name\": \"Homer Simpson\"})\"_json;\n    auto p2 = j2.get<ns::person>();\n\n    // incomplete deserialization:\n    json j3 = R\"({\"address\": \"742 Evergreen Terrace\", \"name\": \"Maggie Simpson\"})\"_json;\n    auto p3 = j3.get<ns::person>();\n    std::cout << \"roundtrip: \" << json(p3) << '\\n';\n}\n

Note how a default-initialized person object is used in the from_json to fill missing values.

Example: (3) NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE

Consider the following complete example:

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\nusing namespace nlohmann::literals;\n\nnamespace ns\n{\nstruct person\n{\n    std::string name;\n    std::string address;\n    int age;\n};\n\nNLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE(person, name, address, age)\n} // namespace ns\n\nint main()\n{\n    ns::person p = {\"Ned Flanders\", \"744 Evergreen Terrace\", 60};\n\n    // serialization: person -> json\n    json j = p;\n    std::cout << \"serialization: \" << j << '\\n';\n}\n

Output:

serialization: {\"address\":\"744 Evergreen Terrace\",\"age\":60,\"name\":\"Ned Flanders\"}\n

Notes:

  • ns::person is non-default-constructible. This allows this macro to be used instead of NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE and NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT.
  • ns::person has only public member variables. This makes NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE applicable.
  • The macro NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE is used outside the class, but inside its namespace ns.

The macro is equivalent to:

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\nusing namespace nlohmann::literals;\n\nnamespace ns\n{\nstruct person\n{\n    std::string name;\n    std::string address;\n    int age;\n};\n\ntemplate<typename BasicJsonType>\nvoid to_json(BasicJsonType& nlohmann_json_j, const person& nlohmann_json_t)\n{\n    nlohmann_json_j[\"name\"] = nlohmann_json_t.name;\n    nlohmann_json_j[\"address\"] = nlohmann_json_t.address;\n    nlohmann_json_j[\"age\"] = nlohmann_json_t.age;\n}\n} // namespace ns\n\nint main()\n{\n    ns::person p = {\"Ned Flanders\", \"744 Evergreen Terrace\", 60};\n\n    // serialization: person -> json\n    json j = p;\n    std::cout << \"serialization: \" << j << '\\n';\n}\n
"},{"location":"api/macros/nlohmann_define_type_non_intrusive/#see-also","title":"See also","text":"
  • NLOHMANN_DEFINE_TYPE_INTRUSIVE / NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT / NLOHMANN_DEFINE_TYPE_INTRUSIVE_ONLY_SERIALIZE - a similar macro that can be defined inside the type
  • NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE / NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_WITH_DEFAULT / NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_ONLY_SERIALIZE / NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE / NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_WITH_DEFAULT / NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE - similar macros for derived types
  • Arbitrary Type Conversions - overview of the supported conversions
"},{"location":"api/macros/nlohmann_define_type_non_intrusive/#version-history","title":"Version history","text":"
  1. Added in version 3.9.0.
  2. Added in version 3.11.0.
  3. Added in version 3.11.3.

All three macros were changed to work with any basic_json specialization (not only nlohmann::json) in version 3.12.0, and to allow an empty member list in version 3.13.0 unreleased.

The generated from_json() reads the views of json_documents since version 3.13.0 unreleased.

"},{"location":"api/macros/nlohmann_define_type_with_names/","title":"NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_NAMES, NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT_WITH_NAMES, NLOHMANN_DEFINE_TYPE_INTRUSIVE_ONLY_SERIALIZE_WITH_NAMES, NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_NAMES, NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT_WITH_NAMES, NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE_WITH_NAMES, NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_WITH_NAMES, NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_WITH_DEFAULT_WITH_NAMES, NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_ONLY_SERIALIZE_WITH_NAMES, NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_WITH_NAMES, NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_WITH_DEFAULT_WITH_NAMES, NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE_WITH_NAMES","text":"NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_NAMES, NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT_WITH_NAMES, NLOHMANN_DEFINE_TYPE_INTRUSIVE_ONLY_SERIALIZE_WITH_NAMES, NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_NAMES, NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT_WITH_NAMES, NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE_WITH_NAMES, NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_WITH_NAMES, NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_WITH_DEFAULT_WITH_NAMES, NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_ONLY_SERIALIZE_WITH_NAMES, NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_WITH_NAMES, NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_WITH_DEFAULT_WITH_NAMES, NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE_WITH_NAMES
#define NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_NAMES(type, \"json_member_name\", member...)\n#define NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT_WITH_NAMES(type, \"json_member_name\", member...)\n#define NLOHMANN_DEFINE_TYPE_INTRUSIVE_ONLY_SERIALIZE_WITH_NAMES(type, \"json_member_name\", member...)\n#define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_NAMES(type, \"json_member_name\", member...)\n#define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT_WITH_NAMES(type, \"json_member_name\", member...)\n#define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE_WITH_NAMES(type, \"json_member_name\", member...)\n#define NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_WITH_NAMES(type, base_type, \"json_member_name\", member...)\n#define NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_WITH_DEFAULT_WITH_NAMES(type, base_type, \"json_member_name\", member...)\n#define NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_ONLY_SERIALIZE_WITH_NAMES(type, base_type, \"json_member_name\", member...)\n#define NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_WITH_NAMES(type, base_type, \"json_member_name\", member...)\n#define NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_WITH_DEFAULT_WITH_NAMES(type, base_type, \"json_member_name\", member...)\n#define NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE_WITH_NAMES(type, base_type, \"json_member_name\", member...)\n

These macros can be used in case you want to use the custom names for the member variables in the resulting JSON. They behave exactly as their non-WITH_NAMES counterparts, but require an additional parameter for each member variable which will be used in JSON. Both serialization and deserialization will only use the custom names for JSON, the names of the member variables themselves will be ignored.

Using the named conversion macros will halve the maximum number of member variables from 63 to 31.

For further information please refer to the corresponding macros without WITH_NAMES.

"},{"location":"api/macros/nlohmann_define_type_with_names/#parameters","title":"Parameters","text":"type (in) name of the type (class, struct) to serialize/deserialize base_type (in) name of the base type (class, struct) type is derived from (used only in DEFINE_DERIVED_TYPE macros) json_member_name (in) the string that will be used as the name for the next value member (in) name of the member variable to serialize/deserialize"},{"location":"api/macros/nlohmann_define_type_with_names/#examples","title":"Examples","text":"Example: NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_NAMES

Consider the following complete example:

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\nusing namespace nlohmann::literals;\n\nnamespace ns\n{\nstruct person\n{\n    std::string name;\n    std::string address;\n    int age;\n};\n\nNLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_NAMES(person, \"json_name\", name, \"json_address\", address, \"json_age\", age)\n} // namespace ns\n\nint main()\n{\n    ns::person p = {\"Ned Flanders\", \"744 Evergreen Terrace\", 60};\n\n    // serialization: person -> json\n    json j = p;\n    std::cout << \"serialization: \" << j << '\\n';\n\n    // deserialization: json -> person\n    json j2 = R\"({\"json_address\": \"742 Evergreen Terrace\", \"json_age\": 40, \"json_name\": \"Homer Simpson\"})\"_json;\n    auto p2 = j2.template get<ns::person>();\n\n    // incomplete deserialization:\n    json j3 = R\"({\"json_address\": \"742 Evergreen Terrace\", \"json_name\": \"Maggie Simpson\"})\"_json;\n    try\n    {\n        auto p3 = j3.template get<ns::person>();\n    }\n    catch (const json::exception& e)\n    {\n        std::cout << \"deserialization failed: \" << e.what() << '\\n';\n    }\n}\n

Output:

serialization: {\"json_address\":\"744 Evergreen Terrace\",\"json_age\":60,\"json_name\":\"Ned Flanders\"}\ndeserialization failed: [json.exception.out_of_range.403] key 'json_age' not found\n

Notes:

  • ns::person is default-constructible. This is a requirement for using the macro.
  • ns::person has only public member variables. This makes NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_NAMES applicable.
  • The macro NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_NAMES is used outside the class, but inside its namespace ns.
  • A missing key \"age\" in the deserialization yields an exception. To fall back to the default value, NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT_WITH_NAMES can be used.

The macro is equivalent to:

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\nusing namespace nlohmann::literals;\n\nnamespace ns\n{\nstruct person\n{\n    std::string name;\n    std::string address;\n    int age;\n};\n\ntemplate <typename BasicJsonType, nlohmann::detail::enable_if_t<nlohmann::detail::is_basic_json<BasicJsonType>::value, int> = 0>\nvoid to_json(BasicJsonType& nlohmann_json_j, const person& nlohmann_json_t)\n{\n    nlohmann_json_j[\"json_name\"] = nlohmann_json_t.name;\n    nlohmann_json_j[\"json_address\"] = nlohmann_json_t.address;\n    nlohmann_json_j[\"json_age\"] = nlohmann_json_t.age;\n}\n\ntemplate <typename BasicJsonType, nlohmann::detail::enable_if_t<nlohmann::detail::is_basic_json<BasicJsonType>::value, int> = 0>\nvoid from_json(const BasicJsonType& nlohmann_json_j, person& nlohmann_json_t)\n{\n    nlohmann_json_j.at(\"json_name\").get_to(nlohmann_json_t.name);\n    nlohmann_json_j.at(\"json_address\").get_to(nlohmann_json_t.address);\n    nlohmann_json_j.at(\"json_age\").get_to(nlohmann_json_t.age);\n}\n} // namespace ns\n\nint main()\n{\n    ns::person p = {\"Ned Flanders\", \"744 Evergreen Terrace\", 60};\n\n    // serialization: person -> json\n    json j = p;\n    std::cout << \"serialization: \" << j << '\\n';\n\n    // deserialization: json -> person\n    json j2 = R\"({\"json_address\": \"742 Evergreen Terrace\", \"json_age\": 40, \"json_name\": \"Homer Simpson\"})\"_json;\n    auto p2 = j2.template get<ns::person>();\n\n    // incomplete deserialization:\n    json j3 = R\"({\"json_address\": \"742 Evergreen Terrace\", \"json_name\": \"Maggie Simpson\"})\"_json;\n    try\n    {\n        auto p3 = j3.template get<ns::person>();\n    }\n    catch (const json::exception& e)\n    {\n        std::cout << \"deserialization failed: \" << e.what() << '\\n';\n    }\n}\n
"},{"location":"api/macros/nlohmann_define_type_with_names/#see-also","title":"See also","text":"
  • NLOHMANN_DEFINE_TYPE_INTRUSIVE / NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT / NLOHMANN_DEFINE_TYPE_INTRUSIVE_ONLY_SERIALIZE - the macros these variants add custom JSON key names to
  • NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE / NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT / NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE - the macros these variants add custom JSON key names to
  • NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE / NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_WITH_DEFAULT / NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_ONLY_SERIALIZE / NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE / NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_WITH_DEFAULT / NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE - similar macros for derived types, also available with custom names
  • Arbitrary Type Conversions - overview of type conversion mechanisms
"},{"location":"api/macros/nlohmann_define_type_with_names/#version-history","title":"Version history","text":"
  • Added in version 3.13.0 unreleased.
"},{"location":"api/macros/nlohmann_json_namespace/","title":"NLOHMANN_JSON_NAMESPACE","text":"
#define NLOHMANN_JSON_NAMESPACE /* value */\n

This macro evaluates to the full name of the nlohmann namespace.

"},{"location":"api/macros/nlohmann_json_namespace/#default-definition","title":"Default definition","text":"

The default value consists of the root namespace (nlohmann) and an inline ABI namespace. See nlohmann Namespace for details.

When the macro is not defined, the library will define it to its default value. Overriding this value has no effect on the library.

"},{"location":"api/macros/nlohmann_json_namespace/#examples","title":"Examples","text":"Example

The example shows how to use NLOHMANN_JSON_NAMESPACE instead of just nlohmann, as well as how to output the value of NLOHMANN_JSON_NAMESPACE.

#include <iostream>\n#include <nlohmann/json.hpp>\n\n// possible use case: use NLOHMANN_JSON_NAMESPACE instead of nlohmann\nusing NLOHMANN_JSON_NAMESPACE::json;\n\n// macro needed to output the NLOHMANN_JSON_NAMESPACE as string literal\n#define Q(x) #x\n#define QUOTE(x) Q(x)\n\nint main()\n{\n    std::cout << QUOTE(NLOHMANN_JSON_NAMESPACE) << '\\n';\n}\n

Output:

nlohmann::json_abi_v3_12_0\n
"},{"location":"api/macros/nlohmann_json_namespace/#see-also","title":"See also","text":"
  • NLOHMANN_JSON_NAMESPACE_BEGIN, NLOHMANN_JSON_NAMESPACE_END - macros to open and close the library namespace
  • NLOHMANN_JSON_NAMESPACE_NO_VERSION - disable the inline versioned namespace
  • Supported Macros - guide to all supported macros
  • nlohmann Namespace - the library namespace
"},{"location":"api/macros/nlohmann_json_namespace/#version-history","title":"Version history","text":"
  • Added in version 3.11.0. Changed inline namespace name in version 3.11.2. Added the ABI tag _dp in version 3.12.0, and the ABI tags _bics, _psp, _snul, _sbu8, _ekmo, _dsbs, _dufio, and _ns in version 3.13.0 unreleased; see nlohmann Namespace.
"},{"location":"api/macros/nlohmann_json_namespace_begin/","title":"NLOHMANN_JSON_NAMESPACE_BEGIN, NLOHMANN_JSON_NAMESPACE_END","text":"
#define NLOHMANN_JSON_NAMESPACE_BEGIN /* value */  // (1)\n#define NLOHMANN_JSON_NAMESPACE_END   /* value */  // (2)\n

These macros can be used to open and close the nlohmann namespace. See nlohmann Namespace for details.

  1. Opens the namespace.
  2. Closes the namespace.
"},{"location":"api/macros/nlohmann_json_namespace_begin/#default-definition","title":"Default definition","text":"

The default definitions open and close the nlohmann namespace. The precise definition of NLOHMANN_JSON_NAMESPACE_BEGIN varies as described here.

  1. Default definition of NLOHMANN_JSON_NAMESPACE_BEGIN:

    namespace nlohmann\n{\ninline namespace json_abi_v3_12_0\n{\n
  2. Default definition of NLOHMANN_JSON_NAMESPACE_END:

    }  // namespace json_abi_v3_12_0\n}  // namespace nlohmann\n

When these macros are not defined, the library will define them to their default definitions.

"},{"location":"api/macros/nlohmann_json_namespace_begin/#examples","title":"Examples","text":"Example

The example shows how to use NLOHMANN_JSON_NAMESPACE_BEGIN/NLOHMANN_JSON_NAMESPACE_END from the How do I convert third-party types? page.

#include <iostream>\n#include <optional>\n#include <nlohmann/json.hpp>\n\n// partial specialization (see https://json.nlohmann.me/features/arbitrary_types/)\nNLOHMANN_JSON_NAMESPACE_BEGIN\ntemplate <typename T>\nstruct adl_serializer<std::optional<T>>\n{\n    static void to_json(json& j, const std::optional<T>& opt)\n    {\n        if (opt == std::nullopt)\n        {\n            j = nullptr;\n        }\n        else\n        {\n            j = *opt;\n        }\n    }\n};\nNLOHMANN_JSON_NAMESPACE_END\n\nint main()\n{\n    std::optional<int> o1 = 1;\n    std::optional<int> o2 = std::nullopt;\n\n    NLOHMANN_JSON_NAMESPACE::json j;\n    j.push_back(o1);\n    j.push_back(o2);\n    std::cout << j << '\\n';\n}\n

Output:

[1,null]\n
"},{"location":"api/macros/nlohmann_json_namespace_begin/#see-also","title":"See also","text":"
  • nlohmann Namespace - how the library's namespace is defined and versioned
  • NLOHMANN_JSON_NAMESPACE - macro expanding to the library namespace
  • NLOHMANN_JSON_NAMESPACE_NO_VERSION - disable the inline versioned namespace
  • Supported Macros - guide to all supported macros
"},{"location":"api/macros/nlohmann_json_namespace_begin/#version-history","title":"Version history","text":"
  • Added in version 3.11.0. Changed inline namespace name in version 3.11.2.
"},{"location":"api/macros/nlohmann_json_namespace_no_version/","title":"NLOHMANN_JSON_NAMESPACE_NO_VERSION","text":"
#define NLOHMANN_JSON_NAMESPACE_NO_VERSION /* value */\n

If defined to 1, the version component is omitted from the inline namespace. See nlohmann Namespace for details.

"},{"location":"api/macros/nlohmann_json_namespace_no_version/#default-definition","title":"Default definition","text":"

The default value is 0.

#define NLOHMANN_JSON_NAMESPACE_NO_VERSION 0\n

When the macro is not defined, the library will define it to its default value.

"},{"location":"api/macros/nlohmann_json_namespace_no_version/#examples","title":"Examples","text":"Example

The example shows how to use NLOHMANN_JSON_NAMESPACE_NO_VERSION to disable the version component of the inline namespace.

#include <iostream>\n\n#define NLOHMANN_JSON_NAMESPACE_NO_VERSION 1\n#include <nlohmann/json.hpp>\n\n// macro needed to output the NLOHMANN_JSON_NAMESPACE as string literal\n#define Q(x) #x\n#define QUOTE(x) Q(x)\n\nint main()\n{\n    std::cout << QUOTE(NLOHMANN_JSON_NAMESPACE) << '\\n';\n}\n

Output:

nlohmann::json_abi\n
"},{"location":"api/macros/nlohmann_json_namespace_no_version/#see-also","title":"See also","text":"
  • nlohmann Namespace - how the library's namespace is defined and versioned
  • NLOHMANN_JSON_NAMESPACE - macro expanding to the library namespace
  • NLOHMANN_JSON_NAMESPACE_BEGIN, NLOHMANN_JSON_NAMESPACE_END - macros to open and close the library namespace
  • Supported Macros - guide to all supported macros
"},{"location":"api/macros/nlohmann_json_namespace_no_version/#version-history","title":"Version history","text":"
  • Added in version 3.11.2.
"},{"location":"api/macros/nlohmann_json_serialize_enum/","title":"NLOHMANN_JSON_SERIALIZE_ENUM","text":"
#define NLOHMANN_JSON_SERIALIZE_ENUM(type, conversion...)\n

By default, enum values are serialized to JSON as integers. In some cases, this could result in undesired behavior. If an enum is modified or re-ordered after data has been serialized to JSON, the later deserialized JSON data may be undefined or a different enum value than was originally intended.

The NLOHMANN_JSON_SERIALIZE_ENUM allows to define a user-defined serialization for every enumerator.

"},{"location":"api/macros/nlohmann_json_serialize_enum/#parameters","title":"Parameters","text":"type (in) name of the enum to serialize/deserialize conversion (in) a pair of an enumerator and a JSON serialization; arbitrary pairs can be given as a comma-separated list"},{"location":"api/macros/nlohmann_json_serialize_enum/#default-definition","title":"Default definition","text":"

The macro adds two functions to the namespace which take care of the serialization and deserialization:

template<typename BasicJsonType>\ninline void to_json(BasicJsonType& j, const type& e);\ntemplate<typename BasicJsonType>\ninline void from_json(const BasicJsonType& j, type& e);\n
"},{"location":"api/macros/nlohmann_json_serialize_enum/#notes","title":"Notes","text":"

Prerequisites

The macro must be used inside the namespace of the enum.

Important notes

  • When using get<ENUM_TYPE>(), undefined JSON values will default to the first specified conversion. Select this default pair carefully. See example 1 below.
  • If an enum or JSON value is specified in multiple conversions, the first matching conversion from the top of the list will be returned when converting to or from JSON. See example 2 below.
  • Maps with enum keys (e.g., std::map<ENUM_TYPE, T>) are stored as arrays of [key, value] pairs by default. Define JSON_USE_OBJECTS_FOR_ENUM_KEYED_MAPS to store them as objects with the converted keys. Such maps can be read from both forms.

Views

The generated from_json() also reads the views of json_documents (<nlohmann/json_view.hpp>), comparing the view with the entries of the mapping, without building a json value first.

"},{"location":"api/macros/nlohmann_json_serialize_enum/#examples","title":"Examples","text":"Example: Basic usage

The example shows how NLOHMANN_JSON_SERIALIZE_ENUM can be used to serialize/deserialize both classical enums and C++11 enum classes:

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nnamespace ns\n{\nenum TaskState\n{\n    TS_STOPPED,\n    TS_RUNNING,\n    TS_COMPLETED,\n    TS_INVALID = -1\n};\n\nNLOHMANN_JSON_SERIALIZE_ENUM(TaskState,\n{\n    { TS_INVALID, nullptr },\n    { TS_STOPPED, \"stopped\" },\n    { TS_RUNNING, \"running\" },\n    { TS_COMPLETED, \"completed\" }\n})\n\nenum class Color\n{\n    red, green, blue, unknown\n};\n\nNLOHMANN_JSON_SERIALIZE_ENUM(Color,\n{\n    { Color::unknown, \"unknown\" }, { Color::red, \"red\" },\n    { Color::green, \"green\" }, { Color::blue, \"blue\" }\n})\n} // namespace ns\n\nint main()\n{\n    // serialization\n    json j_stopped = ns::TS_STOPPED;\n    json j_red = ns::Color::red;\n    std::cout << \"ns::TS_STOPPED -> \" << j_stopped\n              << \", ns::Color::red -> \" << j_red << '\\n';\n\n    // deserialization\n    json j_running = \"running\";\n    json j_blue = \"blue\";\n    auto running = j_running.get<ns::TaskState>();\n    auto blue = j_blue.get<ns::Color>();\n    std::cout << j_running << \" -> \" << running\n              << \", \" << j_blue << \" -> \" << static_cast<int>(blue) << '\\n';\n\n    // deserializing undefined JSON value to enum\n    // (where the first map entry above is the default)\n    json j_pi = 3.14;\n    auto invalid = j_pi.get<ns::TaskState>();\n    auto unknown = j_pi.get<ns::Color>();\n    std::cout << j_pi << \" -> \" << invalid << \", \"\n              << j_pi << \" -> \" << static_cast<int>(unknown) << '\\n';\n}\n

Output:

ns::TS_STOPPED -> \"stopped\", ns::Color::red -> \"red\"\n\"running\" -> 1, \"blue\" -> 2\n3.14 -> -1, 3.14 -> 3\n
Example: Multiple conversions for one enumerator

The example shows how to use multiple conversions for a single enumerator. In the example, Color::red will always be serialized to \"red\", because the first occurring conversion. The second conversion, however, offers an alternative deserialization from \"rot\" to Color::red.

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nnamespace ns\n{\nenum class Color\n{\n    red, green, blue, unknown\n};\n\nNLOHMANN_JSON_SERIALIZE_ENUM(Color,\n{\n    { Color::unknown, \"unknown\" }, { Color::red, \"red\" },\n    { Color::green, \"green\" }, { Color::blue, \"blue\" },\n    { Color::red, \"rot\" } // a second conversion for Color::red\n})\n}\n\nint main()\n{\n    // serialization\n    json j_red = ns::Color::red;\n    std::cout << static_cast<int>(ns::Color::red) << \" -> \" << j_red << '\\n';\n\n    // deserialization\n    json j_rot = \"rot\";\n    auto rot = j_rot.get<ns::Color>();\n    auto red = j_red.get<ns::Color>();\n    std::cout << j_rot << \" -> \" << static_cast<int>(rot) << '\\n';\n    std::cout << j_red << \" -> \" << static_cast<int>(red) << '\\n';\n}\n

Output:

0 -> \"red\"\n\"rot\" -> 0\n\"red\" -> 0\n
"},{"location":"api/macros/nlohmann_json_serialize_enum/#see-also","title":"See also","text":"
  • Specializing enum conversion - serializing enums as JSON strings
  • NLOHMANN_JSON_SERIALIZE_ENUM_STRICT - strict variant that throws on unmapped values
  • JSON_DISABLE_ENUM_SERIALIZATION - disable the default enum conversion
  • JSON_USE_OBJECTS_FOR_ENUM_KEYED_MAPS - serialize maps with enum keys as objects
"},{"location":"api/macros/nlohmann_json_serialize_enum/#version-history","title":"Version history","text":"

Added in version 3.4.0.

The generated from_json() reads the views of json_documents since version 3.13.0 unreleased.

"},{"location":"api/macros/nlohmann_json_serialize_enum_strict/","title":"NLOHMANN_JSON_SERIALIZE_ENUM_STRICT","text":"
#define NLOHMANN_JSON_SERIALIZE_ENUM_STRICT(type, conversion...)\n

By default, enum values are serialized to JSON as integers. In some cases, this could result in undesired behavior. If an enum is modified or re-ordered after data has been serialized to JSON, the later deserialized JSON data may be undefined or a different enum value than was originally intended.

NLOHMANN_JSON_SERIALIZE_ENUM_STRICT allows to define a user-defined serialization for every enumerator that throws an exception on undefined input.

"},{"location":"api/macros/nlohmann_json_serialize_enum_strict/#parameters","title":"Parameters","text":"type (in) name of the enum to serialize/deserialize conversion (in) a pair of an enumerator and a JSON serialization; arbitrary pairs can be given as a comma-separated list"},{"location":"api/macros/nlohmann_json_serialize_enum_strict/#default-definition","title":"Default definition","text":"

The macro adds two functions to the namespace which take care of the serialization and deserialization:

template<typename BasicJsonType>\ninline void to_json(BasicJsonType& j, const type& e);\ntemplate<typename BasicJsonType>\ninline void from_json(const BasicJsonType& j, type& e);\n
"},{"location":"api/macros/nlohmann_json_serialize_enum_strict/#notes","title":"Notes","text":"

Prerequisites

The macro must be used inside the namespace of the enum.

Important notes

  • Undefined input throws out_of_range.410 in both directions: when serializing an enum value not listed in the conversions, and when deserializing (e.g., via get<ENUM_TYPE>()) a JSON value that matches no conversion; example: \"enum value out of range for <type>\".
  • If an enum or JSON value is specified in multiple conversions, the first matching conversion from the top of the list will be returned when converting to or from JSON. See example 2 below.
  • Maps with enum keys (e.g., std::map<ENUM_TYPE, T>) are stored as arrays of [key, value] pairs by default. Define JSON_USE_OBJECTS_FOR_ENUM_KEYED_MAPS to store them as objects with the converted keys. Such maps can be read from both forms.

Views

The generated from_json() also reads the views of json_documents (<nlohmann/json_view.hpp>), comparing the view with the entries of the mapping, without building a json value first.

"},{"location":"api/macros/nlohmann_json_serialize_enum_strict/#examples","title":"Examples","text":"Example: Basic usage

The example shows how NLOHMANN_JSON_SERIALIZE_ENUM_STRICT can be used to serialize/deserialize both classical enums and C++11 enum classes:

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nnamespace ns\n{\nenum TaskState\n{\n    TS_STOPPED,\n    TS_RUNNING,\n    TS_COMPLETED,\n    TS_INVALID = -1\n};\n\nNLOHMANN_JSON_SERIALIZE_ENUM_STRICT(TaskState,\n{\n    { TS_INVALID, nullptr },\n    { TS_STOPPED, \"stopped\" },\n    { TS_RUNNING, \"running\" },\n    { TS_COMPLETED, \"completed\" }\n})\n\nenum class Color\n{\n    red, green, blue, unknown\n};\n\nNLOHMANN_JSON_SERIALIZE_ENUM_STRICT(Color,\n{\n    { Color::unknown, \"unknown\" }, { Color::red, \"red\" },\n    { Color::green, \"green\" }, { Color::blue, \"blue\" }\n})\n} // namespace ns\n\nint main()\n{\n    // serialization\n    json j_stopped = ns::TS_STOPPED;\n    json j_red = ns::Color::red;\n    std::cout << \"ns::TS_STOPPED -> \" << j_stopped\n              << \", ns::Color::red -> \" << j_red << '\\n';\n\n    // deserialization\n    json j_running = \"running\";\n    json j_blue = \"blue\";\n    auto running = j_running.get<ns::TaskState>();\n    auto blue = j_blue.get<ns::Color>();\n    std::cout << j_running << \" -> \" << running\n              << \", \" << j_blue << \" -> \" << static_cast<int>(blue) << '\\n';\n\n}\n

Output:

ns::TS_STOPPED -> \"stopped\", ns::Color::red -> \"red\"\n\"running\" -> 1, \"blue\" -> 2\n
Example: Multiple conversions for one enumerator

The example shows how to use multiple conversions for a single enumerator. In the example, Color::red will always be serialized to \"red\", because the first occurring conversion. The second conversion, however, offers an alternative deserialization from \"rot\" to Color::red.

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nnamespace ns\n{\nenum class Color\n{\n    red, green, blue, unknown\n};\n\nNLOHMANN_JSON_SERIALIZE_ENUM_STRICT(Color,\n{\n    { Color::unknown, \"unknown\" }, { Color::red, \"red\" },\n    { Color::green, \"green\" }, { Color::blue, \"blue\" },\n    { Color::red, \"rot\" } // a second conversion for Color::red\n})\n}\n\nint main()\n{\n    // serialization\n    json j_red = ns::Color::red;\n    std::cout << static_cast<int>(ns::Color::red) << \" -> \" << j_red << '\\n';\n\n    // deserialization\n    json j_rot = \"rot\";\n    auto rot = j_rot.get<ns::Color>();\n    auto red = j_red.get<ns::Color>();\n    std::cout << j_rot << \" -> \" << static_cast<int>(rot) << '\\n';\n    std::cout << j_red << \" -> \" << static_cast<int>(red) << '\\n';\n}\n

Output:

0 -> \"red\"\n\"rot\" -> 0\n\"red\" -> 0\n
Example: exceptions on invalid serialization

The example shows how an invalid serialization causes an exception to be thrown. In the example, Color::unknown is not defined in the mapping used to call NLOHMANN_JSON_SERIALIZE_ENUM_STRICT so causes an exception when used to serialize. Similarly, \"what\" does not refer to an enum value so also causes an exception when deserialization is attempted.

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nnamespace ns\n{\n\nenum class Color\n{\n    red,\n    green,\n    blue,\n    unknown // not mapped in JSON_SERIALIZE_ENUM_STRICT\n};\n\nNLOHMANN_JSON_SERIALIZE_ENUM_STRICT(Color,\n{\n    {Color::red, \"red\"},\n    {Color::green, \"green\"},\n    {Color::blue, \"blue\"}\n})\n\n} // namespace ns\n\n\nint main()\n{\n    // invalid serialization\n    try\n    {\n        // ns::color::unknown was not mapped in macro\n        json invalid_serialization = ns::Color::unknown;\n    }\n    catch (const json::exception e)\n    {\n        std::cout << \"deserialization failed: \" << e.what() << '\\n';\n    }\n\n    // invalid deserialization\n    try\n    {\n        // what does not map to an enum\n        json invalid_deserialization(\"what\");\n        ns::Color color = invalid_deserialization.get<ns::Color>();\n    }\n    catch (const json::exception e)\n    {\n        std::cout << \"deserialization failed: \" << e.what() << '\\n';\n    }\n\n    return 0;\n}\n

Output:

deserialization failed: [json.exception.out_of_range.410] enum value out of range for Color\ndeserialization failed: [json.exception.out_of_range.410] enum value out of range for Color: \"what\"\n

"},{"location":"api/macros/nlohmann_json_serialize_enum_strict/#see-also","title":"See also","text":"
  • Specializing enum conversion - serializing enums as JSON strings
  • NLOHMANN_JSON_SERIALIZE_ENUM - non-strict variant that uses the first mapping as default
  • JSON_DISABLE_ENUM_SERIALIZATION - disable the default enum conversion
  • JSON_USE_OBJECTS_FOR_ENUM_KEYED_MAPS - serialize maps with enum keys as objects
  • Arbitrary Type Conversions - converting your own types
"},{"location":"api/macros/nlohmann_json_serialize_enum_strict/#version-history","title":"Version history","text":"

Added in version 3.13.0 unreleased.

"},{"location":"api/macros/nlohmann_json_version_major/","title":"NLOHMANN_JSON_VERSION_MAJOR, NLOHMANN_JSON_VERSION_MINOR, NLOHMANN_JSON_VERSION_PATCH","text":"
#define NLOHMANN_JSON_VERSION_MAJOR /* value */\n#define NLOHMANN_JSON_VERSION_MINOR /* value */\n#define NLOHMANN_JSON_VERSION_PATCH /* value */\n

These macros are defined by the library and contain the version numbers according to Semantic Versioning 2.0.0.

"},{"location":"api/macros/nlohmann_json_version_major/#default-definition","title":"Default definition","text":"

The macros are defined according to the current library version.

"},{"location":"api/macros/nlohmann_json_version_major/#examples","title":"Examples","text":"Example

The example below shows how NLOHMANN_JSON_VERSION_MAJOR, NLOHMANN_JSON_VERSION_MINOR, and NLOHMANN_JSON_VERSION_PATCH are defined by the library.

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    std::cout << \"JSON for Modern C++ version \"\n              << NLOHMANN_JSON_VERSION_MAJOR << \".\"\n              << NLOHMANN_JSON_VERSION_MINOR << \".\"\n              << NLOHMANN_JSON_VERSION_PATCH << '\\n';\n}\n

Output:

JSON for Modern C++ version 3.12.0\n
"},{"location":"api/macros/nlohmann_json_version_major/#see-also","title":"See also","text":"
  • meta - returns version information on the library
  • JSON_SKIP_LIBRARY_VERSION_CHECK - skip library version check
  • Supported Macros - guide to all supported macros
  • Integration - integrate the library
"},{"location":"api/macros/nlohmann_json_version_major/#version-history","title":"Version history","text":"
  • Added in version 3.1.0.
"},{"location":"community/","title":"Community","text":"
  • Ecosystem - third-party projects built on top of this library
  • Code of Conduct - the rules and norms of this project
  • Contribution Guidelines - guidelines how to contribute to this project
  • Governance - the governance model of this project
  • Quality Assurance - how the quality of this project is assured
  • Roadmap - what the project will and will not do
  • Security Policy - the security policy of the project
  • Assurance Case - why the library meets its security requirements
"},{"location":"community/assurance_case/","title":"Assurance case","text":"

This page argues why the library meets its security requirements. It describes the threats the library faces, where the trust boundaries lie, and how the library's design and the quality assurance counter these threats. To report a vulnerability, see the security policy.

"},{"location":"community/assurance_case/#threat-model","title":"Threat model","text":"

The library parses, stores, and serializes JSON values in memory. It does not open network connections, does not open files (it only reads from streams or std::FILE* handles that the caller has already opened), does not read environment variables, and does not implement cryptography or handle credentials.

The primary threat is therefore untrusted input: JSON text or binary data (BJData, BON8, BSON, CBOR, MessagePack, UBJSON) that an attacker controls, passed to parse, accept, sax_parse, or one of the from_* functions such as from_cbor. Such input may try to

  • make the library read or write out of bounds (malformed lengths, truncated input, invalid UTF-8),
  • trigger undefined behavior (integer overflow in sizes or numbers, invalid casts),
  • exhaust memory (huge announced sizes), or
  • exhaust the call stack (deeply nested arrays and objects).
"},{"location":"community/assurance_case/#trust-boundaries","title":"Trust boundaries","text":"
  • Untrusted: all serialized input read by the parser, the SAX interface, and the binary readers. The library must handle every possible input by either producing a value or throwing a parse_error (or returning false when exceptions are disabled for the call).
  • Trusted: the C++ code that calls the library. Calling a function with violated preconditions, for instance accessing an array with operator[] out of range, is a programming error and not a security boundary. Such preconditions are checked with runtime assertions in debug builds; functions such as at offer checked access with exceptions.
flowchart LR\n    A[Untrusted input] --> B[Parser]\n    A --> C[SAX interface]\n    A --> D[Binary readers]\n    B --> E[\"Value tree (basic_json)\"]\n    C --> E\n    D --> E\n    E --> F[Trusted caller]

The trust boundary: untrusted input enters on the left through the parser, the SAX interface, or the binary readers, and only a value tree reaches the trusted caller on the right.

"},{"location":"community/assurance_case/#secure-design","title":"Secure design","text":"
  • Strict parsing. The parser accepts exactly the JSON grammar of RFC 8259. Extensions such as comments and trailing commas must be enabled explicitly. Invalid UTF-8 is rejected.
  • Errors are reported, not ignored. Malformed input results in a parse_error with the byte position of the error. Binary readers do not trust announced sizes: strings and binary values grow only as bytes are actually read, arrays reserve at most a fixed number of elements up front, and sizes that no container can hold are rejected.
  • Memory is owned by values. Each basic_json value owns its content, and there is no manual memory management in user code. The destructor does not recurse, so destroying a deeply nested value does not exhaust the stack.
  • Bounded recursion. The JSON parser and the binary readers keep their state in explicit stacks instead of recursing per nesting level. Operations that walk a value, such as dump, copying, comparison, hashing, merge_patch, diff, flatten, and the binary writers, recurse only up to a fixed depth and continue with an explicit stack below it. Applications that process untrusted input can limit its nesting depth with a parser callback.
  • Invariants are checked. The class invariant (for instance, that the pointer for the stored type is never null) is checked with runtime assertions throughout the test suite.
"},{"location":"community/assurance_case/#common-weaknesses","title":"Common weaknesses","text":"

The following table maps the relevant classes of the Common Weakness Enumeration to the measures that counter them. The measures are described in detail in Quality assurance.

Weakness Countermeasures Out-of-bounds read/write (CWE-125, CWE-787) bounds checks on all reads from the input; AddressSanitizer and Valgrind on the test suite; OSS-Fuzz Integer overflow (CWE-190) UndefinedBehaviorSanitizer with integer overflow detection; Clang-Tidy; Cppcheck Use after free, double free (CWE-416, CWE-415) ownership of all memory by values; AddressSanitizer and Valgrind; Clang Static Analyzer Memory leaks (CWE-401) Valgrind (Memcheck) on the test suite Uncontrolled recursion (CWE-674) iterative parser, binary readers, and destructor; bounded recursion in value operations; tests with deeply nested inputs Uncontrolled resource consumption (CWE-400) allocations based on announced sizes are capped; OSS-Fuzz with memory limits Undefined behavior in general (CWE-758) UndefinedBehaviorSanitizer; runtime assertions; Clang-Tidy, Cppcheck, Clang Static Analyzer, Infer

In addition, every line of the library is covered by the unit tests, and all parsers are fuzz-tested around the clock by OSS-Fuzz.

"},{"location":"community/code_of_conduct/","title":"Contributor Covenant Code of Conduct","text":""},{"location":"community/code_of_conduct/#our-pledge","title":"Our Pledge","text":"

We as members, contributors, and leaders pledge to make participation in our community a harassment-free experience for everyone, regardless of age, body size, visible or invisible disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, caste, color, religion, or sexual identity and orientation.

We pledge to act and interact in ways that contribute to an open, welcoming, diverse, inclusive, and healthy community.

"},{"location":"community/code_of_conduct/#our-standards","title":"Our Standards","text":"

Examples of behavior that contributes to a positive environment for our community include:

  • Demonstrating empathy and kindness toward other people
  • Being respectful of differing opinions, viewpoints, and experiences
  • Giving and gracefully accepting constructive feedback
  • Accepting responsibility and apologizing to those affected by our mistakes, and learning from the experience
  • Focusing on what is best not just for us as individuals, but for the overall community

Examples of unacceptable behavior include:

  • The use of sexualized language or imagery, and sexual attention or advances of any kind
  • Trolling, insulting or derogatory comments, and personal or political attacks
  • Public or private harassment
  • Publishing others' private information, such as a physical or email address, without their explicit permission
  • Other conduct which could reasonably be considered inappropriate in a professional setting
"},{"location":"community/code_of_conduct/#enforcement-responsibilities","title":"Enforcement Responsibilities","text":"

Community leaders are responsible for clarifying and enforcing our standards of acceptable behavior and will take appropriate and fair corrective action in response to any behavior that they deem inappropriate, threatening, offensive, or harmful.

Community leaders have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, and will communicate reasons for moderation decisions when appropriate.

"},{"location":"community/code_of_conduct/#scope","title":"Scope","text":"

This Code of Conduct applies within all community spaces, and also applies when an individual is officially representing the community in public spaces. Examples of representing our community include using an official email address, posting via an official social media account, or acting as an appointed representative at an online or offline event.

"},{"location":"community/code_of_conduct/#enforcement","title":"Enforcement","text":"

Instances of abusive, harassing, or otherwise unacceptable behavior may be reported to the community leaders responsible for enforcement at mail@nlohmann.me. All complaints will be reviewed and investigated promptly and fairly.

All community leaders are obligated to respect the privacy and security of the reporter of any incident.

"},{"location":"community/code_of_conduct/#enforcement-guidelines","title":"Enforcement Guidelines","text":"

Community leaders will follow these Community Impact Guidelines in determining the consequences for any action they deem in violation of this Code of Conduct:

"},{"location":"community/code_of_conduct/#1-correction","title":"1. Correction","text":"

Community Impact: Use of inappropriate language or other behavior deemed unprofessional or unwelcome in the community.

Consequence: A private, written warning from community leaders, providing clarity around the nature of the violation and an explanation of why the behavior was inappropriate. A public apology may be requested.

"},{"location":"community/code_of_conduct/#2-warning","title":"2. Warning","text":"

Community Impact: A violation through a single incident or series of actions.

Consequence: A warning with consequences for continued behavior. No interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, for a specified period of time. This includes avoiding interactions in community spaces as well as external channels like social media. Violating these terms may lead to a temporary or permanent ban.

"},{"location":"community/code_of_conduct/#3-temporary-ban","title":"3. Temporary Ban","text":"

Community Impact: A serious violation of community standards, including sustained inappropriate behavior.

Consequence: A temporary ban from any sort of interaction or public communication with the community for a specified period of time. No public or private interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, is allowed during this period. Violating these terms may lead to a permanent ban.

"},{"location":"community/code_of_conduct/#4-permanent-ban","title":"4. Permanent Ban","text":"

Community Impact: Demonstrating a pattern of violation of community standards, including sustained inappropriate behavior, harassment of an individual, or aggression toward or disparagement of classes of individuals.

Consequence: A permanent ban from any sort of public interaction within the community.

"},{"location":"community/code_of_conduct/#attribution","title":"Attribution","text":"

This Code of Conduct is adapted from the Contributor Covenant, version 2.1, available at https://www.contributor-covenant.org/version/2/1/code_of_conduct.html.

Community Impact Guidelines were inspired by Mozilla's code of conduct enforcement ladder.

For answers to common questions about this code of conduct, see the FAQ at https://www.contributor-covenant.org/faq. Translations are available at https://www.contributor-covenant.org/translations.

"},{"location":"community/contribution_guidelines/","title":"Contribution Guidelines","text":"

Thank you for your interest in contributing to this project! What began as an exercise to explore the exciting features of C++11 has evolved into a widely used JSON library. I truly appreciate all the contributions from the community, whether it's proposing features, identifying bugs, or fixing mistakes! To ensure that our collaboration is efficient and effective, please follow these guidelines.

Feel free to discuss or suggest improvements to this document by submitting a pull request.

"},{"location":"community/contribution_guidelines/#ways-to-contribute","title":"Ways to Contribute","text":"

There are multiple ways to contribute.

"},{"location":"community/contribution_guidelines/#reporting-an-issue","title":"Reporting an issue","text":"

Please create an issue, assuming one does not already exist, and describe your concern. Note you need a GitHub account for this.

Clearly describe the issue:

  • If it is a bug, please describe how to reproduce it. If possible, attach a complete example which demonstrates the error. Please also state what you expected to happen instead of the error.
  • If you propose a change or addition, try to give an example what the improved code could look like or how to use it.
  • If you found a compilation error, please tell us which compiler (version and operating system) you used and paste the (relevant part of) the error messages to the ticket.

Please stick to the provided issue template bug report if possible.

"},{"location":"community/contribution_guidelines/#reporting-a-security-vulnerability","title":"Reporting a security vulnerability","text":"

You can report a security vulnerability according to our security policy.

"},{"location":"community/contribution_guidelines/#discussing-a-new-feature","title":"Discussing a new feature","text":"

For questions, feature or support requests, please open a discussion. If you find a proposed answer satisfactory, please use the \"Mark as answer\" button to make it easier for readers to see what helped and for the community to filter for open questions.

"},{"location":"community/contribution_guidelines/#proposing-a-fix-or-an-improvement","title":"Proposing a fix or an improvement","text":"

Join an ongoing discussion or comment on an existing issue before starting to code. This can help to avoid duplicate efforts or other frustration during the later review.

Create a pull request against the develop branch and follow the pull request template. In particular,

  • describe the changes in detail, both the what and why,
  • reference existing issues where applicable,
  • add tests to maintain 100% test coverage,
  • update the documentation as needed, and
  • ensure the source code is amalgamated.

We describe all points in detail below.

All contributions (including pull requests) must agree to the Developer Certificate of Origin (DCO) version 1.1. This is exactly the same one created and used by the Linux kernel developers and posted on http://developercertificate.org/. This is a developer's certification that he or she has the right to submit the patch for inclusion into the project.

"},{"location":"community/contribution_guidelines/#how-to","title":"How to...","text":""},{"location":"community/contribution_guidelines/#describe-your-changes","title":"Describe your changes","text":"

This library is primarily maintained as a spare-time project. As such, I cannot make any guarantee how quickly changes are merged and released. Therefore, it is very important to make the review as smooth as possible by explaining not only what you changed, but why. This rationale can be very valuable down the road when improvements or bugs are discussed years later.

"},{"location":"community/contribution_guidelines/#reference-an-existing-issue","title":"Reference an existing issue","text":"

Link a pull request to an issue to clarify that a fix is forthcoming and which issue can be closed after merging. Only a few cases (e.g., fixing typos) do not require prior discussions.

"},{"location":"community/contribution_guidelines/#write-tests","title":"Write tests","text":"

The library has an extensive test suite that currently covers 100 % of the library's code. These tests are crucial to maintain API stability and give future contributors confidence that they do not accidentally break things. As Titus Winters aptly put it:

If you liked it, you should have put a test on it.

"},{"location":"community/contribution_guidelines/#run-the-tests","title":"Run the tests","text":"

First, ensure the test suite runs before making any changes:

$ cmake -S. -B build\n$ cmake --build build -j 10\n$ ctest --test-dir build -j 10\n

The test suite should report:

100% tests passed, 0 tests failed out of <number of tests>\n
"},{"location":"community/contribution_guidelines/#add-tests","title":"Add tests","text":"

The tests are located in tests/src/unit-*.cpp and contain doctest assertions like CHECK. The tests are structured along the features of the library or the nature of the tests. Usually, it should be clear from the context which existing file needs to be extended, and only very few cases require creating new test files.

When fixing a bug, edit unit-regression3.cpp and add a section referencing the fixed issue. unit-regression2.cpp holds the older tests; the two files exist because a single one grew large enough for the MinGW linker to fail relocating it, so please keep adding to the smaller file rather than growing the larger one.

"},{"location":"community/contribution_guidelines/#exceptions","title":"Exceptions","text":"

When you test exceptions, please use CHECK_THROWS_WITH_AS which also takes the what() argument of the thrown exception into account.

"},{"location":"community/contribution_guidelines/#coverage","title":"Coverage","text":"

If test coverage decreases, an automatic warning comment will be posted on the pull request. You can access a code coverage report as an artifact to the \u201cUbuntu\u201d workflow.

"},{"location":"community/contribution_guidelines/#update-the-documentation","title":"Update the documentation","text":"

The main documentation of the library is generated from the files docs/mkdocs/docs. This folder contains dedicated pages for certain features, a list of all exceptions, and extensive API documentation with details on every public API function.

Build the documentation locally using:

make install_venv -C docs/mkdocs\nmake serve -C docs/mkdocs\n

The documentation will then be available at http://127.0.0.1:8000/. See the documentation of mkdocs and Material for MkDocs for more information.

Before opening a pull request, check the documentation like the CI does:

make build -C docs/mkdocs          # strict build: fails on broken links, anchors, and structure problems\nmake check_mermaid -C docs/mkdocs  # checks the Mermaid diagrams (requires Node.js)\n

The search index of the docset is generated from mkdocs.yml and each page's title (H1) and declaration by docs/docset/generate_docset.py; make build reports API pages that cannot be classified.

"},{"location":"community/contribution_guidelines/#amalgamate-the-source-code","title":"Amalgamate the source code","text":"

The single-header files single_include/nlohmann/json.hpp, single_include/nlohmann/json_fwd.hpp, and single_include/nlohmann/json_literals.hpp are generated from the source files in the include/nlohmann directory. Do not edit the files directly; instead, modify the include/nlohmann sources and regenerate the files by executing:

make amalgamate\n

Running make amalgamate will also apply automatic formatting to the source files using Artistic Style. This formatting may modify your source files in-place. Be certain to review and commit any changes to avoid unintended formatting diffs in commits.

If you add, rename, or remove a header in include/nlohmann, also regenerate the header list in BUILD.bazel (requires CMake) by executing:

make BUILD.bazel\n

The amalgamation check in CI fails if any of these generated files is out of date.

"},{"location":"community/contribution_guidelines/#recommended-documentation","title":"Recommended documentation","text":"
  • The library\u2019s README file is an excellent starting point to understand its functionality.
  • The documentation page is the reference documentation of the library.
  • RFC 8259 is the reference for the JavaScript Object Notation (JSON) Data Interchange Format.
"},{"location":"community/contribution_guidelines/#please-dont","title":"Please don't...","text":"

Certain contributions are not helpful.

"},{"location":"community/contribution_guidelines/#break-the-public-api","title":"Break the public API","text":"

We take pride in the library being used by numerous customers across various industries. They all rely on the guarantees provided by semantic versioning. Please do not change the library such that the public API of the 3.x.y version is broken. This includes:

  • Changing function signatures (altering parameter types, return types, number of parameters) or changing the const-ness of member functions.
  • Removing functions.
  • Renaming functions or classes.
  • Changing exception handling.
  • Changing exception ids.
  • Changing access specifiers.
  • Changing default arguments.

What is and is not covered by this guarantee is described in the roadmap.

Although these guidelines may seem restrictive, they are essential for maintaining the library\u2019s utility.

Breaking changes may be introduced when they are guarded with a feature macro such as JSON_USE_IMPLICIT_CONVERSIONS which allows selectively changing the behavior of the library. In next steps, the current behavior can then be deprecated. Using feature macros then allows users to test their code against the library in the next major release.

"},{"location":"community/contribution_guidelines/#break-c11-language-conformance","title":"Break C++11 language conformance","text":"

This library is designed to work with C++11 and later. This means that any supported C++11 compiler should compile the library without problems. Some compilers like GCC 4.7 (and earlier), Clang 3.3 (and earlier), or Microsoft Visual C++ 2013 and earlier are known not to work due to missing or incomplete C++11 support.

Please do not add features that do not work with the mentioned supported compilers. Please guard features from C++14 and later against the respective JSON_HAS_CPP_14 macros.

"},{"location":"community/contribution_guidelines/#break-json-conformance","title":"Break JSON conformance","text":"

Please refrain from proposing changes that would break JSON conformance. If you propose a conformant extension of JSON to be supported by the library, please motivate this extension.

"},{"location":"community/contribution_guidelines/#wanted","title":"Wanted","text":"

The following areas really need contribution and are always welcomed:

  • Extending the continuous integration toward more exotic compilers such as Android NDK, Intel's Compiler, or the bleeding-edge versions of Clang.
  • Improving the efficiency of the JSON parser. The current parser is a hand-written iterative parser that keeps an explicit stack instead of recursing, with hand-coded string handling. Speeding up the lexer or the value construction would be appreciated. Parser generators like Bison or ANTLR do not play nice with single-header files -- I really would like to keep the parser inside the json.hpp header.
  • Extending and updating existing benchmarks to include (the most recent version of) this library. Though efficiency is not everything, speed and memory consumption are very important characteristics for C++ developers, so having proper comparisons would be interesting.

We look forward to your contributions and collaboration to enhance the library!

"},{"location":"community/ecosystem/","title":"Ecosystem","text":"

The projects below build on top of nlohmann::json rather than merely using it - schema validators, language bindings, format converters, and similar building blocks. The list is not exhaustive, and is curated rather than automatically generated. If you maintain or know of a project that belongs here, please let me know.

For products, applications, and organizations that use the library, see Customers instead.

"},{"location":"community/ecosystem/#schema-validation","title":"Schema validation","text":"
  • json-schema-validator, a JSON Schema (draft 7) validator with human-readable error messages
"},{"location":"community/ecosystem/#serialization-and-reflection","title":"Serialization and reflection","text":"
  • nlohmann_json_reflect, a reflection extension for (de)serializing nested containers-in-structs-in-containers
"},{"location":"community/ecosystem/#encodings","title":"Encodings","text":"
  • base-encode-decode, a header-only Base64/32/16/8/4/2 (and DNA/RNA) encoding library, with an adapter that serializes binary data through nlohmann::json
"},{"location":"community/ecosystem/#language-bindings-and-interop","title":"Language bindings and interop","text":"
  • pybind11_json, a bidirectional type caster between nlohmann::json and Python objects for pybind11 bindings
  • nanobind_json, the same idea for nanobind bindings
  • nlohmann_json_qt, deserialization helpers for Qt types (QString, QUrl, QDateTime, QVector, ...) from nlohmann::json
  • vulkan2json, serialization and deserialization of Vulkan API structs
"},{"location":"community/ecosystem/#format-converters","title":"Format converters","text":"
  • tojson, a header-only converter between YAML/XML documents and nlohmann::json
  • json2xml, a header-only converter from nlohmann::json to XML for simple configuration documents
"},{"location":"community/governance/","title":"Governance","text":"

The governance model for the JSON for Modern C++ project is a Benevolent Dictator for Life (BDFL) structure. As the sole maintainer, Niels Lohmann is responsible for all key aspects of the project. The project governance may evolve as the project grows, but any changes will be documented here and communicated to contributors.

"},{"location":"community/governance/#overview","title":"Overview","text":"

This project is led by a benevolent dictator, Niels Lohmann, and managed by the community. That is, the community actively contributes to the day-to-day maintenance of the project, but the general strategic line is drawn by the benevolent dictator. In case of disagreement, they have the last word. It is the benevolent dictator\u2019s job to resolve disputes within the community and to ensure that the project is able to progress in a coordinated way. In turn, it is the community\u2019s job to guide the decisions of the benevolent dictator through active engagement and contribution.

"},{"location":"community/governance/#roles-and-responsibilities","title":"Roles and responsibilities","text":""},{"location":"community/governance/#benevolent-dictator-project-lead","title":"Benevolent dictator (project lead)","text":"

Typically, the benevolent dictator, or project lead, is self-appointed. However, because the community always has the ability to fork, this person is fully answerable to the community. The project lead\u2019s role is a difficult one: they set the strategic objectives of the project and communicate these clearly to the community. They also have to understand the community as a whole and strive to satisfy as many conflicting needs as possible, while ensuring that the project survives in the long term.

In many ways, the role of the benevolent dictator is less about dictatorship and more about diplomacy. The key is to ensure that, as the project expands, the right people are given influence over it and the community rallies behind the vision of the project lead. The lead\u2019s job is then to ensure that the committers (see below) make the right decisions on behalf of the project. Generally speaking, as long as the committers are aligned with the project\u2019s strategy, the project lead will allow them to proceed as they desire.

"},{"location":"community/governance/#committers","title":"Committers","text":"

Committers are contributors who have made several valuable contributions to the project and are now relied upon to both write code directly to the repository and screen the contributions of others. In many cases they are programmers but it is also possible that they contribute in a different role. Typically, a committer will focus on a specific aspect of the project, and will bring a level of expertise and understanding that earns them the respect of the community and the project lead. The role of committer is not an official one, it is simply a position that influential members of the community will find themselves in as the project lead looks to them for guidance and support.

Committers have no authority over the overall direction of the project. However, they do have the ear of the project lead. It is a committer\u2019s job to ensure that the lead is aware of the community\u2019s needs and collective objectives, and to help develop or elicit appropriate contributions to the project. Often, committers are given informal control over their specific areas of responsibility, and are assigned rights to directly modify certain areas of the source code. That is, although committers do not have explicit decision-making authority, they will often find that their actions are synonymous with the decisions made by the lead.

"},{"location":"community/governance/#contributors","title":"Contributors","text":"

Contributors are community members who either have no desire to become committers, or have not yet been given the opportunity by the benevolent dictator. They make valuable contributions, such as those outlined in the list below, but generally do not have the authority to make direct changes to the project code. Contributors engage with the project through communication tools, such as email lists, and via reports and patches attached to issues in the issue tracker, as detailed in our community tools document.

Anyone can become a contributor. There is no expectation of commitment to the project, no specific skill requirements and no selection process. To become a contributor, a community member simply has to perform one or more actions that are beneficial to the project.

Some contributors will already be engaging with the project as users, but will also find themselves doing one or more of the following:

  • supporting new users (current users often provide the most effective new user support)
  • reporting bugs
  • identifying requirements
  • supplying graphics and web design
  • programming
  • assisting with project infrastructure
  • writing documentation
  • fixing bugs
  • adding features

As contributors gain experience and familiarity with the project, they may find that the project lead starts relying on them more and more. When this begins to happen, they gradually adopt the role of committer, as described above.

"},{"location":"community/governance/#users","title":"Users","text":"

Users are community members who have a need for the project. They are the most important members of the community: without them, the project would have no purpose. Anyone can be a user; there are no specific requirements.

Users should be encouraged to participate in the life of the project and the community as much as possible. User contributions enable the project team to ensure that they are satisfying the needs of those users. Common user activities include (but are not limited to):

  • evangelising about the project
  • informing developers of project strengths and weaknesses from a new user\u2019s perspective
  • providing moral support (a \u2018thank you\u2019 goes a long way)
  • providing financial support

Users who continue to engage with the project and its community will often find themselves becoming more and more involved. Such users may then go on to become contributors, as described above.

"},{"location":"community/governance/#access-to-project-resources","title":"Access to project resources","text":"

The project's resources are the GitHub repository with its settings, CI workflows and secrets, and the documentation at json.nlohmann.me, which is built and deployed from the repository. Currently, the project lead is the only person with write or admin access to them.

"},{"location":"community/governance/#granting-access","title":"Granting access","text":"

Write or admin access is only granted by the project lead, and only to a contributor whose track record in the project the project lead has reviewed first. The role is assigned manually and is the lowest one that is needed for the task. Access is removed when it is no longer needed. GitHub requires two-factor authentication for everyone who can modify the repository.

"},{"location":"community/governance/#secrets","title":"Secrets","text":"

The CI workflows mostly use the token that GitHub creates for each workflow run. It is read-only by default, and each workflow requests only the additional permissions it needs. The few other credentials, such as the token for Semgrep, are stored as encrypted GitHub Actions secrets:

  • Only people with admin access can create, change, or delete them. Their values cannot be read back, not even by admins.
  • They are not passed to workflows that run for pull requests from forks.
  • They must never be committed to the repository or printed in logs.
  • They are rotated whenever someone with admin access leaves the project, and immediately if a leak is suspected.
"},{"location":"community/governance/#support","title":"Support","text":"

All participants in the community are encouraged to provide support for new users within the project management infrastructure. This support is provided as a way of growing the community. Those seeking support should recognise that all support activity within the project is voluntary and is therefore provided as and when time allows. A user requiring guaranteed response times or results should therefore seek to purchase a support contract from a vendor. (Of course, that vendor should be an active member of the community.) However, for those willing to engage with the project on its own terms, and willing to help support other users, the community support channels are ideal.

"},{"location":"community/governance/#contribution-process","title":"Contribution Process","text":"

Anyone can contribute to the project, regardless of their skills, as there are many ways to contribute. For instance, a contributor might be active on the project mailing list and issue tracker, or might supply patches. The various ways of contributing are described in more detail in our roles in open source document.

The developer mailing list is the most appropriate place for a contributor to ask for help when making their first contribution.

"},{"location":"community/governance/#decision-making-process","title":"Decision-Making Process","text":"

The benevolent dictatorship model does not need a formal conflict resolution process, since the project lead\u2019s word is final. If the community chooses to question the wisdom of the actions of a committer, the project lead can review their decisions by checking the email archives, and either uphold or reverse them.

Source

The text was taken from http://oss-watch.ac.uk/resources/benevolentdictatorgovernancemodel.

"},{"location":"community/quality_assurance/","title":"Quality assurance","text":"

Ensuring quality is paramount for this project, particularly because numerous other projects depend on it. Each commit to the library undergoes rigorous checks against the following requirements, and any violations will result in a failed build.

The overview shows the checks a change passes on its way from a push or pull request to a release; the sections below describe each of them.

Quality assurance pipeline Every push or pull request starts these checks in parallel: Build matrix (every push / PR): 50+ compilers: G\u200bCC, Clang, M\u200bSVC, AppleClang, Intel, NVIDIA, ... C++11, 14, 17, 20, 23, and 26 libc++ and libstdc++ warnings: Clang -Weverything, G\u200bCC 300+ warnings; Unit tests (doctest) (every push / PR): every public A\u200bPI function every exception id and message all Unicode code points single header and split headers custom number, string, array, and object types; Coverage (every push / PR): unit tests cover all lines of the code base; Static analysis (every push / PR, scheduled): Clang-Tidy, Cppcheck, Infer Clang Static Analyzer (52 checkers), I\u200bWYU, Codacy CodeQL, Semgrep, Flawfinder (also scheduled); Dynamic analysis (every push / PR): runtime assertions Valgrind (Memcheck) address and undefined behavior sanitizers, integer overflow, nullability violations; Fuzzing (every PR, continuous): CIFuzz on every pull request OSS-Fuzz: billions of inputs every crash fixed with a reproducing unit test; Style (every push / PR): Artistic Style (astyle), enforced in the C\u200bI cpplint with 61 rules; Docs and examples (every push / PR, scheduled): every documentation example is tested; changed output fails site built with warnings as errors; links checked regularly (scheduled); Integration, supply chain (every push / PR, scheduled): CMake 3.5, 3.31.6, and 4.0.0 Meson, Swift Package Manager dependency review on every PR Dependabot daily, OpenSSF Scorecard, R\u200bEUSE. When they pass, the change is merged into develop; a release is made only when no vulnerability alert is open. push or pull request checks, run in parallel on GitHub Actions and AppVeyor Build matrix every push / PR 50+ compilers: G\u200bCC, Clang, M\u200bSVC, AppleClang, Intel, NVIDIA, ... C++11, 14, 17, 20, 23, and 26 libc++ and libstdc++ warnings: Clang -Weverything, G\u200bCC 300+ warnings Unit tests (doctest) every push / PR every public A\u200bPI function every exception id and message all Unicode code points single header and split headers custom number, string, array, and object types Coverage every push / PR unit tests cover all lines of the code base Static analysis every push / PR scheduled Clang-Tidy, Cppcheck, Infer Clang Static Analyzer (52 checkers), I\u200bWYU, Codacy CodeQL, Semgrep, Flawfinder (also scheduled) Dynamic analysis every push / PR runtime assertions Valgrind (Memcheck) address and undefined behavior sanitizers, integer overflow, nullability violations Fuzzing every PR continuous CIFuzz on every pull request OSS-Fuzz: billions of inputs every crash fixed with a reproducing unit test Style every push / PR Artistic Style (astyle), enforced in the C\u200bI cpplint with 61 rules Docs and examples every push / PR scheduled every documentation example is tested; changed output fails site built with warnings as errors; links checked regularly (scheduled) Integration, supply chain every push / PR scheduled CMake 3.5, 3.31.6, and 4.0.0 Meson, Swift Package Manager dependency review on every PR Dependabot daily, OpenSSF Scorecard, R\u200bEUSE merge into develop release no open vulnerability alert Quality assurance pipeline Every push or pull request starts these checks in parallel: Build matrix (every push / PR): 50+ compilers: G\u200bCC, Clang, M\u200bSVC, AppleClang, Intel, NVIDIA, ... C++11, 14, 17, 20, 23, and 26 libc++ and libstdc++ warnings: Clang -Weverything, G\u200bCC 300+ warnings; Unit tests (doctest) (every push / PR): every public A\u200bPI function every exception id and message all Unicode code points single header and split headers custom number, string, array, and object types; Coverage (every push / PR): unit tests cover all lines of the code base; Static analysis (every push / PR, scheduled): Clang-Tidy, Cppcheck, Infer Clang Static Analyzer (52 checkers), I\u200bWYU, Codacy CodeQL, Semgrep, Flawfinder (also scheduled); Dynamic analysis (every push / PR): runtime assertions Valgrind (Memcheck) address and undefined behavior sanitizers, integer overflow, nullability violations; Fuzzing (every PR, continuous): CIFuzz on every pull request OSS-Fuzz: billions of inputs every crash fixed with a reproducing unit test; Style (every push / PR): Artistic Style (astyle), enforced in the C\u200bI cpplint with 61 rules; Docs and examples (every push / PR, scheduled): every documentation example is tested; changed output fails site built with warnings as errors; links checked regularly (scheduled); Integration, supply chain (every push / PR, scheduled): CMake 3.5, 3.31.6, and 4.0.0 Meson, Swift Package Manager dependency review on every PR Dependabot daily, OpenSSF Scorecard, R\u200bEUSE. When they pass, the change is merged into develop; a release is made only when no vulnerability alert is open. push or pull request checks, run in parallel Build matrix every push / PR 50+ compilers: G\u200bCC, Clang, M\u200bSVC, AppleClang, Intel, NVIDIA, ... C++11, 14, 17, 20, 23, and 26 libc++ and libstdc++ warnings: Clang -Weverything, G\u200bCC 300+ warnings Unit tests (doctest) every push / PR every public A\u200bPI function every exception id and message all Unicode code points single header and split headers custom number, string, array, and object types Coverage every push / PR unit tests cover all lines of the code base Static analysis every push / PR scheduled Clang-Tidy, Cppcheck, Infer Clang Static Analyzer (52 checkers), I\u200bWYU, Codacy CodeQL, Semgrep, Flawfinder (also scheduled) Dynamic analysis every push / PR runtime assertions Valgrind (Memcheck) address and undefined behavior sanitizers, integer overflow, nullability violations Fuzzing every PR continuous CIFuzz on every pull request OSS-Fuzz: billions of inputs every crash fixed with a reproducing unit test Style every push / PR Artistic Style (astyle), enforced in the C\u200bI cpplint with 61 rules Docs and examples every push / PR scheduled every documentation example is tested; changed output fails site built with warnings as errors; links checked regularly (scheduled) Integration, supply chain every push / PR scheduled CMake 3.5, 3.31.6, and 4.0.0 Meson, Swift Package Manager dependency review on every PR Dependabot daily, OpenSSF Scorecard, R\u200bEUSE merge into develop release no open vulnerability alert

The checks grouped by the stage at which they run, from push or pull request through the merge into develop to a release. The badge on each card says whether the check runs on every push or PR, on a schedule, or continuously.

"},{"location":"community/quality_assurance/#c-language-compliance-and-compiler-compatibility","title":"C++ language compliance and compiler compatibility","text":"

Requirement: Compiler support

Any compiler with complete C++11 support can compile the library without warnings.

Note: C++20 modules support may hit compiler-specific issues not covered by the general compiler matrix below. See Modules for known issues and workarounds.

Note: Some modern features (like C++20 ranges or filesystem support) may be disabled on specific broken or incomplete toolchains even when standard feature-test macros indicate support. See JSON_HAS_RANGES, JSON_HAS_RANGE_VIEW_CONVERSION, and JSON_HAS_FILESYSTEM for details on known exclusions.

  • The library is compiled with 50+ different C++ compilers with different operating systems and platforms, including the oldest versions known to compile the library.

    Compilers used in continuous integration Compiler Architecture Operating System CI AppleClang 16.0.0.16000026; Xcode 16 arm64 macOS 15.2 (Sequoia) GitHub AppleClang 16.0.0.16000026; Xcode 16.1 arm64 macOS 15.2 (Sequoia) GitHub AppleClang 16.0.0.16000026; Xcode 16.2 arm64 macOS 15.2 (Sequoia) GitHub AppleClang 17.0.0.17000013; Xcode 16.3 arm64 macOS 15.5 (Sequoia) GitHub AppleClang 17.0.0.17000013; Xcode 16.4 arm64 macOS 15.5 (Sequoia) GitHub AppleClang 17.0.0.17000319; Xcode 26.0.1 arm64 macOS 15.5 (Sequoia) GitHub AppleClang 17.0.0.17000404; Xcode 26.1.1 arm64 macOS 15.7.9 (Sequoia) GitHub AppleClang 17.0.0.17000603; Xcode 26.2 arm64 macOS 15.7.9 (Sequoia) GitHub AppleClang 17.0.0.17000604; Xcode 26.3 arm64 macOS 15.7.9 (Sequoia) GitHub AppleClang 21.0.0.21000099; Xcode 26.4.1 arm64 macOS 26.6.2 (Tahoe) GitHub AppleClang 21.0.0.21000101; Xcode 26.5 arm64 macOS 26.6.2 (Tahoe) GitHub AppleClang 21.0.0.21000101; Xcode 26.6 arm64 macOS 26.6.2 (Tahoe) GitHub Clang 3.4.2 x86_64 Ubuntu 22.04.1 LTS GitHub Clang 3.5.2 x86_64 Ubuntu 22.04.1 LTS GitHub Clang 3.6.2 x86_64 Ubuntu 22.04.1 LTS GitHub Clang 3.7.1 x86_64 Ubuntu 22.04.1 LTS GitHub Clang 3.8.1 x86_64 Ubuntu 22.04.1 LTS GitHub Clang 3.9.1 x86_64 Ubuntu 22.04.1 LTS GitHub Clang 4.0.1 x86_64 Ubuntu 22.04.1 LTS GitHub Clang 5.0.2 x86_64 Ubuntu 22.04.1 LTS GitHub Clang 6.0.1 x86_64 Ubuntu 22.04.1 LTS GitHub Clang 7.1.0 x86_64 Ubuntu 22.04.1 LTS GitHub Clang 8.0.1 x86_64 Ubuntu 22.04.1 LTS GitHub Clang 9.0.1 x86_64 Ubuntu 22.04.1 LTS GitHub Clang 10.0.1 x86_64 Ubuntu 22.04.1 LTS GitHub Clang 11.0.1 with GNU-like command-line x86_64 Windows Server 2022 (Build 20348) GitHub Clang 11.1.0 x86_64 Ubuntu 22.04.1 LTS GitHub Clang 12.0.1 with GNU-like command-line x86_64 Windows Server 2022 (Build 20348) GitHub Clang 12.0.1 x86_64 Ubuntu 22.04.1 LTS GitHub Clang 13.0.1 with GNU-like command-line x86_64 Windows Server 2022 (Build 20348) GitHub Clang 13.0.1 x86_64 Ubuntu 22.04.1 LTS GitHub Clang 14.0.6 x86_64 Ubuntu 22.04.1 LTS GitHub Clang 14.0.6 with GNU-like command-line x86_64 Windows Server 2022 (Build 20348) GitHub Clang 15.0.7 x86_64 Ubuntu 22.04.1 LTS GitHub Clang 15.0.7 with GNU-like command-line x86_64 Windows Server 2022 (Build 20348) GitHub Clang 16.0.6 x86_64 Ubuntu 22.04.1 LTS GitHub Clang 16.0.6 with GNU-like command-line x86_64 Windows Server 2022 (Build 20348) GitHub Clang 17.0.6 x86_64 Ubuntu 22.04.1 LTS GitHub Clang 18.1.8 x86_64 Ubuntu 22.04.1 LTS GitHub Clang 18.1.8 with GNU-like command-line x86_64 Windows Server 2022 (Build 20348) GitHub Clang 19.1.5 with MSVC-like command-line x86_64 Windows Server 2022 (Build 20348) GitHub Clang 19.1.7 x86_64 Ubuntu 22.04.1 LTS GitHub Clang 19.1.7 with GNU-like command-line x86_64 Windows Server 2022 (Build 20348) GitHub Clang 20.1.1 x86_64 Ubuntu 22.04.1 LTS GitHub Clang 20.1.8 with GNU-like command-line x86_64 Windows Server 2022 (Build 20348) GitHub Clang 21.1.8 x86_64 Ubuntu 22.04.1 LTS GitHub Clang 22.1.8 x86_64 Ubuntu 22.04.1 LTS GitHub CUDA 11.8.0 (nvcc) x86_64 Ubuntu 22.04 LTS GitHub CUDA 12.1.1 (nvcc) x86_64 Ubuntu 22.04 LTS GitHub CUDA 12.6.3 (nvcc) x86_64 Ubuntu 22.04 LTS GitHub Emscripten 4.0.6 x86_64 Ubuntu 22.04.1 LTS GitHub GNU 4.8.5 x86_64 Ubuntu 20.04 LTS GitHub GNU 4.9.3 x86_64 Ubuntu 20.04 LTS GitHub GNU 5.5.0 x86_64 Ubuntu 20.04 LTS GitHub GNU 6.4.0 x86_64 Ubuntu 20.04 LTS GitHub GNU 7.5.0 x86_64 Ubuntu 22.04.1 LTS GitHub GNU 8.5.0 x86_64 Ubuntu 22.04.1 LTS GitHub GNU 9.3.0 x86_64 Ubuntu 22.04.1 LTS GitHub GNU 9.4.0 x86_64 Ubuntu 22.04.1 LTS GitHub GNU 9.5.0 x86_64 Ubuntu 22.04.1 LTS GitHub GNU 10.5.0 x86_64 Ubuntu 22.04.1 LTS GitHub GNU 11.4.0 x86_64 Ubuntu 22.04.1 LTS GitHub GNU 11.5.0 x86_64 Ubuntu 22.04.1 LTS GitHub GNU 12.2.0 (MinGW-W64 i686-ucrt-posix-dwarf) x86_64 Windows Server 2022 (Build 20348) GitHub GNU 12.2.0 (MinGW-W64 x86_64-ucrt-posix-seh) x86_64 Windows Server 2022 (Build 20348) GitHub GNU 12.4.0 x86_64 Ubuntu 22.04.1 LTS GitHub GNU 13.3.0 x86_64 Ubuntu 22.04.1 LTS GitHub GNU 14.2.0 x86_64 Ubuntu 22.04.1 LTS GitHub GNU 15.1.0 x86_64 Ubuntu 22.04.1 LTS GitHub GNU 16.2.0 x86_64 Ubuntu 22.04.1 LTS GitHub GNU 16.1.0 arm64 Ubuntu 24.04 GitHub icpc (ICC) 2021.10.0 20230609 x86_64 Ubuntu 22.04 LTS GitHub icpx (Intel oneAPI DPC++/C++) 2025.3.2 x86_64 Ubuntu 24.04 LTS GitHub nvc++ (NVIDIA HPC SDK) 25.5-0 x86_64 Ubuntu 22.04 LTS GitHub MSVC 19.0.24241.7 x86 Windows 8.1 AppVeyor MSVC 19.16.27035.0 x86 Windows-10 (Build 14393) AppVeyor MSVC 19.29.30157.0 x86 Windows-10 (Build 17763) AppVeyor MSVC 19.44.35207.0 arm64 Windows 11 (Build 26200) GitHub MSVC 19.44.35214.0 x86 Windows Server 2022 (Build 20348) GitHub MSVC 19.44.35214.0 x86_64 Windows Server 2022 (Build 20348) GitHub MSVC 19.51.36231.0 x86 Windows Server 2025 (Build 26100) GitHub MSVC 19.51.36231.0 x86_64 Windows Server 2025 (Build 26100) GitHub
  • The library is compiled with all C++ language revisions (C++11, C++14, C++17, C++20, C++23, and C++26) to detect and fix language deprecations early.

  • The library is checked for compiler warnings:
  • On Clang, -Weverything is used with 7 exceptions.

    Clang warnings
    # Ignored Clang warnings:\n# -Wno-c++98-compat               The library targets C++11.\n# -Wno-c++98-compat-pedantic      The library targets C++11.\n# -Wno-deprecated-declarations    The library contains annotations for deprecated functions.\n# -Wno-padded                     We do not care about padding warnings.\n# -Wno-covered-switch-default     All switches list all cases and a default case.\n# -Wno-c2y-extensions             Clang 22.1 diagnoses __COUNTER__ as a C2y extension, also in\n#                                 C++ mode. The library does not use __COUNTER__; the warnings\n#                                 all come from vendored Doctest (SECTION/TEST_CASE macros).\n# -Wno-unsafe-buffer-usage        Pervasive: the library's own low-level numeric/buffer code\n#                                 (to_chars, serializer, lexer, binary reader/writer, input\n#                                 adapters, json_pointer) plus vendored Doctest itself (~208\n#                                 distinct sites measured 2026-07-08 on clang trunk) all use\n#                                 raw pointer arithmetic / libc string calls by necessity.\n\nset(CLANG_CXXFLAGS\n    -Werror\n    -Weverything\n    -Wno-c++98-compat\n    -Wno-c++98-compat-pedantic\n    -Wno-deprecated-declarations\n    -Wno-padded\n    -Wno-covered-switch-default\n    -Wno-c2y-extensions\n    -Wno-unsafe-buffer-usage\n)\n
  • On GCC, 300+ warnings are enabled with 8 exceptions.

    GCC warnings
    # Warning flags determined for GCC 16.2.0 with https://github.com/nlohmann/gcc_flags:\n# Ignored GCC warnings:\n# -Wno-abi-tag           We do not care about ABI tags.\n# -Wno-aggregate-return  The library uses aggregate returns.\n# -Wno-long-long         The library uses the long long type to interface with system functions.\n# -Wno-namespaces        The library uses namespaces.\n# -Wno-nrvo              Doctest triggers this warning.\n# -Wno-padded            We do not care about padding warnings.\n# -Wno-system-headers    We do not care about warnings in system headers.\n# -Wno-templates         The library uses templates.\n\nset(GCC_CXXFLAGS\n    -pedantic\n    -Werror\n    --all-warnings\n    --extra-warnings\n    -W\n    -WNSObject-attribute\n    -Wabbreviated-auto-in-template-arg\n    -Wabi\n    -Wno-abi-tag\n    -Waddress\n    -Waddress-of-packed-member\n    -Wno-aggregate-return\n    -Waggressive-loop-optimizations\n    -Waligned-new=all\n    -Wall\n    -Walloc-size\n    -Walloc-zero\n    -Walloca\n    -Wanalyzer-allocation-size\n    -Wanalyzer-deref-before-check\n    -Wanalyzer-double-fclose\n    -Wanalyzer-double-free\n    -Wanalyzer-exposure-through-output-file\n    -Wanalyzer-exposure-through-uninit-copy\n    -Wanalyzer-fd-access-mode-mismatch\n    -Wanalyzer-fd-double-close\n    -Wanalyzer-fd-leak\n    -Wanalyzer-fd-phase-mismatch\n    -Wanalyzer-fd-type-mismatch\n    -Wanalyzer-fd-use-after-close\n    -Wanalyzer-fd-use-without-check\n    -Wanalyzer-file-leak\n    -Wanalyzer-free-of-non-heap\n    -Wanalyzer-imprecise-fp-arithmetic\n    -Wanalyzer-infinite-loop\n    -Wanalyzer-infinite-recursion\n    -Wanalyzer-jump-through-null\n    -Wanalyzer-malloc-leak\n    -Wanalyzer-mismatching-deallocation\n    -Wanalyzer-null-argument\n    -Wanalyzer-null-dereference\n    -Wanalyzer-out-of-bounds\n    -Wanalyzer-overlapping-buffers\n    -Wanalyzer-possible-null-argument\n    -Wanalyzer-possible-null-dereference\n    -Wanalyzer-putenv-of-auto-var\n    -Wanalyzer-shift-count-negative\n    -Wanalyzer-shift-count-overflow\n    -Wanalyzer-stale-setjmp-buffer\n    -Wanalyzer-symbol-too-complex\n    -Wanalyzer-tainted-allocation-size\n    -Wanalyzer-tainted-array-index\n    -Wanalyzer-tainted-assertion\n    -Wanalyzer-tainted-divisor\n    -Wanalyzer-tainted-offset\n    -Wanalyzer-tainted-size\n    -Wanalyzer-throw-of-unexpected-type\n    -Wanalyzer-too-complex\n    -Wanalyzer-undefined-behavior-ptrdiff\n    -Wanalyzer-undefined-behavior-strtok\n    -Wanalyzer-unsafe-call-within-signal-handler\n    -Wanalyzer-use-after-free\n    -Wanalyzer-use-of-pointer-in-stale-stack-frame\n    -Wanalyzer-use-of-uninitialized-value\n    -Wanalyzer-va-arg-type-mismatch\n    -Wanalyzer-va-list-exhausted\n    -Wanalyzer-va-list-leak\n    -Wanalyzer-va-list-use-after-va-end\n    -Wanalyzer-write-to-const\n    -Wanalyzer-write-to-string-literal\n    -Warith-conversion\n    -Warray-bounds=2\n    -Warray-compare\n    -Warray-parameter\n    -Warray-parameter=2\n    -Wattribute-alias=2\n    -Wattribute-warning\n    -Wattributes\n    -Wauto-profile\n    -Wbidi-chars=any\n    -Wbool-compare\n    -Wbool-operation\n    -Wbuiltin-declaration-mismatch\n    -Wbuiltin-macro-redefined\n    -Wc++0x-compat\n    -Wc++11-compat\n    -Wc++11-extensions\n    -Wc++14-compat\n    -Wc++14-extensions\n    -Wc++17-compat\n    -Wc++17-extensions\n    -Wc++1z-compat\n    -Wc++20-compat\n    -Wc++20-extensions\n    -Wc++23-extensions\n    -Wc++26-compat\n    -Wc++26-extensions\n    -Wc++2a-compat\n    -Wcalloc-transposed-args\n    -Wcannot-profile\n    -Wcast-align\n    -Wcast-align=strict\n    -Wcast-function-type\n    -Wcast-qual\n    -Wcast-user-defined\n    -Wcatch-value=3\n    -Wchanges-meaning\n    -Wchar-subscripts\n    -Wclass-conversion\n    -Wclass-memaccess\n    -Wclobbered\n    -Wcomma-subscript\n    -Wcomment\n    -Wcomments\n    -Wcomplain-wrong-lang\n    -Wconditionally-supported\n    -Wconversion\n    -Wconversion-null\n    -Wcoverage-invalid-line-number\n    -Wcoverage-mismatch\n    -Wcoverage-too-many-conditions\n    -Wcoverage-too-many-paths\n    -Wcpp\n    -Wctad-maybe-unsupported\n    -Wctor-dtor-privacy\n    -Wdangling-else\n    -Wdangling-pointer=2\n    -Wdangling-reference\n    -Wdate-time\n    -Wdefaulted-function-deleted\n    -Wdelete-incomplete\n    -Wdelete-non-virtual-dtor\n    -Wdeprecated\n    -Wdeprecated-copy\n    -Wdeprecated-copy-dtor\n    -Wdeprecated-declarations\n    -Wdeprecated-enum-enum-conversion\n    -Wdeprecated-enum-float-conversion\n    -Wdeprecated-literal-operator\n    -Wdeprecated-openmp\n    -Wdeprecated-variadic-comma-omission\n    -Wdisabled-optimization\n    -Wdiv-by-zero\n    -Wdouble-promotion\n    -Wduplicated-branches\n    -Wduplicated-cond\n    -Weffc++\n    -Welaborated-enum-base\n    -Wempty-body\n    -Wendif-labels\n    -Wenum-compare\n    -Wenum-conversion\n    -Wexceptions\n    -Wexpansion-to-defined\n    -Wexpose-global-module-tu-local\n    -Wexternal-tu-local\n    -Wextra\n    -Wextra-semi\n    -Wflex-array-member-not-at-end\n    -Wfloat-conversion\n    -Wfloat-equal\n    -Wformat-diag\n    -Wformat-overflow=2\n    -Wformat-signedness\n    -Wformat-truncation=2\n    -Wformat=2\n    -Wframe-address\n    -Wfree-nonheap-object\n    -Wglobal-module\n    -Whardened\n    -Wheader-guard\n    -Whsa\n    -Wif-not-aligned\n    -Wignored-attributes\n    -Wignored-qualifiers\n    -Wimplicit-fallthrough=5\n    -Winaccessible-base\n    -Winfinite-recursion\n    -Winherited-variadic-ctor\n    -Winit-list-lifetime\n    -Winit-self\n    -Winline\n    -Wint-in-bool-context\n    -Wint-to-pointer-cast\n    -Winterference-size\n    -Winvalid-constexpr\n    -Winvalid-imported-macros\n    -Winvalid-memory-model\n    -Winvalid-offsetof\n    -Winvalid-pch\n    -Winvalid-utf8\n    -Wkeyword-macro\n    -Wleading-whitespace=spaces\n    -Wliteral-suffix\n    -Wlogical-not-parentheses\n    -Wlogical-op\n    -Wno-long-long\n    -Wlto-type-mismatch\n    -Wmain\n    -Wmaybe-musttail-local-addr\n    -Wmaybe-uninitialized\n    -Wmemset-elt-size\n    -Wmemset-transposed-args\n    -Wmisleading-indentation\n    -Wmismatched-dealloc\n    -Wmismatched-new-delete\n    -Wmismatched-tags\n    -Wmissing-attributes\n    -Wmissing-braces\n    -Wmissing-declarations\n    -Wmissing-field-initializers\n    -Wmissing-include-dirs\n    -Wmissing-profile\n    -Wmissing-requires\n    -Wmissing-template-keyword\n    -Wmultichar\n    -Wmultiple-inheritance\n    -Wmultistatement-macros\n    -Wmusttail-local-addr\n    -Wno-namespaces\n    -Wnarrowing\n    -Wnoexcept\n    -Wnoexcept-type\n    -Wnon-c-typedef-for-linkage\n    -Wnon-template-friend\n    -Wnon-virtual-dtor\n    -Wnonnull\n    -Wnonnull-compare\n    -Wnormalized=nfkc\n    -Wno-nrvo\n    -Wnull-dereference\n    -Wodr\n    -Wold-style-cast\n    -Wopenacc-parallelism\n    -Wopenmp\n    -Wopenmp-simd\n    -Woverflow\n    -Woverlength-strings\n    -Woverloaded-virtual=2\n    -Wpacked\n    -Wpacked-bitfield-compat\n    -Wpacked-not-aligned\n    -Wno-padded\n    -Wparentheses\n    -Wpedantic\n    -Wpessimizing-move\n    -Wplacement-new=2\n    -Wpmf-conversions\n    -Wpointer-arith\n    -Wpointer-compare\n    -Wpragma-once-outside-header\n    -Wpragmas\n    -Wprio-ctor-dtor\n    -Wpsabi\n    -Wrange-loop-construct\n    -Wredundant-decls\n    -Wredundant-move\n    -Wredundant-tags\n    -Wregister\n    -Wreorder\n    -Wrestrict\n    -Wreturn-local-addr\n    -Wreturn-type\n    -Wscalar-storage-order\n    -Wself-move\n    -Wsequence-point\n    -Wsfinae-incomplete\n    -Wsfinae-incomplete=2\n    -Wshadow=compatible-local\n    -Wshadow=global\n    -Wshadow=local\n    -Wshift-count-negative\n    -Wshift-count-overflow\n    -Wshift-negative-value\n    -Wshift-overflow=2\n    -Wsign-compare\n    -Wsign-conversion\n    -Wsign-promo\n    -Wsized-deallocation\n    -Wsizeof-array-argument\n    -Wsizeof-array-div\n    -Wsizeof-pointer-div\n    -Wsizeof-pointer-memaccess\n    -Wstack-protector\n    -Wstrict-aliasing\n    -Wstrict-aliasing=3\n    -Wstrict-null-sentinel\n    -Wstrict-overflow\n    -Wstrict-overflow=5\n    -Wstring-compare\n    -Wstringop-overflow\n    -Wstringop-overflow=4\n    -Wstringop-overread\n    -Wstringop-truncation\n    -Wsubobject-linkage\n    -Wsuggest-attribute=cold\n    -Wsuggest-attribute=const\n    -Wsuggest-attribute=format\n    -Wsuggest-attribute=malloc\n    -Wsuggest-attribute=noreturn\n    -Wsuggest-attribute=pure\n    -Wsuggest-attribute=returns_nonnull\n    -Wsuggest-final-methods\n    -Wsuggest-final-types\n    -Wsuggest-override\n    -Wswitch\n    -Wswitch-bool\n    -Wswitch-default\n    -Wswitch-enum\n    -Wswitch-outside-range\n    -Wswitch-unreachable\n    -Wsync-nand\n    -Wsynth\n    -Wno-system-headers\n    -Wtautological-compare\n    -Wtemplate-body\n    -Wtemplate-id-cdtor\n    -Wtemplate-names-tu-local\n    -Wno-templates\n    -Wterminate\n    -Wtrailing-whitespace\n    -Wtrampolines\n    -Wtrigraphs\n    -Wtrivial-auto-var-init\n    -Wtsan\n    -Wtype-limits\n    -Wundef\n    -Wunicode\n    -Wuninitialized\n    -Wunknown-pragmas\n    -Wunreachable-code\n    -Wunsafe-loop-optimizations\n    -Wunused\n    -Wunused-but-set-parameter=3\n    -Wunused-but-set-variable=3\n    -Wunused-const-variable=2\n    -Wunused-function\n    -Wunused-label\n    -Wunused-local-typedefs\n    -Wunused-macros\n    -Wunused-parameter\n    -Wunused-result\n    -Wunused-value\n    -Wunused-variable\n    -Wuse-after-free=3\n    -Wuseless-cast\n    -Wvarargs\n    -Wvariadic-macros\n    -Wvector-operation-performance\n    -Wvexing-parse\n    -Wvirtual-inheritance\n    -Wvirtual-move-assign\n    -Wvla\n    -Wvla-parameter\n    -Wvolatile\n    -Wvolatile-register-var\n    -Wwrite-strings\n    -Wxor-used-as-pow\n    -Wzero-as-null-pointer-constant\n    -Wzero-length-bounds\n)\n
"},{"location":"community/quality_assurance/#c-standard-library-compliance","title":"C++ standard library compliance","text":"

Requirement: No prerequisites

The library has no prerequisites other than the Standard Template Library (STL).

  • The library is compiled and tested with both libc++ and libstdc++ to detect subtle differences or incompatibilities.
  • The code checked with Include What You Use (IWYU) that all required standard headers are included.
  • On Windows, the library is compiled with <Windows.h> being included to detect and avoid common bugs (see unit-windows_h.cpp).
  • The library is compiled with Qt's keyword macros (slots, signals, emit, foreach, forever) being defined to make sure it does not use them as identifiers (see unit-qt_keywords.cpp).
  • The library is compiled with exceptions disabled to support alternative means of error handling.
"},{"location":"community/quality_assurance/#stable-public-api","title":"Stable public API","text":"

Requirement: Stable public API

Any change to the library does not break the public API.

  • All public API functions are tested with a variety of arguments.
  • The library is compiled and tested with different template arguments for number, string, array, and object types.
  • Unit tests cover all lines of the code base.
  • Every exception of the library is thrown in the test suite, and the error messages and exception ids are checked.

Requirement: Complete documentation

The public API is extensively documented.

  • Every public API function has a dedicated page in the API reference documentation with a self-contained code example.
  • All examples in the documentation are tested, and changes in their output are treated as an error.
"},{"location":"community/quality_assurance/#robust-input-processing","title":"Robust input processing","text":"

Requirement: Standards compliance

The library is compliant to JSON as defined in RFC 8259.

  • The lexer is tested with all valid Unicode code points and all prefixes of all invalid Unicode code points.
  • The parser is tested against extensive correctness suites for JSON compliance.
  • In addition, the library is continuously fuzz-tested at OSS-Fuzz where the library is checked against billions of inputs.
  • Every crash reported by OSS-Fuzz is fixed together with a unit test that reproduces it, and the fix references the OSS-Fuzz issue. The round-trip checks of the fuzzer drivers are also part of the unit tests. See the fuzz testing documentation.
"},{"location":"community/quality_assurance/#static-analysis","title":"Static analysis","text":"

Requirement: State-of-the-art code analysis

The code is checked with state-of-the-art static code analysis tools.

  • The code is checked with the latest Clang-Tidy.

    Clang-Tidy configuration (.clang-tidy)
    # Style or vendor rule sets that do not fit a header-only library:\n#   altera-*, fuchsia-*, llvmlibc-*, android-cloexec-fopen, boost-use-ranges, llvm-header-guard,\n#   llvm-include-order, llvm-prefer-static-over-anonymous-namespace, llvm-use-ranges,\n#   misc-use-anonymous-namespace, google-runtime-float, google-runtime-int, hicpp-signed-bitwise,\n#   bugprone-signed-bitwise, hicpp-explicit-conversions, google-explicit-constructor,\n#   cppcoreguidelines-explicit-constructor, misc-explicit-constructor (implicit conversions are the\n#   API), readability-trailing-comma,\n#   hicpp-avoid-goto / cppcoreguidelines-avoid-goto, hicpp-no-array-decay,\n#   hicpp-uppercase-literal-suffix, readability-uppercase-literal-suffix, modernize-use-trailing-return-type.\n# Constructs the library needs on purpose (the library supports C++11 and legacy compilers):\n#   cppcoreguidelines-macro-usage, cppcoreguidelines-avoid-do-while (macros),\n#   cppcoreguidelines-pro-bounds-*, cppcoreguidelines-pro-type-reinterpret-cast,\n#   cppcoreguidelines-pro-type-union-access (parsers, serializers, basic_json's value union),\n#   cppcoreguidelines-avoid-const-or-ref-data-members, cppcoreguidelines-rvalue-reference-param-not-moved,\n#   cppcoreguidelines-avoid-non-const-global-variables, misc-non-private-member-variables-in-classes,\n#   misc-no-recursion (value walks are recursive, bounded by detail::recursion_depth_limit()),\n#   modernize-type-traits, modernize-use-constraints, modernize-use-ranges, modernize-use-std-numbers,\n#   modernize-use-designated-initializers, modernize-use-nodiscard, modernize-concat-nested-namespaces,\n#   readability-redundant-typename, readability-redundant-parentheses,\n#   readability-redundant-access-specifiers, readability-simplify-boolean-expr,\n#   readability-use-concise-preprocessor-directives, modernize-use-string-view,\n#   modernize-use-integer-sign-comparison (needs std::cmp_less; the flagged\n#   static_cast<std::size_t>(end - pos) < n comparisons are deliberate)\n#   (all need a newer standard or compiler than C++11, or would change macro-generated or\n#   deliberately explicit code).\n# Too noisy to be useful (numeric parsing/formatting code, doctest, tests):\n#   bugprone-easily-swappable-parameters, cppcoreguidelines-avoid-magic-numbers, readability-magic-numbers,\n#   readability-identifier-length, readability-function-cognitive-complexity, performance-enum-size,\n#   concurrency-mt-unsafe, misc-confusable-identifiers, misc-include-cleaner (run on its own for\n#   the consumer headers in cmake/ci.cmake).\n# portability-avoid-pragma-once: kept disabled on purpose. #pragma once is accepted\n# by every supported compiler, and tools/amalgamate/amalgamate.py strips it from\n# single_include, so there is nothing left to fix here.\n\nChecks: '*,\n\n         -altera-id-dependent-backward-branch,\n         -altera-struct-pack-align,\n         -altera-unroll-loops,\n         -android-cloexec-fopen,\n         -boost-use-ranges,\n         -bugprone-easily-swappable-parameters,\n         -bugprone-signed-bitwise,\n         -concurrency-mt-unsafe,\n         -cppcoreguidelines-avoid-const-or-ref-data-members,\n         -cppcoreguidelines-avoid-do-while,\n         -cppcoreguidelines-avoid-goto,\n         -cppcoreguidelines-avoid-magic-numbers,\n         -cppcoreguidelines-avoid-non-const-global-variables,\n         -cppcoreguidelines-explicit-constructor,\n         -cppcoreguidelines-macro-usage,\n         -cppcoreguidelines-pro-bounds-avoid-unchecked-container-access,\n         -cppcoreguidelines-pro-bounds-array-to-pointer-decay,\n         -cppcoreguidelines-pro-bounds-constant-array-index,\n         -cppcoreguidelines-pro-bounds-pointer-arithmetic,\n         -cppcoreguidelines-pro-type-reinterpret-cast,\n         -cppcoreguidelines-pro-type-union-access,\n         -cppcoreguidelines-rvalue-reference-param-not-moved,\n         -fuchsia-default-arguments-calls,\n         -fuchsia-default-arguments-declarations,\n         -fuchsia-overloaded-operator,\n         -google-explicit-constructor,\n         -google-runtime-float,\n         -google-runtime-int,\n         -hicpp-avoid-goto,\n         -hicpp-explicit-conversions,\n         -hicpp-no-array-decay,\n         -hicpp-signed-bitwise,\n         -hicpp-uppercase-literal-suffix,\n         -llvm-header-guard,\n         -llvm-include-order,\n         -llvm-prefer-static-over-anonymous-namespace,\n         -llvm-use-ranges,\n         -llvmlibc-*,\n         -misc-use-anonymous-namespace,\n         -misc-confusable-identifiers,\n         -misc-explicit-constructor,\n         -misc-include-cleaner,\n         -misc-no-recursion,\n         -misc-non-private-member-variables-in-classes,\n         -modernize-concat-nested-namespaces,\n         -modernize-type-traits,\n         -modernize-use-constraints,\n         -modernize-use-designated-initializers,\n         -modernize-use-integer-sign-comparison,\n         -modernize-use-nodiscard,\n         -modernize-use-ranges,\n         -modernize-use-string-view,\n         -modernize-use-std-numbers,\n         -modernize-use-trailing-return-type,\n         -performance-enum-size,\n         -portability-avoid-pragma-once,\n         -readability-function-cognitive-complexity,\n         -readability-identifier-length,\n         -readability-magic-numbers,\n         -readability-redundant-access-specifiers,\n         -readability-redundant-parentheses,\n         -readability-redundant-typename,\n         -readability-simplify-boolean-expr,\n         -readability-trailing-comma,\n         -readability-uppercase-literal-suffix,\n         -readability-use-concise-preprocessor-directives'\n\nCheckOptions:\n  - key: hicpp-special-member-functions.AllowSoleDefaultDtor\n    value: 1\n  # clang-tidy 22.1 extended this check to classes and enums; the test files\n  # define many such helper types at namespace scope, which is harmless\n  - key: misc-use-internal-linkage.AnalyzeTypes\n    value: false\n\nWarningsAsErrors: '*'\n\nHeaderFilterRegex: '.*hpp$'\n
  • The code is checked with the latest Cppcheck with all warnings enabled.

  • The code is checked with the latest Clang Static Analyzer with 52 enabled checkers.
  • The code is checked with Infer.
  • The code is checked with Codacy.
  • The code is scanned with CodeQL, Semgrep, and Flawfinder on every push and pull request and on a schedule; the findings are reported to GitHub's code scanning.
"},{"location":"community/quality_assurance/#dynamic-analysis","title":"Dynamic analysis","text":"

Requirement: Correctness

The library is checked for memory correctness and absence of undefined behavior.

  • The test suite is executed with enabled runtime assertions to check invariants and preconditions of functions to detect undefined behavior.
  • The test suite is executed with Valgrind (Memcheck) to detect memory leaks.
  • The test suite is executed with Sanitizers (address sanitizer, undefined behavior sanitizer, integer overflow detection, nullability violations).
  • The fuzz targets are run with CIFuzz on every pull request to catch regressions before they are merged.
"},{"location":"community/quality_assurance/#dependencies","title":"Dependencies","text":"

Requirement: No vulnerable dependencies

The library has no dependencies besides the C++ standard library. The tools used to build, test, and document it are kept free of known vulnerabilities.

  • GitHub Actions are pinned to a commit hash, and the Python packages used by the documentation and the tools are pinned to exact versions.
  • Dependabot checks these dependencies daily and proposes updates as pull requests.
  • Every pull request is checked with the dependency review action. A pull request that adds a dependency with a known vulnerability of any severity fails this check and is not merged.
  • Vulnerability alerts for dependencies are fixed or dismissed with a documented reason before the next release. No release is made while such an alert is open.
  • Third-party code included in the repository for testing, such as doctest, is updated manually.
  • The repository is evaluated with the OpenSSF Scorecard on a schedule and on every push to the default branch, and the results are reported to GitHub's code scanning.
"},{"location":"community/quality_assurance/#style-check","title":"Style check","text":"

Requirement: Common code style

A common code style is used throughout all code files of the library.

  • The code is formatted with Artistic Style (astyle) against a style configuration that is also enforced in the CI.

    Astyle configuration (tools/astyle/.astylerc)
    # Configuration for Artistic Style\n# see https://astyle.sourceforge.net/astyle.html\n\n#######################\n# Brace Style Options #\n#######################\n\n# use Allman style for braces\n--style=allman\n\n###############\n# Tab Options #\n###############\n\n# indent using 4 spaces\n--indent=spaces=4\n\n#######################\n# Indentation Options #\n#######################\n\n# indent access modifiers one half indent\n--indent-modifiers\n\n# indent switch cases to the switch block\n--indent-switches\n\n# indent preprocessor blocks\n--indent-preproc-block\n\n# indent preprocessor defines\n--indent-preproc-define\n\n# indent C++ comments\n--indent-col1-comments\n\n###################\n# Padding Options #\n###################\n\n# insert space padding around operators\n--pad-oper\n\n# insert space between if/for/while... and the following parentheses\n--pad-header\n\n# attach the pointer to the variable type (left)\n--align-pointer=type\n\n# attach the reference to the variable type (left)\n--align-reference=type\n\n######################\n# Formatting Options #\n######################\n\n# add braces to unbraced one line conditional statements\n--add-braces\n\n# convert tabs to spaces\n--convert-tabs\n\n# closes whitespace between the ending angle brackets of template definitions\n--close-templates\n\n#################\n# Other Options #\n#################\n\n# do not create backup files\n--suffix=none\n\n# preserve the original file date\n--preserve-date\n\n# display only the files that have been formatted\n--formatted\n\n# for the linux (LF) line end style\n--lineend=linux\n
  • The code style is checked with cpplint with 61 enabled rules.

"},{"location":"community/quality_assurance/#simple-integration","title":"Simple integration","text":"

Requirement: Single header

The library can be used by adding a single header to a C++ project.

  • An amalgamation script is used to check if the source code is exposed as a self-contained single-header file.
  • The test suite is checked against the amalgamated source file as well as the individual source file.

Requirement: CMake as primary development tool

All library functions are exposed and usable by CMake.

  • All library options are exposed as CMake options and tested.
  • The library is tested against relevant CMake versions:
  • CMake 3.5 (the earliest supported)
  • CMake 3.31.6 (the latest 3.x release)
  • CMake 4.0.0 (the first 4.x release)

Requirement: Other build systems

The library can be used with build systems and package managers other than CMake.

  • The library can be consumed with Meson and the Swift Package Manager; the installation with Meson and the resolution of Package.swift are tested in the CI.

Requirement: Reproducible and verifiable builds

The library can be built and tested without network access or a Git checkout, and its licensing is machine-readable.

  • The test suite is executed from an exported source tree without the .git directory and with the test data being available offline.
  • The test suite is executed without the tests that change installed files to check that builds are reproducible.
  • The repository is checked for compliance with the REUSE specification so that the license and copyright of every file is machine-readable.
  • The documentation is built with warnings treated as errors, and its links are checked regularly.
"},{"location":"community/roadmap/","title":"Roadmap","text":"

This page describes what the project intends to do, and what it does not intend to do, over the next year. Concrete work items are tracked in the GitHub milestones and the issue tracker.

"},{"location":"community/roadmap/#what-the-project-will-do","title":"What the project will do","text":"
  • Keep the C++11 baseline. The library will continue to compile with every supported C++11 compiler. Features of later standards are only used when they are guarded by the JSON_HAS_CPP_* macros.
  • Stay conformant to JSON. The parser and serializer follow RFC 8259. Extensions such as comments or trailing commas remain opt-in.
  • Keep the 3.x public API stable. Releases follow semantic versioning. Changes that would break existing code are only added behind a feature macro, so users can opt in and test their code before a next major release, see Version 4.0.
  • Support a broad range of compilers and platforms. The CI keeps testing old and new versions of GCC, Clang, MSVC, and other compilers on Linux, macOS, and Windows.
  • Keep the quality assurance up. Every change keeps the test coverage at 100%, passes the static and dynamic analysis, and is fuzz-tested by OSS-Fuzz, see Quality assurance.
  • Harden the library against hostile input. Handling deeply nested values without exhausting the call stack is ongoing work.
  • Fix bugs and security issues reported through the issue tracker and the security policy.
"},{"location":"community/roadmap/#what-the-project-will-not-do","title":"What the project will not do","text":"
  • Break the public API of version 3.x. See API stability for what this covers.
  • Require a newer C++ standard than C++11.
  • Break JSON conformance or enable non-standard extensions by default.
  • Add dependencies or require a build step. The library remains header-only, and the single header json.hpp remains a complete distribution.
  • Trade simplicity for speed or memory efficiency. Performance improvements are welcome, but the library is not meant to compete with the fastest JSON libraries, see Design goals.
"},{"location":"community/roadmap/#api-stability","title":"API stability","text":"

Releases follow semantic versioning: a minor or patch release of version 3.x does not break code that uses the public API, unless that code opts in to a change with a macro as described below. In particular, a 3.x release does not:

  • make breaking changes to the signature of a function: the types or order of its existing parameters, its return type, its noexcept or constexpr specifier, or the const-ness of a member function. New parameters may be added if they have a default value;
  • remove or rename a function or class, or change the template parameters of a public class template;
  • change which exceptions a function throws, or the exception ids;
  • change access specifiers, or change or remove existing default arguments. New default arguments may be added;
  • change the JSON type that a valid input parses to, or the text that dump() produces for a valid value;
  • accept input that was rejected before, or reject input that was accepted before;
  • change the order in which the keys of an object are iterated. The default type sorts keys, and ordered_json keeps insertion order;
  • change when iterators, pointers, or references are invalidated, or the state of a moved-from basic_json;
  • add or remove implicit conversions from basic_json;
  • change how to_json and from_json functions are found, or the behavior of adl_serializer;
  • add pure virtual functions to the json_sax interface;
  • remove, rename, renumber, or add enumerators of value_t;
  • remove or rename a documented macro, CMake option, CMake target, or header, or change what a documented macro does.

Exceptions to these rules, for instance when fixing a bug requires changing the exception a function throws, are documented in the release notes.

The following are not part of the public API and may change in any release, including patch releases:

  • The text of exception messages returned by what(). Use the exception id to tell errors apart.
  • The ABI, including sizeof(basic_json) and the memory layout of its values. The versioned inline namespace turns mixing versions into a link error.
  • The hash values returned by std::hash for basic_json. Numbers that compare equal still hash equally.
  • Everything in namespace nlohmann::detail, and macros and type traits that are not documented in the API reference.

Breaking changes are only added behind a macro whose default keeps the 3.x behavior. See Version 4.0 and the macro overview.

"},{"location":"community/roadmap/#version-40","title":"Version 4.0","text":"

There is no release date for version 4.0 yet. Proposals that need a major version, for instance stricter type conversions, are collected in issue #3453.

Not final

The plan for version 4.0 described below is not final and may still change: macros may be added to or removed from the list, and planned defaults may be revised. Any such change will be documented on this page.

"},{"location":"community/roadmap/#trying-out-40-today","title":"Trying out 4.0 today","text":"

Version 4.0 will not be developed on a separate branch. Instead, every breaking change is first added to a 3.x release behind a macro whose default keeps the 3.x behavior. Version 4.0 then switches the defaults and removes the macros. Version 4.0 is therefore the sum of these macros: you can try it on the 3.x release train today by defining each macro to its 4.0 value and fixing what no longer compiles or behaves differently. Once your code works with all of them, it is ready for version 4.0.

Each macro has a default value in 3.x and a different value in version 4.0. Define the macro to the 4.0 value to try it on the 3.x release train today; version 4.0 makes that value the default:

Two lanes: the 3.x release train, whose minor and patch releases do not break code that uses the public A\u200bPI, followed by version 4.0, which has no release date yet. Each breaking change is a macro that is available in 3.x today with its 3.x default and becomes the default in 4.0: JSON_USE_IMPLICIT_CONVERSIONS, added in 3.9.0, 3.x default 1, 4.0 value 0; JSON_USE_GLOBAL_UDLS, added in 3.11.0, 3.x default 1, 4.0 value 0; JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON, added in 3.11.0, 3.x default 0, 4.0 value 0, macro removed; JSON_BRACE_INIT_COPY_SEMANTICS, added in 3.13.0, 3.x default 0, 4.0 value 1; JSON_PRECISE_STREAM_POSITION, added in 3.13.0, 3.x default 0, 4.0 value 1; JSON_STRICT_NUL_HANDLING, added in 3.13.0, 3.x default 0, 4.0 value 1; JSON_STRICT_BINARY_UTF8, added in 3.13.0, 3.x default 0, 4.0 value 1; JSON_DISABLE_TUPLE_REFERENCE_CONVERSION, added in 3.13.0, 3.x default 0, 4.0 value 1; JSON_DELETE_DEPRECATED_FUNCTIONS, added in 3.13.0, 3.x default 0, 4.0 value 1, macro removed. 3.x release train available today 3.9.0 3.11.0 3.13.0 4.0 no release date yet A minor or patch release of 3.x does not break code that uses the public A\u200bPI, unless that code opts in with a macro. 4.0 is not developed on a separate branch: it switches the defaults of these macros and removes the macros. Macro added 3.x default define to try today 4.0 default JSON_USE_IMPLICIT_CONVERSIONS 3.9.0 1 0 JSON_USE_GLOBAL_UDLS 3.11.0 1 0 JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON 3.11.0 0 removed JSON_BRACE_INIT_COPY_SEMANTICS 3.13.0 0 1 JSON_PRECISE_STREAM_POSITION 3.13.0 0 1 JSON_STRICT_NUL_HANDLING 3.13.0 0 1 JSON_STRICT_BINARY_UTF8 3.13.0 0 1 JSON_DISABLE_TUPLE_REFERENCE_CONVERSION 3.13.0 0 1 JSON_DELETE_DEPRECATED_FUNCTIONS 3.13.0 0 removed Versions on the 3.x lane are the ones that added a macro, not to scale. \u201cremoved\u201d: see the 4.0 behavior column of the table.

Each row is one macro: the 3.x release that added it, its default in 3.x, and its value in version 4.0 (highlighted) or \"removed\". Versions on the 3.x lane are not to scale.

The following macros guard changes that are planned to become the default in version 4.0:

Macro 3.x default 4.0 behavior CMake option Added JSON_USE_IMPLICIT_CONVERSIONS 1 0: no implicit conversions from basic_json to other types; use get instead JSON_ImplicitConversions 3.9.0 JSON_USE_GLOBAL_UDLS 1 0: the string literals _json and _json_pointer are only available in namespace nlohmann::literals JSON_GlobalUDLs 3.11.0 JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON 0 removed: the deprecated legacy comparison of discarded values can no longer be enabled JSON_LegacyDiscardedValueComparison 3.11.0 JSON_BRACE_INIT_COPY_SEMANTICS 0 1: single-element brace initialization such as json j{obj}; copies the element instead of creating an array \u2013 3.13.0 JSON_PRECISE_STREAM_POSITION 0 1: reading from a stream does not consume the character after a number \u2013 3.13.0 JSON_STRICT_NUL_HANDLING 0 1: a NUL byte in the input is a parse error instead of the end of input JSON_StrictNulHandling 3.13.0 JSON_STRICT_BINARY_UTF8 0 1: to_cbor, to_ubjson, to_bjdata, and to_bson throw for strings that are not valid UTF-8 by default JSON_StrictBinaryUTF8 3.13.0 JSON_DISABLE_TUPLE_REFERENCE_CONVERSION 0 1: a basic_json value can no longer be created from a one-element tuple of a reference to it, such as std::forward_as_tuple(j) JSON_DisableTupleReferenceConversion 3.13.0 JSON_DELETE_DEPRECATED_FUNCTIONS 0 removed: the deprecated functions are removed (see below); the from_*(ptr, len) overloads stay deleted JSON_DeleteDeprecatedFunctions 3.13.0

Opt-in macros for the version 4.0 behavior. \"3.x default\" is the value the library uses when the macro is not defined, \"Added\" is the release that introduced the macro, and \u2013 means there is no CMake option.

For example, the following makes a 3.x release behave like version 4.0 with respect to these changes:

#define JSON_USE_IMPLICIT_CONVERSIONS 0\n#define JSON_USE_GLOBAL_UDLS 0\n#define JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON 0\n#define JSON_BRACE_INIT_COPY_SEMANTICS 1\n#define JSON_PRECISE_STREAM_POSITION 1\n#define JSON_STRICT_NUL_HANDLING 1\n#define JSON_STRICT_BINARY_UTF8 1\n#define JSON_DISABLE_TUPLE_REFERENCE_CONVERSION 1\n#define JSON_DELETE_DEPRECATED_FUNCTIONS 1\n#include <nlohmann/json.hpp>\n

The macros must be defined before the library header is included; setting them once in the build system is the easiest way to achieve this.

"},{"location":"community/roadmap/#removal-of-deprecated-functions","title":"Removal of deprecated functions","text":"

Version 4.0 will remove all deprecated functions. Compiling with deprecation warnings enabled shows which of them your code still uses. Defining JSON_DELETE_DEPRECATED_FUNCTIONS to 1 turns these warnings into errors, as the deprecated functions are then deleted. The migration guide shows how to replace each of them.

The from_* overloads taking a pointer and a length are not removed in version 4.0, but stay deleted. Without them, a call like from_cbor(ptr, len) would still compile: it would read ptr as a NUL-terminated string and convert len to the strict parameter.

Deprecated Since Migration operator<<(basic_json&, std::istream&) 3.0.0 Parsing operator>>(const basic_json&, std::ostream&) 3.0.0 Miscellaneous functions iterator_wrapper 3.1.0 Miscellaneous functions parse, accept, and sax_parse with an initializer list {ptr, len} or {first, last} 3.8.0 Parsing from_bson, from_cbor, from_msgpack, and from_ubjson with (ptr, len) or an initializer list 3.8.0 Parsing json_pointer::operator string_t 3.11.0 JSON Pointers json_pointer with a basic_json type as template argument, and the overloads of value, contains, operator[], and at accepting such a pointer 3.11.0 JSON Pointers Comparing a json_pointer with a string via operator== or operator!= 3.11.2 JSON Pointers from_bjdata and from_bon8 with (ptr, len) 3.13.0 Parsing

Deprecated functions, with the release that deprecated each one and the section of the migration guide that shows its replacement.

The deprecated legacy comparison of discarded values is controlled by a macro and therefore listed in the table above.

New breaking changes will follow the same path: they are added to these tables when they land in a 3.x release.

"},{"location":"community/security_policy/","title":"Security Policy","text":""},{"location":"community/security_policy/#reporting-a-vulnerability","title":"Reporting a Vulnerability","text":"

We value the security of our users and appreciate your efforts to responsibly disclose vulnerabilities. If you have identified a security vulnerability in this repository, please use the GitHub Security Advisory \"Report a Vulnerability\" tab.

Until it is published, this draft security advisory will only be visible to the maintainers of this project. Other users and teams may be added once the advisory is created.

We will send a first response within 14 days, indicating the next steps in handling your report. After the initial reply to your report, we will keep you informed of the progress towards a fix and full announcement and may ask for additional information or guidance.

For vulnerabilities in third-party dependencies or modules, please report them directly to the respective maintainers.

"},{"location":"community/security_policy/#disclosure-and-credit","title":"Disclosure and credit","text":"

Once a fix is released, we publish the security advisory and list the fixed vulnerability in the release notes. We credit the reporter in both, unless they ask not to be named.

"},{"location":"community/security_policy/#supported-versions","title":"Supported versions","text":"

Security fixes are made on the develop branch and shipped with the next release. Only the latest release receives security fixes; they are not backported to older releases. A release stops receiving security fixes when the next release is published, so please update to the latest release to get them.

"},{"location":"community/security_policy/#unofficial-packages","title":"Unofficial packages","text":"

This project does not publish an official npm package. The npm package nlohmann-json (or similarly named packages) is not maintained or endorsed by this project. See the package managers documentation for supported integration options.

"},{"location":"community/security_policy/#additional-resources","title":"Additional Resources","text":"
  • Explore security-related topics and contribute to tools and projects through GitHub Security Lab.
  • Learn more about responsible disclosure and reporting vulnerabilities in GitHub at About coordinated disclosure of security vulnerabilities.

We sincerely thank you for contributing to the security and integrity of this project!

"},{"location":"features/","title":"Features","text":"

This section describes the features of the library in detail. If you are new to the library, the pages below are roughly ordered along a typical workflow: create or parse a value, access and modify it, convert it to and from your own C++ types, and finally serialize it again.

"},{"location":"features/#creating-and-reading-values","title":"Creating and reading values","text":"
  • Creating JSON values \u2014 build values from literals, initializer lists, and STL containers, and understand the {} vs. [] ambiguity.
  • Parsing \u2014 read a JSON value from a string, file, or stream, including JSON Lines, callbacks, the SAX interface, error handling, large and partial input, and parsing untrusted input.
  • Zero-copy JSON views \u2014 read a JSON text through a flat index instead of building a json tree; strings and numbers stay in the input and are only decoded when needed.
  • Editable documents \u2014 modify a parsed document without building a json tree.
  • Images \u2014 save a parsed document and load it again without parsing it.
  • Comments and trailing commas \u2014 opt-in relaxations of the JSON grammar.
"},{"location":"features/#accessing-and-modifying-values","title":"Accessing and modifying values","text":"
  • Element access \u2014 unchecked (operator[]), checked (at), and access with a default value.
  • JSON Pointer \u2014 address values deep inside a document with RFC 6901 pointers.
  • Iterators \u2014 traverse arrays and objects.
  • Modifying values \u2014 add, update, merge, and remove elements.
  • JSON Patch and Diff and JSON Merge Patch \u2014 apply and compute structured changes.
"},{"location":"features/#converting-to-and-from-c-types","title":"Converting to and from C++ types","text":"
  • Converting values \u2014 get values out with get/get_to, and understand implicit conversions.
  • Arbitrary types conversions \u2014 teach the library about your own structs and classes.
  • Recipes for common types \u2014 convert smart pointers, std::variant, std::chrono types, and class hierarchies, which the library deliberately leaves to you.
  • Specializing enum conversion \u2014 map enums to strings instead of integers.
"},{"location":"features/#serializing-values","title":"Serializing values","text":"
  • Serialization \u2014 turn a value back into JSON text with dump, including pretty-printing and handling of non-ASCII and invalid UTF-8.
  • Binary formats \u2014 encode values more compactly as BJData, BON8, BSON, CBOR, MessagePack, or UBJSON.
  • Binary values \u2014 store and exchange raw byte sequences.
"},{"location":"features/#how-values-are-stored-and-configured","title":"How values are stored and configured","text":"
  • Types and number handling \u2014 how JSON types map to C++ types and how numbers are treated.
  • Template parameter requirements \u2014 what a type passed as one of basic_json's template parameters has to provide.
  • Object order \u2014 keep insertion order with ordered_json.
  • Performance \u2014 practical advice on parsing, memory use, serialization, and compile times.
  • Working without exceptions \u2014 what to use when exceptions are unwanted or unavailable.
  • Runtime assertions, supported macros, the nlohmann namespace, and C++ modules \u2014 build-time and runtime configuration.

Looking for a specific function?

This section gives conceptual overviews. For the precise signature, parameters, and return value of a function, see the API Documentation.

"},{"location":"features/#see-also","title":"See also","text":"
  • API documentation - reference of all classes and functions
  • FAQ - answers to common questions
  • Exceptions - all exceptions and their error codes
  • Design goals - the goals behind the library
  • Integration - how to add the library to a project
  • Macros - reference of all macros
  • json_pointer - the JSON Pointer class
  • adl_serializer - customization point for type conversions
  • json_sax - interface of the SAX parser events
  • json_document - an immutable document with a flat index
  • json_view - a non-owning view of a value in a document
  • byte_container_with_subtype - binary values with a subtype
  • ordered_json - a JSON type preserving insertion order
  • Supported Macros - all supported macros
  • nlohmann Namespace - the library namespace
"},{"location":"features/arbitrary_types/","title":"Arbitrary Type Conversions","text":"

Every type can be serialized in JSON, not just STL containers and scalar types. Usually, you would do something along those lines:

namespace ns {\n    // a simple struct to model a person\n    struct person {\n        std::string name;\n        std::string address;\n        int age;\n    };\n} // namespace ns\n\nns::person p = {\"Ned Flanders\", \"744 Evergreen Terrace\", 60};\n\n// convert to JSON: copy each value into the JSON object\njson j;\nj[\"name\"] = p.name;\nj[\"address\"] = p.address;\nj[\"age\"] = p.age;\n\n// ...\n\n// convert from JSON: copy each value from the JSON object\nns::person p {\n    j[\"name\"].get<std::string>(),\n    j[\"address\"].get<std::string>(),\n    j[\"age\"].get<int>()\n};\n

It works, but that's quite a lot of boilerplate... Fortunately, there's a better way:

// create a person\nns::person p {\"Ned Flanders\", \"744 Evergreen Terrace\", 60};\n\n// conversion: person -> json\njson j = p;\n\nstd::cout << j << std::endl;\n// {\"address\":\"744 Evergreen Terrace\",\"age\":60,\"name\":\"Ned Flanders\"}\n\n// conversion: json -> person\nauto p2 = j.get<ns::person>();\n\n// that's it\nassert(p == p2);\n
"},{"location":"features/arbitrary_types/#basic-usage","title":"Basic usage","text":"

To make this work with one of your types, you only need to provide two functions:

using nlohmann::json;\n\nnamespace ns {\n    void to_json(json& j, const person& p) {\n        j = json{ {\"name\", p.name}, {\"address\", p.address}, {\"age\", p.age} };\n    }\n\n    void from_json(const json& j, person& p) {\n        j.at(\"name\").get_to(p.name);\n        j.at(\"address\").get_to(p.address);\n        j.at(\"age\").get_to(p.age);\n    }\n} // namespace ns\n

That's all! When calling the json constructor with your type, your custom to_json method will be automatically called. Likewise, when calling get<your_type>() or get_to(your_type&), the from_json method will be called.

Some important things:

  • Those methods MUST be in your type's namespace (which can be the global namespace), or the library will not be able to locate them (in this example, they are in namespace ns, where person is defined).
  • Those methods MUST be available (e.g., proper headers must be included) everywhere you use these conversions. Look at #1108 for errors that may occur otherwise.
  • When using get<your_type>(), your_type MUST be DefaultConstructible. (There is a way to bypass this requirement described later.)
  • In function from_json, use function at() to access the object values rather than operator[]. In case a key does not exist, at throws an exception that you can handle, whereas operator[] exhibits undefined behavior.
  • You do not need to add serializers or deserializers for STL types like std::vector: the library already implements these.
  • If you control the type, consider defining to_json/from_json as friend functions inside the class (\"hidden friends\"). Argument-dependent lookup then only finds them for your type, which also avoids a GCC < 11 compilation error.
Example: serialize a person to JSON with to_json
#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nnamespace ns\n{\n// a simple struct to model a person\nstruct person\n{\n    std::string name;\n    std::string address;\n    int age;\n};\n} // namespace ns\n\nnamespace ns\n{\nvoid to_json(json& j, const person& p)\n{\n    j = json{ {\"name\", p.name}, {\"address\", p.address}, {\"age\", p.age} };\n}\n} // namespace ns\n\nint main()\n{\n    ns::person p = {\"Ned Flanders\", \"744 Evergreen Terrace\", 60};\n\n    json j = p;\n\n    std::cout << j << '\\n';\n}\n

Output:

{\"address\":\"744 Evergreen Terrace\",\"age\":60,\"name\":\"Ned Flanders\"}\n
Example: deserialize a person from JSON with from_json
#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nnamespace ns\n{\n// a simple struct to model a person\nstruct person\n{\n    std::string name;\n    std::string address;\n    int age;\n};\n} // namespace ns\n\nnamespace ns\n{\nvoid from_json(const json& j, person& p)\n{\n    j.at(\"name\").get_to(p.name);\n    j.at(\"address\").get_to(p.address);\n    j.at(\"age\").get_to(p.age);\n}\n} // namespace ns\n\nint main()\n{\n    json j;\n    j[\"name\"] = \"Ned Flanders\";\n    j[\"address\"] = \"744 Evergreen Terrace\";\n    j[\"age\"] = 60;\n\n    auto p = j.get<ns::person>();\n\n    std::cout << p.name << \" (\" << p.age << \") lives in \" << p.address << '\\n';\n}\n

Output:

Ned Flanders (60) lives in 744 Evergreen Terrace\n
"},{"location":"features/arbitrary_types/#simplify-your-life-with-macros","title":"Simplify your life with macros","text":"

If you just want to serialize/deserialize some structs, the to_json/from_json functions can be a lot of boilerplate.

There are several macros to make your life easier as long as you want to use a JSON object as serialization. The macros are following the naming pattern, and you can choose the macro based on the needed features:

  • All the macros start with NLOHMANN_DEFINE.
  • If you want a macro for the derived object, use the DERIVED_TYPE variant, otherwise use TYPE.
    • The DERIVED_TYPE variant requires an additional parameter of a base type, which should have the to_json/from_json functions defined. For instance, with a macro of its own.
  • If you need access to the private fields use INTRUSIVE variant, otherwise use NON_INTRUSIVE.
    • The INTRUSIVE macro should be defined inside the target class/struct, NON_INTRUSIVE should be defined within the same namespace.
  • If you want to deserialize the incomplete JSONs, use the WITH_DEFAULTS variant, which will use the default values for the member variables absent in JSON, the variant without WITH_DEFAULTS will raise an exception.
  • If you do not need deserialization at all and only interested in to_json function, you can use the ONLY_SERIALIZE variant.
  • If you want to use the custom JSON names for member variables, use WITH_NAMES variant, otherwise the JSON name of the variable will be the same as its regular name.

For all the macros, the first parameter is the name of the class/struct. The DERIVED_TYPE macros require a second parameter of a base class. All the remaining parameters name the member variables. The WITH_NAMES macros require a JSON name before each of the variables.

flowchart TD\n    A[\"choosing a NLOHMANN_DEFINE_* macro\"] --> B{{\"adding fields to a base class?\"}}\n    B -->|\"yes\"| C[\"...DERIVED_TYPE...\"]\n    B -->|\"no\"| D[\"...TYPE...\"]\n    C --> E{{\"need access to private members?\"}}\n    D --> E\n    E -->|\"yes\"| F[\"...INTRUSIVE... (used inside the class)\"]\n    E -->|\"no\"| G[\"...NON_INTRUSIVE... (used in the namespace)\"]\n    F --> H{{\"only serializing, never parsing back?\"}}\n    G --> H\n    H -->|\"yes\"| I[\"...ONLY_SERIALIZE\"]\n    H -->|\"no\"| J{{\"allow missing keys when parsing?\"}}\n    J -->|\"yes\"| K[\"...WITH_DEFAULT\"]\n    J -->|\"no\"| L[\"plain (missing keys throw)\"]\n    I --> M{{\"need custom JSON key names?\"}}\n    K --> M\n    L --> M\n    M -->|\"yes\"| N[\"...WITH_NAMES\"]\n    M -->|\"no\"| O[\"done\"]

Decision tree for choosing a NLOHMANN_DEFINE_* macro: answer the questions from top to bottom; each answer picks one part of the macro name, and the parts are combined in this order. The table below lists the resulting macros.

Need access to private members Need only serialization Allow missing values when de-serializing macro NLOHMANN_DEFINE_TYPE_INTRUSIVE NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT NLOHMANN_DEFINE_TYPE_INTRUSIVE_ONLY_SERIALIZE NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE

Macros for classes and structs without a base class. A green check means yes, a red cross means no, and a grey skip sign means the column does not apply, as a macro that only serializes never reads values.

For derived classes and structs, use the following macros

Need access to private members Need only serialization Allow missing values when de-serializing macro NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_WITH_DEFAULT NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_ONLY_SERIALIZE NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_WITH_DEFAULT NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE

Macros for derived classes and structs, read as Table 1.

Implementation limits

  • The current macro implementations are limited to at most 63 member variables. If you want to serialize/deserialize types with more than 63 member variables, you need to define the to_json/from_json functions manually.
  • For the WITH_NAMES variants the limit is halved to 31 member variables.

To pick the macro for your own type and get code to start from, answer the questions below.

  • Members are private: use an INTRUSIVE macro inside the class (reference).
  • All members are public, or you cannot edit the class: use a NON_INTRUSIVE macro in the class's namespace (reference).
  • The class adds members to a serializable base class: use a DERIVED_TYPE macro with the base class as second argument (reference).
  • Missing keys should keep their default values: append _WITH_DEFAULT; otherwise a missing key throws.
  • You only convert to JSON: append _ONLY_SERIALIZE instead.
  • JSON keys differ from the member names: append _WITH_NAMES and write \"key\", member pairs (reference).
  • Private members of a class you cannot edit: no macro works; write the conversion by hand (third-party types).
  • The type is not default constructible and is converted in both directions: no macro works; specialize adl_serializer with a from_json that returns the value, or append _ONLY_SERIALIZE if you only convert to JSON (non-default-constructible types).

Macro chooser: each answer selects one part of the macro name; the generated program defines the type, calls the macro and converts a value to JSON and back. Combinations that no macro supports show the alternative instead of code.

Example: using the NLOHMANN_DEFINE_TYPE_* macros

The to_json/from_json functions for the person struct above can be created with:

namespace ns {\n    NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(person, name, address, age)\n}\n

If you want to inherit the person struct and add a field to it, it can be done with:

namespace ns {\n    struct person_derived : person {\n        std::string email;\n    };\n\n    NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE(person_derived, person, email)\n}\n

Here is another example with private members, where NLOHMANN_DEFINE_TYPE_INTRUSIVE is needed:

namespace ns {\n    class address {\n      private:\n        std::string street;\n        int housenumber;\n        int postcode;\n\n      public:\n        NLOHMANN_DEFINE_TYPE_INTRUSIVE(address, street, housenumber, postcode)\n    };\n}\n

Or in case if you use some naming convention that you do not want to expose to JSON:

namespace ns {\n    class address {\n      private:\n        std::string m_street;\n        int m_housenumber;\n        int m_postcode;\n\n      public:\n        NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_NAMES(address, \"street\", m_street,\n                                                           \"housenumber\", m_housenumber,\n                                                           \"postcode\", m_postcode)\n    };\n}\n

Overriding conversions for natively-supported types

The library already provides built-in to_json/from_json conversions for STL containers such as std::vector, std::array, and std::map. Defining your own free-function to_json/from_json overload for one of these container types directly (instead of for your own type) can conflict with the built-in overload during overload resolution, producing compiler errors (\"no matching overloaded function\", \"call is ambiguous\") that vary by compiler and library version. If you need different conversion behavior for a container type the library already handles, wrap it in your own type (or use adl_serializer specialization, as shown above for boost::optional) instead of trying to re-specialize to_json/from_json for the container type itself.

Raw C-style arrays

Members declared as raw C-style arrays (e.g., char buf[1024]) do not round-trip safely through NLOHMANN_DEFINE_TYPE_* macros or the default (de)serializers: to_json serializes any char array as a JSON string (matching the std::string-constructible overload), but the from_json overload for fixed-size arrays expects a JSON array and iterates it element-wise, which fails with a type_error when given a string. Use std::string, std::array<char, N>, or a manually written to_json/from_json pair for such members instead.

Macros and nlohmann::ordered_json

The NLOHMANN_DEFINE_TYPE_*/NLOHMANN_DEFINE_DERIVED_TYPE_* macros are generic over any basic_json specialization, including nlohmann::ordered_json. Simply use ordered_json as the target type and members are serialized in declaration order \u2014 no separate macro or extra code is needed.

namespace ns {\n    NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(person, name, address, age)\n}\n\nns::person p{\"Ned Flanders\", \"744 Evergreen Terrace\", 60};\nnlohmann::ordered_json j = p; // keys appear in declaration order: name, address, age\n

Zero-member types

All 12 NLOHMANN_DEFINE_TYPE_*/NLOHMANN_DEFINE_DERIVED_TYPE_* macros (excluding the WITH_NAMES variants) also accept types with no member variables to serialize, producing/accepting an empty JSON object {} (or, for the derived-type macros, just the base class's own JSON representation):

namespace ns {\n    struct marker {\n        bool operator==(const marker&) const { return true; }\n        NLOHMANN_DEFINE_TYPE_INTRUSIVE(marker)\n    };\n}\n\nns::marker m{};\nnlohmann::json j = m; // {}\n

No macro for non-default-constructible types

There is currently no NLOHMANN_DEFINE_TYPE_*-style macro for types that are not DefaultConstructible. This is not an intentional omission of documentation \u2014 no such macro exists yet; see How can I use get() for non-default constructible/non-copyable types? for the manual pattern to use instead.

"},{"location":"features/arbitrary_types/#how-do-i-convert-third-party-types","title":"How do I convert third-party types?","text":"

This requires a bit more advanced technique. But first, let us see how this conversion mechanism works:

flowchart LR\n    A[\"construct json j = t, or call j.get() for T\"] --> B[\"JSONSerializer for T: to_json / from_json\"]\n    B -->|\"default JSONSerializer\"| C[\"adl_serializer for T: to_json / from_json\"]\n    C -->|\"unqualified call, found via ADL\"| D[\"free to_json(j, t) / from_json(j, t) in T's namespace\"]\n    B -->|\"user specialization replaces the default\"| E[\"user's adl_serializer specialization for T\"]

How a conversion between json and a type T is dispatched: the default adl_serializer calls the free to_json/from_json functions found by argument-dependent lookup, while a user specialization of adl_serializer replaces this path.

The library uses JSON Serializers to convert types to JSON. The default serializer for nlohmann::json is nlohmann::adl_serializer (ADL means Argument-Dependent Lookup).

It is implemented like this (simplified):

template <typename T>\nstruct adl_serializer {\n    static void to_json(json& j, const T& value) {\n        // calls the \"to_json\" method in T's namespace\n    }\n\n    static void from_json(const json& j, T& value) {\n        // same thing, but with the \"from_json\" method\n    }\n};\n

This serializer works fine when you have control over the type's namespace. However, what about boost::optional or std::filesystem::path (C++17)? Hijacking the boost namespace is pretty bad, and it's illegal to add something other than template specializations to std...

To solve this, you need to add a specialization of adl_serializer to the nlohmann namespace, here's an example:

// partial specialization (full specialization works too)\nNLOHMANN_JSON_NAMESPACE_BEGIN\ntemplate <typename T>\nstruct adl_serializer<boost::optional<T>> {\n    static void to_json(json& j, const boost::optional<T>& opt) {\n        if (opt == boost::none) {\n            j = nullptr;\n        } else {\n            j = *opt; // this will call adl_serializer<T>::to_json which will\n                      // find the free function to_json in T's namespace!\n        }\n    }\n\n    static void from_json(const json& j, boost::optional<T>& opt) {\n        if (j.is_null()) {\n            opt = boost::none;\n        } else {\n            opt = j.get<T>(); // same as above, but with\n                              // adl_serializer<T>::from_json\n        }\n    }\n};\nNLOHMANN_JSON_NAMESPACE_END\n

std::optional needs no serializer

Since version 3.12.0, std::optional<T> is supported out of the box when compiling with C++17 (std::nullopt is converted to and from null). Do not write an adl_serializer for it; this pattern is only needed for types such as boost::optional or for custom semantics. See Conversions and Omitting a field when serializing std::optional.

ABI compatibility

Use NLOHMANN_JSON_NAMESPACE_BEGIN and NLOHMANN_JSON_NAMESPACE_END instead of namespace nlohmann { } in code which may be linked with different versions of this library.

"},{"location":"features/arbitrary_types/#how-can-i-use-get-for-non-default-constructiblenon-copyable-types","title":"How can I use get() for non-default constructible/non-copyable types?","text":"

For a type that is not DefaultConstructible but is otherwise an ordinary value type, specialize adl_serializer with a from_json overload that returns the value instead of writing into a reference:

Example: get() for a non-default-constructible type
#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nnamespace ns\n{\n// a simple struct to model a person (not default constructible)\nstruct person\n{\n    person(std::string n, std::string a, int aa)\n        : name(std::move(n)), address(std::move(a)), age(aa)\n    {}\n\n    std::string name;\n    std::string address;\n    int age;\n};\n} // namespace ns\n\nnamespace nlohmann\n{\ntemplate <>\nstruct adl_serializer<ns::person>\n{\n    static ns::person from_json(const json& j)\n    {\n        return {j.at(\"name\"), j.at(\"address\"), j.at(\"age\")};\n    }\n\n    // Here's the catch! You must provide a to_json method! Otherwise, you\n    // will not be able to convert person to json, since you fully\n    // specialized adl_serializer on that type\n    static void to_json(json& j, ns::person p)\n    {\n        j[\"name\"] = p.name;\n        j[\"address\"] = p.address;\n        j[\"age\"] = p.age;\n    }\n};\n} // namespace nlohmann\n\nint main()\n{\n    json j;\n    j[\"name\"] = \"Ned Flanders\";\n    j[\"address\"] = \"744 Evergreen Terrace\";\n    j[\"age\"] = 60;\n\n    auto p = j.get<ns::person>();\n\n    std::cout << p.name << \" (\" << p.age << \") lives in \" << p.address << '\\n';\n}\n

Output:

Ned Flanders (60) lives in 744 Evergreen Terrace\n

The same technique also works if your type is not copyable, as long as it is MoveConstructible:

struct move_only_type {\n    move_only_type() = delete;\n    move_only_type(int ii): i(ii) {}\n    move_only_type(const move_only_type&) = delete;\n    move_only_type(move_only_type&&) = default;\n\n    int i;\n};\n\nnamespace nlohmann {\n    template <>\n    struct adl_serializer<move_only_type> {\n        // note: the return type is no longer 'void', and the method only takes\n        // one argument\n        static move_only_type from_json(const json& j) {\n            return {j.get<int>()};\n        }\n\n        // Here's the catch! You must provide a to_json method! Otherwise, you\n        // will not be able to convert move_only_type to json, since you fully\n        // specialized adl_serializer on that type\n        static void to_json(json& j, move_only_type t) {\n            j = t.i;\n        }\n    };\n}\n
"},{"location":"features/arbitrary_types/#why-isnt-my-to_json-or-from_json-found","title":"Why isn't my to_json or from_json found?","text":"

The library calls to_json and from_json without qualification, so the compiler finds them by argument-dependent lookup in the namespace of the type, or in the namespaces of its template arguments. The usual reasons for a function that is \"not found\" are:

  • The type is an alias of a standard type. After using Hash = std::array<std::uint8_t, 6>; the type is std::array<std::uint8_t, 6>, which lives in namespace std. A to_json(json&, const Hash&) in your namespace is never selected. Either give the type its own identity, for example struct Hash : std::array<std::uint8_t, 6> {}; (the function is then found in Hash's namespace), or specialize adl_serializer<Hash>.
  • The function is in the wrong namespace. It must be in the namespace of the type (a global type needs a global function), not in the namespace of the code that calls the conversion. Specializations of adl_serializer belong in namespace nlohmann.
  • It is declared too late. A conversion can only use what has been declared when it is instantiated. If json j = std::vector<third_party::string>{...}; appears before the adl_serializer specialization, the compiler reports an error such as \"explicit specialization of adl_serializer<...> after instantiation\". Put the specialization in a small header that every file includes before it uses the type with json.
  • It is a template. For template <class T> struct box, write template <class T> void to_json(json&, const box<T>&), not an overload for one T.
  • It worked by accident. Some versions found to_json overloads in nlohmann::detail through argument-dependent lookup of the base class of basic_json. Do not rely on this; it is not part of the interface.

For smart pointers, class hierarchies, std::variant, and std::chrono, see Recipes for common types.

"},{"location":"features/arbitrary_types/#why-cant-i-convert-tofrom-stdany","title":"Why can't I convert to/from std::any?","text":"

std::any is intentionally excluded from get<T>()/generic conversion support, so get<std::any>() and containers like std::map<std::string, std::any> fail to compile by design \u2014 there is no way to know, from a json value alone, which concrete type to store inside the std::any. To work with heterogeneous JSON values, dispatch on the value's type manually and construct the std::any (or extract from it) yourself:

std::any value_to_any(const json& j) {\n    if (j.is_boolean())      { return j.get<bool>(); }\n    if (j.is_number_integer()) { return j.get<int>(); }\n    if (j.is_number_float()) { return j.get<double>(); }\n    if (j.is_string())       { return j.get<std::string>(); }\n    // ... handle other types (arrays, objects) as needed for your use case\n    return {};\n}\n\njson any_to_json(const std::any& a) {\n    if (a.type() == typeid(bool))        { return std::any_cast<bool>(a); }\n    if (a.type() == typeid(int))         { return std::any_cast<int>(a); }\n    if (a.type() == typeid(double))      { return std::any_cast<double>(a); }\n    if (a.type() == typeid(std::string)) { return std::any_cast<std::string>(a); }\n    return nullptr;\n}\n
"},{"location":"features/arbitrary_types/#why-does-serializing-a-stdmapstdunordered_map-with-non-string-keys-produce-an-array","title":"Why does serializing a std::map/std::unordered_map with non-string keys produce an array?","text":"

A std::map/std::unordered_map whose key type is not string-like (e.g., std::map<int, std::string>) cannot be serialized as a JSON object, because JSON object keys must be strings. See Converting maps with non-string keys in the types article for what the library does instead.

"},{"location":"features/arbitrary_types/#why-does-stdwstring-convert-or-dump-incorrectly","title":"Why does std::wstring convert or dump incorrectly?","text":"

The library assumes UTF-8 encoding internally, so std::wstring is not supported out of the box \u2014 see the FAQ entry on wide string handling for why, and for a UTF-8 conversion recipe.

"},{"location":"features/arbitrary_types/#can-i-write-my-own-serializer-advanced-use","title":"Can I write my own serializer? (Advanced use)","text":"

Yes. You might want to take a look at unit-udt.cpp in the test suite, to see a few examples.

If you write your own serializer, you will need to do a few things:

  • use a different basic_json alias than nlohmann::json (the last template parameter of basic_json is the JSONSerializer)
  • use your basic_json alias (or a template parameter) in all your to_json/from_json methods
  • use nlohmann::to_json and nlohmann::from_json when you need ADL

Here is an example, without simplifications, that only accepts types with a size <= 32, and uses ADL.

// You should use void as a second template argument\n// if you don't need compile-time checks on T\ntemplate<typename T, typename SFINAE = typename std::enable_if<sizeof(T) <= 32>::type>\nstruct less_than_32_serializer {\n    template <typename BasicJsonType>\n    static void to_json(BasicJsonType& j, T value) {\n        // we want to use ADL, and call the correct to_json overload\n        using nlohmann::to_json; // this method is called by adl_serializer,\n                                 // this is where the magic happens\n        to_json(j, value);\n    }\n\n    template <typename BasicJsonType>\n    static void from_json(const BasicJsonType& j, T& value) {\n        // same thing here\n        using nlohmann::from_json;\n        from_json(j, value);\n    }\n};\n

Be very careful when reimplementing your serializer, you can stack overflow if you don't pay attention:

template <typename T, typename = void>\nstruct bad_serializer\n{\n    template <typename BasicJsonType>\n    static void to_json(BasicJsonType& j, const T& value) {\n      // this calls BasicJsonType::json_serializer<T>::to_json(j, value);\n      // if BasicJsonType::json_serializer == bad_serializer ... oops!\n      j = value;\n    }\n\n    template <typename BasicJsonType>\n    static void from_json(const BasicJsonType& j, T& value) {\n      // this calls BasicJsonType::json_serializer<T>::from_json(j, value);\n      // if BasicJsonType::json_serializer == bad_serializer ... oops!\n      value = j.template get<T>(); // oops!\n    }\n};\n
"},{"location":"features/arbitrary_types/#see-also","title":"See also","text":"
  • Recipes for common types - smart pointers, class hierarchies, std::variant, and std::chrono
  • Converting values - the general overview of get/get_to and implicit conversions
  • Specializing enum conversion - map enums to JSON strings instead of integers
  • Supported macros - reference for NLOHMANN_DEFINE_TYPE_* and related macros
  • adl_serializer - the default JSONSerializer used in the conversion dispatch
  • NLOHMANN_DEFINE_TYPE_INTRUSIVE - generate the conversion functions inside the type
  • NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE - generate the conversion functions outside the type
  • NLOHMANN_DEFINE_TYPE_WITH_NAMES - use JSON keys that differ from the member names
  • NLOHMANN_DEFINE_DERIVED_TYPE - generate the conversion functions for derived classes
  • NLOHMANN_JSON_SERIALIZE_ENUM - map enum values to JSON values
  • get - convert a JSON value to a C++ type
  • get_to - convert a JSON value into an existing variable
  • json_serializer - the JSONSerializer template parameter
"},{"location":"features/assertions/","title":"Runtime Assertions","text":"

The code contains numerous debug assertions to ensure class invariants are valid or to detect undefined behavior. Whereas the former class invariants are nothing to be concerned with, the latter checks for undefined behavior are to detect bugs in client code.

"},{"location":"features/assertions/#switch-off-runtime-assertions","title":"Switch off runtime assertions","text":"

Runtime assertions can be switched off by defining the preprocessor macro NDEBUG (see the documentation of assert) which is the default for release builds. Without NDEBUG, the assertions are compiled in and contain the name of the source file (__FILE__); see notes for builds and distribution if that path must not end up in your binaries.

"},{"location":"features/assertions/#change-assertion-behavior","title":"Change assertion behavior","text":"

The behavior of runtime assertions can be changed by defining macro JSON_ASSERT(x) before including the json.hpp header.

"},{"location":"features/assertions/#function-with-runtime-assertions","title":"Function with runtime assertions","text":""},{"location":"features/assertions/#unchecked-access-to-a-const-value","title":"Unchecked access to a const value","text":"

Function operator[] implements unchecked access for arrays and objects. Whereas a missing element is added in the case of non-const values, accessing a const value with a missing object key or an invalid array index is undefined behavior (think of a dereferenced null pointer) and yields a runtime assertion. This also applies to a JSON pointer that refers to a missing key or an invalid index.

If you are not sure whether an element exists, use checked access with the at function or call the contains function before.

See also the documentation on element access.

Example: missing object key

The following code will trigger an assertion at runtime:

#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    const json j = {{\"key\", \"value\"}};\n    auto v = j[\"missing\"];\n}\n

Output:

Assertion failed: (it != m_data.m_value.object->end()), function operator[], file json.hpp, line 28795.\n
Example 2: Invalid array index in a JSON pointer

The following code will trigger an assertion at runtime:

#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\nusing namespace nlohmann::literals;\n\nint main()\n{\n    const json j = {{\"array\", {1, 2, 3}}};\n    auto v = j[\"/array/5\"_json_pointer];\n}\n

Output:

Assertion failed: (idx < m_data.m_value.array->size()), function operator[], file json.hpp, line 28758.\n
"},{"location":"features/assertions/#constructing-from-an-uninitialized-iterator-range","title":"Constructing from an uninitialized iterator range","text":"

Constructing a JSON value from an iterator range (see constructor) with an uninitialized iterator is undefined behavior and yields a runtime assertion.

Example: uninitialized iterator range

The following code will trigger an assertion at runtime:

#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    json::iterator it1, it2;\n    json j(it1, it2);\n}\n

Output:

Assertion failed: (m_object != nullptr), function operator++, file iter_impl.hpp, line 368.\n
"},{"location":"features/assertions/#operations-on-uninitialized-iterators","title":"Operations on uninitialized iterators","text":"

Any operation on uninitialized iterators (i.e., iterators that are not associated with any JSON value) is undefined behavior and yields a runtime assertion.

Example: uninitialized iterator

The following code will trigger an assertion at runtime:

#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n  json::iterator it;\n  ++it;\n}\n

Output:

Assertion failed: (m_object != nullptr), function operator++, file iter_impl.hpp, line 368.\n
"},{"location":"features/assertions/#changes","title":"Changes","text":""},{"location":"features/assertions/#reading-from-a-null-file-or-char-pointer","title":"Reading from a null FILE or char pointer","text":"

Reading from a null FILE or char pointer in C++ is undefined behavior. Until version 3.12.0, this library asserted that the pointer was not nullptr using a runtime assertion. If assertions were disabled, this would result in undefined behavior. Since version 3.12.0, this library checks for nullptr and throws a parse_error.101 to prevent the undefined behavior.

Example: reading from null pointer

The following code will trigger an assertion at runtime:

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    std::FILE* f = std::fopen(\"nonexistent_file.json\", \"r\");\n    try {\n        json j = json::parse(f);\n    } catch (std::exception& e) {\n        std::cerr << e.what() << std::endl;\n    }\n}\n

Output:

[json.exception.parse_error.101] parse error: attempting to parse an empty input; check that your input string or stream contains the expected JSON\n
"},{"location":"features/assertions/#see-also","title":"See also","text":"
  • JSON_ASSERT - control behavior of runtime assertions
  • Supported Macros - all supported macros
  • Working Without Exceptions - using the library without exceptions
  • Exceptions - all exceptions and their error codes
  • Macros - reference of all macros
"},{"location":"features/binary_values/","title":"Binary Values","text":"

The library implements several binary formats that encode JSON in an efficient way. Most of these formats support binary values; that is, values that have semantics defined outside the library and only define a sequence of bytes to be stored.

JSON itself does not have a binary value. As such, binary values are an extension that this library implements to store values received by a binary format. Binary values are never created by the JSON parser and are only part of a serialized JSON text if they have been created manually or via a binary format.

"},{"location":"features/binary_values/#api-for-binary-values","title":"API for binary values","text":"
classDiagram\n\nclass binary_t [\"json::binary_t\"] {\n    +void set_subtype(std::uint64_t subtype)\n    +void clear_subtype()\n    +std::uint64_t subtype() const\n    +bool has_subtype() const\n}\n\nclass vector [\"std::vector<uint8_t>\"]\n\nvector <|-- binary_t

Class diagram of json::binary_t: it derives from std::vector<uint8_t> and adds functions to set, clear, query, and test an optional subtype.

By default, binary values are stored as std::vector<std::uint8_t>. This type can be changed by providing a template parameter to the basic_json type. To store binary subtypes, the storage type is extended and exposed as json::binary_t:

auto binary = json::binary_t({0xCA, 0xFE, 0xBA, 0xBE});\nauto binary_with_subtype = json::binary_t({0xCA, 0xFE, 0xBA, 0xBE}, 42);\n

There are several convenience functions to check and set the subtype:

binary.has_subtype();                   // returns false\nbinary_with_subtype.has_subtype();      // returns true\n\nbinary_with_subtype.clear_subtype();\nbinary_with_subtype.has_subtype();      // returns false\n\nbinary_with_subtype.set_subtype(42);\nbinary.set_subtype(23);\n\nbinary.subtype();                       // returns 23\n

As json::binary_t is subclassing std::vector<std::uint8_t>, all member functions are available:

binary.size();  // returns 4\nbinary[1];      // returns 0xFE\n

JSON values can be constructed from json::binary_t:

json j = binary;\n

Binary values are primitive values just like numbers or strings, as reflected by is_binary() and is_primitive():

j.is_binary();    // returns true\nj.is_primitive(); // returns true\n

Given a binary JSON value, the binary_t can be accessed by reference via get_binary():

j.get_binary().has_subtype();  // returns true\nj.get_binary().size();         // returns 4\n

For convenience, binary JSON values can be constructed via json::binary:

auto j2 = json::binary({0xCA, 0xFE, 0xBA, 0xBE}, 23);\nauto j3 = json::binary({0xCA, 0xFE, 0xBA, 0xBE});\n\nj2 == j;                        // returns true\nj3.get_binary().has_subtype();  // returns false\nj3.get_binary().subtype();      // returns std::uint64_t(-1) as j3 has no subtype\n
"},{"location":"features/binary_values/#serialization","title":"Serialization","text":"

Binary values are serialized differently according to the formats.

"},{"location":"features/binary_values/#json","title":"JSON","text":"

JSON does not have a binary type, and this library does not introduce a new type as this would break conformance. Instead, binary values are serialized as an object with two keys: bytes holds an array of integers, and subtype is an integer or null.

Example: serialize a binary value to JSON

Code:

// create a binary value of subtype 42\njson j;\nj[\"binary\"] = json::binary({0xCA, 0xFE, 0xBA, 0xBE}, 42);\n\n// serialize to standard output\nstd::cout << j.dump(2) << std::endl;\n

Output:

{\n  \"binary\": {\n    \"bytes\": [202, 254, 186, 190],\n    \"subtype\": 42\n  }\n}\n

No roundtrip for binary values

The JSON parser will not parse the objects generated by binary values back to binary values. This is by design to remain standards compliant. Serializing binary values to JSON is only implemented for debugging purposes.

"},{"location":"features/binary_values/#bjdata","title":"BJData","text":"

BJData Draft 3 supports binary values as optimized arrays of B (byte) elements, but no subtypes. With version = bjdata_version_t::draft3 and both use_size and use_type set, to_bjdata writes a binary value as [$B#..., and from_bjdata reads it back as a binary value (without subtype). In all other cases, including the default Draft 2 mode, the library follows the Draft 2 proposal and writes an array of integers (U in Draft 2, B in Draft 3), which is read back as an array.

Example: serialize a binary value to BJData

Code:

// create a binary value of subtype 42 (will be ignored in BJData)\njson j;\nj[\"binary\"] = json::binary({0xCA, 0xFE, 0xBA, 0xBE}, 42);\n\n// convert to BJData\nauto v = json::to_bjdata(j);      \n

v is a std::vector<std::uint8_t> with the following 20 elements:

0x7B                                             // '{'\n    0x69 0x06                                    // i 6 (length of the key)\n    0x62 0x69 0x6E 0x61 0x72 0x79                // \"binary\"\n    0x5B                                         // '['\n        0x55 0xCA 0x55 0xFE 0x55 0xBA 0x55 0xBE  // content (each byte prefixed with 'U')\n    0x5D                                         // ']'\n0x7D                                             // '}'\n

The following code uses the type and size optimization for BJData:

// convert to BJData using the size and type optimization\nauto v = json::to_bjdata(j, true, true);\n

The resulting vector has 22 elements; the optimization is not effective for examples with few values:

0x7B                                // '{'\n    0x23 0x69 0x01                  // '#' 'i' 1 number of object members\n    0x69 0x06                       // i 6 (length of the key)\n    0x62 0x69 0x6E 0x61 0x72 0x79   // \"binary\"\n    0x5B                            // '[' array\n        0x24 0x55                   // '$' 'U' type of the array elements: unsigned integers\n        0x23 0x69 0x04              // '#' i 4 number of array elements\n        0xCA 0xFE 0xBA 0xBE         // content\n

Note that subtype (42) is not serialized and that, in Draft 2 mode, BJData has no binary type, and deserializing v would yield the following value:

{\n  \"binary\": [202, 254, 186, 190]\n}\n
"},{"location":"features/binary_values/#bon8","title":"BON8","text":"

BON8 neither supports binary values nor subtypes. The library serializes binary values as an array of integers.

Example: serialize a binary value to BON8

Code:

// create a binary value of subtype 42 (will be ignored in BON8)\njson j;\nj[\"binary\"] = json::binary({0xCA, 0xFE, 0xBA, 0xBE}, 42);\n\n// convert to BON8\nauto v = json::to_bon8(j);\n

v is a std::vector<std::uint8_t> with the following 16 elements:

0x87                                     // object with 1 member\n    0x62 0x69 0x6E 0x61 0x72 0x79        // \"binary\"\n    0x84                                 // array with 4 elements\n        0xC3 0x22 0xC3 0x56 0xC3 0x12 0xC3 0x16  // content (each byte, here all above 39, as a 2-byte integer)\n

Note that the subtype is lost, and deserializing v would yield the following value:

{\n  \"binary\": [202, 254, 186, 190]\n}\n
"},{"location":"features/binary_values/#bson","title":"BSON","text":"

BSON supports binary values and subtypes. If a subtype is given, it is used and added as an unsigned 8-bit integer; a subtype above 255 throws out_of_range.415. If no subtype is given, the generic binary subtype 0x00 is used. The payload of the \"old binary\" subtype 0x02 is preceded by a second length, which the library writes and removes again when reading; it is not part of the payload.

Example: serialize a binary value to BSON

Code:

// create a binary value of subtype 42\njson j;\nj[\"binary\"] = json::binary({0xCA, 0xFE, 0xBA, 0xBE}, 42);\n\n// convert to BSON\nauto v = json::to_bson(j);      \n

v is a std::vector<std::uint8_t> with the following 22 elements:

0x16 0x00 0x00 0x00                         // number of bytes in the document\n    0x05                                    // binary value\n        0x62 0x69 0x6E 0x61 0x72 0x79 0x00  // key \"binary\" + null byte\n        0x04 0x00 0x00 0x00                 // number of bytes\n        0x2a                                // subtype\n        0xCA 0xFE 0xBA 0xBE                 // content\n0x00                                        // end of the document\n

Note that the serialization preserves the subtype, and deserializing v would yield the following value:

{\n  \"binary\": {\n    \"bytes\": [202, 254, 186, 190],\n    \"subtype\": 42\n  }\n}\n
"},{"location":"features/binary_values/#cbor","title":"CBOR","text":"

CBOR supports binary values and subtypes. Any binary value will be serialized as a byte string; a subtype is serialized as a tag preceding it. When parsing, tags are only read back as subtypes with cbor_tag_handler_t::store (see from_cbor). The library will choose the smallest representation using the length of the byte array.

Example: serialize a binary value to CBOR

Code:

// create a binary value of subtype 42\njson j;\nj[\"binary\"] = json::binary({0xCA, 0xFE, 0xBA, 0xBE}, 42);\n\n// convert to CBOR\nauto v = json::to_cbor(j);      \n

v is a std::vector<std::uint8_t> with the following 15 elements:

0xA1                                   // map(1)\n    0x66                               // text(6)\n        0x62 0x69 0x6E 0x61 0x72 0x79  // \"binary\"\n    0xD8 0x2A                          // tag(42)\n    0x44                               // bytes(4)\n        0xCA 0xFE 0xBA 0xBE            // content\n

Note that the subtype is serialized as tag. However, parsing tagged values yield a parse error unless json::cbor_tag_handler_t::ignore or json::cbor_tag_handler_t::store is passed to json::from_cbor (see cbor_tag_handler_t).

With ignore, the subtype is dropped (\"subtype\": null); with store, the tag is kept (\"subtype\": 42):

{\n  \"binary\": {\n    \"bytes\": [202, 254, 186, 190],\n    \"subtype\": null\n  }\n}\n
{\n  \"binary\": {\n    \"bytes\": [202, 254, 186, 190],\n    \"subtype\": 42\n  }\n}\n
"},{"location":"features/binary_values/#messagepack","title":"MessagePack","text":"

MessagePack supports binary values and subtypes. If a subtype is given, the ext family is used. The library will choose the smallest representation among fixext1, fixext2, fixext4, fixext8, fixext16, ext8, ext16, and ext32. The subtype is then written as the signed 8-bit ext type: subtypes 128 to 255 map to the negative (reserved) ext types, and on reading the ext type is exposed as an unsigned subtype from 0 to 255.

If no subtype is given, the bin family (bin8, bin16, bin32) is used.

Example: serialize a binary value to MessagePack

Code:

// create a binary value of subtype 42\njson j;\nj[\"binary\"] = json::binary({0xCA, 0xFE, 0xBA, 0xBE}, 42);\n\n// convert to MessagePack\nauto v = json::to_msgpack(j);      \n

v is a std::vector<std::uint8_t> with the following 14 elements:

0x81                                   // fixmap1\n    0xA6                               // fixstr6\n        0x62 0x69 0x6E 0x61 0x72 0x79  // \"binary\"\n    0xD6                               // fixext4\n        0x2A                           // subtype\n        0xCA 0xFE 0xBA 0xBE            // content\n

Note that the serialization preserves the subtype, and deserializing v would yield the following value:

{\n  \"binary\": {\n    \"bytes\": [202, 254, 186, 190],\n    \"subtype\": 42\n  }\n}\n
"},{"location":"features/binary_values/#ubjson","title":"UBJSON","text":"

UBJSON neither supports binary values nor subtypes and proposes to serialize binary values as an array of uint8 values. The library implements this translation.

Example: serialize a binary value to UBJSON

Code:

// create a binary value of subtype 42 (will be ignored in UBJSON)\njson j;\nj[\"binary\"] = json::binary({0xCA, 0xFE, 0xBA, 0xBE}, 42);\n\n// convert to UBJSON\nauto v = json::to_ubjson(j);      \n

v is a std::vector<std::uint8_t> with the following 20 elements:

0x7B                                             // '{'\n    0x69 0x06                                    // i 6 (length of the key)\n    0x62 0x69 0x6E 0x61 0x72 0x79                // \"binary\"\n    0x5B                                         // '['\n        0x55 0xCA 0x55 0xFE 0x55 0xBA 0x55 0xBE  // content (each byte prefixed with 'U')\n    0x5D                                         // ']'\n0x7D                                             // '}'\n

The following code uses the type and size optimization for UBJSON:

// convert to UBJSON using the size and type optimization\nauto v = json::to_ubjson(j, true, true);\n

The resulting vector has 23 elements; the optimization is not effective for examples with few values:

0x7B                                // '{'\n    0x24                            // '$' type of the object elements\n    0x5B                            // '[' array\n    0x23 0x69 0x01                  // '#' i 1 number of object elements\n    0x69 0x06                       // i 6 (length of the key)\n    0x62 0x69 0x6E 0x61 0x72 0x79   // \"binary\"\n        0x24 0x55                   // '$' 'U' type of the array elements: unsigned integers\n        0x23 0x69 0x04              // '#' i 4 number of array elements\n        0xCA 0xFE 0xBA 0xBE         // content\n

Note that subtype (42) is not serialized and that UBJSON has no binary type, and deserializing v would yield the following value:

{\n  \"binary\": [202, 254, 186, 190]\n}\n
"},{"location":"features/binary_values/#see-also","title":"See also","text":"
  • Binary formats - the formats that can store binary values
  • binary_t - type for binary values
  • byte_container_with_subtype - container for binary values with subtype
  • binary - create a binary value
  • get_binary - access the stored binary value
  • is_binary - check whether a value is binary
  • cbor_tag_handler_t - store or ignore CBOR tags when parsing
"},{"location":"features/comments/","title":"Comments","text":"

This library does not support comments by default. It does so for three reasons:

  1. Comments are not part of the JSON specification. You may argue that // or /* */ are allowed in JavaScript, but JSON is not JavaScript.
  2. This was not an oversight: Douglas Crockford wrote on this in May 2012:

    I removed comments from JSON because I saw people were using them to hold parsing directives, a practice which would have destroyed interoperability. I know that the lack of comments makes some people sad, but it shouldn't.

    Suppose you are using JSON to keep configuration files, which you would like to annotate. Go ahead and insert all the comments you like. Then pipe it through JSMin before handing it to your JSON parser.

  3. It is dangerous for interoperability if some libraries add comment support while others do not. Please check The Harmful Consequences of the Robustness Principle on this.

However, you can set parameter ignore_comments to true in the parse function to ignore // or /* */ comments. Comments will then be treated as whitespace. Combined with ignore_trailing_commas (also a parse parameter), this covers what is commonly referred to as JSONC (JSON with Comments, as used e.g. by Visual Studio Code's .jsonc files) \u2014 comments and trailing commas, nothing more. This is a different, smaller extension than JSON5, which additionally allows unquoted keys, single-quoted strings, and other syntax changes that this library does not support.

For more information, see JSON With Commas and Comments (JWCC).

Example

Consider the following JSON with comments.

{\n    // update in 2006: removed Pluto\n    \"planets\": [\"Mercury\", \"Venus\", \"Earth\", \"Mars\",\n                \"Jupiter\", \"Uranus\", \"Neptune\" /*, \"Pluto\" */]\n}\n

When calling parse without additional argument, a parse error exception is thrown. If ignore_comments is set to true, the comments are ignored during parsing:

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    std::string s = R\"(\n    {\n        // update in 2006: removed Pluto\n        \"planets\": [\"Mercury\", \"Venus\", \"Earth\", \"Mars\",\n                    \"Jupiter\", \"Uranus\", \"Neptune\" /*, \"Pluto\" */]\n    }\n    )\";\n\n    try\n    {\n        json j = json::parse(s);\n    }\n    catch (json::exception& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n\n    json j = json::parse(s,\n                         /* callback */ nullptr,\n                         /* allow exceptions */ true,\n                         /* ignore_comments */ true);\n    std::cout << j.dump(2) << '\\n';\n}\n

Output:

[json.exception.parse_error.101] parse error at line 3, column 9: syntax error while parsing object key - invalid literal; last read: '<U+000A>    {<U+000A>        /'; expected string literal\n{\n  \"planets\": [\n    \"Mercury\",\n    \"Venus\",\n    \"Earth\",\n    \"Mars\",\n    \"Jupiter\",\n    \"Uranus\",\n    \"Neptune\"\n  ]\n}\n
"},{"location":"features/comments/#see-also","title":"See also","text":"
  • parse - deserialize from a compatible input
  • Trailing Commas - accept trailing commas in arrays and objects
  • Parsing - overview of the parsing functions
  • Parsing Untrusted Input - limits and checks for input you do not control
"},{"location":"features/conversions/","title":"Converting values","text":"

A basic_json value stores JSON data, but most of the time you want to move that data into ordinary C++ types (an int, a std::string, a std::vector, or one of your own structs) and back. This page describes how these conversions work.

"},{"location":"features/conversions/#getting-values-out","title":"Getting values out","text":"

The get function template returns a copy of the stored value converted to the requested type:

json j = R\"({\"name\": \"Mary\", \"age\": 42, \"hobbies\": [\"hiking\", \"reading\"]})\"_json;\n\nauto name = j[\"name\"].get<std::string>();               // \"Mary\"\nauto age  = j[\"age\"].get<int>();                        // 42\nauto hobbies = j[\"hobbies\"].get<std::vector<std::string>>();  // {\"hiking\", \"reading\"}\n

Getting a string without quotes

A frequent point of confusion: use get, not dump, to read a string value. j[\"name\"].get<std::string>() yields Mary, whereas j[\"name\"].dump() yields the JSON text \"Mary\" (with quotes), because dump always produces a JSON text.

Alternatively, get_to writes into an existing variable and deduces the target type, which avoids repeating it:

Example
#include <iostream>\n#include <map>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create a JSON value with different types\n    json json_types =\n    {\n        {\"boolean\", true},\n        {\n            \"number\", {\n                {\"integer\", 42},\n                {\"floating-point\", 17.23}\n            }\n        },\n        {\"string\", \"Hello, world!\"},\n        {\"array\", {1, 2, 3, 4, 5}},\n        {\"null\", nullptr}\n    };\n\n    bool v1;\n    int v2;\n    short v3;\n    float v4;\n    int v5;\n    std::string v6;\n    std::vector<short> v7;\n    std::map<std::string, json> v8;\n\n    // use explicit conversions\n    json_types[\"boolean\"].get_to(v1);\n    json_types[\"number\"][\"integer\"].get_to(v2);\n    json_types[\"number\"][\"integer\"].get_to(v3);\n    json_types[\"number\"][\"floating-point\"].get_to(v4);\n    json_types[\"number\"][\"floating-point\"].get_to(v5);\n    json_types[\"string\"].get_to(v6);\n    json_types[\"array\"].get_to(v7);\n    json_types.get_to(v8);\n\n    // print the conversion results\n    std::cout << v1 << '\\n';\n    std::cout << v2 << ' ' << v3 << '\\n';\n    std::cout << v4 << ' ' << v5 << '\\n';\n    std::cout << v6 << '\\n';\n\n    for (auto i : v7)\n    {\n        std::cout << i << ' ';\n    }\n    std::cout << \"\\n\\n\";\n\n    for (const auto& i : v8)\n    {\n        std::cout << i.first << \": \" << i.second << '\\n';\n    }\n}\n

Output:

1\n42 42\n17.23 17\nHello, world!\n1 2 3 4 5 \n\narray: [1,2,3,4,5]\nboolean: true\nnull: null\nnumber: {\"floating-point\":17.23,\"integer\":42}\nstring: \"Hello, world!\"\n

Getting values out of a document or a view

A view offers the same get<T>() conversion. For the built-in types (booleans, numbers, strings, std::vector, std::map, ...) it reads the value straight from the document's index, without building a basic_json value first; user-defined types with a from_json() are converted from a basic_json value, see the list. Two conversions never copy at all: get_string() returns a string as a view into the source text, and number_token() returns a number exactly as it was written. Every other type is obtained from a subtree that is built on demand with materialize(). See Zero-copy JSON views.

The library already knows how to convert to and from the scalar types and the STL containers (such as std::vector, std::map, std::array, std::optional, and many more). Converting a JSON object back to a std::map or a JSON array back to a std::vector therefore works without any extra code:

json j = {{\"one\", 1}, {\"two\", 2}};\nauto m = j.get<std::map<std::string, int>>();  // {{\"one\", 1}, {\"two\", 2}}\n

std::pair and std::tuple are also supported, converting positionally to and from a JSON array:

json j = {1.0, \"hello\", 42};\nauto t = j.get<std::tuple<double, std::string, int>>();  // {1.0, \"hello\", 42}\n

Serializing a std::pair/std::tuple whose every element is a string-keyed pair

When every element of a std::pair or std::tuple is itself a two-element array whose first element is a string (for example std::pair<std::string, int>), serializing it produces a JSON object instead of the expected array:

using kv = std::pair<std::string, int>;\njson j = std::pair<kv, kv>{{\"a\", 1}, {\"b\", 2}};  // {\"a\":1,\"b\":2}, not [[\"a\",1],[\"b\",2]]\n

This is a consequence of the brace-initializer object-detection rule: the same rule that lets json{{\"a\", 1}, {\"b\", 2}} create an object also fires here. The resulting object cannot be read back into the original type (get<std::pair<kv, kv>>() throws type_error.302), and duplicate keys collapse into one, losing elements. This only affects std::pair/std::tuple themselves; a std::vector<std::pair<std::string, int>>, or a pair/tuple with at least one element that is not a string-keyed pair, serializes to an array as expected. To force an array, build one explicitly from the elements with array:

std::pair<kv, kv> p{{\"a\", 1}, {\"b\", 2}};\njson a = json::array({p.first, p.second});  // [[\"a\",1],[\"b\",2]]\n

Extracting references into a tuple

A tuple type may also hold references (e.g. std::tuple<double&, std::string&>) to avoid copying: get then returns a tuple of references pointing directly at the elements stored inside the basic_json array, rather than a tuple of copies:

json j = {1.0, \"hello\"};\nauto refs = j.get<std::tuple<double&, std::string&>>();\nstd::get<1>(refs) = \"world\";  // modifies j[1] in place\n

A referenced element must name the type the library actually stores \u2014 one of boolean_t, number_integer_t, number_unsigned_t, number_float_t, string_t, binary_t, array_t, or object_t. There is nothing else to refer to, so a reference to any other type is a compile error even when a conversion would exist: std::tuple<int&> is rejected, because the library stores a number_integer_t (std::int64_t by default) and not an int. This restriction applies only to reference elements \u2014 a plain std::tuple<int> converts by value as usual.

"},{"location":"features/conversions/#implicit-conversions","title":"Implicit conversions","text":"

By default, a JSON value implicitly converts to a compatible C++ type, so the explicit get call can often be omitted:

json j = \"Hello\";\nstd::string s = j;   // implicit conversion, same as j.get<std::string>()\n

Implicit conversions are convenient but can be surprising (for example, in overload resolution or with auto). They can be disabled by defining JSON_USE_IMPLICIT_CONVERSIONS to 0, which forces the explicit get form and can catch unintended conversions at compile time.

auto copies the JSON value; it does not convert it

The type of j[\"name\"] is json, not the C++ type of the value inside. auto therefore deduces json:

json j = {{\"name\", \"Mary\"}, {\"age\", 42}};\n\nauto name = j[\"name\"];                       // json: a copy of the value; prints as \"Mary\" (with quotes)\nstd::string s1 = j[\"name\"];                  // std::string: implicit conversion\nauto s2 = j[\"name\"].get<std::string>();      // std::string: explicit conversion\nauto& age = j[\"age\"];                        // json&: a reference, no copy\nage = 43;                                    // changes j\n

This is also why std::cout << j[\"name\"] prints the quotes (see getting a string without quotes), and why a json value cannot be passed to printf: the argument is not an int or a char*, and a compiler either rejects passing it through ... (Clang does) or compiles it and prints garbage. Convert first: std::printf(\"%d\", j[\"age\"].get<int>());.

Prefer get<T>() over auto when you want the C++ value, and auto& or const auto& when you want to avoid a copy of a large value.

Conversions do not range-check numbers

Just like C++ itself, the get family performs numeric conversions without range checks \u2014 retrieving a floating-point value as an integer truncates it, and narrowing conversions may overflow. See number conversion for details and how to guard against it.

std::optional direct construction from JSON null throws

Constructing or assigning std::optional<T> directly from a JSON value does not correctly produce std::nullopt for a JSON null:

json j_null;\nstd::optional<std::string> opt = j_null;  // \u274c throws type_error 302\n

This is due to C++ language rules: std::optional<T> has its own converting constructor that is chosen over basic_json::operator T() when both are viable. Use get<std::optional<T>>() or get_to() instead:

auto opt = j_null.get<std::optional<std::string>>();  // \u2705 std::nullopt\nj_null.get_to(opt);                                     // \u2705 std::nullopt\n

static_cast and get<std::optional<T>>() are not guaranteed equivalent

operator ValueType() (used by static_cast and implicit conversions) intentionally excludes std::optional<T> from delegating to get<T>(), to avoid a constructor ambiguity with std::optional<T>'s own converting constructor from basic_json. As a result, static_cast<std::optional<T>>(json_value) goes through std::optional<T>'s own converting constructor rather than through get<std::optional<T>>(), which can behave differently \u2014 for example, with a custom adl_serializer<std::optional<T>> specialization. Prefer get<std::optional<T>>()/get_to() over static_cast for optional types.

Converting to a fixed-size destination does not check the array size

Some destination types have a size that is fixed by their C++ type rather than by the JSON value: std::pair<A, B>, std::tuple<Ts...>, std::array<T, N>, C arrays T[N], and std::map/std::unordered_map with a non-string key type (which is read from an array of two-element arrays). All of them read exactly as many elements as they need via at and never compare the JSON array's size to that number. The two mismatch directions therefore behave differently:

  • The JSON array has too many elements: the surplus is silently discarded, and no exception is thrown.
  • The JSON array has too few elements: at throws out_of_range.401 for the first missing index \u2014 an out-of-range error, not a type_error, even though the cause is a shape mismatch.
json j = {1, 2, 3, 4, 5};\n\nauto a = j.get<std::array<int, 3>>();       // {1, 2, 3} -- elements 4 and 5 silently dropped\nauto p = j.get<std::pair<int, int>>();      // (1, 2)    -- elements 3, 4, and 5 silently dropped\n\njson k = {1};\nauto q = k.get<std::pair<int, int>>();      // \u274c throws out_of_range.401\n

If a size mismatch is an error in your application, check the size yourself before converting.

"},{"location":"features/conversions/#omitting-a-field-when-serializing-stdoptional","title":"Omitting a field when serializing std::optional","text":"

By default, to_json for std::optional<T> writes either the value or null \u2014 there is no built-in way to make a field disappear from the serialized object entirely when the std::optional is std::nullopt. Because a specialization of adl_serializer<std::optional<T>> only controls how the value is converted (it cannot prevent the containing object's to_json from inserting the key in the first place), omission has to be implemented in the containing type's to_json:

struct person {\n    std::string name;\n    std::optional<int> age;\n};\n\nvoid to_json(json& j, const person& p) {\n    j = json{{\"name\", p.name}};\n    if (p.age) {\n        j[\"age\"] = *p.age;  // key is only inserted when the optional has a value\n    }\n}\n
"},{"location":"features/conversions/#putting-values-in","title":"Putting values in","text":"

The reverse direction works the same way: assigning or constructing a json from a C++ value converts it to JSON.

std::vector<int> numbers = {1, 2, 3};\njson j = numbers;   // [1,2,3]\n

Constructing from a C++20 range view

A json array can also be constructed directly from a C++20 range view (std::ranges::view), such as the result of std::views::filter or std::views::transform \u2014 no intermediate container is needed:

std::vector<int> nums{1, 2, 37, 42, 21};\nauto filtered = nums | std::views::filter([](int i) { return i > 10; });\njson j(filtered);   // [37,42,21]\n

This requires JSON_HAS_RANGES to be enabled and is unavailable on MinGW due to incomplete C++20 ranges support there; see JSON_HAS_RANGE_VIEW_CONVERSION.

"},{"location":"features/conversions/#your-own-types","title":"Your own types","text":"

The conversions above are built in for standard types. To make the same syntax work for your own types, provide to_json/from_json functions (or use one of the convenience macros). This is described in detail on the arbitrary types conversions page. Enums can be mapped to strings as described in specializing enum conversion.

"},{"location":"features/conversions/#see-also","title":"See also","text":"
  • get - get a copy converted to a given type
  • get_to - convert into an existing variable
  • get_ref - / get_ptr - access the stored value without copying
  • Arbitrary types conversions - support your own types
  • JSON_USE_IMPLICIT_CONVERSIONS - toggle implicit conversions
  • Zero-copy JSON views - get values out of a document or a view
  • adl_serializer - the default serializer behind the conversions
  • type - query the type of a value
  • JSON_DISABLE_TUPLE_REFERENCE_CONVERSION - toggle conversion to tuples of references
  • JSON_HAS_RANGE_VIEW_CONVERSION - toggle conversion from ranges
"},{"location":"features/creating_values/","title":"Creating JSON values","text":"

There are several ways to create a JSON value in memory. This page gives an overview; to read a value from JSON text instead, see parsing. A JSON text can also be parsed into a document and read through a view instead of into a value; see Zero-copy JSON views.

"},{"location":"features/creating_values/#from-c-values","title":"From C++ values","text":"

Any value of a supported C++ type can be assigned to or used to construct a json:

json j_number  = 42;\njson j_float   = 3.141;\njson j_string  = \"Hello\";\njson j_boolean = true;\njson j_null    = nullptr;\njson j_vector  = std::vector<int>{1, 2, 3};   // array\n

See converting values for the full set of supported types.

"},{"location":"features/creating_values/#with-initializer-lists","title":"With initializer lists","text":"

Objects and arrays can be written concisely with brace-enclosed initializer lists:

// an array\njson array = {1, 2, 3, 4};\n\n// an object (a list of key/value pairs)\njson object = {\n    {\"pi\", 3.141},\n    {\"happy\", true},\n    {\"name\", \"Niels\"},\n    {\"nothing\", nullptr},\n    {\"list\", {1, 0, 2}},\n    {\"object\", {{\"currency\", \"USD\"}, {\"value\", 42.99}}}\n};\n

The library decides between an array and an object based on the content: a list whose elements are all two-element lists with a string as the first element is treated as an object, everything else as an array.

Ambiguous cases: {} vs. []

Because the same {} syntax is used for both arrays and objects, some cases are ambiguous. To force a particular type, use the explicit factory functions json::array and json::object:

json empty_array_explicit = json::array();               // []\njson empty_object_explicit = json::object();             // {}\n\n// a JSON array with one object, not an object with one member\njson array_of_objects = json::array({{\"key\", \"value\"}}); // [{\"key\":\"value\"}]\n

Related to this, single-element brace initialization such as json j{value}; wraps the element in a single-element array by default, and its behavior even differs between compilers. See the FAQ for details and the opt-in JSON_BRACE_INIT_COPY_SEMANTICS macro.

"},{"location":"features/creating_values/#what-does-this-produce","title":"What does this produce?","text":"

The following table shows how some common spellings are interpreted. When in doubt, use json::array(), json::object(), or the json(value) form with parentheses.

code result note json j = {}; / json j{}; null use json::object() or json::array() json j = json::object(); {} json j = json::array(); [] json j(true); true parentheses create the value itself json j = {true}; [true] braces create a one-element array (json j{true}; depends on the compiler, see the FAQ) json j = {{\"a\", 1}}; {\"a\":1} all elements are [string, value] pairs: object json j = {{\"a\", 1}, {\"b\"}}; [[\"a\",1],[\"b\"]] one element is not a pair: array json j = {{\"a\", 1}, 2}; [[\"a\",1],2] a plain value among pairs: array json j = {{\"a\", 1, 2}}; [[\"a\",1,2]] a three-element list is not a pair: array json j = \"{\\\"a\\\":1}\"; \"{\\\"a\\\":1}\" a string value; it is not parsed json j = json::parse(\"{\\\"a\\\":1}\"); {\"a\":1} parse text with parse or _json"},{"location":"features/creating_values/#building-incrementally","title":"Building incrementally","text":"

A value can also be built up piece by piece. Accessing a non-existing object key or array index with operator[] creates the element on the fly:

json j;                    // null\nj[\"answer\"][\"everything\"] = 42;   // becomes an object\nj[\"list\"] = {1, 0, 2};\nj[\"list\"].push_back(3);           // [1,0,2,3]\n

See modifying values for push_back, emplace, and related functions.

"},{"location":"features/creating_values/#with-the-_json-literal","title":"With the _json literal","text":"

The _json user-defined literal parses a string at the call site and is a convenient way to write a JSON value inline:

Example
#include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\nusing namespace nlohmann::literals;\n\nint main()\n{\n    json j = R\"( {\"hello\": \"world\", \"answer\": 42} )\"_json;\n\n    std::cout << std::setw(2) << j << '\\n';\n}\n

Output:

{\n  \"answer\": 42,\n  \"hello\": \"world\"\n}\n

Note this parses the string, so \"42\"_json is the number 42, whereas json(\"42\") is the JSON string \"42\".

"},{"location":"features/creating_values/#see-also","title":"See also","text":"
  • basic_json constructors - all ways to construct a value
  • array - / object - force array or object type
  • operator\"\"_json - the _json literal
  • Converting values - which C++ types can be used
  • Parsing - create a value from JSON text
  • Zero-copy JSON views - create a document and a view from JSON text instead of a value
  • basic_json - the class template and its member functions
  • Types - the JSON value types
  • JSON_BRACE_INIT_COPY_SEMANTICS - change how a single braced value is interpreted
  • operator= - assign a new value
"},{"location":"features/enum_conversion/","title":"Specializing enum conversion","text":"

By default, enum values are serialized to JSON as integers. In some cases, this could result in undesired behavior. If the integer values of any enum values are changed after data using those enum values has been serialized to JSON, then deserializing that JSON would result in a different enum value being restored, or the value not being found at all.

It is possible to more precisely specify how a given enum is mapped to and from JSON as shown below:

// example enum type declaration\nenum TaskState {\n    TS_STOPPED,\n    TS_RUNNING,\n    TS_COMPLETED,\n    TS_INVALID=-1,\n};\n\n// map TaskState values to JSON as strings\nNLOHMANN_JSON_SERIALIZE_ENUM( TaskState, {\n    {TS_INVALID, nullptr},\n    {TS_STOPPED, \"stopped\"},\n    {TS_RUNNING, \"running\"},\n    {TS_COMPLETED, \"completed\"},\n})\n

The NLOHMANN_JSON_SERIALIZE_ENUM() macro declares a set of to_json() / from_json() functions for type TaskState while avoiding repetition and boilerplate serialization code.

"},{"location":"features/enum_conversion/#usage","title":"Usage","text":"

Serialization converts an enum value to its mapped string, deserialization does the reverse, and an unrecognized JSON value deserializes to the first pair in the map:

// enum to JSON as string\njson j = TS_STOPPED;\nassert(j == \"stopped\");\n\n// json string to enum\njson j3 = \"running\";\nassert(j3.get<TaskState>() == TS_RUNNING);\n\n// undefined json value to enum (where the first map entry above is the default)\njson jPi = 3.14;\nassert(jPi.get<TaskState>() == TS_INVALID );\n
Example: serializing/deserializing enums, including a second enum type
#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nnamespace ns\n{\nenum TaskState\n{\n    TS_STOPPED,\n    TS_RUNNING,\n    TS_COMPLETED,\n    TS_INVALID = -1\n};\n\nNLOHMANN_JSON_SERIALIZE_ENUM(TaskState,\n{\n    { TS_INVALID, nullptr },\n    { TS_STOPPED, \"stopped\" },\n    { TS_RUNNING, \"running\" },\n    { TS_COMPLETED, \"completed\" }\n})\n\nenum class Color\n{\n    red, green, blue, unknown\n};\n\nNLOHMANN_JSON_SERIALIZE_ENUM(Color,\n{\n    { Color::unknown, \"unknown\" }, { Color::red, \"red\" },\n    { Color::green, \"green\" }, { Color::blue, \"blue\" }\n})\n} // namespace ns\n\nint main()\n{\n    // serialization\n    json j_stopped = ns::TS_STOPPED;\n    json j_red = ns::Color::red;\n    std::cout << \"ns::TS_STOPPED -> \" << j_stopped\n              << \", ns::Color::red -> \" << j_red << '\\n';\n\n    // deserialization\n    json j_running = \"running\";\n    json j_blue = \"blue\";\n    auto running = j_running.get<ns::TaskState>();\n    auto blue = j_blue.get<ns::Color>();\n    std::cout << j_running << \" -> \" << running\n              << \", \" << j_blue << \" -> \" << static_cast<int>(blue) << '\\n';\n\n    // deserializing undefined JSON value to enum\n    // (where the first map entry above is the default)\n    json j_pi = 3.14;\n    auto invalid = j_pi.get<ns::TaskState>();\n    auto unknown = j_pi.get<ns::Color>();\n    std::cout << j_pi << \" -> \" << invalid << \", \"\n              << j_pi << \" -> \" << static_cast<int>(unknown) << '\\n';\n}\n

Output:

ns::TS_STOPPED -> \"stopped\", ns::Color::red -> \"red\"\n\"running\" -> 1, \"blue\" -> 2\n3.14 -> -1, 3.14 -> 3\n
"},{"location":"features/enum_conversion/#maps-with-enum-keys","title":"Maps with enum keys","text":"

By default, maps with enum keys, such as std::map<TaskState, std::string>, are stored as arrays of [key, value] pairs, because JSON object keys must be strings. Define JSON_USE_OBJECTS_FOR_ENUM_KEYED_MAPS before including the library to store them as objects, with the keys converted by the enum's to_json() function:

std::map<TaskState, std::string> m = {{TS_STOPPED, \"aa\"}, {TS_COMPLETED, \"bb\"}};\n\njson j = m;\n// default:                                   [[\"stopped\",\"aa\"],[\"completed\",\"bb\"]]\n// with JSON_USE_OBJECTS_FOR_ENUM_KEYED_MAPS: {\"completed\":\"bb\",\"stopped\":\"aa\"}\n

Either form can be read back, with or without the macro.

"},{"location":"features/enum_conversion/#notes","title":"Notes","text":"

Just as in Arbitrary Type Conversions above,

  • NLOHMANN_JSON_SERIALIZE_ENUM() MUST be declared in your enum type's namespace (which can be the global namespace), or the library will not be able to locate it, and it will default to integer serialization.
  • It MUST be available (e.g., proper headers must be included) everywhere you use the conversions.

Other Important points:

  • When using get<ENUM_TYPE>(), undefined JSON values will default to the first pair specified in your map. Select this default pair carefully. If you desire an exception in this circumstance use NLOHMANN_JSON_SERIALIZE_ENUM_STRICT() which behaves identically except for throwing an out_of_range.410 exception on unrecognized values, both when serializing an enum value not listed in the map and when deserializing a JSON value that matches none of the map's entries.
  • If an enum or JSON value is specified more than once in your map, the first matching occurrence from the top of the map will be returned when converting to or from JSON.
  • To disable the default serialization of enumerators as integers and force a compiler error instead, see JSON_DISABLE_ENUM_SERIALIZATION.
Example: NLOHMANN_JSON_SERIALIZE_ENUM_STRICT throwing on unrecognized values
#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nnamespace ns\n{\n\nenum class Color\n{\n    red,\n    green,\n    blue,\n    unknown // not mapped in JSON_SERIALIZE_ENUM_STRICT\n};\n\nNLOHMANN_JSON_SERIALIZE_ENUM_STRICT(Color,\n{\n    {Color::red, \"red\"},\n    {Color::green, \"green\"},\n    {Color::blue, \"blue\"}\n})\n\n} // namespace ns\n\n\nint main()\n{\n    // invalid serialization\n    try\n    {\n        // ns::color::unknown was not mapped in macro\n        json invalid_serialization = ns::Color::unknown;\n    }\n    catch (const json::exception e)\n    {\n        std::cout << \"deserialization failed: \" << e.what() << '\\n';\n    }\n\n    // invalid deserialization\n    try\n    {\n        // what does not map to an enum\n        json invalid_deserialization(\"what\");\n        ns::Color color = invalid_deserialization.get<ns::Color>();\n    }\n    catch (const json::exception e)\n    {\n        std::cout << \"deserialization failed: \" << e.what() << '\\n';\n    }\n\n    return 0;\n}\n

Output:

deserialization failed: [json.exception.out_of_range.410] enum value out of range for Color\ndeserialization failed: [json.exception.out_of_range.410] enum value out of range for Color: \"what\"\n
"},{"location":"features/enum_conversion/#see-also","title":"See also","text":"
  • Arbitrary Type Conversions - convert your own types
  • Converting values - the general overview of get/get_to
  • NLOHMANN_JSON_SERIALIZE_ENUM - define the enum-to-JSON mapping
  • NLOHMANN_JSON_SERIALIZE_ENUM_STRICT - throw on unmapped values
  • JSON_DISABLE_ENUM_SERIALIZATION - disable the default enum conversion
  • JSON_USE_OBJECTS_FOR_ENUM_KEYED_MAPS - serialize maps with enum keys as objects
"},{"location":"features/iterators/","title":"Iterators","text":""},{"location":"features/iterators/#overview","title":"Overview","text":"

A basic_json value is a container and allows access via iterators. Depending on the value type, basic_json stores zero or more values.

As for other containers, begin() returns an iterator to the first value and end() returns an iterator to the value following the last value. The latter iterator is a placeholder and cannot be dereferenced. In case of null values, empty arrays, or empty objects, begin() will return end().

A row of fifteen elements followed by a dashed past-the-last position. begin() points to the first element and end() points to the past-the-last position. begin end Past-the-last element

The range of begin() and end(): begin() refers to the first element, end() to the position after the last element, which must not be dereferenced.

"},{"location":"features/iterators/#iteration-order-for-objects","title":"Iteration order for objects","text":"

When iterating over objects, values are ordered with respect to the object_comparator_t type which defaults to std::less. See the types documentation for more information.

Example: iteration order of object values
// create JSON object {\"one\": 1, \"two\": 2, \"three\": 3}\njson j;\nj[\"one\"] = 1;\nj[\"two\"] = 2;\nj[\"three\"] = 3;\n\nfor (auto it = j.begin(); it != j.end(); ++it)\n{\n    std::cout << *it << std::endl;\n}\n

Output:

1\n3\n2\n

The reason for the order is the lexicographic ordering of the object keys \"one\", \"three\", \"two\".

"},{"location":"features/iterators/#access-object-keys-during-iteration","title":"Access object keys during iteration","text":"

The JSON iterators have two member functions, key() and value() to access the object key and stored value, respectively. When calling key() on a non-object iterator, an invalid_iterator.207 exception is thrown.

Example: access object keys with key() and value()
// create JSON object {\"one\": 1, \"two\": 2, \"three\": 3}\njson j;\nj[\"one\"] = 1;\nj[\"two\"] = 2;\nj[\"three\"] = 3;\n\nfor (auto it = j.begin(); it != j.end(); ++it)\n{\n    std::cout << it.key() << \" : \" << it.value() << std::endl;\n}\n

Output:

one : 1\nthree : 3\ntwo : 2\n
"},{"location":"features/iterators/#range-based-for-loops","title":"Range-based for loops","text":"

C++11 allows using range-based for loops to iterate over a container.

for (auto it : j_object)\n{\n    // \"it\" is of type json::reference and has no key() member\n    std::cout << \"value: \" << it << '\\n';\n}\n

For this reason, the items() function allows accessing iterator::key() and iterator::value() during range-based for loops. In these loops, a reference to the JSON values is returned, so there is no access to the underlying iterator.

for (auto& el : j_object.items())\n{\n    std::cout << \"key: \" << el.key() << \", value:\" << el.value() << '\\n';\n}\n

The items() function also allows using structured bindings (C++17):

for (auto& [key, val] : j_object.items())\n{\n    std::cout << \"key: \" << key << \", value:\" << val << '\\n';\n}\n

Note

When iterating over an array, key() will return the index of the element as string. For primitive types (e.g., numbers), key() returns an empty string.

Warning

Using items() on temporary objects is dangerous. Make sure the object's lifetime exceeds the iteration. See #2040 for more information.

"},{"location":"features/iterators/#reverse-iteration-order","title":"Reverse iteration order","text":"

rbegin() and rend() return iterators in the reverse sequence.

Two rows of sixteen cells. The upper row shows the reversed sequence: rend() points to a dashed position before the first element and rbegin() to the last element. The lower row shows the forward sequence: begin() points to the first element and end() to a dashed position after the last element. A reverse iterator stores an iterator to the next element, so rend() corresponds to begin() and rbegin() to end(). rend rbegin Reverse past-the-last element A reverse iterator stores an iterator to the next element begin end Past-the-last element

The range of rbegin() and rend() over the same elements: rbegin() refers to the last element and rend() to the position before the first one. Each reverse iterator stores an iterator to the element after the one it refers to.

Example: reverse iteration with rbegin() and rend()
json j = {1, 2, 3, 4};\n\nfor (auto it = j.rbegin(); it != j.rend(); ++it)\n{\n    std::cout << *it << std::endl;\n}\n

Output:

4\n3\n2\n1\n
"},{"location":"features/iterators/#iterating-strings-and-binary-values","title":"Iterating strings and binary values","text":"

Note that \"value\" means a JSON value in this setting, not values stored in the underlying containers. That is, *begin() returns the complete string or binary array and is also safe if the underlying string or binary array is empty.

Example: iterate over a string value
json j = \"Hello, world\";\nfor (auto it = j.begin(); it != j.end(); ++it)\n{\n    std::cout << *it << std::endl;\n}\n

Output:

\"Hello, world\"\n
"},{"location":"features/iterators/#iterator-invalidation","title":"Iterator invalidation","text":"Operations invalidated iterators clear all"},{"location":"features/iterators/#see-also","title":"See also","text":"
  • begin - / end - iterators to the first and one past the last element
  • rbegin - / rend - reverse iterators
  • cbegin - / cend - const iterators
  • items - iterate over keys and values
  • Object Order - iteration order of object keys
  • Element Access - access single elements
  • Modifying values - add and remove elements (including iterator invalidation rules)
"},{"location":"features/json_patch/","title":"JSON Patch and Diff","text":""},{"location":"features/json_patch/#patches","title":"Patches","text":"

JSON Patch (RFC 6902) defines a JSON document structure for expressing a sequence of operations to apply to a JSON document. Operations address locations in the document using JSON Pointer paths. With the patch function, a JSON Patch is applied to the current JSON value by executing all operations from the patch, yielding the patched document as a new value.

The following steps through one operation of each kind. The first three operations are those of the example below; the other three continue on its result.

Operation Before After {\"op\": \"replace\", \"path\": \"/baz\", \"value\": \"boo\"} {\"baz\": \"qux\", \"foo\": \"bar\"} {\"baz\": \"boo\", \"foo\": \"bar\"} {\"op\": \"add\", \"path\": \"/hello\", \"value\": [\"world\"]} {\"baz\": \"boo\", \"foo\": \"bar\"} {\"baz\": \"boo\", \"foo\": \"bar\", \"hello\": [\"world\"]} {\"op\": \"remove\", \"path\": \"/foo\"} {\"baz\": \"boo\", \"foo\": \"bar\", \"hello\": [\"world\"]} {\"baz\": \"boo\", \"hello\": [\"world\"]} {\"op\": \"move\", \"from\": \"/baz\", \"path\": \"/hello/1\"} {\"baz\": \"boo\", \"hello\": [\"world\"]} {\"hello\": [\"world\", \"boo\"]} {\"op\": \"copy\", \"from\": \"/hello/0\", \"path\": \"/greeting\"} {\"hello\": [\"world\", \"boo\"]} {\"greeting\": \"world\", \"hello\": [\"world\", \"boo\"]} {\"op\": \"test\", \"path\": \"/greeting\", \"value\": \"world\"} {\"greeting\": \"world\", \"hello\": [\"world\", \"boo\"]} unchanged (a failed test throws)

Stepper through the six operations: Next applies the next operation, Back undoes it, and Reset returns to the original document. The current operation is highlighted in the patch list, and the lines it changes are marked in the document.

Applying a patch without copying

patch leaves the original value unchanged and returns the patched result as a copy. If the document is large and the original value is no longer needed, patch_inplace applies the same operations in place instead.

Duplicate member names

Duplicate member names inside an operation object are resolved by the parser before the patch is applied (the last one is kept, see object_t), so {\"op\": \"add\", \"op\": \"remove\", \"path\": \"/a\"} is a remove operation.

Example: apply a JSON Patch

The following code shows how a JSON patch is applied to a value.

#include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\nusing namespace nlohmann::literals;\n\nint main()\n{\n    // the original document\n    json doc = R\"(\n        {\n          \"baz\": \"qux\",\n          \"foo\": \"bar\"\n        }\n    )\"_json;\n\n    // the patch\n    json patch = R\"(\n        [\n          { \"op\": \"replace\", \"path\": \"/baz\", \"value\": \"boo\" },\n          { \"op\": \"add\", \"path\": \"/hello\", \"value\": [\"world\"] },\n          { \"op\": \"remove\", \"path\": \"/foo\"}\n        ]\n    )\"_json;\n\n    // apply the patch\n    json patched_doc = doc.patch(patch);\n\n    // output original and patched document\n    std::cout << std::setw(4) << doc << \"\\n\\n\"\n              << std::setw(4) << patched_doc << '\\n';\n}\n

Output:

{\n    \"baz\": \"qux\",\n    \"foo\": \"bar\"\n}\n\n{\n    \"baz\": \"boo\",\n    \"hello\": [\n        \"world\"\n    ]\n}\n
"},{"location":"features/json_patch/#diff","title":"Diff","text":"

The library can also calculate a JSON patch (i.e., a diff) given two JSON values with the diff function.

flowchart LR\n    S[\"source\"] -->|\"diff(source, target)\"| P[\"patch\"]\n    S -->|\"source.patch(patch)\"| T[\"target\"]\n    P -.->|\"applied to source, yields\"| T

How diff and patch relate: diff(source, target) yields a patch, and applying that patch to the source yields the target.

Invariant

For two JSON values source and target, the following code yields true:

source.patch(diff(source, target)) == target;\n

The equality holds up to operator==, with these exceptions:

  • NaN and discarded values are not equal to themselves, so the invariant cannot hold for them. diff emits a replace operation for such a value, and a NaN in a patch is serialized as null.
  • Numbers that compare equal produce no operation even if their types differ: diff(1, 1.0), diff(1u, 1), and diff(0.0, -0.0) return [], so the patched value keeps the number type of source.
  • A binary value in a patch is serialized as an object ({\"bytes\":[...],\"subtype\":null}), so a patch that was dumped and parsed again no longer holds a binary value.
Example: create a JSON Patch from the difference of two values

The following code shows how a JSON patch is created as a diff for two JSON values.

#include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\nusing namespace nlohmann::literals;\n\nint main()\n{\n    // the source document\n    json source = R\"(\n        {\n            \"baz\": \"qux\",\n            \"foo\": \"bar\"\n        }\n    )\"_json;\n\n    // the target document\n    json target = R\"(\n        {\n            \"baz\": \"boo\",\n            \"hello\": [\n                \"world\"\n            ]\n        }\n    )\"_json;\n\n    // create the patch\n    json patch = json::diff(source, target);\n\n    // roundtrip\n    json patched_source = source.patch(patch);\n\n    // output patch and roundtrip result\n    std::cout << std::setw(4) << patch << \"\\n\\n\"\n              << std::setw(4) << patched_source << '\\n';\n}\n

Output:

[\n    {\n        \"op\": \"replace\",\n        \"path\": \"/baz\",\n        \"value\": \"boo\"\n    },\n    {\n        \"op\": \"remove\",\n        \"path\": \"/foo\"\n    },\n    {\n        \"op\": \"add\",\n        \"path\": \"/hello\",\n        \"value\": [\n            \"world\"\n        ]\n    }\n]\n\n{\n    \"baz\": \"boo\",\n    \"hello\": [\n        \"world\"\n    ]\n}\n
"},{"location":"features/json_patch/#see-also","title":"See also","text":"
  • JSON Pointer - the addressing scheme used for patch paths
  • JSON Merge Patch - a simpler, less expressive alternative patch format
  • patch - apply a JSON Patch, returning the result as a copy
  • patch_inplace - apply a JSON Patch without copying
  • diff - compute a JSON Patch from two values
  • json_pointer - type to represent JSON Pointers
  • merge_diff - compute a JSON Merge Patch from two values
  • Modifying values - simple in-place modifications
"},{"location":"features/json_pointer/","title":"JSON Pointer","text":""},{"location":"features/json_pointer/#introduction","title":"Introduction","text":"

The library supports JSON Pointer (RFC 6901) as an alternative means to address structured values. A JSON Pointer is a string that identifies a specific value within a JSON document.

Consider the following JSON document

{\n    \"array\": [\"A\", \"B\", \"C\"],\n    \"nested\": {\n        \"one\": 1,\n        \"two\": 2,\n        \"three\": [true, false]\n    }\n}\n

Select a pointer (or a node of the tree) to walk it through this document; each segment of the pointer goes one level deeper. The table below lists the same pointers.

Highlighted: the path of the pointer /nested/three/1, which identifies false.

  • root object
    • \"array\" array
      • 0: \"A\"
      • 1: \"B\"
      • 2: \"C\"
    • \"nested\" object
      • \"one\": 1
      • \"two\": 2
      • \"three\" array
        • 0: true
        • 1: false

The highlighted nodes are the path from the root to the selected level, and the line below the tree shows the value the pointer resolves to. Select a segment in the pointer bar to stop at a shallower level, or a node of the tree to select its pointer.

Then every value inside the JSON document can be identified as follows:

JSON Pointer JSON value `` {\"array\":[\"A\",\"B\",\"C\"],\"nested\":{\"one\":1,\"two\":2,\"three\":[true,false]}} /array [\"A\",\"B\",\"C\"] /array/0 A /array/1 B /array/2 C /nested {\"one\":1,\"two\":2,\"three\":[true,false]} /nested/one 1 /nested/two 2 /nested/three [true,false] /nested/three/0 true /nested/three/1 false

Note / does not identify the root (i.e., the whole document), but an object entry with empty key \"\". See RFC 6901 for more information.

RFC 6901, section 4 states that evaluation fails if an object has non-unique member names. A basic_json object holds one value per key (see object_t for how duplicate keys are handled while parsing), so evaluating a JSON Pointer never encounters duplicates.

"},{"location":"features/json_pointer/#json-pointer-creation","title":"JSON Pointer creation","text":"

JSON Pointers can be created from a string:

json::json_pointer p(\"/nested/one\");\n

Furthermore, a user-defined string literal can be used to achieve the same result:

auto p = \"/nested/one\"_json_pointer;\n

The escaping rules of RFC 6901 are implemented. See the constructor documentation for more information.

URI fragment representation

RFC 6901, section 6 also defines a URI fragment identifier representation (#/a%20b). It is not supported: json::json_pointer(\"#/a\") throws parse_error.107. Strip the leading # and percent-decode the remainder before creating the JSON pointer.

"},{"location":"features/json_pointer/#value-access","title":"Value access","text":"

JSON Pointers can be used in the at, operator[], and value functions just like object keys or array indices.

// the JSON value from above\nauto j = json::parse(R\"({\n    \"array\": [\"A\", \"B\", \"C\"],\n    \"nested\": {\n        \"one\": 1,\n        \"two\": 2,\n        \"three\": [true, false]\n    }\n})\");\n\n// access values\nauto val = j[\"\"_json_pointer];                              // {\"array\":[\"A\",\"B\",\"C\"],...}\nauto val1 = j[\"/nested/one\"_json_pointer];                  // 1\nauto val2 = j.at(json::json_pointer(\"/nested/three/1\"));    // false\nauto val3 = j.value(json::json_pointer(\"/nested/four\"), 0); // 0\n

To read a value with a fallback, use value with a JSON Pointer; to test for existence, use contains. Neither needs intermediate checks, see Nested values.

Creating intermediate levels that don't exist

See the operator[] notes for how array vs. object is decided when a pointer creates intermediate levels that don't exist yet.

"},{"location":"features/json_pointer/#flatten-unflatten","title":"Flatten / unflatten","text":"

The library implements a function flatten to convert any JSON document into a JSON object where each key is a JSON Pointer and each value is a primitive JSON value (i.e., a string, boolean, number, or null).

// the JSON value from above\nauto j = json::parse(R\"({\n    \"array\": [\"A\", \"B\", \"C\"],\n    \"nested\": {\n        \"one\": 1,\n        \"two\": 2,\n        \"three\": [true, false]\n    }\n})\");\n\n// create flattened value\nauto j_flat = j.flatten();\n

The resulting value j_flat is:

{\n  \"/array/0\": \"A\",\n  \"/array/1\": \"B\",\n  \"/array/2\": \"C\",\n  \"/nested/one\": 1,\n  \"/nested/two\": 2,\n  \"/nested/three/0\": true,\n  \"/nested/three/1\": false\n}\n

The reverse function, unflatten recreates the original value.

auto j_original = j_flat.unflatten();\n

Each leaf of the document becomes one key of the flat object, and unflatten() reverses the mapping:

flatten() turns the nested example document into a flat object, and unflatten() turns it back. Left, the document as a tree: array with the elements A, B, C, and nested with one = 1, two = 2, and three with the elements true and false. Right, the flat object with one key per leaf: /array/0 = A, /array/1 = B, /array/2 = C, /nested/one = 1, /nested/two = 2, /nested/three/0 = true, /nested/three/1 = false. Each leaf is joined to its key by a line. nested value flat object: key = J\u200bSON Pointer flatten() unflatten() \"/array/0\": \"A\" \"/array/1\": \"B\" \"/array/2\": \"C\" \"/nested/one\": 1 \"/nested/two\": 2 \"/nested/three/0\": true \"/nested/three/1\": false root \"array\" 0: \"A\" 1: \"B\" 2: \"C\" \"nested\" \"one\": 1 \"two\": 2 \"three\" 0: true 1: false

Left: the example document as a tree; right: the flat object it becomes. flatten() converts from left to right, unflatten() from right to left.

"},{"location":"features/json_pointer/#see-also","title":"See also","text":"
  • json_pointer - the JSON Pointer class
  • Nested values - value, contains, and at accept JSON Pointers
  • flatten - convert a value to an object of JSON Pointers and primitive values
  • unflatten - restore a value from a flattened object
  • JSON Patch - paths inside a patch are JSON Pointers
  • JSON Merge Patch - an alternative patch format that does not use JSON Pointer
  • operator\"\"_json_pointer - user-defined literal to create a JSON pointer
  • Element Access - other ways to access elements
"},{"location":"features/json_view/","title":"Zero-copy JSON views","text":"

<nlohmann/json_view.hpp> adds a read-only, non-owning way to look at a parsed JSON text, as an alternative to building a basic_json tree with parse().

"},{"location":"features/json_view/#the-problem","title":"The problem","text":"

basic_json::parse() builds a tree of basic_json values: one allocation for every array and object, and every string copied into its own std::string. That is the right trade-off when the program goes on to read and write the value freely, but it does more work than necessary when only a small part of a large JSON text is actually needed, or when the same text is parsed over and over (many small messages, for instance) and most of the resulting tree is thrown away almost immediately.

"},{"location":"features/json_view/#the-idea","title":"The idea","text":"

basic_json_document::parse() parses the same JSON grammar, with the same options, but instead of a tree it builds a flat index of the values it found: one 16-byte entry per value (and one per object key), in document order. Integers are converted while parsing and stored in their entry. Floating-point numbers and strings are referenced in place in the source text: a float is converted when it is read, and only strings that contain escape sequences are decoded, into one shared buffer owned by the document.

basic_json_view is a small, trivially copyable handle (two pointers) into that index. It gives you the read-only, type-inspection part of the basic_json interface \u2014 type() and the is_*() predicates, size()/empty() \u2014 as well as element access (operator[], at, front/back), lookup (find, contains, count), and iteration (begin/end, items) \u2014 without ever allocating a basic_json value. When you do need an actual basic_json value for a subtree, materialize() builds exactly the one parse() would have produced for it.

The same small text, parsed both ways:

The same J\u200bSON text parsed by basic_json::parse() and by json_document::parse() The text {\"port\": 6379, \"price\": 19.90, \"tags\": [\"eu\", \"a\\\"b\"]}. Top: basic_json::parse() builds a tree: the root json value points to a std::map whose three nodes are separate heap allocations; the price is stored as the double 19.9; the tags array is a std::vector of two json values, each pointing to its own std::string. Bottom: json_document::parse() keeps the 54 bytes of source text and builds a flat index of nine 16-byte nodes in document order: object, key port, unsigned integer 6379 (the converted value is in the node), key price, float, key tags, array, string eu, and an escaped string. Keys, the float, and the plain string point back into the source text; the escaped string points into the document's buffer of decoded strings. A json_view is two pointers: one to the document and one to a node, here the array. basic_json::parse(): a tree, every array, object, and string in its own heap allocation json std::map \"port\" 6379 \"price\" 19.9 double: 19.90 is gone \"tags\" \u2022 std::vector json json std::string eu std::string a\"b a separate heap allocation json_document::parse(): the source text stays where it is; one flat index of 16-byte nodes source text, 54 bytes (borrowed, or owned by the document) { \" p o r t \" : 6 3 7 9 , \" p r i c e \" : 1 9 . 9 0 , \" t a g s \" : [ \" e u \" , \" a \\ \" b \" ] } 0 10 20 30 40 50 json_document: owns the node index and the buffer of decoded strings node index: 9 nodes \u00d7 16 bytes = 144 bytes, in document order 0 object len 3 next 9 1 key off 2 len 4 2 uint 6379 (converted) 3 key off 16 len 5 4 float off 24 len 5 5 key off 32 len 4 6 array len 2 next 3 7 string off 41 len 2 8 string escaped len 3 decoded strings a \" b json_view v = doc.root()[\"tags\"] doc* node* integers are converted while parsing and kept in their node; floats and strings point back into the text

Top: the tree of separate heap allocations that basic_json::parse() builds. Bottom: json_document::parse() keeps the source text and builds one flat index of 16-byte nodes that point back into it, plus a buffer of decoded strings.

"},{"location":"features/json_view/#how-to-use-it","title":"How to use it","text":"

Include <nlohmann/json_view.hpp> in addition to (or instead of) <nlohmann/json.hpp>. Parse into a json_document, inspect its root(), and materialize() when you need a real value. materialize() works on any view, not just the root, so you can turn just the subtree you need into a value:

Example: parse a document, inspect its root, and materialize it
#include <iostream>\n#include <nlohmann/json_view.hpp>\n\nusing nlohmann::json_document;\n\nint main()\n{\n    std::cout << std::boolalpha;\n\n    // json_document is basic_json_document<nlohmann::json>: same value types\n    // and containers as the ordinary json specialization\n    json_document doc = json_document::parse(R\"({\"pi\": 3.14, \"numbers\": [1, 2, 3]})\");\n\n    std::cout << doc.root().is_object() << '\\n';\n    std::cout << doc.root().materialize().dump() << '\\n';\n}\n

Output:

true\n{\"numbers\":[1,2,3],\"pi\":3.14}\n

ordered_json_document is the equivalent for ordered_json, just as ordered_json is to json.

"},{"location":"features/json_view/#ownership-and-lifetime","title":"Ownership and lifetime","text":"

A document either borrows the text it was parsed from, or owns its own copy of it; call owns_source() to find out which happened. parse() decides this from the value category and type of its argument (an lvalue std::string is borrowed; an rvalue std::string is moved in, owned without a copy; a stream is read into an owned buffer; and so on \u2014 see parse's Notes for the full table). parse_copy() always owns a copy, regardless of the input.

A borrowed document depends on your buffer

If a document borrows its text, that text must outlive the document (and every view taken from it) and must stay unmodified for as long as the document exists, since floating-point values and unescaped strings are read from it lazily. Reading or writing through a view after the underlying buffer is gone is undefined behavior, exactly as it would be for a dangling std::string_view.

A view is valid only while all of the following hold:

  • the document is alive,
  • the document has not been re-parsed since the view was taken (with read() or parse() into it),
  • the document has not had shrink_to_fit() called on it since, and
  • if the document borrows its source text, that text is still alive and unmodified.

Moving the basic_json_document<> itself is fine and does not invalidate its views: the index is a separate heap allocation that keeps its address across the move. Take a fresh view from root() whenever any of the other conditions above was not met.

When a json_view becomes invalid Four timelines. First: a document borrows a std::string; when the string is destroyed, the document and every view taken from it dangle. Second: doc.read() re-parses the document; views taken before are invalid, a fresh view from root() is valid. Third: doc.shrink_to_fit() has the same effect. Fourth: moving the document does not invalidate its views; destroying the moved-to document does. alive / valid dangling: using it is undefined behavior time \u2192 The borrowed text is destroyed std::string text json_document doc json_view v text destroyed every view, and the document itself The document is re-parsed json_document doc json_view v v = doc.root() doc.read(other) views taken before a fresh view is valid again The document is shrunk json_document doc json_view v v = doc.root() doc.shrink_to_fit() views taken before a fresh view is valid again The document is moved, then destroyed json_document doc moved = std::move(doc) json_view v std::move: views stay valid moved is destroyed

Four timelines of a document and its views, each bar showing when an object is alive or valid and when it dangles. Destroying the borrowed text, re-parsing, or shrinking the document invalidates the views taken before; moving the document does not.

A view can dangle, exactly like a std::string_view: nothing stops you from using it after its document is gone. This is deliberate. A view is two pointers and trivially copyable; making it safe (a std::shared_ptr in the document and a std::weak_ptr in each view) would make it larger, add reference counting to every copy, and a lock() to every access \u2014 exactly the costs the view exists to avoid. What is caught is the obvious case: because a view dies with its document, root() is not callable on a temporary document: auto v = json_document::parse(text).root(); does not compile. Give the document a name first.

Example: borrowed and owned documents, and when views become invalid
#include <iostream>\n#include <string>\n#include <utility>\n#include <nlohmann/json_view.hpp>\n\nusing nlohmann::json_document;\n\nint main()\n{\n    std::cout << std::boolalpha;\n\n    // BORROWED: doc only points into `text`; `text` must outlive `doc`\n    std::string text = R\"({\"a\": 1})\";\n    json_document doc = json_document::parse(text);\n    std::cout << doc.owns_source() << '\\n'; // false\n\n    // a view is valid as long as the document is alive, has not been\n    // re-parsed (read()) or shrunk (shrink_to_fit()), and -- if borrowed --\n    // the source text is alive\n    nlohmann::json_view v = doc.root();\n    std::cout << v.is_object() << '\\n';\n\n    // re-parsing the SAME document invalidates views taken before the call;\n    // `v` above must not be used after this line\n    doc.read(R\"([1, 2, 3])\");\n    v = doc.root(); // take a fresh view instead\n    std::cout << v.is_array() << '\\n';\n\n    // moving the document does not invalidate views: the node index is\n    // heap-allocated and does not move with the document object\n    json_document moved = std::move(doc);\n    std::cout << v.is_array() << '\\n';\n}\n

Output:

false\ntrue\ntrue\ntrue\n
"},{"location":"features/json_view/#what-is-the-same-as-parse","title":"What is the same as parse()","text":"
  • Accept/reject. accept() and parse() accept and reject exactly the same inputs as basic_json::accept()/basic_json::parse(), with the same ignore_comments and ignore_trailing_commas options.
  • Errors. A failing parse throws the same exception \u2014 the same id, message, and position \u2014 because on failure the library's own parser is run on the same bytes to produce the diagnostic. Valid input never pays for this, and the replay builds no values: it costs about a lexing pass up to the error. allow_exceptions == false skips the replay and gives a discarded document instead of throwing, just as it gives a discarded value for basic_json::parse().
  • Number classification. An integer literal that does not fit into the 64-bit integer type becomes a floating-point value, exactly as it does for basic_json::parse().
  • Macros. JSON_STRICT_NUL_HANDLING and JSON_NOEXCEPTION/JSON_THROW_USER behave the same way they do for <nlohmann/json.hpp>. These are the macros that change what the parser accepts or how it reports errors. The others either do not apply (JSON_DIAGNOSTICS needs parent pointers in basic_json values) or only affect the values materialize() produces, through BasicJsonType.
"},{"location":"features/json_view/#what-is-different","title":"What is different","text":"
  • Only 64-bit integers. basic_json_document<BasicJsonType> requires BasicJsonType::number_integer_t and number_unsigned_t to both be 64 bits wide; this is a compile-time static_assert.
  • A 4 GiB input limit. An input of 4294967280 bytes (4 GiB minus 16 bytes) or more throws out_of_range.416, a limit basic_json::parse() does not have. It keeps an index entry at 16 bytes: offsets and counts are 32 bits wide. The limit is 16 bytes below 2^32, because the parser reads in 16-byte steps, and a position one step past the end must still fit.
  • A stream is always read to its end. There is no partial/streaming read of an std::istream: the stream is read to its end into a buffer the document owns, and parsing starts after that.
  • No source positions on materialize(). Even with JSON_DIAGNOSTIC_POSITIONS enabled, materialize() does not set them. The index has the start offset of every value, but not the end of arrays, objects, and escaped strings, which the positions also need.
  • Objects iterate in document order. begin()/ end() and items() visit an object's members in the order they appear in the source text. basic_json's default object_t is a std::map, which sorts by key, so iterating a materialize()d value can print members in a different order than iterating the view they came from.
  • Chained access is safe. operator[] with a missing key, an index out of range, or an unresolvable JSON pointer returns a discarded view, and operator[] on a discarded view returns a discarded view without throwing: v[\"a\"][\"b\"][0] can be tested once at the end. Type errors on values that exist (a key on an array, an index on an object) still throw, and at throws for every missing value.
  • Duplicate keys: lookups find the first member, parse() keeps the last. See Duplicate keys below.
  • No JSON_DIAGNOSTICS path. Exceptions thrown by basic_json_view's own element access and lookup functions never carry the JSON Pointer path JSON_DIAGNOSTICS would otherwise add: the view has no basic_json value to point at, so the exception is created without one, regardless of how BasicJsonType was built.
  • Ordering comparisons are not provided by basic_json_view \u2014 there is no operator<. operator== and operator!= are provided, though: two views, or a view and a BasicJsonType value, compare equal exactly when materialize() or parse() would produce equal values for them, without ever building a tree to do it. For ordering, too, materialize() is the way to get a value you can compare.
"},{"location":"features/json_view/#duplicate-keys","title":"Duplicate keys","text":"

A lookup in a view and in the parsed value can give different answers

If an object in the source text repeats a key, operator[], at, find, value, contains, and JSON pointer resolution all return the first member with that key. basic_json::parse() instead keeps the last value of a repeated key, so for {\"a\":1,\"a\":2}, view[\"a\"] is 1 while parse(text)[\"a\"] is 2. count counts every member with the key, so it is 2 here.

begin()/end() and items() visit every occurrence, in document order, and size() counts all of them, so view.size() can be larger than view.materialize().size().

Why the first? A lookup can stop as soon as it finds a match. Returning the last member would force every lookup to scan all members of the object, even when the key is found at the very first one: this made lookups in small objects 1.6 to 3.4 times slower. The hash index of the keys of objects with 128 members or more leads to the first member of a key as well. Other zero-copy parsers that index the source text, such as yyjson and simdjson, also return the first member. RFC 8259 only says that names within an object SHOULD be unique and that the behavior of a receiver that sees duplicates is unpredictable, so neither choice is wrong.

The same holds for get<T>() of a type whose from_json() reads the view, such as the types of the NLOHMANN_DEFINE_TYPE_* macros: their members are looked up, so get<point>() of {\"x\":1,\"x\":2} reads x == 1, while materialize().get<point>() reads 2.

What stays the same as parse()? materialize() and get<std::map<...>>() replay every member in order, so they keep the last value exactly like basic_json::parse() (at the position of the first occurrence of the key, for an ordered_json).

How do I get the value parse() would give? Either call view.materialize() and look the key up in the result, or iterate the members and keep the last match:

// the last member with the key \"a\", as parse() would keep it\njson_view last;\nfor (const auto item : view.items())\n{\n    if (item.key() == \"a\")\n    {\n        last = item.value();\n    }\n}\n

If you cannot trust the source text to have unique keys, check size() against the number of distinct keys, or reject duplicates when iterating.

"},{"location":"features/json_view/#getting-values-out-without-copying","title":"Getting values out without copying","text":"

get<T>() converts most T directly from the flat index, without ever building a basic_json value for the conversion: bool, arithmetic types, std::nullptr_t, std::string/other std::basic_strings (copied once), basic_json_view itself, the standard containers and other types the library converts (std::vector, std::map, std::list, std::array, std::pair, std::tuple, std::optional, ...), and the types of the NLOHMANN_DEFINE_TYPE_* and NLOHMANN_JSON_SERIALIZE_ENUM macros. Types whose from_json() is written for basic_json only go through materialize().get<T>() instead: the subtree is built into a real basic_json value first, exactly as parse() would, and converted from there. See Writing generic code for how to write a from_json() that reads views.

Two conversions never copy at all:

  • get_string() (equivalently, get<string_view_t>()) returns a string as a string_view_t pointing into the document's source() text \u2014 or, for a string that contains escape sequences, into the document's own buffer of decoded strings \u2014 instead of allocating a new std::string.
  • number_token() returns a number exactly as it was written in the source, e.g. \"1.50\", \"1E2\", or an integer with more digits than any number type holds, instead of rounding it into a double/int64_t the way get<T>() (and basic_json::parse()) would.

Both results are only valid as long as the view \u2014 and, for a string with no escapes, the borrowed source text \u2014 is.

"},{"location":"features/json_view/#writing-generic-code","title":"Writing generic code","text":"

A view's type names its BasicJsonType and its view_mode: json_view is basic_json_view<json, view_mode::read_only>, and json_editable_view is basic_json_view<json, view_mode::editable>. These are different types. The only conversion between them turns a view of a read-only document into a view of an editable document of the same BasicJsonType, so a function written for one shortcut accepts few other views:

void print_names(json_view v);           // accepts neither an ordered_json_view nor a json_editable_view\nvoid print_names(json_editable_view v);  // also accepts a json_view, but no ordered_json_view\n

This is the same pitfall as a to_json/from_json written for json instead of any BasicJsonType, which then does not work for ordered_json. The shortcuts are for declaring documents and views; a function that takes a view names the views it accepts with a template:

// views of editable documents only\ntemplate<typename BasicJsonType>\nvoid f(basic_json_view<BasicJsonType, view_mode::editable> v);\n\n// views of read-only documents only\ntemplate<typename BasicJsonType>\nvoid f(basic_json_view<BasicJsonType, view_mode::read_only> v);\n\n// views of either document type\ntemplate<typename BasicJsonType, view_mode Mode>\nvoid f(basic_json_view<BasicJsonType, Mode> v);\n

Views are passed by value: they are two pointers, cheap to copy, like a std::string_view. A const& works as well, but a non-const reference does not bind to the views that root(), operator[], and at() return, so f(doc.root()) would not compile.

There is no conversion from an editable view to a read-only one, by design: the mode decides how a view walks the index. A read-only view reads a container in place, while a view of an editable document follows the links that edits leave behind, so a read-only view of an edited document would read stale values. The other direction is safe: a read-only document has no edits, so a view of it converts to an editable view, which reads it like an editable document before its first edit. A template deduces the mode without conversions, so the template forms above still accept only the modes they name. Views of both modes compare with operator==.

is_json_view<T> tells views from other types, for constraints that cannot be written as a basic_json_view<...> parameter.

"},{"location":"features/json_view/#a-from_json-that-reads-views","title":"A from_json() that reads views","text":"

get<T>() on a view calls T's from_json() with the view itself if that from_json() accepts views, and with materialize() otherwise. The from_json() functions of the NLOHMANN_DEFINE_TYPE_*, NLOHMANN_DEFINE_DERIVED_TYPE_*, and NLOHMANN_JSON_SERIALIZE_ENUM macros, and those of the library for the standard types, accept views, so these types need nothing else. For decoding the statuses of twitter.json into structs, reading the view is about 5 times faster than materialize().get<T>().

A hand-written from_json() reads views if it is constrained to json values and views:

template < typename J, typename std::enable_if <\n               nlohmann::is_json_view<J>::value || std::is_same<J, nlohmann::json>::value, int >::type = 0 >\nvoid from_json(const J& j, person& p)\n{\n    p.name = j.at(\"name\").template get<std::string>();\n    p.age = j.at(\"age\").template get<int>();\n}\n

Its body may only use what views and basic_json have in common: the type checks, at(), operator[], contains(), value(), size(), iteration and items(), and get<T>()/get_to(). An unconstrained template<typename BasicJsonType> void from_json(const BasicJsonType& j, person& p), as in arbitrary type conversions, is never called with a view, as it might use basic_json functions a view does not have; such a type is converted through materialize(). A from_json() for json only is converted through materialize() as well.

Two things differ when a from_json() reads the view:

  • Duplicate keys. Members looked up by name (at(), value(), ... and thus the macros) find the first member with a repeated key, see Duplicate keys; materialize().get<T>() would see the last one. Containers built from an object, such as std::map, keep the last value either way, as parse() does.
  • JSON_DIAGNOSTICS. Exceptions thrown by the view carry no path to the value.

to_json() is unaffected: it writes basic_json values, never views.

"},{"location":"features/json_view/#writing-a-view-back","title":"Writing a view back","text":"

dump() serializes a view directly from the flat index, without ever building a basic_json value. An object's members are written in document order, not sorted by key, and every occurrence of a repeated key is written, not only the last one \u2014 the same two ways iteration already differs from a materialize()d value, see Duplicate keys. materialize().dump() gives a different result in both respects for a json_view.

By default, numbers are written the way basic_json::dump() would. number_format::source instead copies every number exactly as it was written in the source text \u2014 a price like 19.90, a long order or account ID with more digits than any number type holds, or a high-precision coordinate \u2014 something basic_json cannot do at all, since parsing already reduces a number to its parsed double/int64_t value.

operator<< writes a view to a stream the way basic_json's does, using the stream's width/fill for indentation.

"},{"location":"features/json_view/#editing-a-document","title":"Editing a document","text":"

Everything above is read-only: a json_document/json_view lets you look at a parsed text without copying it, but not change it. basic_json_document<BasicJsonType, view_mode::editable> \u2014 more conveniently spelled json_editable_document or ordered_json_editable_document \u2014 also lets you set a value, push_back onto or insert into an array, and erase an object member or an array element, still without ever building a basic_json tree for parts you do not touch.

The mode defaults to view_mode::read_only, so json_document/ordered_json_document are unaffected \u2014 they carry none of the bookkeeping edits need, and calling set/push_back/insert/erase on one is a compile error, not a runtime one.

"},{"location":"features/json_view/#why-editing-without-reformatting","title":"Why: editing without reformatting","text":"

The 19.90 price from above is exactly the kind of value that makes editing a json or ordered_json value in place lossy. Say you parse a configuration file, patch one field, and write it back:

  • json re-sorts every key on the way in (object_t is a std::map) and rewrites every number to its shortest round-trip form on the way out \u2014 a one-field patch turns into a diff that reorders the whole file and rewrites 19.90 to 19.9.
  • ordered_json keeps the key order, but still rewrites every number the same way: parsing has already reduced it to a double/int64_t, and there is no way back to how it was spelled in the source text.

The patch of the example below (set \"host\", add \"retries\") written back by each of them:

json

keys sorted, numbers rewritten

{\"host\":\"db2\",\n \"name\":\"cache\",\n \"port\":6379,\n \"price\":19.9,\n \"retries\":3}

ordered_json

key order kept, numbers rewritten

{\"name\":\"cache\",\n \"host\":\"db2\",\n \"port\":6379,\n \"price\":19.9,\n \"retries\":3}

json_editable_document

order and spelling kept

{\"name\":\"cache\",\n \"host\":\"db2\",\n \"port\":6379,\n \"price\":19.90,\n \"retries\":3}

An editable document keeps both. dump() of an edited document writes members in document order \u2014 a member set added goes at the end, exactly where it was inserted, and an erased member simply leaves a gap: everything around it keeps its place \u2014 and number_format::source keeps the exact spelling of every number an edit did not itself touch; a number an edit did touch is written the way BasicJsonType::dump() would write it, since there is no source spelling for a brand new value.

Example: patch a configuration, keeping member order and number spellings
#include <iostream>\n#include <nlohmann/json_view.hpp>\n\nusing nlohmann::json;\nusing nlohmann::json_editable_document;\nusing nlohmann::json_editable_view;\n\nint main()\n{\n    // a configuration file, as it might be read from disk\n    const std::string text = R\"({\"name\": \"cache\", \"host\": \"db1\", \"port\": 6379, \"price\": 19.90})\";\n    std::cout << text << \"\\n\\n\";\n\n    // patch two fields -- \"price\" is never touched\n    json_editable_document doc = json_editable_document::parse(text);\n    doc.set(doc.root(), \"host\", \"db2\");\n    doc.set(doc.root(), \"retries\", 3);\n\n    // member order (the new member at the end) and the untouched number's\n    // exact spelling survive\n    std::cout << doc.root().dump(-1, ' ', false, json_editable_view::number_format::source) << '\\n';\n\n    // the same patch on a plain json value: keys are sorted (object_t is a\n    // std::map), and \"price\" is rewritten even though the patch never\n    // touched it\n    json plain = json::parse(text);\n    plain[\"host\"] = \"db2\";\n    plain[\"retries\"] = 3;\n    std::cout << plain.dump() << '\\n';\n}\n

Output:

{\"name\": \"cache\", \"host\": \"db1\", \"port\": 6379, \"price\": 19.90}\n\n{\"name\":\"cache\",\"host\":\"db2\",\"port\":6379,\"price\":19.90,\"retries\":3}\n{\"host\":\"db2\",\"name\":\"cache\",\"port\":6379,\"price\":19.9,\"retries\":3}\n
"},{"location":"features/json_view/#what-stays-valid-and-what-an-edit-costs","title":"What stays valid, and what an edit costs","text":"

The source text itself is never written, and the parsed index never moves \u2014 a value keeps the node it was parsed into for as long as it is not itself replaced. So every view taken before an edit, including a previously obtained root(), stays valid and, if it still refers to the edited value, sees the edit; a view of a value a later edit drops or replaces just keeps showing what it last held. New values go to storage the document allocates and owns on demand. The one thing an edit does invalidate is the iterators taken over an edited array or object: the first time an element is added to it, inserted into it, erased from it, or replaced by a value that spans a different number of nodes, its elements move from the parsed, fixed layout to a growable block of links so that push_back can later grow it in amortized constant time \u2014 existing elements are not touched, but an iterator that was walking the old layout no longer matches. A string obtained with get_string() is unaffected either way and stays valid across further edits. See basic_json_document's Edits for the details, and set's Exception safety for what an edit guarantees if it throws (the basic guarantee, not the strong one dump() and the read-only functions provide). How edits are kept in the index is described in the architecture overview.

Step through the edits of a small document (the node fields follow the architecture overview):

Step 1 of 5: parsed After parse: nine nodes, nothing owned yet. The dump with number_format::source is {\"port\":6379,\"price\":19.90,\"tags\":[\"eu\",\"a\\\"b\"]}. parsed index: fixed, never moves the source text is never written 0 object { } 3 1 key port 2 uint 6379 3 key price 4 float 19.90 5 key tags 6 array [ ] 2 7 string \"eu\" 8 string a\"b owned storage: allocated on demand, never moves empty: a read-only json_document has none of this view v = root()[\"tags\"] (taken after parse): valid, sees every edit iterator over tags (taken after parse): valid dump(): {\"port\":6379,\"price\":19.90,\"tags\":[\"eu\",\"a\\\"b\"]} Step 1 of 5. After parsing: nine nodes in the parsed index, no owned storage yet. Step 2 of 5: doc.set(doc.root(), \"port\", 6380) set: the node of the integer is overwritten in place. The dump with number_format::source is {\"port\":6380,\"price\":19.90,\"tags\":[\"eu\",\"a\\\"b\"]}. parsed index: fixed, never moves the source text is never written 0 object { } 3 1 key port 2 uint 6380 3 key price 4 float 19.90 5 key tags 6 array [ ] 2 7 string \"eu\" 8 string a\"b owned storage: allocated on demand, never moves empty: a read-only json_document has none of this view v = root()[\"tags\"] (taken after parse): valid, sees every edit iterator over tags (taken after parse): valid dump(): {\"port\":6380,\"price\":19.90,\"tags\":[\"eu\",\"a\\\"b\"]} Step 2 of 5. doc.set(doc.root(), \"port\", 6380) overwrites the node of the integer in place; no member is added or removed, so the object keeps its parsed layout. Step 3 of 5: doc.erase(doc.root()[\"tags\"], 0) erase: the array moves to a block of links in owned storage. The dump with number_format::source is {\"port\":6380,\"price\":19.90,\"tags\":[\"a\\\"b\"]}. parsed index: fixed, never moves the source text is never written 0 object { } 3 1 key port 2 uint 6380 3 key price 4 float 19.90 5 key tags 6 array moved [ ] 2 7 string \"eu\" unreferenced 8 string a\"b owned storage: allocated on demand, never moves 0' header [ ] 1 1' link \u2192 8 free view v = root()[\"tags\"] (taken after parse): valid, sees every edit iterator over tags (taken after parse): invalid: tags no longer uses the parsed layout dump(): {\"port\":6380,\"price\":19.90,\"tags\":[\"a\\\"b\"]} Step 3 of 5. doc.erase(doc.root()[\"tags\"], 0): the array is edited for the first time, so its elements move to a block of links in owned storage. The node of \"eu\" stays in the index, but nothing refers to it any more; iterators over the array taken before are invalid. Step 4 of 5: doc.push_back(doc.root()[\"tags\"], \"new\") push_back: a new node, and a link appended to the block. The dump with number_format::source is {\"port\":6380,\"price\":19.90,\"tags\":[\"a\\\"b\",\"new\"]}. parsed index: fixed, never moves the source text is never written 0 object { } 3 1 key port 2 uint 6380 3 key price 4 float 19.90 5 key tags 6 array moved [ ] 2 7 string \"eu\" unreferenced 8 string a\"b owned storage: allocated on demand, never moves 0' header [ ] 2 1' link \u2192 8 2' link \u2192 3' 3' string \"new\" edited text new view v = root()[\"tags\"] (taken after parse): valid, sees every edit iterator over tags (taken after parse): invalid: tags no longer uses the parsed layout dump(): {\"port\":6380,\"price\":19.90,\"tags\":[\"a\\\"b\",\"new\"]} Step 4 of 5. doc.push_back(doc.root()[\"tags\"], \"new\"): the new string gets its own node, its text goes to the buffer of edited text, and a link to it is appended to the block of the array. Step 5 of 5: doc.set(doc.root(), \"retries\", 3) set of a new member: the object moves to a block as well. The dump with number_format::source is {\"port\":6380,\"price\":19.90,\"tags\":[\"a\\\"b\",\"new\"],\"retries\":3}. parsed index: fixed, never moves the source text is never written 0 object moved { } 3 1 key port 2 uint 6380 3 key price 4 float 19.90 5 key tags 6 array moved [ ] 2 7 string \"eu\" unreferenced 8 string a\"b owned storage: allocated on demand, never moves 0' header [ ] 2 1' link \u2192 8 2' link \u2192 3' 3' string \"new\" 4' uint 3 5' header { } 4 6' key port 7' link \u2192 2 8' key price 9' link \u2192 4 10' key tags 11' link \u2192 6 12' key retries 13' link \u2192 4' edited text newretries view v = root()[\"tags\"] (taken after parse): valid, sees every edit iterator over tags (taken after parse): invalid: tags no longer uses the parsed layout dump(): {\"port\":6380,\"price\":19.90,\"tags\":[\"a\\\"b\",\"new\"],\"retries\":3} Step 5 of 5. doc.set(doc.root(), \"retries\", 3): a new member, so the object moves to a block too: copies of its keys, links to the values it already had, then the new key and a link to the new integer.

The node index and the owned storage of the document after each of five edits. Use Back, Next, or the numbered buttons to switch between the steps; without JavaScript all steps are shown one below the other.

"},{"location":"features/json_view/#images","title":"Images","text":"

save() writes a document as an image: a byte buffer that load() reads back into a document without parsing \u2014 no lexing, no building the node index, nothing but copying the nodes and pointing the text and the decoded strings at the image. Where parse_copy() still has to scan the whole input, load() turns that scan into a copy of the node index alone.

Why. A document that is parsed once and then read many times \u2014 a configuration loaded at startup, a template rendered on every request, a large reference dataset a worker process needs in memory \u2014 pays for parsing once but can amortize save()'s cost across every later load. That makes images useful for a cache: save a document the first time it is parsed (to a file, a shared-memory segment, an in-process cache), and load() it on every later use instead of parsing the source text again. They are just as useful for handing a parsed document to another process (or a forked worker) running the same build of the library, since load() turns the transfer into a copy of the node index plus pointers into the received bytes, not a re-parse.

Choosing a check. load() takes an image_check that trades validation against speed: image_check::full (the default) checks everything the parser itself guarantees, so a checked image is exactly as safe to read and serialize as a freshly parsed document \u2014 the right choice whenever the image did not come straight from this process's own save(), such as a file or a network peer. image_check::bounds only checks structure and bounds \u2014 cheaper, since it skips scanning the text and the decoded strings \u2014 and fits a cache the process trusts, one it wrote and reads back itself. image_check::none skips validation entirely, for an image trusted as much as the process's own memory. See load()'s Notes for exactly what each level does and does not guarantee.

Example: cache a parsed configuration as an image
#include <cstdint>\n#include <iostream>\n#include <string>\n#include <vector>\n#include <nlohmann/json_view.hpp>\n\nusing nlohmann::json_document;\n\nint main()\n{\n    std::cout << std::boolalpha;\n\n    // a configuration a service parses once and then caches as an image, so\n    // that later requests can load() it instead of parsing the text again\n    const std::string text = R\"({\"name\": \"cache\", \"host\": \"db1\", \"port\": 6379, \"replicas\": [\"db2\", \"db3\"]})\";\n    const json_document config = json_document::parse(text);\n\n    // save() turns the parsed document into a byte buffer: a 64-byte header,\n    // the node index, the source text, and the decoded strings\n    const std::vector<std::uint8_t> image = config.save();\n    std::cout << image.size() << '\\n';\n\n    // the same document always saves to the same bytes\n    std::cout << (image == json_document::parse(text).save()) << '\\n';\n\n    // loading the image back needs no parsing, yet dumps exactly what\n    // parsing the text produced\n    const json_document reloaded = json_document::load(image);\n    std::cout << (reloaded.root().dump() == config.root().dump()) << '\\n';\n}\n

Output:

316\ntrue\ntrue\n

Experimental

The image format is versioned but not yet stable, and may change in an incompatible way before it is declared stable. It is little-endian only (on big-endian targets, save() and load() do not exist), and tied to the library build that wrote it \u2014 use it to cache a document or to hand one to another process running the same build, not as a long-term storage format; keep the original JSON text if a saved document needs to be readable by a future library version.

The idea of a document you can read without parsing comes from zero-copy formats such as FlatBuffers and YaFF; the check load() runs follows the idea of FlatBuffers' Verifier. No code is taken from either.

"},{"location":"features/json_view/#choosing-between-json-ordered_json-the-sax-interface-and-json_view","title":"Choosing between json, ordered_json, the SAX interface, and json_view","text":"json / ordered_json SAX interface json_document / json_view json_editable_document / json_editable_view Ownership owns every value owns nothing; you decide what to keep, in your handler borrows or owns the text; the index is always owned by the document same as json_document; edits go to storage the document owns Mutability freely mutable not applicable (a one-shot event stream) read-only set/push_back/insert/erase edit in place; the source text is never rewritten What you get a full tree you can read, write, and keep as long as you like a sequence of callbacks; whatever your handler builds from them a flat index plus, on demand, materialize()d json/ordered_json values for the parts you actually use the same, plus dump() of an edited document that keeps the member order and, with number_format::source, the spelling of every untouched number Typical use general-purpose JSON handling: config, request/response bodies you build or modify, anything you hold onto validating or projecting a text into your own data structure without ever holding the whole thing as JSON large or high-volume input where you only need part of it, or need it repeatedly, and can keep the source text (or a copy) alive for as long as the document lives a document you read, patch a few fields of, and write back \u2014 a configuration file, for instance \u2014 where the rest of it should come back exactly as it was Caching/reload not applicable \u2014 re-parse, or roll your own serialization not applicable save()/load(): cache the parsed index as an image and reload it without parsing same, saving the document's current \u2014 possibly edited \u2014 state

Each column is one way to work with JSON in this library, and each row compares one property of them.

"},{"location":"features/json_view/#see-also","title":"See also","text":"
  • basic_json_document - the document that owns the parsed index (parse, access, images, edits)
  • basic_json_view - the non-owning handle to a value in a document
  • json_document - and ordered_json_document - the read-only documents
  • json_editable_document - and ordered_json_editable_document - the documents that can be edited in place
  • Architecture - the layout of the node index
  • SAX interface - event-based parsing without building a tree
  • Performance - benchmarks and tuning of parsing and serialization
  • Large, Streamed, and Partial Input - reading only the part of a text you need
"},{"location":"features/json_view/#version-history","title":"Version history","text":"
  • Added in version 3.13.0 unreleased.
"},{"location":"features/macros/","title":"Supported Macros","text":"

Some aspects of the library can be configured by defining preprocessor macros before including the json.hpp header. See also the API documentation for macros for examples and more information.

"},{"location":"features/macros/#json_assertx","title":"JSON_ASSERT(x)","text":"

This macro controls which code is executed for runtime assertions of the library.

See full documentation of JSON_ASSERT(x).

"},{"location":"features/macros/#json_brace_init_copy_semantics","title":"JSON_BRACE_INIT_COPY_SEMANTICS","text":"

When defined to 1, single-element brace initialization of a basic_json value (e.g., json j{value};) is treated as a copy/move of the element rather than wrapping it in a single-element array. The default value is 0, which preserves the existing behavior.

See full documentation of JSON_BRACE_INIT_COPY_SEMANTICS.

"},{"location":"features/macros/#json_catch_userexception","title":"JSON_CATCH_USER(exception)","text":"

This macro overrides catch calls inside the library.

See full documentation of JSON_CATCH_USER(exception).

"},{"location":"features/macros/#json_delete_deprecated_functions","title":"JSON_DELETE_DEPRECATED_FUNCTIONS","text":"

When defined to 1, all deprecated functions are declared as deleted instead of only being marked as deprecated, so code that still calls them no longer compiles. This way, you can find all calls that need to be replaced before version 4.0.0 removes these functions.

The macro can also be set with the CMake option JSON_DeleteDeprecatedFunctions (OFF by default).

See full documentation of JSON_DELETE_DEPRECATED_FUNCTIONS.

"},{"location":"features/macros/#json_diagnostics","title":"JSON_DIAGNOSTICS","text":"

This macro enables extended diagnostics for exception messages. Possible values are 1 to enable or 0 to disable (default).

When enabled, exception messages contain a JSON Pointer to the JSON value that triggered the exception, see Extended diagnostic messages for an example. Note that enabling this macro increases the size of every JSON value by one pointer and adds some runtime overhead.

The diagnostics messages can also be controlled with the CMake option JSON_Diagnostics (OFF by default) which sets JSON_DIAGNOSTICS accordingly.

See full documentation of JSON_DIAGNOSTICS.

"},{"location":"features/macros/#json_diagnostic_positions","title":"JSON_DIAGNOSTIC_POSITIONS","text":"

When enabled, two new member functions start_pos() and end_pos() are added to basic_json values. If the value was created by calling theparse function, then these functions allow querying the byte positions of the value in the input it was parsed from. The byte positions are also used in exceptions to help locate errors.

The diagnostics positions can also be controlled with the CMake option JSON_Diagnostic_Positions (OFF by default) which sets JSON_DIAGNOSTIC_POSITIONS accordingly.

See full documentation of JSON_DIAGNOSTIC_POSITIONS

"},{"location":"features/macros/#json_has_cpp_11-json_has_cpp_14-json_has_cpp_17-json_has_cpp_20-json_has_cpp_23-json_has_cpp_26","title":"JSON_HAS_CPP_11, JSON_HAS_CPP_14, JSON_HAS_CPP_17, JSON_HAS_CPP_20, JSON_HAS_CPP_23, JSON_HAS_CPP_26","text":"

The library targets C++11, but also supports some features introduced in later C++ versions (e.g., std::string_view support for C++17). For these new features, the library implements some preprocessor checks to determine the C++ standard. By defining any of these symbols, the internal check is overridden and the provided C++ version is unconditionally assumed. This can be helpful for compilers that only implement parts of the standard and would be detected incorrectly.

See full documentation of JSON_HAS_CPP_11, JSON_HAS_CPP_14, JSON_HAS_CPP_17, JSON_HAS_CPP_20, JSON_HAS_CPP_23, and JSON_HAS_CPP_26.

"},{"location":"features/macros/#json_has_filesystem-json_has_experimental_filesystem","title":"JSON_HAS_FILESYSTEM, JSON_HAS_EXPERIMENTAL_FILESYSTEM","text":"

When compiling with C++17, the library provides conversions from and to std::filesystem::path. As compiler support for filesystem is limited, the library tries to detect whether <filesystem>/std::filesystem (JSON_HAS_FILESYSTEM) or <experimental/filesystem>/std::experimental::filesystem (JSON_HAS_EXPERIMENTAL_FILESYSTEM) should be used. To override the built-in check, define JSON_HAS_FILESYSTEM or JSON_HAS_EXPERIMENTAL_FILESYSTEM to 1.

See full documentation of JSON_HAS_FILESYSTEM and JSON_HAS_EXPERIMENTAL_FILESYSTEM.

"},{"location":"features/macros/#json_has_ranges","title":"JSON_HAS_RANGES","text":"

The library uses std::ranges (and concepts) where available, for example, to parse from C++20 ranges and to construct JSON arrays from range views. The library detects whether the standard library supports ranges and disables the support on toolchains with an incomplete implementation. To override the built-in check, define JSON_HAS_RANGES to 1 or 0.

See full documentation of JSON_HAS_RANGES.

"},{"location":"features/macros/#json_has_range_view_conversion","title":"JSON_HAS_RANGE_VIEW_CONVERSION","text":"

When JSON_HAS_RANGES is enabled (and the compiler is not MinGW), a JSON array can be constructed directly from a C++20 range view such as std::views::filter(...). To override the built-in check, define JSON_HAS_RANGE_VIEW_CONVERSION to 1 or 0.

See full documentation of JSON_HAS_RANGE_VIEW_CONVERSION.

"},{"location":"features/macros/#json_has_static_rtti","title":"JSON_HAS_STATIC_RTTI","text":"

The library detects whether the compiler supports run time type information (RTTI), which it needs, for instance, to exclude std::any from the candidate types of the implicit conversion on C++17. To override the built-in check, define JSON_HAS_STATIC_RTTI to 1 or 0.

See full documentation of JSON_HAS_STATIC_RTTI.

"},{"location":"features/macros/#json_has_std_format","title":"JSON_HAS_STD_FORMAT","text":"

When compiling with C++20 and a standard library that provides <format>, the library provides a std::formatter specialization for JSON values. To override the built-in check, define JSON_HAS_STD_FORMAT to 1 or 0.

See full documentation of JSON_HAS_STD_FORMAT.

"},{"location":"features/macros/#json_has_three_way_comparison","title":"JSON_HAS_THREE_WAY_COMPARISON","text":"

When the compiler and standard library support 3-way comparison (the spaceship operator <=>), the library provides it for JSON values. To override the built-in check, define JSON_HAS_THREE_WAY_COMPARISON to 1 or 0.

See full documentation of JSON_HAS_THREE_WAY_COMPARISON.

"},{"location":"features/macros/#json_noexception","title":"JSON_NOEXCEPTION","text":"

Exceptions can be switched off by defining the symbol JSON_NOEXCEPTION.

See full documentation of JSON_NOEXCEPTION.

"},{"location":"features/macros/#json_disable_enum_serialization","title":"JSON_DISABLE_ENUM_SERIALIZATION","text":"

When defined, default parse and serialize functions for enums are excluded and have to be provided by the user, for example, using NLOHMANN_JSON_SERIALIZE_ENUM.

See full documentation of JSON_DISABLE_ENUM_SERIALIZATION.

"},{"location":"features/macros/#json_disable_stream_bulk_scan","title":"JSON_DISABLE_STREAM_BULK_SCAN","text":"

When defined to 1, parsing from a std::istream reads one character at a time instead of scanning the characters that the stream buffer holds in bulk. Results are the same either way; the macro is an escape hatch for stream buffers that do not follow the usual std::streambuf contract. The default value is 0.

See full documentation of JSON_DISABLE_STREAM_BULK_SCAN.

"},{"location":"features/macros/#json_disable_tuple_reference_conversion","title":"JSON_DISABLE_TUPLE_REFERENCE_CONVERSION","text":"

When defined to 1, a JSON value can no longer be created from a one-element std::tuple holding a reference to a JSON value, such as the result of std::forward_as_tuple(j). This lets std::tuple convert such tuples element-wise. This is planned to become the default in version 4.0.0.

See full documentation of JSON_DISABLE_TUPLE_REFERENCE_CONVERSION.

"},{"location":"features/macros/#json_disable_unlocked_file_io","title":"JSON_DISABLE_UNLOCKED_FILE_IO","text":"

When defined to 1, parsing from a FILE* reads every character with std::fgetc, which locks the file each time, instead of locking the file once and reading it with the unlocked stdio functions. Results are the same either way. The default value is 0.

See full documentation of JSON_DISABLE_UNLOCKED_FILE_IO.

"},{"location":"features/macros/#json_no_automatic_udls","title":"JSON_NO_AUTOMATIC_UDLS","text":"

When defined, <nlohmann/json.hpp> does not include <nlohmann/json_literals.hpp> with the user-defined string literals operator\"\"_json and operator\"\"_json_pointer. This reduces the compile time of translation units that do not use them, because the literals instantiate the parser in every translation unit that includes them. Include <nlohmann/json_literals.hpp> where the literals are needed.

See full documentation of JSON_NO_AUTOMATIC_UDLS.

"},{"location":"features/macros/#json_no_io","title":"JSON_NO_IO","text":"

When defined, headers <cstdio>, <ios>, <iosfwd>, <istream>, and <ostream> are not included and parse functions relying on these headers are excluded. This is relevant for environment where these I/O functions are disallowed for security reasons (e.g., Intel Software Guard Extensions (SGX)).

See full documentation of JSON_NO_IO.

"},{"location":"features/macros/#json_no_simd","title":"JSON_NO_SIMD","text":"

When defined, the library uses only portable code instead of vector instructions (SSE2, SSSE3, NEON) for scanning strings and writing floating-point numbers. Results are the same either way. It is not defined by default.

See full documentation of JSON_NO_SIMD.

"},{"location":"features/macros/#json_no_thread_local","title":"JSON_NO_THREAD_LOCAL","text":"

When defined, the library does not use thread_local storage. Copying a value and comparing two values then always avoid the call stack rather than descending into a bounded number of levels first, which is slower but yields the same values and the same comparisons.

See full documentation of JSON_NO_THREAD_LOCAL.

"},{"location":"features/macros/#json_precise_stream_position","title":"JSON_PRECISE_STREAM_POSITION","text":"

When defined to 1, operator>> and non-strict sax_parse leave an input stream positioned right after the parsed value, instead of also consuming the character that terminates a number. The default value is 0, which preserves the existing behavior; this is planned to become the default in version 4.0.0.

See full documentation of JSON_PRECISE_STREAM_POSITION.

"},{"location":"features/macros/#json_skip_library_version_check","title":"JSON_SKIP_LIBRARY_VERSION_CHECK","text":"

When defined, the library will not create a compiler warning when a different version of the library was already included.

See full documentation of JSON_SKIP_LIBRARY_VERSION_CHECK.

"},{"location":"features/macros/#json_skip_unsupported_compiler_check","title":"JSON_SKIP_UNSUPPORTED_COMPILER_CHECK","text":"

When defined, the library will not create a compile error when a known unsupported compiler is detected. This allows using the library with compilers that do not fully support C++11 and may only work if unsupported features are not used.

See full documentation of JSON_SKIP_UNSUPPORTED_COMPILER_CHECK.

"},{"location":"features/macros/#json_strict_binary_utf8","title":"JSON_STRICT_BINARY_UTF8","text":"

When defined to 1, to_cbor, to_ubjson, to_bjdata, and to_bson throw type_error.316 for a string value or object key that is not valid UTF-8. The default value is 0, which writes the bytes unchanged as before version 3.13.0 unreleased; this is planned to become the default in version 4.0.0.

The check can also be enabled with the CMake option JSON_StrictBinaryUTF8 (OFF by default) which sets JSON_STRICT_BINARY_UTF8 accordingly.

See full documentation of JSON_STRICT_BINARY_UTF8.

"},{"location":"features/macros/#json_strict_nul_handling","title":"JSON_STRICT_NUL_HANDLING","text":"

When defined to 1, a '\\0' (NUL) byte anywhere in the input is rejected with parse_error.101, like any other unexpected byte, instead of being silently treated as end of input (see the FAQ entry for background). The default value is 0, which preserves the existing behavior; this is planned to become the default in version 4.0.0.

The strict handling can also be enabled with the CMake option JSON_StrictNulHandling (OFF by default) which sets JSON_STRICT_NUL_HANDLING accordingly.

See full documentation of JSON_STRICT_NUL_HANDLING.

"},{"location":"features/macros/#json_throw_userexception","title":"JSON_THROW_USER(exception)","text":"

This macro overrides throw calls inside the library. The argument is the exception to be thrown.

See full documentation of JSON_THROW_USER(exception).

"},{"location":"features/macros/#json_try_user","title":"JSON_TRY_USER","text":"

This macro overrides try calls inside the library.

See full documentation of JSON_TRY_USER.

"},{"location":"features/macros/#json_use_implicit_conversions","title":"JSON_USE_IMPLICIT_CONVERSIONS","text":"

When defined to 0, implicit conversions are switched off. By default, implicit conversions are switched on.

See full documentation of JSON_USE_IMPLICIT_CONVERSIONS.

"},{"location":"features/macros/#json_use_global_udls","title":"JSON_USE_GLOBAL_UDLS","text":"

When defined to 1 (default), the user-defined string literals operator\"\"_json and operator\"\"_json_pointer are placed into the global namespace instead of nlohmann::literals::json_literals.

See full documentation of JSON_USE_GLOBAL_UDLS.

"},{"location":"features/macros/#json_use_legacy_discarded_value_comparison","title":"JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON","text":"

When defined to 1, the library restores the legacy behavior in which comparing a discarded value with <= or >= yields true instead of false. This behavior is deprecated and switched off (0) by default.

See full documentation of JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON.

"},{"location":"features/macros/#json_use_objects_for_enum_keyed_maps","title":"JSON_USE_OBJECTS_FOR_ENUM_KEYED_MAPS","text":"

When defined to 1, maps with enum keys (e.g., std::map<E, T>) are stored as objects, using the enum's conversion for the keys, instead of arrays of [key, value] pairs. It is switched off (0) by default.

See full documentation of JSON_USE_OBJECTS_FOR_ENUM_KEYED_MAPS.

"},{"location":"features/macros/#json_use_simdutf","title":"JSON_USE_SIMDUTF","text":"

When defined, UTF-8 validation of JSON strings read from contiguous byte input is delegated to the simdutf library instead of the built-in scalar validator. This is an opt-in external dependency and is not defined by default.

See full documentation of JSON_USE_SIMDUTF.

"},{"location":"features/macros/#nlohmann_define_type_-nlohmann_define_derived_type_","title":"NLOHMANN_DEFINE_TYPE_*(...), NLOHMANN_DEFINE_DERIVED_TYPE_*(...)","text":"

The library defines 12 macros to simplify the serialization/deserialization of types. See the page on arbitrary type conversion for a detailed discussion.

"},{"location":"features/macros/#nlohmann_json_namespace-nlohmann_json_namespace_begin-nlohmann_json_namespace_end-nlohmann_json_namespace_no_version","title":"NLOHMANN_JSON_NAMESPACE, NLOHMANN_JSON_NAMESPACE_BEGIN, NLOHMANN_JSON_NAMESPACE_END, NLOHMANN_JSON_NAMESPACE_NO_VERSION","text":"

These macros relate to the versioned, inline nlohmann namespace:

  • NLOHMANN_JSON_NAMESPACE evaluates to the full name of the nlohmann namespace (including the inline ABI namespace).
  • NLOHMANN_JSON_NAMESPACE_BEGIN / NLOHMANN_JSON_NAMESPACE_END open and close the namespace (for example, to add specializations).
  • NLOHMANN_JSON_NAMESPACE_NO_VERSION, when defined to 1, omits the version component from the inline namespace.

See the nlohmann Namespace page, and the full documentation of NLOHMANN_JSON_NAMESPACE, NLOHMANN_JSON_NAMESPACE_BEGIN / NLOHMANN_JSON_NAMESPACE_END, and NLOHMANN_JSON_NAMESPACE_NO_VERSION.

"},{"location":"features/macros/#nlohmann_json_serialize_enumtype","title":"NLOHMANN_JSON_SERIALIZE_ENUM(type, ...)","text":"

This macro simplifies the serialization/deserialization of enum types. See Specializing enum conversion for more information.

See full documentation of NLOHMANN_JSON_SERIALIZE_ENUM.

A strict variant NLOHMANN_JSON_SERIALIZE_ENUM_STRICT throws an exception on undefined input instead of falling back to the first mapping.

"},{"location":"features/macros/#nlohmann_json_version_major-nlohmann_json_version_minor-nlohmann_json_version_patch","title":"NLOHMANN_JSON_VERSION_MAJOR, NLOHMANN_JSON_VERSION_MINOR, NLOHMANN_JSON_VERSION_PATCH","text":"

These macros are defined by the library and contain the version numbers according to Semantic Versioning 2.0.0.

See full documentation of NLOHMANN_JSON_VERSION_MAJOR, NLOHMANN_JSON_VERSION_MINOR, and NLOHMANN_JSON_VERSION_PATCH.

"},{"location":"features/macros/#see-also","title":"See also","text":"
  • Macros - reference of all macros
  • Runtime Assertions - runtime assertions in detail
  • nlohmann Namespace - the library namespace and its macros
  • Working Without Exceptions - using the library without exceptions
  • Modules - macros and C++20 modules
  • Exceptions - all exceptions and their error codes
  • CMake - set macros via CMake options
  • Compile times - reduce compile times with macros
  • Architecture - how the library is put together
  • Specializing enum conversion - enum macros
  • Arbitrary Type Conversions - type conversion macros
"},{"location":"features/merge_patch/","title":"JSON Merge Patch","text":"

The library supports JSON Merge Patch (RFC 7396) as a patch format. The merge patch format is primarily intended for use with the HTTP PATCH method as a means of describing a set of modifications to a target resource's content. Applying a merge patch changes the JSON value the patch is applied to.

Instead of using JSON Pointer to specify values to be manipulated, it describes the changes using a syntax that closely mimics the document being modified. Unlike JSON Patch, a JSON Merge Patch cannot express every kind of change (e.g., it cannot reorder array elements or remove a specific array element), but it is easier to read and write for object-shaped documents.

The function merge_diff creates a merge patch that changes one JSON value into another.

The example below applies one patch to one document. Here is the document before:

{\n    \"title\": \"Goodbye!\",\n    \"author\": {\n        \"givenName\": \"John\",\n        \"familyName\": \"Doe\"\n    },\n    \"tags\": [\"example\", \"sample\"],\n    \"content\": \"This will be unchanged\"\n}\n

This is the patch:

{\n    \"title\": \"Hello!\",\n    \"phoneNumber\": \"+01-123-456-7890\",\n    \"author\": {\n        \"familyName\": null\n    },\n    \"tags\": [\"example\"]\n}\n

And this is the document after applying it:

{\n    \"title\": \"Hello!\",\n    \"author\": {\n        \"givenName\": \"John\"\n    },\n    \"tags\": [\"example\"],\n    \"content\": \"This will be unchanged\",\n    \"phoneNumber\": \"+01-123-456-7890\"\n}\n

The table goes through the members one by one. \"Member\" is the name of an object member in the patch (and in the document); it is not a JSON Pointer and nothing of it is passed to the function: the whole patch is passed to merge_patch.

Rule Member Before Patch After change value title \"Goodbye!\" \"Hello!\" \"Hello!\" add key phoneNumber (no member) \"+01-123-456-7890\" \"+01-123-456-7890\" object merges recursively author {\"givenName\": \"John\", \"familyName\": \"Doe\"} {\"familyName\": null} {\"givenName\": \"John\"} null removes key familyName inside author \"Doe\" null (removed) array replaced whole tags [\"example\", \"sample\"] [\"example\"] [\"example\"] unchanged key content \"This will be unchanged\" (no member) \"This will be unchanged\"

An array in the patch replaces the array in the target, so a merge patch cannot change a single element. Each member of the patch is applied like this; a patch that is not an object replaces the whole target.

flowchart LR\n    M[\"member of the patch\"] --> N{{\"value null?\"}}\n    N -->|yes| D[\"delete the key\"]\n    N -->|no| O{{\"value an object?\"}}\n    O -->|yes| R[\"merge recursively into the target's value\"]\n    O -->|no| S[\"set the key to the value\"]

How one member of a merge patch is applied: a null value deletes the key, an object is merged recursively, and any other value replaces the value of the key.

Not a general deep merge

A merge patch is not a general deep merge: a null value in the patch deletes the key from the target. To merge two objects recursively (e.g., defaults and user settings), use update with merge_objects set to true; see Merging objects.

Limitations of RFC 7396

  • A patch cannot set a member to null, because null removes the member: {\"a\":1} patched with {\"a\":null} gives {}.
  • Arrays are replaced as a whole, never merged, and a null inside an array is kept.
  • null members of the target that the patch does not mention are preserved.
  • A null that would remove a member of a not yet existing object still creates that object: {} patched with {\"a\":{\"b\":null}} gives {\"a\":{}}.
  • A patch that is not an object replaces the whole target (a null patch makes the target null); an object patch applied to a non-object target starts from an empty object.
  • merge_diff has a matching limitation for null members.
Example

The following code shows how a JSON Merge Patch is applied to a JSON document.

#include <iostream>\n#include <nlohmann/json.hpp>\n#include <iomanip> // for std::setw\n\nusing nlohmann::json;\nusing namespace nlohmann::literals;\n\nint main()\n{\n    // the original document\n    json document = R\"({\n                \"title\": \"Goodbye!\",\n                \"author\": {\n                    \"givenName\": \"John\",\n                    \"familyName\": \"Doe\"\n                },\n                \"tags\": [\n                    \"example\",\n                    \"sample\"\n                ],\n                \"content\": \"This will be unchanged\"\n            })\"_json;\n\n    // the patch\n    json patch = R\"({\n                \"title\": \"Hello!\",\n                \"phoneNumber\": \"+01-123-456-7890\",\n                \"author\": {\n                    \"familyName\": null\n                },\n                \"tags\": [\n                    \"example\"\n                ]\n            })\"_json;\n\n    // apply the patch\n    document.merge_patch(patch);\n\n    // output original and patched document\n    std::cout << std::setw(4) << document << '\\n';\n}\n

Output:

{\n    \"author\": {\n        \"givenName\": \"John\"\n    },\n    \"content\": \"This will be unchanged\",\n    \"phoneNumber\": \"+01-123-456-7890\",\n    \"tags\": [\n        \"example\"\n    ],\n    \"title\": \"Hello!\"\n}\n
"},{"location":"features/merge_patch/#see-also","title":"See also","text":"
  • JSON Patch and Diff - a more expressive alternative that describes a sequence of operations
  • JSON Pointer - the addressing scheme used by JSON Patch
  • merge_patch - apply a JSON Merge Patch to a value
  • merge_diff - create a JSON Merge Patch from two values
  • Function update - merge objects, optionally recursively
  • Modifying values - simple in-place modifications
"},{"location":"features/modifying_values/","title":"Modifying values","text":"

Once a JSON value exists, its content can be changed: elements can be added, replaced, merged, and removed. This page gives an overview of the available operations. For read access, see element access.

"},{"location":"features/modifying_values/#adding-to-arrays","title":"Adding to arrays","text":"

New elements are appended to an array with push_back or constructed in place with emplace_back. If the value is null, it is converted to an array first, so these functions can also be used to build an array from scratch.

json j;                 // null\nj.push_back(1);         // [1]\nj.push_back(2);         // [1,2]\nj.emplace_back(3);      // [1,2,3]\n\n// operator+= is a shorthand for push_back\nj += 4;                 // [1,2,3,4]\n
"},{"location":"features/modifying_values/#adding-to-objects","title":"Adding to objects","text":"

The most common way to add or replace a member is operator[], which inserts the key if it does not exist yet:

json j;\nj[\"name\"] = \"Mary\";     // {\"name\":\"Mary\"}\nj[\"name\"] = \"John\";     // {\"name\":\"John\"}  (replaced)\n

emplace inserts a member only if the key is not already present, and reports whether the insertion happened \u2014 useful for \"add if absent\" semantics.

"},{"location":"features/modifying_values/#merging-objects","title":"Merging objects","text":"

To merge one object into another, update copies all members from another object (similar to Python's dict.update). This is the idiomatic way to combine two objects. It has two modes:

  • By default, the merge is shallow: existing keys are overwritten, even if both values are objects.
  • With merge_objects = #!cpp true, keys whose values are objects in both JSON values are merged recursively. Everything else is overwritten. In particular, arrays are replaced, not concatenated.
Example
#include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\nusing namespace nlohmann::literals;\n\nint main()\n{\n    // create two JSON objects\n    json o1 = R\"( {\"color\": \"red\", \"price\": 17.99, \"names\": {\"de\": \"Flugzeug\"}} )\"_json;\n    json o2 = R\"( {\"color\": \"blue\", \"speed\": 100, \"names\": {\"en\": \"plane\"}} )\"_json;\n    json o3 = o1;\n\n    // add all keys from o2 to o1 (updating \"color\", replacing \"names\")\n    o1.update(o2);\n\n    // add all keys from o2 to o1 (updating \"color\", merging \"names\")\n    o3.update(o2, true);\n\n    // output updated object o1 and o3\n    std::cout << std::setw(2) << o1 << '\\n';\n    std::cout << std::setw(2) << o3 << '\\n';\n}\n

Output:

{\n  \"color\": \"blue\",\n  \"names\": {\n    \"en\": \"plane\"\n  },\n  \"price\": 17.99,\n  \"speed\": 100\n}\n{\n  \"color\": \"blue\",\n  \"names\": {\n    \"de\": \"Flugzeug\",\n    \"en\": \"plane\"\n  },\n  \"price\": 17.99,\n  \"speed\": 100\n}\n

A common use of the recursive mode is combining defaults with user settings. Nested defaults that the user did not set are kept:

json defaults = {{\"log\", {{\"level\", \"info\"}, {\"file\", \"app.log\"}}}, {\"retries\", 3}};\njson user_settings = {{\"log\", {{\"level\", \"debug\"}}}};\n\njson config = defaults;\nconfig.update(user_settings, true);\n// {\"log\":{\"file\":\"app.log\",\"level\":\"debug\"},\"retries\":3}\n

JSON Merge Patch (RFC 7396) also merges objects recursively, but it is a different tool: a null in the patch means \"remove this key\". It is meant for applying merge patch documents (e.g., received via HTTP PATCH). To merge configuration-like objects, use update(..., true). To apply a sequence of well-defined edit operations, see JSON Patch.

"},{"location":"features/modifying_values/#removing-elements","title":"Removing elements","text":"

Elements are removed with erase, which accepts an object key, an array index, or an iterator. clear empties a value while keeping its type, and operator[] combined with assignment can overwrite a value entirely.

json j = {{\"a\", 1}, {\"b\", 2}, {\"c\", 3}};\nj.erase(\"b\");           // {\"a\":1,\"c\":3}\n\njson a = {1, 2, 3, 4};\na.erase(1);             // [1,3,4]  (erase by index)\n
"},{"location":"features/modifying_values/#editing-a-document","title":"Editing a document","text":"

The operations above work on a basic_json value. A JSON text that was parsed into a document can also be changed in place, without building a basic_json tree for the parts that are not touched: set replaces a value, adds or replaces an object member, or replaces an array element (also through a JSON pointer), push_back appends to an array, insert inserts into an array (unlike basic_json::insert, it has no object overload; members are added with set), and erase removes a member or an element. These functions are available on the editable document types, such as json_editable_document.

"},{"location":"features/modifying_values/#see-also","title":"See also","text":"
  • push_back - / emplace_back - append to an array
  • emplace - insert into an object if the key is absent
  • update - merge objects (shallow, or recursive with merge_objects)
  • merge_patch - apply an RFC 7396 merge patch
  • erase - / clear - remove elements
  • JSON Patch and Diff - and JSON Merge Patch - structured modifications
  • Editing a document - change a parsed document in place
  • insert - insert elements at an iterator position or merge a range
  • operator+= - shorthand for push_back
  • Element Access - read elements
  • Iterators - iterate over elements
"},{"location":"features/modules/","title":"Modules","text":"

This library has experimental support for C++ modules, introduced in C++20. The library can be imported by writing import nlohmann.json; instead of #include <nlohmann/json.hpp>.

Please be aware that the module is experimental and a full test is outstanding, and the exported symbols are subject to change.

Importing the module instead of including the header reduces the compile time of every translation unit that uses the library, at the price of building the module once. The Compile times page has measurements and the one-off cost.

"},{"location":"features/modules/#requirements","title":"Requirements","text":"

The nlohmann.json module requires that the build system is configured to build and resolve modules when imported. Obviously, as modules were introduced in C++20, this feature can only be used in C++20 and subsequent versions.

To enable building the nlohmann.json module (which is not done by default), the macro NLOHMANN_JSON_BUILD_MODULES must be passed to the build system.

"},{"location":"features/modules/#example","title":"Example","text":"

When using modules rather than headers, the previous example for creating a json object through a JSON file, would instead be:

import std;\nimport nlohmann.json;\n\nusing nlohmann::json;\n\n// ...\n\nstd::ifstream f(\"example.json\");\njson data = json::parse(f);\n

"},{"location":"features/modules/#modules-do-not-export-macros","title":"Modules do not export macros","text":"

It should be noted that as modules do not export macros, the nlohmann.json module will not export any macros.

"},{"location":"features/modules/#exported-symbols","title":"Exported symbols","text":"

Only the following symbols are exported from nlohmann.json:

  • nlohmann::adl_serializer
  • nlohmann::basic_json
  • nlohmann::basic_json_document
  • nlohmann::basic_json_view
  • nlohmann::json
  • nlohmann::json_document
  • nlohmann::json_pointer
  • nlohmann::json_view
  • nlohmann::ordered_json
  • nlohmann::ordered_json_document
  • nlohmann::ordered_json_view
  • nlohmann::ordered_map
  • nlohmann::to_string
  • nlohmann::literals::json_literals::operator\"\"_json
  • nlohmann::literals::json_literals::operator\"\"_json_pointer

The module always exports the two user-defined string literals, even if JSON_NO_AUTOMATIC_UDLS is defined when building it.

Additionally, the following nlohmann::detail symbols are exported, solely to work around an MSVC compilation issue (#3970). They are implementation details, not part of the public API, and should not be used directly:

  • nlohmann::detail::json_sax_dom_callback_parser
  • nlohmann::detail::unknown_size
"},{"location":"features/modules/#known-issues","title":"Known issues","text":"

C++20 modules support is exercised in CI against current GCC and Clang on Ubuntu, and the default MSVC toolset on Windows Server 2022 \u2014 there is no documented minimum compiler version, unlike feature-test-macro-gated features such as JSON_HAS_RANGES.

Known compiler issues

  • GCC may emit \"redefinition\" errors when #include <nlohmann/json.hpp> appears in a module preamble together with other imports. This is an upstream GCC bug, not yet resolved as of GCC 16. Workarounds: include nlohmann/json.hpp before other #includes, use import nlohmann.json; instead, or upgrade GCC. (issue #5103)
  • MSVC could fail with C2039: 'json_sax_dom_callback_parser' is not a member of ... detail; fixed by exporting the required internal symbols from json.cppm (see Exported symbols above). (issue #3970)

If you hit a different module-related build failure, search existing issues before filing a new one.

"},{"location":"features/modules/#see-also","title":"See also","text":"
  • Supported Macros - macros are not exported by modules
  • Macros - reference of all macros
  • nlohmann Namespace - the library namespace
  • CMake - enable the module build in CMake
  • Compile times - reduce compile times
  • basic_json - the main class and all its member functions
"},{"location":"features/namespace/","title":"nlohmann Namespace","text":"

The 3.11.0 release introduced an inline namespace to allow different parts of a codebase to safely use different versions of the JSON library as long as they never exchange instances of library types.

"},{"location":"features/namespace/#structure","title":"Structure","text":"

The complete default namespace name is derived as follows:

  • The root namespace is always nlohmann.
  • The inline namespace starts with json_abi and is followed by several optional ABI tags according to the value of these ABI-affecting macros, in order:
    • JSON_DIAGNOSTICS defined non-zero appends _diag.
    • JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON defined non-zero appends _ldvcmp.
    • JSON_DIAGNOSTIC_POSITIONS defined non-zero appends _dp.
    • JSON_BRACE_INIT_COPY_SEMANTICS defined non-zero appends _bics.
    • JSON_PRECISE_STREAM_POSITION defined non-zero appends _psp.
    • JSON_STRICT_NUL_HANDLING defined non-zero appends _snul.
    • JSON_STRICT_BINARY_UTF8 defined non-zero appends _sbu8.
    • JSON_USE_OBJECTS_FOR_ENUM_KEYED_MAPS defined non-zero appends _ekmo.
    • JSON_DISABLE_STREAM_BULK_SCAN defined non-zero appends _dsbs.
    • JSON_DISABLE_UNLOCKED_FILE_IO defined non-zero appends _dufio.
    • JSON_NO_SIMD defined appends _ns.
  • The inline namespace ends with the suffix _v followed by the 3 components of the version number separated by underscores. To omit the version component, see Disabling the version component below.

For example, the namespace name for version 3.11.2 with JSON_DIAGNOSTICS defined to 1 is:

nlohmann::json_abi_diag_v3_11_2\n

The name is assembled from these segments; pick a version and macros to see the resulting name:

nlohmannroot namespace :: json_abialways _diagJSON_DIAGNOSTICS=1 _v3_11_2version 3.11.2 Version 3.11.2 with JSON_DIAGNOSTICS defined to 1. ABI tags are appended in the order of the list above, the version suffix comes last.

The name of the inline namespace, assembled from its segments. Select a version and macros to see which ABI tags appear; a tag the chosen version does not have is disabled.

"},{"location":"features/namespace/#purpose","title":"Purpose","text":"

Several incompatibilities have been observed. Amongst the most common ones is linking code compiled with different definitions of JSON_DIAGNOSTICS. This is illustrated in the diagram below.

graph\n    json[\"<strong>nlohmann_json (v3.10.5)</strong><br>JSON_DIAGNOSTICS=0\"]\n    json_diag[\"<strong>nlohmann_json (v3.10.5)</strong><br>JSON_DIAGNOSTICS=1\"]\n    library[\"<strong>some library</strong>\"]\n    app[\"<strong>application</strong>\"]\n\n    library --> json\n    app --> json_diag\n    app --> library

The application uses the library with JSON_DIAGNOSTICS=1 and links some library, which uses the same library version with JSON_DIAGNOSTICS=0. Arrows point from a component to what it uses.

In releases prior to 3.11.0, mixing any version of the JSON library with different JSON_DIAGNOSTICS settings would result in a crashing application. If some_library never passes instances of JSON library types to the application, this scenario became safe in version 3.11.0 and above due to the inline namespace yielding distinct symbol names.

"},{"location":"features/namespace/#limitations","title":"Limitations","text":"

Neither the compiler nor the linker will issue as much as a warning when translation units \u2013 intended to be linked together and that include different versions and/or configurations of the JSON library \u2013 exchange and use library types.

There is an exception when forward declarations are used (i.e., when including json_fwd.hpp) in which case the linker may complain about undefined references.

"},{"location":"features/namespace/#disabling-the-version-component","title":"Disabling the version component","text":"

Different versions are not necessarily ABI-incompatible, but the project does not actively track changes in the ABI and recommends that all parts of a codebase exchanging library types be built with the same version. Users can, at their own risk, disable the version component of the inline namespace, allowing different versions \u2013 but not configurations \u2013 to be used in cases where the linker would otherwise output undefined reference errors.

To do so, define NLOHMANN_JSON_NAMESPACE_NO_VERSION to 1.

This applies to version 3.11.2 and above only; versions 3.11.0 and 3.11.1 can apply the technique described in the next section to emulate the effect of the NLOHMANN_JSON_NAMESPACE_NO_VERSION macro.

Use at your own risk

Disabling the namespace version component and mixing ABI-incompatible versions will result in crashes or incorrect behavior. You have been warned!

"},{"location":"features/namespace/#disabling-the-inline-namespace-completely","title":"Disabling the inline namespace completely","text":"

When interoperability with code using a pre-3.11.0 version of the library is required, users can, at their own risk restore the old namespace layout by redefining NLOHMANN_JSON_NAMESPACE_BEGIN, NLOHMANN_JSON_NAMESPACE_END as follows:

#define NLOHMANN_JSON_NAMESPACE_BEGIN  namespace nlohmann {\n#define NLOHMANN_JSON_NAMESPACE_END    }\n

Use at your own risk

Overriding the namespace and mixing ABI-incompatible versions will result in crashes or incorrect behavior. You have been warned!

"},{"location":"features/namespace/#see-also","title":"See also","text":"
  • NLOHMANN_JSON_NAMESPACE - the library namespace as macro
  • NLOHMANN_JSON_NAMESPACE_BEGIN, NLOHMANN_JSON_NAMESPACE_END - open and close the library namespace
  • NLOHMANN_JSON_NAMESPACE_NO_VERSION - disable the version component
  • Supported Macros - all supported macros
  • Migration Guide - do not hard-code the library namespace
  • basic_json - the main class and all its member functions
"},{"location":"features/namespace/#version-history","title":"Version history","text":"
  • Introduced inline namespace (json_v3_11_0[_abi-tag]*) in version 3.11.0.
  • Changed structure of inline namespace in version 3.11.2.
  • Added ABI tag _dp (JSON_DIAGNOSTIC_POSITIONS) in version 3.12.0.
  • Added ABI tags _bics (JSON_BRACE_INIT_COPY_SEMANTICS), _psp (JSON_PRECISE_STREAM_POSITION), _snul (JSON_STRICT_NUL_HANDLING), _sbu8 (JSON_STRICT_BINARY_UTF8), _ekmo (JSON_USE_OBJECTS_FOR_ENUM_KEYED_MAPS), _dsbs (JSON_DISABLE_STREAM_BULK_SCAN), _dufio (JSON_DISABLE_UNLOCKED_FILE_IO), and _ns (JSON_NO_SIMD) in version 3.13.0 unreleased.
"},{"location":"features/no_exceptions/","title":"Working Without Exceptions","text":"

By default, the library reports errors by throwing exceptions (see Exceptions). This page collects what to use when exceptions are unwanted or unavailable, for example in embedded systems, game engines, or code compiled with -fno-exceptions.

"},{"location":"features/no_exceptions/#two-different-questions","title":"Two different questions","text":"
  1. Can my code avoid catching exceptions? Yes. For parsing and for accessing values there are functions that report failure through a return value. They work in a normal build and need no try/catch.
  2. Can the library be compiled without exceptions? Yes, with -fno-exceptions or by defining JSON_NOEXCEPTION. Both have the same effect: every throw in the library becomes a call to std::abort(). The functions listed below never reach a throw for the failures they report, so they keep working in this configuration. Anything else that fails aborts the program.
"},{"location":"features/no_exceptions/#parsing","title":"Parsing","text":"function on invalid input json::parse(input, nullptr, false) returns a discarded value; test with is_discarded() accept returns false json::from_cbor(input, true, false) (and the other from_* functions) returns a discarded value sax_parse with your own handler returns false after calling parse_error Example: parse and validate without exceptions
#include <cstdint>\n#include <iostream>\n#include <vector>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\n// None of the calls below throws, so this example also works with -fno-exceptions.\nint main()\n{\n    const std::string invalid = R\"({\"name\": \"Mary\", \"age\": )\";\n\n    // parse() with allow_exceptions = false returns a discarded value\n    json j = json::parse(invalid, nullptr, false);\n    std::cout << std::boolalpha << \"parse: discarded = \" << j.is_discarded() << '\\n';\n\n    // accept() only tells whether the input is valid JSON\n    std::cout << \"accept: \" << json::accept(invalid) << '\\n';\n\n    // the binary formats have the same parameter\n    const std::vector<std::uint8_t> truncated_cbor = {0x83, 0x01};\n    json c = json::from_cbor(truncated_cbor, true, false);\n    std::cout << \"from_cbor: discarded = \" << c.is_discarded() << '\\n';\n\n    // valid input is parsed as usual\n    json valid = json::parse(R\"({\"name\": \"Mary\"})\", nullptr, false);\n    std::cout << \"valid input: \" << valid << '\\n';\n}\n

Output:

parse: discarded = true\naccept: false\nfrom_cbor: discarded = true\nvalid input: {\"name\":\"Mary\"}\n

None of the calls in this example throws, so it also compiles and runs with -fno-exceptions.

The discarded value carries no message. If you need the position or the reason, use the SAX interface; see Parsing and exceptions.

"},{"location":"features/no_exceptions/#accessing-values","title":"Accessing values","text":"

The access functions are not equally safe. Only some of them never throw:

expression if the key is missing or the type is wrong j.contains(\"k\") returns false for a missing key; never throws j.find(\"k\") returns end() for a missing key; never throws j.is_string(), ... the is_* functions test the type; never throw j.get_ptr<const std::string*>() returns nullptr for a different type; never throws j.at(\"k\") throws out_of_range.403 for a missing key j.get<int>() throws type_error.302 for a value that is not a number j.value(\"k\", 0) returns the default for a missing key, but throws type_error.302 if k exists with another type j[\"k\"] (non-const) inserts null for a missing key j[\"k\"] (const) undefined behavior for a missing key

So reading a value that may be absent or of the wrong type without exceptions takes two steps: look up, then test the type.

Example: look up a key and test its type
#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    json j = json::parse(R\"({\"name\": \"Mary\", \"age\": 42})\");\n\n    // look up the key, then test the type: neither step throws\n    const auto keys = {\"name\", \"age\", \"city\"};\n    for (const char* key : keys)\n    {\n        const auto it = j.find(key);\n        if (it == j.end())\n        {\n            std::cout << key << \": missing\\n\";\n        }\n        else if (it->is_string())\n        {\n            std::cout << key << \": string \\\"\" << it->get_ref<const std::string&>() << \"\\\"\\n\";\n        }\n        else\n        {\n            std::cout << key << \": not a string, but \" << it->type_name() << '\\n';\n        }\n    }\n\n    // get_ptr returns a null pointer if the value has another type\n    const std::string* name = j[\"name\"].get_ptr<const std::string*>();\n    const std::string* age = j[\"age\"].get_ptr<const std::string*>();\n    std::cout << \"get_ptr<string*>: name = \" << (name != nullptr) << \", age = \" << (age != nullptr) << '\\n';\n\n    // value() is NOT exception-free: it throws if the key exists with a different type\n    try\n    {\n        std::cout << j.value(\"name\", 0) << '\\n';\n    }\n    catch (const json::type_error& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n}\n

Output:

name: string \"Mary\"\nage: not a string, but number\ncity: missing\nget_ptr<string*>: name = 1, age = 0\n[json.exception.type_error.302] type must be number, but is string\n

The last lines of the example show why value is not on the safe list: it returns the default only for a missing key.

For numbers, test with is_number() (or is_number_integer(), is_number_unsigned(), is_number_float()) before calling get<int>(), and see number handling for range and precision. Whether a value fits into the target type is not checked by get.

"},{"location":"features/no_exceptions/#converting-to-your-own-types","title":"Converting to your own types","text":"

from_json functions (including the ones generated by the NLOHMANN_DEFINE_TYPE_* macros) report problems by throwing. There is no variant that returns an error code. Without exceptions you have two options:

  • Validate the JSON value yourself, as shown above, and fill your struct field by field.
  • Convert in a function that is compiled with exceptions enabled and catches them at the boundary, returning std::optional or an error code to the rest of your code:
Example: convert to a struct and report failure as std::optional
#include <iostream>\n#include <optional>\n#include <string>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nstruct person\n{\n    std::string name;\n    int age;\n};\n\nNLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(person, name, age)\n\n// Compile this function with exceptions enabled and call it from code that does not use them.\nstd::optional<person> to_person(const json& j)\n{\n    try\n    {\n        return j.get<person>();\n    }\n    catch (const json::exception&)\n    {\n        return std::nullopt;\n    }\n}\n\nint main()\n{\n    const json good = {{\"name\", \"Mary\"}, {\"age\", 42}};\n    const json bad = {{\"name\", \"Mary\"}, {\"age\", \"forty-two\"}};\n    const json incomplete = {{\"name\", \"Mary\"}};\n\n    const auto inputs = {good, bad, incomplete};\n\n    for (const json& j : inputs)\n    {\n        if (const auto p = to_person(j))\n        {\n            std::cout << \"person: \" << p->name << \", \" << p->age << '\\n';\n        }\n        else\n        {\n            std::cout << \"not a person: \" << j << '\\n';\n        }\n    }\n}\n

Output:

person: Mary, 42\nnot a person: {\"age\":\"forty-two\",\"name\":\"Mary\"}\nnot a person: {\"name\":\"Mary\"}\n
"},{"location":"features/no_exceptions/#overriding-what-happens-instead-of-an-exception","title":"Overriding what happens instead of an exception","text":"

With exceptions off, you can replace the abort() by your own code, for example to log the message first. See Switch off exceptions and JSON_THROW_USER. The handler must not return normally.

"},{"location":"features/no_exceptions/#see-also","title":"See also","text":"
  • Exceptions - all exceptions and their ids
  • Parsing and exceptions - the parsing alternatives in detail
  • Parsing untrusted input - harden an application that parses data it does not control
  • JSON_NOEXCEPTION - disable exceptions in the library
  • exception - base class of all exceptions thrown by the library
  • JSON_THROW_USER - replace the throw statements of the library
  • parse - deserialize from a compatible input
  • accept - check whether the input is valid JSON
  • Supported Macros - all supported macros
"},{"location":"features/object_order/","title":"Object Order","text":"

The JSON standard defines objects as \"an unordered collection of zero or more name/value pairs\". As such, an implementation does not need to preserve any specific order of object keys.

"},{"location":"features/object_order/#default-behavior-sort-keys","title":"Default behavior: sort keys","text":"

The default type nlohmann::json uses a std::map to store JSON objects, and thus stores object keys sorted alphabetically.

Example: json sorts object keys
#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    json j;\n    j[\"one\"] = 1;\n    j[\"two\"] = 2;\n    j[\"three\"] = 3;\n\n    std::cout << j.dump(2) << '\\n';\n}\n

Output:

{\n  \"one\": 1,\n  \"three\": 3,\n  \"two\": 2\n}\n
"},{"location":"features/object_order/#alternative-behavior-preserve-insertion-order","title":"Alternative behavior: preserve insertion order","text":"

If you do want to preserve the insertion order, you can use the type nlohmann::ordered_json.

Example: ordered_json preserves insertion order
#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::ordered_json;\n\nint main()\n{\n    ordered_json j;\n    j[\"one\"] = 1;\n    j[\"two\"] = 2;\n    j[\"three\"] = 3;\n\n    std::cout << j.dump(2) << '\\n';\n}\n

Output:

{\n  \"one\": 1,\n  \"two\": 2,\n  \"three\": 3\n}\n

Alternatively, nlohmann::fifo_map also preserves the insertion order and, unlike ordered_map, keeps a lookup index, so it does not have the quadratic cost described below. It is used through a small adapter (integration).

If the order does not matter and you only want faster lookup, boost::unordered_flat_map, absl::flat_hash_map, absl::node_hash_map, and several other hash maps work through an adapter that restores the template argument order basic_json expects; see Template Parameter Requirements. Note these are unordered, not insertion-ordered.

tsl::ordered_map cannot be used: its iterators expose the mapped value as const, while basic_json needs to modify it in place.

The ordered_map behind nlohmann::ordered_json is deliberately minimal and has no lookup index, so every key access is a linear scan and building an object of n keys costs O(n\u00b2). This is unnoticeable at typical object sizes but becomes significant for objects with many thousands of keys; see ordered_map complexity. The alternatives above keep a lookup index and do not have this cost.

"},{"location":"features/object_order/#notes-on-parsing","title":"Notes on parsing","text":"

Note that you also need to call the right parse function when reading from a file. Assume file input.json contains the JSON object above:

{\n  \"one\": 1,\n  \"two\": 2,\n  \"three\": 3\n}\n

Right way

The following code correctly calls the parse function from nlohmann::ordered_json:

std::ifstream i(\"input.json\");\nauto j = nlohmann::ordered_json::parse(i);\nstd::cout << j.dump(2) << std::endl;\n

The output will be:

{\n  \"one\": 1,\n  \"two\": 2,\n  \"three\": 3\n}\n
Wrong way

The following code incorrectly calls the parse function from nlohmann::json which does not preserve the insertion order, but sorts object keys. Assigning the result to nlohmann::ordered_json compiles, but does not restore the order from the input file.

std::ifstream i(\"input.json\");\nnlohmann::ordered_json j = nlohmann::json::parse(i);\nstd::cout << j.dump(2) << std::endl;\n

The output will be:

{\n  \"one\": 1,\n  \"three\": 3,\n  \"two\": 2\n}\n
"},{"location":"features/object_order/#see-also","title":"See also","text":"
  • ordered_json - JSON type that preserves insertion order
  • ordered_map - the container behind ordered_json
  • object_t - type used to store JSON objects
  • Iterators - iteration order of object keys
  • Element Access - access elements by key
"},{"location":"features/performance/","title":"Performance","text":"

Speed was never the primary goal of this library. The design goals page says so plainly: \"There are certainly faster JSON libraries out there.\" Intuitive syntax, trivial integration, and thorough testing came first. If a hard real-time budget or the last percent of throughput matters more than convenience, a faster, more specialized library may be a better fit.

That said, how you use this library still makes a measurable difference. This page collects practical, code-verified techniques for reducing time, memory, and compile-time cost \u2014 without repeating the detailed pages it links to.

"},{"location":"features/performance/#parsing-input","title":"Parsing input","text":"

parse accepts a string, a pair of iterators, a container, a std::istream, or a FILE* (see Parsing). Internally, every input is wrapped in an input adapter, and not all adapters are equally fast.

For inputs backed by contiguous, single-byte memory \u2014 a std::string, a std::vector<char>, a string literal, or a pointer range \u2014 the library uses iterator_input_adapter, wrapped in a raw pointer so the fast paths below apply on every supported standard. This adapter exposes two optimizations the lexer detects at compile time:

  • it can reconstruct already-consumed input on demand for error messages, instead of copying every character as it is read, and
  • the lexer can scan ordinary string characters, numbers, and indentation directly out of the buffer, several bytes at a time, rather than one character (and one function call) at a time.

A std::istream (including std::ifstream) gets the same bulk scanning: input_stream_adapter scans the characters its stream buffer already holds (the get area) and asks the stream buffer for more only when they are used up. Nothing is read ahead, so the stream is left exactly where it would be after reading one character at a time, and operator>> can still read several values from one stream. A stream buffer without a get area is read one character at a time. A FILE* is still read one character at a time, but file_input_adapter locks the file once per parse instead of once per character. See input sources and performance for the full table. According to the description of #5828, parsing from a stream is within about 10 to 20 % of parsing an equivalent std::string.

Inputs that are still read one character at a time: iterator ranges that are not contiguous (e.g. std::list<char> or std::istreambuf_iterator<char>), wide strings, and user-defined adapters. An iterator pair over non-contiguous but random-access storage (e.g. std::deque<char>::iterator) gets the first optimization but not the second, since the byte-scanning fast path requires contiguous storage.

Practically: a file can be passed directly to parse, which also avoids the memory for a copy of the file. Reading it into a string first is no longer necessary for speed:

// fast: the stream buffer's get area is scanned in bulk\nstd::ifstream f(\"example.json\");\njson j = json::parse(f);\n

Two macros switch the stream optimizations off without changing any result: JSON_DISABLE_STREAM_BULK_SCAN for stream buffers that do not follow the usual std::streambuf contract, and JSON_DISABLE_UNLOCKED_FILE_IO for programs in which another thread must use the same FILE object while it is parsed.

For contiguous input with many non-ASCII characters, JSON_USE_SIMDUTF can additionally speed up UTF-8 validation by using the simdutf library instead of the built-in scalar validator; streaming inputs (files, std::istream, wide strings, user-defined adapters) always use the scalar path regardless of this macro.

"},{"location":"features/performance/#large-documents","title":"Large documents","text":"

Parsing always produces SAX events internally; parse simply feeds them to a consumer that builds a complete basic_json value tree (a DOM) in memory. For documents too large to comfortably hold as a DOM, three alternatives avoid building it:

  • Implement the SAX interface directly and pass it to sax_parse; only the parts of the input you choose to keep ever become basic_json values.
  • Pass a parser callback to parse. This still builds a DOM, but the callback can discard finished elements as soon as they are handled, so memory usage stays bounded by one element (plus the unparsed remainder of the input) instead of the whole document \u2014 see the recipe for streaming a large homogeneous array.
  • Parse into a json_document (<nlohmann/json_view.hpp>) instead of a basic_json. It keeps the input text and builds a flat index of 16 bytes per value; strings and floating-point numbers are not copied, but read from the text when needed. Read-only views give the familiar element access, and only the parts you materialize() become basic_json values. A document that borrows the text instead of owning a copy needs the text to outlive it; see choosing between json, the SAX interface, and json_view.

If the data is naturally record-oriented, consider JSON Lines instead of one large JSON document: reading and parsing it line by line with std::getline means only one line's value is ever in memory at a time, and a malformed line does not invalidate lines already processed.

"},{"location":"features/performance/#binary-formats","title":"Binary formats","text":"

JSON text is not a compact format. If the data is only exchanged between programs (not read by humans), the binary formats \u2014 BJData, BON8, BSON, CBOR, MessagePack, and UBJSON \u2014 encode the same values more compactly, which reduces both the bytes transferred and, for most of them, the work needed to parse them back. The size comparison on that page, measured against minified JSON for four reference documents, shows the effect varies a lot by document shape: CBOR and MessagePack come out at 50.5% of the minified JSON size for the numeric-array-heavy canada.json, but only around 87-88% for the string-heavy jeopardy.json, where there is less numeric data to encode more compactly. BON8 is the most compact option in that comparison for text-heavy documents (63.5%-87.5%), at the cost of an incomplete serializer (no unsigned integers above int64). Which format \u2014 and whether it is worth the loss of human readability at all \u2014 depends on the actual data; see the comparison tables before choosing one.

Size of canada.json in each binary format relative to minified J\u200bSON B\u200bJData 53.2 %; B\u200bON8 50.5 %; B\u200bSON 85.8 %; C\u200bBOR 50.5 %; MessagePack 50.5 %; U\u200bBJSON 53.2 %. Smallest: B\u200bON8 and C\u200bBOR and MessagePack. canada.json 0 % 50 % B\u200bJData canada.json, B\u200bJData: 53.2 % of minified J\u200bSON B\u200bON8 canada.json, B\u200bON8: 50.5 % of minified J\u200bSON (smallest) B\u200bSON canada.json, B\u200bSON: 85.8 % of minified J\u200bSON C\u200bBOR canada.json, C\u200bBOR: 50.5 % of minified J\u200bSON (smallest) MessagePack canada.json, MessagePack: 50.5 % of minified J\u200bSON (smallest) U\u200bBJSON canada.json, U\u200bBJSON: 53.2 % of minified J\u200bSON minified J\u200bSON = 100 % 100 % 53.2 % 50.5 % 85.8 % 50.5 % 50.5 % 53.2 %

Size of jeopardy.json in each binary format relative to minified J\u200bSON B\u200bJData 96.6 %; B\u200bON8 87.5 %; B\u200bSON 106.7 %; C\u200bBOR 88 %; MessagePack 87.9 %; U\u200bBJSON 96.6 %. Smallest: B\u200bON8. jeopardy.json 0 % 50 % B\u200bJData jeopardy.json, B\u200bJData: 96.6 % of minified J\u200bSON B\u200bON8 jeopardy.json, B\u200bON8: 87.5 % of minified J\u200bSON (smallest) B\u200bSON jeopardy.json, B\u200bSON: 106.7 % of minified J\u200bSON C\u200bBOR jeopardy.json, C\u200bBOR: 88 % of minified J\u200bSON MessagePack jeopardy.json, MessagePack: 87.9 % of minified J\u200bSON U\u200bBJSON jeopardy.json, U\u200bBJSON: 96.6 % of minified J\u200bSON minified J\u200bSON = 100 % 100 % 96.6 % 87.5 % 106.7 % 88.0 % 87.9 % 96.6 %

Two of the four panels from the size comparison; the smallest format per file is drawn in a stronger colour than the others.

"},{"location":"features/performance/#object-type-json-vs-ordered_json","title":"Object type: json vs. ordered_json","text":"

The default json type stores object keys in a std::map, giving logarithmic-time lookup, insertion, and erasure, at the cost of sorting keys alphabetically rather than preserving insertion order (see Object Order). ordered_json uses nlohmann::ordered_map instead, a std::vector-backed container with no lookup index: every key-based operation is a linear scan, so building an object of n distinct keys costs O(n\u00b2) in total \u2014 this applies equally to inserting keys one by one and to parsing an object, since the parser inserts each key as it is read. The measurements on the ordered_map page show this is negligible at typical object sizes (2000 keys: 0.7 ms for json vs. 3.6 ms for ordered_json, a 5x factor) but grows steeply for large, machine-generated objects (16 000 keys: 3.3 ms vs. 181.6 ms, a 54x factor).

Time to parse a flat object of n keys, json against ordered_json, logarithmic axes 2000 keys: json 0.7 ms, ordered_json 3.6 ms (5x). 4000 keys: 0.8 ms and 14.0 ms (19x). 8000 keys: 1.6 ms and 67.8 ms (43x). 16000 keys: 3.3 ms and 181.6 ms (54x). 1 ms 10 ms 100 ms 2\u2009000 4\u2009000 8\u2009000 16\u2009000 json, 2000 keys: 0.7 ms json, 4000 keys: 0.8 ms json, 8000 keys: 1.6 ms json, 16000 keys: 3.3 ms json 3.3 ms 0.7 ms ordered_json, 2000 keys: 3.6 ms ordered_json, 4000 keys: 14 ms ordered_json, 8000 keys: 67.8 ms ordered_json, 16000 keys: 181.6 ms ordered_json 181.6 ms 3.6 ms

Parsing a flat object of n keys, measured with -O2 -DNDEBUG; all four sizes from the table on the ordered_map page, both axes logarithmic.

If insertion order matters and an object routinely has many thousands of keys, ordered_json's quadratic build cost may not be acceptable. The library's ObjectType template parameter can be set to a different container instead: nlohmann::fifo_map keeps insertion order with a real lookup index (avoiding the quadratic cost), while std::unordered_map, boost::unordered_flat_map, absl::flat_hash_map, and similar hash maps trade insertion order for average-case constant-time lookup (through an adapter, since their template argument order does not match what basic_json expects) \u2014 see Object Order for the full list.

"},{"location":"features/performance/#avoiding-copies","title":"Avoiding copies","text":"
  • Move instead of copy. Constructing a basic_json from an existing one is linear in its size for the copy constructor but constant for the move constructor. The same applies to assigning a large std::string, std::vector, or other container into a value: pass it as std::move(x) rather than x whenever x is no longer needed afterwards. Since version 3.13.0 unreleased, converting an rvalue container (json j = std::move(vec);) moves the elements instead of copying them; the source is then left in a valid but unspecified state.
  • Access without copying. get<T>() returns a copy of the stored value converted to T. When a reference or pointer to the value already stored inside the basic_json is enough, get_ref() and get_ptr() access it directly: both pages state, word for word, \"No copies are made.\" \u2014 at the cost of that reference or pointer becoming invalid once the underlying value changes.
  • Iterate by reference. basic_json::iterator::operator*() returns a reference (an alias for basic_json&), but a range-based for loop with a by-value loop variable (for (auto el : j)) still copies each element, because plain auto drops the reference. Write for (const auto& el : j) (or auto& for a mutable loop), and use items() the same way when the key is needed too \u2014 its own examples use for (auto& el : j.items()).
  • Construct in place. emplace_back() (arrays, amortized constant time) and emplace() (objects, logarithmic in the size of the container for json) forward their arguments directly to a basic_json constructor, rather than requiring a temporary value to be constructed and then copied or moved in. push_back() has an rvalue overload (push_back(basic_json&&)) for a value that already exists: j.push_back(std::move(value)) moves it in instead of copying it.
  • Skip the bounds check when it is redundant. at() and operator[] have the same complexity (constant for a valid array index, logarithmic for an object key in json) \u2014 the difference is that at() additionally checks the key or index and throws if it is invalid, while operator[] does not (see unchecked access and checked access). Prefer operator[] when the surrounding code has already established that the access is valid.
  • Reserve array capacity. basic_json has no public reserve(), but when building a large array incrementally with a known final size, get_ref() exposes the underlying array_t so it can be reserved directly \u2014 see \"reserving array capacity\" for the one-line recipe.
"},{"location":"features/performance/#memory","title":"Memory","text":"
  • A value is small, its content is on the heap. A basic_json is 16 bytes on a 64-bit platform (a type tag and a union). Strings, arrays, objects, and binary values are allocated on the heap and owned by the value. Destroying the value frees everything it owns.
  • Copies are deep. After json b = a;, changing b does not change a, and both own their memory. Copying a large value therefore doubles its memory; see Avoiding copies. auto x = j[\"key\"]; is a copy, auto& x = j[\"key\"]; is not.
  • A moved-from value is null. After json c = std::move(a); the value a is null and owns nothing.
  • Reading does not require a tree. If you only read the data, parse it into a json_document (<nlohmann/json_view.hpp>, added in version 3.13.0 unreleased) instead of a basic_json. It stores 16 bytes per value, does not copy floating-point numbers or strings without escape sequences out of the text, and creates no basic_json value except for the parts you materialize(). A document that borrows the text needs the text to outlive it; see Zero-copy JSON views.
  • Containers keep their capacity. clear() and erase() on an array remove the elements, but the underlying std::vector keeps its allocated capacity, like std::vector::clear does. To give the memory back, assign a new value (j = json::array();) or destroy the value.
  • Freed memory does not always go back to the operating system. The library returns memory to the allocator (std::allocator by default, or the one you configured). Whether the process size shrinks then depends on the allocator and the platform, as for any C++ program. A process that parses a large document and drops it is not leaking if its resident size stays high; run it under a tool such as Valgrind or the sanitizers to tell a leak from retained memory.
"},{"location":"features/performance/#serialization","title":"Serialization","text":"

dump() with the default indent = -1 selects \"the most compact representation\" (word for word from the page); any non-negative indent pretty-prints instead, which is more readable but produces more bytes and more work. dump() builds and returns a complete string_t containing the whole serialization. operator<< writes directly to a std::ostream instead, through the same serializer, but without ever materializing that intermediate string \u2014 so if the destination is a stream (a file, or std::cout), os << j; avoids the allocation and copy that os << j.dump(); would incur for large values.

"},{"location":"features/performance/#diagnostics-overhead","title":"Diagnostics overhead","text":"

Two opt-in macros add diagnostic information to exceptions and to every value, at a cost that is only worth paying while it is in use:

  • JSON_DIAGNOSTICS adds a JSON Pointer to exception messages, pointing at the value that triggered the exception. Quoting the page directly: \"enabling this macro increases the size of every JSON value by one pointer and adds some runtime overhead\" \u2014 every value gains a parent pointer that has to be kept up to date as the document is built and modified.
  • JSON_DIAGNOSTIC_POSITIONS adds start_pos() and end_pos(), the byte offsets a value occupied in its parsed input. Quoting the page: \"enabling this macro increases the size of every JSON value by two std::size_t fields and adds slight runtime overhead to parsing, copying JSON value objects, and the generation of error messages for exceptions.\"

Both default to off. Enable them where better diagnostics are worth the overhead (for example, while validating untrusted input, or in a debug build), and keep them off in a release build that does not need them.

"},{"location":"features/performance/#compile-time","title":"Compile time","text":"

<nlohmann/json_fwd.hpp> forward-declares basic_json, json, ordered_json, json_pointer, and adl_serializer, pulling in only a handful of lightweight standard headers instead of the full json.hpp. A header that only needs to name nlohmann::json \u2014 in a function signature or a class member declaration, for instance \u2014 can include json_fwd.hpp and leave #include <nlohmann/json.hpp> to the source files that actually parse, build, or serialize values, the same way a project would forward-declare any other heavy class to keep it out of widely-included headers:

// my_type.hpp\n#include <nlohmann/json_fwd.hpp>\n\nclass my_type\n{\n    nlohmann::json config() const;\n};\n\n// my_type.cpp\n#include <nlohmann/json.hpp>\n#include \"my_type.hpp\"\n\nnlohmann::json my_type::config() const { /* ... */ }\n

One caveat: ABI-affecting macros such as JSON_DIAGNOSTICS and JSON_DIAGNOSTIC_POSITIONS are encoded into the library's inline namespace name. Every translation unit \u2014 whether it includes json_fwd.hpp or the full header \u2014 must define them the same way, or linking fails with undefined references instead of a compile error.

If I/O support is not needed at all, JSON_NO_IO excludes <cstdio>, <ios>, <iosfwd>, <istream>, and <ostream> outright and drops the std::istream/FILE* parse overloads and operator<< that depend on them (dump() itself is unaffected, since it only returns a string); it exists for environments where those headers are unavailable (such as Intel SGX), and as a side effect those headers are then never processed by the compiler at all.

"},{"location":"features/performance/#see-also","title":"See also","text":"
  • Design goals - why this library does not optimize for speed first
  • Architecture - how input adapters, the lexer, and the serializer fit together
  • Parsing - the available parsing functions and inputs
  • SAX interface - parse without building a DOM
  • Zero-copy JSON views - parse into a flat index of the text and read it without building a DOM
  • Binary formats - compact alternatives to JSON text
  • Object Order - json vs. ordered_json and other ObjectType choices
  • Template Parameter Requirements - custom container and allocator types
  • Supported macros - overview of all configuration macros, including the diagnostics ones above
  • JSON_NO_SIMD - disable SIMD acceleration
  • JSON_USE_SIMDUTF - use simdutf for UTF-8 validation
  • JSON_DISABLE_STREAM_BULK_SCAN - disable the stream bulk scan
  • parse - deserialize from a compatible input
  • sax_parse - parse with a SAX interface
  • json_view - a non-owning view of a value in a document
"},{"location":"features/serialization/","title":"Serialization","text":"

Serialization is the process of turning a JSON value back into JSON text. It is the counterpart to parsing. The central function is dump, which returns the JSON text as a string.

json j = {{\"pi\", 3.141}, {\"happy\", true}};\n\nstd::string s = j.dump();   // {\"happy\":true,\"pi\":3.141}\n

To write a value directly to a stream (for example, a file or std::cout), the operator<< is provided:

std::cout << j << std::endl;\n

String, not raw value

dump always returns a JSON text. Serializing a JSON string therefore includes the surrounding quotes and escapes special characters. To obtain the contained string value without quotes, use get<std::string>() instead of dump. See the converting values page.

"},{"location":"features/serialization/#pretty-printing","title":"Pretty-printing","text":"

By default, dump produces the most compact representation without any superfluous whitespace. Passing a non-negative indent argument pretty-prints the output with the given number of spaces per level:

Example: pretty-print JSON values with dump()
#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create JSON values\n    json j_object = {{\"one\", 1}, {\"two\", 2}};\n    json j_array = {1, 2, 4, 8, 16};\n    json j_string = \"Hell\u00f6 \ud83d\ude00!\";\n\n    // call dump()\n    std::cout << \"objects:\" << '\\n'\n              << j_object.dump() << \"\\n\\n\"\n              << j_object.dump(-1) << \"\\n\\n\"\n              << j_object.dump(0) << \"\\n\\n\"\n              << j_object.dump(4) << \"\\n\\n\"\n              << j_object.dump(1, '\\t') << \"\\n\\n\";\n\n    std::cout << \"arrays:\" << '\\n'\n              << j_array.dump() << \"\\n\\n\"\n              << j_array.dump(-1) << \"\\n\\n\"\n              << j_array.dump(0) << \"\\n\\n\"\n              << j_array.dump(4) << \"\\n\\n\"\n              << j_array.dump(1, '\\t') << \"\\n\\n\";\n\n    std::cout << \"strings:\" << '\\n'\n              << j_string.dump() << '\\n'\n              << j_string.dump(-1, ' ', true) << '\\n';\n\n    // create JSON value with invalid UTF-8 byte sequence\n    json j_invalid = \"\u00e4\\xA9\u00fc\";\n    try\n    {\n        std::cout << j_invalid.dump() << '\\n';\n    }\n    catch (const json::type_error& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n\n    std::cout << \"string with replaced invalid characters: \"\n              << j_invalid.dump(-1, ' ', false, json::error_handler_t::replace)\n              << \"\\nstring with ignored invalid characters: \"\n              << j_invalid.dump(-1, ' ', false, json::error_handler_t::ignore)\n              << '\\n';\n}\n

Output:

objects:\n{\"one\":1,\"two\":2}\n\n{\"one\":1,\"two\":2}\n\n{\n\"one\": 1,\n\"two\": 2\n}\n\n{\n    \"one\": 1,\n    \"two\": 2\n}\n\n{\n    \"one\": 1,\n    \"two\": 2\n}\n\narrays:\n[1,2,4,8,16]\n\n[1,2,4,8,16]\n\n[\n1,\n2,\n4,\n8,\n16\n]\n\n[\n    1,\n    2,\n    4,\n    8,\n    16\n]\n\n[\n    1,\n    2,\n    4,\n    8,\n    16\n]\n\nstrings:\n\"Hell\u00f6 \ud83d\ude00!\"\n\"Hell\\u00f6 \\ud83d\\ude00!\"\n[json.exception.type_error.316] invalid UTF-8 byte at index 2: 0xA9\nstring with replaced invalid characters: \"\u00e4\ufffd\u00fc\"\nstring with ignored invalid characters: \"\u00e4\u00fc\"\n

The indentation character can be changed with the second argument (e.g., a tab '\\t'). An indent of 0 inserts newlines but no leading spaces, and the default of -1 selects the compact single-line form.

"},{"location":"features/serialization/#non-ascii-characters","title":"Non-ASCII characters","text":"

Strings are stored and serialized as UTF-8 (see types). By default, dump copies valid non-ASCII characters as-is. Setting the third argument ensure_ascii to true escapes all non-ASCII characters with \\uXXXX sequences, so that the output contains only ASCII characters:

json j = \"\u82f9\u679c\";\nj.dump();               // \"\u82f9\u679c\"\nj.dump(-1, ' ', true);  // \"\\u82f9\\u679c\"\n
"},{"location":"features/serialization/#handling-invalid-utf-8","title":"Handling invalid UTF-8","text":"

If a string contains invalid UTF-8 sequences (for example, because it holds data in another encoding such as Latin-1), serialization fails by default. The fourth argument of dump selects an error_handler:

  • strict (default) \u2014 throw a type_error.316 exception.
  • replace \u2014 replace invalid bytes with the Unicode replacement character U+FFFD (\ufffd).
  • ignore \u2014 silently drop invalid bytes.
  • keep \u2014 copy invalid bytes to the output unchanged; the result is not valid UTF-8.
Example: serialize invalid UTF-8 with different error handlers
#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create JSON value with invalid UTF-8 byte sequence\n    json j_invalid = \"\u00e4\\xA9\u00fc\";\n    try\n    {\n        std::cout << j_invalid.dump() << '\\n';\n    }\n    catch (const json::type_error& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n\n    std::cout << \"string with replaced invalid characters: \"\n              << j_invalid.dump(-1, ' ', false, json::error_handler_t::replace)\n              << \"\\nstring with ignored invalid characters: \"\n              << j_invalid.dump(-1, ' ', false, json::error_handler_t::ignore)\n              << \"\\nstring with the invalid byte kept as is (\" << j_invalid.dump(-1, ' ', false, json::error_handler_t::keep).size()\n              << \" bytes, not valid UTF-8 itself)\\n\";\n}\n

Output:

[json.exception.type_error.316] invalid UTF-8 byte at index 2: 0xA9\nstring with replaced invalid characters: \"\u00e4\ufffd\u00fc\"\nstring with ignored invalid characters: \"\u00e4\u00fc\"\nstring with the invalid byte kept as is (7 bytes, not valid UTF-8 itself)\n

Avoiding invalid UTF-8

The best fix is to ensure that all strings are UTF-8 encoded before storing them. See the FAQ on non-ASCII characters for how to convert wide or Latin-1 strings.

"},{"location":"features/serialization/#numbers-nan-and-binary-values","title":"Numbers, NaN, and binary values","text":"
  • Numbers are serialized with enough precision to round-trip; see number serialization.
  • NaN and infinity cannot be represented in JSON and are serialized as null; see NaN handling. The binary formats can preserve them.
  • Binary values have no JSON representation and are serialized as a helper object for debugging only; see binary values.
"},{"location":"features/serialization/#using-stdformat-stdprint-and-fmt","title":"Using std::format, std::print, and fmt","text":"

Since version 3.12.0, JSON values can be formatted directly with C++20's std::format whenever the standard library provides the <format> header (controlled by JSON_HAS_STD_FORMAT). This is enabled by the std::formatter<basic_json> specialization, which also makes JSON values work with std::format_to and with C++23's std::print/std::println:

std::print(\"{}\", j);      // compact, like j.dump()\nstd::print(\"{:2}\", j);    // pretty-printed with indent 2 (like j.dump(2))\nstd::println(\"{:#}\", j);  // pretty-printed with the default indent\n

The format spec mirrors the dump parameters: \"{:#}\" pretty-prints, a width such as \"{:2}\" sets the indent, and a fill-and-align prefix such as \"{:.>#}\" sets the indent character.

For the {fmt} library, the library ships a format_as helper. Note its behavior depends on the fmt version; see the FAQ entry for the details and a recipe for a full fmt::formatter specialization.

"},{"location":"features/serialization/#serializing-to-other-formats","title":"Serializing to other formats","text":"

Besides JSON text, a value can also be serialized to the more compact binary formats (BJData, BON8, BSON, CBOR, MessagePack, UBJSON).

"},{"location":"features/serialization/#see-also","title":"See also","text":"
  • dump - serialize to a JSON-formatted string
  • operator<< - serialize to a stream
  • to_string - user-defined-conversion helper
  • std::formatter<basic_json> - use JSON values with std::format and std::print
  • format_as - use JSON values with the {fmt} library
  • Parsing - the reverse operation
  • error_handler_t - how to treat invalid UTF-8 when dumping
  • basic_json_view::dump - serialize a view directly
  • JSON_NO_IO - remove stream and file I/O
  • JSON_NO_SIMD - disable SIMD acceleration
"},{"location":"features/trailing_commas/","title":"Trailing Commas","text":"

Like comments, this library does not support trailing commas in arrays and objects by default.

You can set parameter ignore_trailing_commas to true in the parse function to allow trailing commas in arrays and objects. Note that a single comma as the only content of the array or object ([,] or {,}) is not allowed, and multiple trailing commas ([1,,]) are not allowed either.

This library does not add trailing commas when serializing JSON data.

For more information, see JSON With Commas and Comments (JWCC).

Example

Consider the following JSON with trailing commas.

{\n    \"planets\": [\n        \"Mercury\",\n        \"Venus\",\n        \"Earth\",\n        \"Mars\",\n        \"Jupiter\",\n        \"Uranus\",\n        \"Neptune\",\n    ]\n}\n

When calling parse without additional argument, a parse error exception is thrown. If ignore_trailing_commas is set to true, the trailing commas are ignored during parsing:

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    std::string s = R\"(\n    {\n        \"planets\": [\n            \"Mercury\",\n            \"Venus\",\n            \"Earth\",\n            \"Mars\",\n            \"Jupiter\",\n            \"Uranus\",\n            \"Neptune\",\n        ]\n    }\n    )\";\n\n    try\n    {\n        json j = json::parse(s);\n    }\n    catch (json::exception& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n\n    json j = json::parse(s,\n                         /* callback */ nullptr,\n                         /* allow exceptions */ true,\n                         /* ignore_comments */ false,\n                         /* ignore_trailing_commas */ true);\n    std::cout << j.dump(2) << '\\n';\n}\n

Output:

[json.exception.parse_error.101] parse error at line 11, column 9: syntax error while parsing value - unexpected ']'; expected '[', '{', or a literal\n{\n  \"planets\": [\n    \"Mercury\",\n    \"Venus\",\n    \"Earth\",\n    \"Mars\",\n    \"Jupiter\",\n    \"Uranus\",\n    \"Neptune\"\n  ]\n}\n
"},{"location":"features/trailing_commas/#see-also","title":"See also","text":"
  • parse - deserialize from a compatible input
  • Comments - ignore // and /* */ comments while parsing
  • Parsing - overview of the parsing functions
  • Parsing Untrusted Input - limits and checks for input you do not control
"},{"location":"features/type_recipes/","title":"Recipes for Common Types","text":"

The library converts the standard containers, strings, numbers, tuples, std::optional, and std::filesystem::path (the last two since version 3.12.0, C++17) out of the box, and your own types once you write conversion functions or use the macros (see Arbitrary type conversions). It deliberately does not convert smart pointers, std::variant, std::chrono types, or class hierarchies, because there is more than one reasonable JSON representation for each of them. This page shows a representation for each that you can copy and adapt.

All recipes use a specialization of adl_serializer, which you may provide for types you do not own, or free to_json/from_json functions in the namespace of the type. Place them where they are visible before any code that converts the type; see Why isn't my to_json found?.

"},{"location":"features/type_recipes/#smart-pointers","title":"Smart pointers","text":"

A std::shared_ptr<T> or std::unique_ptr<T> is written as the value it points to, or as null for an empty pointer, and read back by allocating a new T:

Example: serialize shared_ptr and unique_ptr
#include <iostream>\n#include <memory>\n#include <vector>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nnamespace nlohmann\n{\ntemplate <typename T>\nstruct adl_serializer<std::shared_ptr<T>>\n{\n    static void to_json(json& j, const std::shared_ptr<T>& p)\n    {\n        if (p)\n        {\n            j = *p;\n        }\n        else\n        {\n            j = nullptr;\n        }\n    }\n\n    static void from_json(const json& j, std::shared_ptr<T>& p)\n    {\n        if (j.is_null())\n        {\n            p = nullptr;\n        }\n        else\n        {\n            p = std::make_shared<T>(j.get<typename std::remove_const<T>::type>());\n        }\n    }\n};\n\ntemplate <typename T>\nstruct adl_serializer<std::unique_ptr<T>>\n{\n    static void to_json(json& j, const std::unique_ptr<T>& p)\n    {\n        if (p)\n        {\n            j = *p;\n        }\n        else\n        {\n            j = nullptr;\n        }\n    }\n\n    static void from_json(const json& j, std::unique_ptr<T>& p)\n    {\n        if (j.is_null())\n        {\n            p = nullptr;\n        }\n        else\n        {\n            p = std::make_unique<T>(j.get<T>());\n        }\n    }\n};\n} // namespace nlohmann\n\nstruct point\n{\n    int x;\n    int y;\n};\n\nNLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(point, x, y)\n\nint main()\n{\n    // an empty pointer is written as null\n    const std::vector<std::shared_ptr<point>> points = {std::make_shared<point>(point{1, 2}), nullptr};\n    const json j = points;\n    std::cout << j << '\\n';\n\n    // reading allocates new objects\n    const auto back = j.get<std::vector<std::shared_ptr<point>>>();\n    std::cout << back[0]->x << \", \" << back[0]->y << \", \" << (back[1] == nullptr) << '\\n';\n\n    // pointers to const and unique_ptr work as well\n    const auto const_ptr = j[0].get<std::shared_ptr<const point>>();\n    const auto unique = j[0].get<std::unique_ptr<point>>();\n    std::cout << const_ptr->y << \", \" << unique->x << '\\n';\n}\n

Output:

[{\"x\":1,\"y\":2},null]\n1, 2, 1\n2, 1\n

With this, containers of smart pointers, pointers to const, and members of these types in your own structs convert as usual. A pointer to a base class cannot be filled this way, because T would have to be created as a derived type; see the next section.

Reading creates a new object. Two shared_ptrs that pointed to the same object are written twice and read back as two separate objects.

"},{"location":"features/type_recipes/#class-hierarchies","title":"Class hierarchies","text":"

Derived classes whose type is known at compile time

If you only need to serialize the data members of a derived class, and the code always knows the concrete type, you do not need a type tag. The NLOHMANN_DEFINE_DERIVED_TYPE_* macros (since version 3.12.0) add the members of the derived class to those of its base class. This section is for the case where the concrete type is only known at run time, such as a std::unique_ptr<shape> that holds a circle or a rectangle.

JSON has no notion of types, so a value in a hierarchy needs a type tag that says which derived class to create. Write the tag in the object, and select the class from it when reading:

Example: serialize a class hierarchy with a type tag
#include <iostream>\n#include <memory>\n#include <stdexcept>\n#include <vector>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nstruct shape\n{\n    virtual ~shape() = default;\n    virtual json serialize() const = 0;\n};\n\nstruct circle : shape\n{\n    double radius;\n\n    explicit circle(double r) : radius(r) {}\n\n    json serialize() const override\n    {\n        return {{\"type\", \"circle\"}, {\"radius\", radius}};\n    }\n};\n\nstruct rectangle : shape\n{\n    double width;\n    double height;\n\n    rectangle(double w, double h) : width(w), height(h) {}\n\n    json serialize() const override\n    {\n        return {{\"type\", \"rectangle\"}, {\"width\", width}, {\"height\", height}};\n    }\n};\n\nnamespace nlohmann\n{\ntemplate <>\nstruct adl_serializer<std::unique_ptr<shape>>\n{\n    static void to_json(json& j, const std::unique_ptr<shape>& p)\n    {\n        j = p ? p->serialize() : json(nullptr);\n    }\n\n    static void from_json(const json& j, std::unique_ptr<shape>& p)\n    {\n        if (j.is_null())\n        {\n            p.reset();\n            return;\n        }\n\n        const auto& type = j.at(\"type\").get_ref<const std::string&>();\n        if (type == \"circle\")\n        {\n            p = std::make_unique<circle>(j.at(\"radius\").get<double>());\n        }\n        else if (type == \"rectangle\")\n        {\n            p = std::make_unique<rectangle>(j.at(\"width\").get<double>(), j.at(\"height\").get<double>());\n        }\n        else\n        {\n            throw std::invalid_argument(\"unknown shape type: \" + type);\n        }\n    }\n};\n} // namespace nlohmann\n\nint main()\n{\n    std::vector<std::unique_ptr<shape>> shapes;\n    shapes.push_back(std::make_unique<circle>(1.5));\n    shapes.push_back(std::make_unique<rectangle>(2, 3));\n\n    const json j = shapes;\n    std::cout << j << '\\n';\n\n    // reading creates objects of the derived types\n    const auto back = j.get<std::vector<std::unique_ptr<shape>>>();\n    std::cout << std::boolalpha;\n    std::cout << \"first is a circle: \" << (dynamic_cast<circle*>(back[0].get()) != nullptr) << '\\n';\n    std::cout << \"second is a rectangle: \" << (dynamic_cast<rectangle*>(back[1].get()) != nullptr) << '\\n';\n\n    // an unknown type tag is reported\n    try\n    {\n        json{{\"type\", \"star\"}}.get<std::unique_ptr<shape>>();\n    }\n    catch (const std::invalid_argument& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n}\n

Output:

[{\"radius\":1.5,\"type\":\"circle\"},{\"height\":3.0,\"type\":\"rectangle\",\"width\":2.0}]\nfirst is a circle: true\nsecond is a rectangle: true\nunknown shape type: star\n

A std::vector<std::unique_ptr<shape>> converts to an array of tagged objects and back, creating a circle and a rectangle. The same works for std::shared_ptr<shape>. Remember the virtual destructor: without it, deleting a derived object through the base pointer is undefined behavior.

"},{"location":"features/type_recipes/#stdvariant","title":"std::variant","text":"

A variant has the same problem: the alternative must be recorded. If the alternatives are your own types, write a type tag next to their members, exactly as for a hierarchy:

Example: serialize a std::variant with a type tag
#include <iostream>\n#include <stdexcept>\n#include <variant>\n#include <vector>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nnamespace geo\n{\nstruct circ\n{\n    double radius;\n};\n\nstruct rect\n{\n    double width;\n    double height;\n};\n\nNLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(circ, radius)\nNLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(rect, width, height)\n\nusing figure = std::variant<circ, rect>;\n\nvoid to_json(json& j, const figure& f)\n{\n    std::visit([&j](const auto & alternative)\n    {\n        j = alternative;\n    }, f);\n    j[\"type\"] = std::holds_alternative<circ>(f) ? \"circ\" : \"rect\";\n}\n\nvoid from_json(const json& j, figure& f)\n{\n    const auto& type = j.at(\"type\").get_ref<const std::string&>();\n    if (type == \"circ\")\n    {\n        f = j.get<circ>();\n    }\n    else if (type == \"rect\")\n    {\n        f = j.get<rect>();\n    }\n    else\n    {\n        throw std::invalid_argument(\"unknown figure type: \" + type);\n    }\n}\n} // namespace geo\n\nint main()\n{\n    const std::vector<geo::figure> figures = {geo::circ{2}, geo::rect{3, 4}};\n\n    const json j = figures;\n    std::cout << j << '\\n';\n\n    const auto back = j.get<std::vector<geo::figure>>();\n    std::cout << \"alternatives read back: \" << back[0].index() << \", \" << back[1].index() << '\\n';\n}\n

Output:

[{\"radius\":2.0,\"type\":\"circ\"},{\"height\":4.0,\"type\":\"rect\",\"width\":3.0}]\nalternatives read back: 0, 1\n

In the example, the functions are found because geo is the namespace of the template arguments of std::variant<circ, rect>; for a variant of only standard types (for example std::variant<int, std::string>) there is no such namespace, and you need an adl_serializer specialization or a wrapper type of your own.

If the alternatives are JSON-native (numbers, strings, ...), a variant such as std::variant<int, std::string> can instead be written as the plain value, and read by testing the JSON type (is_number_integer(), is_string()) to choose the alternative.

"},{"location":"features/type_recipes/#stdchrono","title":"std::chrono","text":"

A duration is written as an object with the keys unit and value, for example {\"unit\": \"ms\", \"value\": 1500}, so the JSON value is self-describing. The serializer names the unit of the period (ns, us, ms, s, min, h; extend the list for other periods), and the deserializer rejects a value whose unit differs from the requested duration type instead of silently misreading it:

Example: serialize durations and system_clock time points
#include <chrono>\n#include <iostream>\n#include <stdexcept>\n#include <string>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\n// the name of a period; extend the list for the periods you use\ntemplate <typename Period> const char* unit_name();\ntemplate <> const char* unit_name<std::nano>()\n{\n    return \"ns\";\n}\ntemplate <> const char* unit_name<std::micro>()\n{\n    return \"us\";\n}\ntemplate <> const char* unit_name<std::milli>()\n{\n    return \"ms\";\n}\ntemplate <> const char* unit_name<std::ratio<1>>()\n{\n    return \"s\";\n}\ntemplate <> const char* unit_name<std::ratio<60>>()\n{\n    return \"min\";\n}\ntemplate <> const char* unit_name<std::ratio<3600>>()\n{\n    return \"h\";\n}\n\nnamespace nlohmann\n{\ntemplate <typename Rep, typename Period>\nstruct adl_serializer<std::chrono::duration<Rep, Period>>\n{\n    static void to_json(json& j, const std::chrono::duration<Rep, Period>& d)\n    {\n        j = {{\"unit\", unit_name<Period>()}, {\"value\", d.count()}};\n    }\n\n    static void from_json(const json& j, std::chrono::duration<Rep, Period>& d)\n    {\n        if (j.at(\"unit\").get<std::string>() != unit_name<Period>())\n        {\n            throw std::invalid_argument(\"unexpected unit \" + j.at(\"unit\").dump());\n        }\n        d = std::chrono::duration<Rep, Period>(j.at(\"value\").get<Rep>());\n    }\n};\n\ntemplate <typename Duration>\nstruct adl_serializer<std::chrono::time_point<std::chrono::system_clock, Duration>>\n{\n    static void to_json(json& j, const std::chrono::time_point<std::chrono::system_clock, Duration>& t)\n    {\n        j = t.time_since_epoch();\n    }\n\n    static void from_json(const json& j, std::chrono::time_point<std::chrono::system_clock, Duration>& t)\n    {\n        t = std::chrono::time_point<std::chrono::system_clock, Duration>(j.get<Duration>());\n    }\n};\n} // namespace nlohmann\n\nint main()\n{\n    using namespace std::chrono;\n\n    std::cout << std::boolalpha;\n\n    // the unit is part of the JSON value\n    const json timeout = milliseconds(1500);\n    std::cout << \"duration: \" << timeout << '\\n';\n    std::cout << \"as milliseconds: \" << timeout.get<milliseconds>().count() << '\\n';\n\n    // reading with a different unit is rejected\n    try\n    {\n        timeout.get<seconds>();\n    }\n    catch (const std::invalid_argument& e)\n    {\n        std::cout << \"error: \" << e.what() << '\\n';\n    }\n\n    // a system_clock time point is the time since the Unix epoch\n    const time_point<system_clock, milliseconds> t(milliseconds(1700000000123));\n    const json stamp = t;\n    std::cout << \"time point: \" << stamp << '\\n';\n\n    const auto back = stamp.get<time_point<system_clock, milliseconds>>();\n    std::cout << \"round trip: \" << (back == t) << '\\n';\n}\n

Output:

duration: {\"unit\":\"ms\",\"value\":1500}\nas milliseconds: 1500\nerror: unexpected unit \"ms\"\ntime point: {\"unit\":\"ms\",\"value\":1700000000123}\nround trip: true\n

A system_clock::time_point with millisecond precision is written as the duration since the Unix epoch, that is, as an object with unit and value. The time point serializer is limited to system_clock, because the epoch of other clocks (for example steady_clock) has no meaning outside the running program.

If you prefer a text representation such as ISO 8601 (2023-11-14T22:13:20Z), write the string with std::format(\"{:%FT%TZ}\", t) and read it with std::chrono::parse (both C++20), or with a date library, in the same two functions.

"},{"location":"features/type_recipes/#see-also","title":"See also","text":"
  • Arbitrary type conversions - the conversion mechanism and macros
  • Why isn't my to_json found? - troubleshoot conversion functions that are not picked up
  • Converting values - get, implicit conversions, and std::optional
  • NLOHMANN_DEFINE_DERIVED_TYPE - conversion functions for derived classes
  • adl_serializer - customize conversions for third-party types
  • get - convert a JSON value to a C++ type
"},{"location":"features/binary_formats/","title":"Binary Formats","text":"

Though JSON is a ubiquitous data format, it is not a very compact format suitable for data exchange, for instance, over a network. Hence, the library supports

  • BJData (Binary JData),
  • BON8 (Binary Object Notation 8),
  • BSON (Binary JSON),
  • CBOR (Concise Binary Object Representation),
  • MessagePack, and
  • UBJSON (Universal Binary JSON)

to efficiently encode JSON values to byte vectors and to decode such vectors.

"},{"location":"features/binary_formats/#comparison","title":"Comparison","text":""},{"location":"features/binary_formats/#completeness","title":"Completeness","text":"Format Serialization Deserialization BJData complete incomplete: no column-major ND-arrays, no Draft 4 SoA/extension types BON8 incomplete: no unsigned integers above int64 complete BSON incomplete: top-level value must be an object incomplete, but all JSON types are supported CBOR complete incomplete, but all JSON types are supported MessagePack complete incomplete, but all JSON types are supported UBJSON complete complete"},{"location":"features/binary_formats/#binary-values","title":"Binary values","text":"Format Binary values Binary subtypes BJData supported (Draft 3 only) not supported BON8 not supported not supported BSON supported supported CBOR supported supported MessagePack supported supported UBJSON not supported not supported

See binary values for more information.

"},{"location":"features/binary_formats/#sizes","title":"Sizes","text":"Format canada.json twitter.json citm_catalog.json jeopardy.json BJData 53.2 % 91.1 % 78.1 % 96.6 % BJData (size) 58.6 % 92.1 % 86.7 % 97.4 % BJData (size+type) 58.6 % 92.1 % 86.5 % 97.4 % BON8 50.5 % 83.8 % 63.5 % 87.5 % BSON 85.8 % 95.2 % 95.8 % 106.7 % CBOR 50.5 % 86.3 % 68.4 % 88.0 % MessagePack 50.5 % 86.0 % 68.5 % 87.9 % UBJSON 53.2 % 91.3 % 78.2 % 96.6 % UBJSON (size) 58.6 % 92.3 % 86.8 % 97.4 % UBJSON (size+type) 55.9 % 92.3 % 85.0 % 95.0 %

Size of each test file in each format, in percent of the minified JSON value; the smallest size per file is printed in bold. The (size) and (size+type) rows are written with the use_size and use_type options of to_bjdata and to_ubjson.

Size of canada.json in each binary format relative to minified J\u200bSON B\u200bJData 53.2 %; B\u200bON8 50.5 %; B\u200bSON 85.8 %; C\u200bBOR 50.5 %; MessagePack 50.5 %; U\u200bBJSON 53.2 %. Smallest: B\u200bON8 and C\u200bBOR and MessagePack. canada.json 0 % 50 % B\u200bJData canada.json, B\u200bJData: 53.2 % of minified J\u200bSON B\u200bON8 canada.json, B\u200bON8: 50.5 % of minified J\u200bSON (smallest) B\u200bSON canada.json, B\u200bSON: 85.8 % of minified J\u200bSON C\u200bBOR canada.json, C\u200bBOR: 50.5 % of minified J\u200bSON (smallest) MessagePack canada.json, MessagePack: 50.5 % of minified J\u200bSON (smallest) U\u200bBJSON canada.json, U\u200bBJSON: 53.2 % of minified J\u200bSON minified J\u200bSON = 100 % 100 % 53.2 % 50.5 % 85.8 % 50.5 % 50.5 % 53.2 %

Size of twitter.json in each binary format relative to minified J\u200bSON B\u200bJData 91.1 %; B\u200bON8 83.8 %; B\u200bSON 95.2 %; C\u200bBOR 86.3 %; MessagePack 86 %; U\u200bBJSON 91.3 %. Smallest: B\u200bON8. twitter.json 0 % 50 % B\u200bJData twitter.json, B\u200bJData: 91.1 % of minified J\u200bSON B\u200bON8 twitter.json, B\u200bON8: 83.8 % of minified J\u200bSON (smallest) B\u200bSON twitter.json, B\u200bSON: 95.2 % of minified J\u200bSON C\u200bBOR twitter.json, C\u200bBOR: 86.3 % of minified J\u200bSON MessagePack twitter.json, MessagePack: 86 % of minified J\u200bSON U\u200bBJSON twitter.json, U\u200bBJSON: 91.3 % of minified J\u200bSON minified J\u200bSON = 100 % 100 % 91.1 % 83.8 % 95.2 % 86.3 % 86.0 % 91.3 %

Size of citm_catalog.json in each binary format relative to minified J\u200bSON B\u200bJData 78.1 %; B\u200bON8 63.5 %; B\u200bSON 95.8 %; C\u200bBOR 68.4 %; MessagePack 68.5 %; U\u200bBJSON 78.2 %. Smallest: B\u200bON8. citm_catalog.json 0 % 50 % B\u200bJData citm_catalog.json, B\u200bJData: 78.1 % of minified J\u200bSON B\u200bON8 citm_catalog.json, B\u200bON8: 63.5 % of minified J\u200bSON (smallest) B\u200bSON citm_catalog.json, B\u200bSON: 95.8 % of minified J\u200bSON C\u200bBOR citm_catalog.json, C\u200bBOR: 68.4 % of minified J\u200bSON MessagePack citm_catalog.json, MessagePack: 68.5 % of minified J\u200bSON U\u200bBJSON citm_catalog.json, U\u200bBJSON: 78.2 % of minified J\u200bSON minified J\u200bSON = 100 % 100 % 78.1 % 63.5 % 95.8 % 68.4 % 68.5 % 78.2 %

Size of jeopardy.json in each binary format relative to minified J\u200bSON B\u200bJData 96.6 %; B\u200bON8 87.5 %; B\u200bSON 106.7 %; C\u200bBOR 88 %; MessagePack 87.9 %; U\u200bBJSON 96.6 %. Smallest: B\u200bON8. jeopardy.json 0 % 50 % B\u200bJData jeopardy.json, B\u200bJData: 96.6 % of minified J\u200bSON B\u200bON8 jeopardy.json, B\u200bON8: 87.5 % of minified J\u200bSON (smallest) B\u200bSON jeopardy.json, B\u200bSON: 106.7 % of minified J\u200bSON C\u200bBOR jeopardy.json, C\u200bBOR: 88 % of minified J\u200bSON MessagePack jeopardy.json, MessagePack: 87.9 % of minified J\u200bSON U\u200bBJSON jeopardy.json, U\u200bBJSON: 96.6 % of minified J\u200bSON minified J\u200bSON = 100 % 100 % 96.6 % 87.5 % 106.7 % 88.0 % 87.9 % 96.6 %

The table above as charts: size per base format relative to minified JSON (vertical line at 100 %); the smallest format per file is drawn in a stronger colour than the others. The size and size+type variants of BJData and UBJSON are omitted here; see the table.

"},{"location":"features/binary_formats/#see-also","title":"See also","text":"
  • cbor_tag_handler_t - how CBOR tags are handled when parsing
  • JSON_STRICT_BINARY_UTF8 - reject ill-formed UTF-8 in strings
  • Binary values - binary values and subtypes
  • to_cbor - / from_cbor, to_msgpack / from_msgpack, to_bson / from_bson, to_ubjson / from_ubjson, to_bjdata / from_bjdata, to_bon8 / from_bon8 - the conversion functions
  • Parsing untrusted input - harden an application that parses untrusted binary data
  • SAX interface - decode binary formats without building a value
"},{"location":"features/binary_formats/bjdata/","title":"BJData","text":"

The BJData format was derived from and improved upon Universal Binary JSON(UBJSON) specification (Draft 12). Specifically, it introduces an optimized array container for efficient storage of N-dimensional packed arrays (ND-arrays); it also adds four new type markers - [u] - uint16, [m] - uint32, [M] - uint64, and [h] - float16 - to unambiguously map common binary numeric types (Draft 3 adds [B] - byte); furthermore, it uses little-endian (LE) to store all numerics instead of big-endian (BE) as in UBJSON to avoid unnecessary conversions on commonly available platforms.

Compared to other binary JSON-like formats such as MessagePack and CBOR, both BJData and UBJSON demonstrate a rare combination of being both binary and quasi-human-readable. This is because all semantic elements in BJData and UBJSON, including the data-type markers and name/string types, are directly human-readable. Data stored in the BJData/UBJSON format is not only compact in size, fast to read/write, but also can be directly searched or read using simple processing.

References

  • BJData Specification (Draft 3)
  • BJData Specification (Draft 2)

Supported drafts

The library supports BJData Draft 2 (the default) and Draft 3, except for column-major N-dimensional arrays (see below). The draft used for writing is selected with the version parameter of to_bjdata; from_bjdata has no such parameter and reads the markers of both drafts.

Draft 4 and column-major ND-arrays are not supported

BJData Draft 4 (April 2026) adds structure-of-arrays (SoA) containers ([$ or {$ followed by a schema object) and the extension type E. from_bjdata does not implement them and throws parse_error.112 for such input; to_bjdata never writes them.

Likewise, column-major ND-arrays of Draft 3 (the # marker followed by an array that wraps the dimension vector) are rejected with parse_error.113.

"},{"location":"features/binary_formats/bjdata/#byte-layout","title":"Byte layout","text":"

BJData follows the structure of UBJSON: a one-byte, human-readable ASCII type marker followed by the payload of that type, with strings prefixed by a length that is itself an integer value. In contrast to UBJSON, numbers are stored in little-endian byte order, and additional markers cover unsigned 16/32/64-bit integers, half-precision floats, and bytes. Containers can be written unoptimized (opened with [ or {, closed with ] or }) or optimized with a count (#), optionally preceded by a declared element type ($). BJData extends the optimized form: the count can be a list of dimensions, which stores an N-dimensional packed array as a flat sequence of values without any per-element markers.

Consider the following JSON value (shown formatted for readability):

{\n  \"id\": 300,\n  \"name\": \"json\",\n  \"pi\": 3.14,\n  \"tags\": [\n    \"a\",\n    \"b\"\n  ]\n}\n

to_bjdata encodes it to 51 bytes (shown in hexadecimal; the encoding contains no whitespace). The colors mark the role of each byte: type/marker length/count/size data.

JSONBytesMeaning {7Bobject start ({) \"id\": 300,69 02 69 64 49 2C 01key: length 2 as int8 (i), then UTF-8 bytes; value: int16 (I), little-endian \"name\": \"json\",69 04 6E 61 6D 65 53 69 04 6A 73 6F 6Ekey: length 4; value: string (S), length 4 as int8, UTF-8 bytes \"pi\": 3.14,69 02 70 69 44 1F 85 EB 51 B8 1E 09 40key: length 2; value: float64 (D), little-endian \"tags\": [69 04 74 61 67 73 5Bkey: length 4; value: array start ([) \"a\",53 69 01 61string, length 1 \"b\"53 69 01 62string, length 1 ]5Darray end (]) }7Dobject end (})"},{"location":"features/binary_formats/bjdata/#serialization","title":"Serialization","text":"

The library uses the following mapping from JSON values types to BJData types according to the BJData specification:

JSON value type value/range BJData type marker null null null Z boolean true true T boolean false false F number_integer -9223372036854775808..-2147483649 int64 L number_integer -2147483648..-32769 int32 l number_integer -32768..-129 int16 I number_integer -128..127 int8 i number_integer 128..255 uint8 U number_integer 256..32767 int16 I number_integer 32768..65535 uint16 u number_integer 65536..2147483647 int32 l number_integer 2147483648..4294967295 uint32 m number_integer 4294967296..9223372036854775807 int64 L number_integer 9223372036854775808..18446744073709551615 uint64 M number_unsigned 0..127 int8 i number_unsigned 128..255 uint8 U number_unsigned 256..32767 int16 I number_unsigned 32768..65535 uint16 u number_unsigned 65536..2147483647 int32 l number_unsigned 2147483648..4294967295 uint32 m number_unsigned 4294967296..9223372036854775807 int64 L number_unsigned 9223372036854775808..18446744073709551615 uint64 M number_float any value float64 D string with shortest length indicator string S array see notes on optimized format/ND-array array [ object see notes on optimized format map { binary see notes on binary values array [$B (Draft 3 with use_size and use_type), [U, or [B otherwise

Complete mapping

The mapping is complete in the sense that any JSON value type can be converted to a BJData value.

Any BJData output created by to_bjdata can be successfully parsed by from_bjdata.

Size constraints

The following values can not be converted to a BJData value:

  • strings with more than 18446744073709551615 bytes, i.e., 264-1 bytes (theoretical)

UTF-8 validation of string values and object keys

BJData strings must use UTF-8 encoding. By default (the error_handler parameter left at keep), to_bjdata() writes the bytes of string values and object keys unchanged, even if they are not valid UTF-8. With error_handler_t::strict, it throws type_error.316 for ill-formed UTF-8 instead; replace/ignore sanitize the string. JSON_STRICT_BINARY_UTF8 makes strict the default.

Unused BJData markers

The following markers are not written:

  • N: no-op values are not created (they are skipped when reading).
  • C: single-character strings are serialized with S markers (C is read, and written for the elements of ND-arrays with \"_ArrayType_\": \"char\").
  • h: floating-point numbers are written as D, not as float16 (h is read).
  • B: only written in Draft 3 mode.
  • d is only written for single ND-arrays or if number_float_t is float; H is only written for integers wider than 64 bits (custom number_integer_t/number_unsigned_t). An unsigned integer above 9223372036854775807 is written as M.

NaN/infinity handling

If NaN or Infinity are stored inside a JSON number, they are serialized properly. This behavior differs from the dump() function which serializes NaN or Infinity to null.

Endianness

A breaking difference between BJData and UBJSON is the endianness of numerical values. In BJData, all numerical data types (integers UiuImlML and floating-point values hdD) are stored in the little-endian (LE) byte order as opposed to big-endian as used by UBJSON. Adopting LE to store numeric records avoids unnecessary byte swapping on most modern computers where LE is used as the default byte order.

Optimized formats

Optimized formats for containers are supported via two parameters of to_bjdata:

  • Parameter use_size adds size information to the beginning of a container and removes the closing marker.
  • Parameter use_type further checks whether all elements of a container have the same type and adds the type marker to the beginning of the container. The use_type parameter must only be used together with use_size = true.

Note that use_size = true alone may result in larger representations - the benefit of this parameter is that the receiving side is immediately informed of the number of elements in the container.

ND-array optimized format

BJData extends UBJSON's optimized array size marker to support ND-arrays of uniform numerical data types (referred to as packed arrays). For example, the 2-D uint8 integer array [[1,2],[3,4],[5,6]], stored as nested optimized array in UBJSON [ [$U#i2 1 2 [$U#i2 3 4 [$U#i2 5 6 ], can be further compressed in BJData to [$U#[$i#i2 3 2 1 2 3 4 5 6 or [$U#[i3 i2] 1 2 3 4 5 6.

To maintain type and size information, ND-arrays are converted to JSON objects following the annotated array format (defined in the JData specification (Draft 3)), when parsed using from_bjdata. For example, the above 2-D uint8 array can be parsed and accessed as

{\n    \"_ArrayType_\": \"uint8\",\n    \"_ArraySize_\": [3,2],\n    \"_ArrayData_\": [1,2,3,4,5,6]\n}\n

ND-arrays with the element type h (float16) are returned with \"_ArrayType_\": \"half\". to_bjdata does not pack \"half\" objects; they are written as regular objects, which read back as an equal value.

Likewise, when a JSON object in the above form is serialized using to_bjdata, it is automatically converted into a compact BJData ND-array.

When parsing, an ND-array whose dimension vector is empty, contains a single integer, contains two integers with the first being 1, or contains a 0 is returned as a regular (possibly empty) array rather than an annotated object.

An object is only converted if the annotation describes a packed array that is parsed back into the same annotated object; otherwise it is serialized as a regular JSON object, so the annotation is never lost in a round trip. This requires all of the following:

  • the object has exactly the three keys \"_ArrayType_\", \"_ArraySize_\", and \"_ArrayData_\" (any other key, e.g., \"_ArrayOrder_\", makes it a regular object),
  • \"_ArrayType_\" is one of uint8, int8, uint16, int16, uint32, int32, uint64, int64, single, double, char, or (only with version = bjdata_version_t::draft3, since the B marker is not part of Draft 2) byte; the names are case-sensitive,
  • \"_ArraySize_\" is an array, since the dimensions are written as the ND-array header's length,
  • \"_ArraySize_\" has at least two entries and is not a two-entry row vector ([1,N]), since other shapes are parsed back as a regular array ([1,2,2] is packed, [1,4] is not),
  • every entry of \"_ArraySize_\" is a positive integer, and their product is representable as a std::size_t,
  • \"_ArrayData_\" is an array holding exactly that many elements, and
  • every element of \"_ArrayData_\" is a number of the kind named by \"_ArrayType_\": for the integer types, an integer (a floating-point number such as 1.0 does not qualify) that fits the named width (for char, 0..127); for double, a floating-point number (an integer such as 1 does not qualify); for single, a floating-point number that survives narrowing to float and back without change (for instance, 0.1 does not, since it is not exactly representable as float).

With ordered_json, an annotated object read from BJData has its keys in the order \"_ArrayType_\", \"_ArraySize_\", \"_ArrayData_\"; with json, they are sorted like those of any other object.

The current version of this library does not yet support automatic detection of and conversion from a nested JSON array input to a BJData ND-array.

Restrictions in optimized data types for arrays and objects

Due to diminished space saving, hampered readability, and increased security risks, in BJData, the allowed data types following the $ marker in an optimized array and object container are restricted to non-zero-fixed-length data types. Therefore, the valid optimized type markers can only be one of UiuImlMLhdDC, plus B since Draft 3 (the reader accepts B in both drafts). This also means other variable ([{SH) or zero-length types (TFZN) can not be used in an optimized array or object in BJData. The library enforces this restriction for both drafts. A C (char) element above 127 is rejected on read with parse_error.113, in 1-D and in N-dimensional arrays. With use_type, the elements must have the same marker ([1,200,3] is not optimized, since it mixes i and U); booleans, null, strings, arrays, and objects are never optimized with $.

Binary values

BJData provides a dedicated B marker (defined in the BJData specification (Draft 3)) that is used in optimized arrays to designate binary data. This means that, unlike UBJSON, binary data can be both serialized and deserialized.

To preserve compatibility with BJData Draft 2, the Draft 3 optimized binary array must be explicitly enabled: pass version = bjdata_version_t::draft3 together with use_size = true and use_type = true to to_bjdata. With Draft 3 and only use_size (or neither), a binary value is written as an array of B elements.

In Draft 2 mode (default), if the JSON data contains the binary type, the value is stored as a list of integers, as suggested by the BJData documentation. In particular, this means that the serialization and the deserialization of JSON containing binary values into BJData and back will result in a different JSON object.

Example: serialize JSON values to BJData, with and without size/type optimization
#include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\nusing namespace nlohmann::literals;\n\n// function to print BJData's diagnostic format\nvoid print_byte(uint8_t byte)\n{\n    if (32 < byte and byte < 128)\n    {\n        std::cout << static_cast<char>(byte);\n    }\n    else\n    {\n        std::cout << static_cast<int>(byte);\n    }\n}\n\nint main()\n{\n    // create a JSON value\n    json j = R\"({\"compact\": true, \"schema\": false})\"_json;\n\n    // serialize it to BJData\n    std::vector<std::uint8_t> v = json::to_bjdata(j);\n\n    // print the vector content\n    for (auto& byte : v)\n    {\n        print_byte(byte);\n    }\n    std::cout << '\\n';\n\n    // create an array of numbers\n    json array = {1, 2, 3, 4, 5, 6, 7, 8};\n\n    // serialize it to BJData using default representation\n    std::vector<std::uint8_t> v_array = json::to_bjdata(array);\n    // serialize it to BJData using size optimization\n    std::vector<std::uint8_t> v_array_size = json::to_bjdata(array, true);\n    // serialize it to BJData using type optimization\n    std::vector<std::uint8_t> v_array_size_and_type = json::to_bjdata(array, true, true);\n\n    // print the vector contents\n    for (auto& byte : v_array)\n    {\n        print_byte(byte);\n    }\n    std::cout << '\\n';\n\n    for (auto& byte : v_array_size)\n    {\n        print_byte(byte);\n    }\n    std::cout << '\\n';\n\n    for (auto& byte : v_array_size_and_type)\n    {\n        print_byte(byte);\n    }\n    std::cout << '\\n';\n}\n

Output:

{i7compactTi6schemaF}\n[i1i2i3i4i5i6i7i8]\n[#i8i1i2i3i4i5i6i7i8\n[$i#i812345678\n
"},{"location":"features/binary_formats/bjdata/#deserialization","title":"Deserialization","text":"

The library maps BJData types to JSON value types as follows:

BJData type JSON value type marker no-op no value, next value is read N null null Z false false F true true T float16 number_float h float32 number_float d float64 number_float D high-precision number number_integer, number_unsigned, or number_float H uint8 number_unsigned U int8 number_integer i uint16 number_unsigned u int16 number_integer I uint32 number_unsigned m int32 number_integer l uint64 number_unsigned M int64 number_integer L byte number_unsigned B string string S char string C array array (optimized values are supported) [ ND-array object (in JData annotated array format) [$.#[. object object (optimized values are supported) { binary binary (strongly-typed byte array) [$B

Complete mapping

The mapping is complete for the BJData types of Draft 2 and Draft 3 with one exception: column-major N-dimensional arrays are rejected with parse_error.113. The Draft 4 constructs (structure-of-arrays containers and the extension type E) are not supported either.

The digits of an H value are parsed like a JSON number: integers that fit 64 bits become number_integer or number_unsigned, anything else a number_float; invalid text throws parse_error.115.

Duplicate object keys

If an object contains the same key more than once, from_bjdata accepts it and keeps the last value; with ordered_json, the key keeps the position of its first occurrence.

Ill-formed UTF-8 in string values and object keys

BJData strings must use UTF-8 encoding, but checking it on read is opt-in: with the error_handler parameter left at keep (the default), from_bjdata() accepts a string value or object key whose bytes are not valid UTF-8 and hands them back unchanged. Passing error_handler_t::strict makes from_bjdata() check and throw parse_error.113 for ill-formed UTF-8, and replace/ignore sanitize the string instead of keeping it. However, dump() still requires valid UTF-8 and throws type_error.316 for a value read with the default keep handler, unless an error handler is passed that replaces or ignores the ill-formed bytes. to_bjdata()'s own error_handler parameter defaults to keep (see above), so such a value is written back unchanged.

Round trips

A value returned by from_bjdata can be serialized with to_bjdata using any combination of options and parsed back into an equal value, and serializing that value again with the same options produces the same bytes. The exception is binary values: they are only written as an optimized binary array ([$B) if Draft 3 is enabled and both use_size and use_type are set. Otherwise, they are written as arrays of integers and parsed back as such (see the notes on binary values above), and serializing such an array again may choose different, but equally valid, type markers. The bytes can then differ, but parsing them again yields the same value.

Example: deserialize a JSON value from BJData
#include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create byte vector\n    std::vector<std::uint8_t> v = {0x7B, 0x69, 0x07, 0x63, 0x6F, 0x6D, 0x70, 0x61,\n                                   0x63, 0x74, 0x54, 0x69, 0x06, 0x73, 0x63, 0x68,\n                                   0x65, 0x6D, 0x61, 0x69, 0x00, 0x7D\n                                  };\n\n    // deserialize it with BJData\n    json j = json::from_bjdata(v);\n\n    // print the deserialized JSON value\n    std::cout << std::setw(2) << j << '\\n';\n}\n

Output:

{\n  \"compact\": true,\n  \"schema\": 0\n}\n
"},{"location":"features/binary_formats/bjdata/#see-also","title":"See also","text":"
  • Binary formats - overview and comparison of the supported binary formats
  • Binary values - how binary values and subtypes map to BJData
  • to_bjdata - serialize a JSON value to BJData
  • from_bjdata - parse a JSON value from BJData
  • JSON_STRICT_BINARY_UTF8 - reject ill-formed UTF-8 in strings
  • SAX interface - decode binary formats without building a value
"},{"location":"features/binary_formats/bon8/","title":"BON8","text":"

BON8 (Binary Object Notation 8) is a compact binary serialization format for JSON values. It uses byte values that cannot begin a UTF-8 character as type markers, so strings are stored as plain UTF-8 without a length prefix: a string ends at the first byte that cannot continue it. Integers from -10 to 39, true, false, null, and the floating-point values -1.0, 0.0, and 1.0 take a single byte, and arrays and objects with up to four elements need no terminator.

References

  • BON8 specification
  • Reference implementation in HikoGUI
"},{"location":"features/binary_formats/bon8/#byte-layout","title":"Byte layout","text":"

BON8 exploits the fact that some byte values can never start a UTF-8 character. These bytes serve as type markers, so strings can be stored as plain UTF-8 without a length prefix: a string ends at the first byte that cannot continue it: a marker byte, or a lead byte 0xC2..0xF7 followed by a byte outside 0x80..0xBF. The ending byte is often the marker of the next value. Small integers, true, false, null, and a few common floats are a single byte. Arrays and objects are introduced by a marker; those with up to four elements encode their size in the marker and need no terminator, while larger ones are closed by the end marker 0xFE.

Consider the following JSON value (shown formatted for readability):

{\n  \"id\": 300,\n  \"name\": \"json\",\n  \"pi\": 3.14,\n  \"tags\": [\n    \"a\",\n    \"b\"\n  ]\n}\n

to_bon8 encodes it to 35 bytes (shown in hexadecimal; the encoding contains no whitespace). The colors mark the role of each byte: type/marker length/count/size data.

JSONBytesMeaning {8Aobject with 4 members \"id\": 300,69 64 C4 04key: UTF-8 bytes; the string ends at 0xC4, because the byte after it (0x04) is not a UTF-8 continuation byte, so 0xC4 starts an integer; value: 2-byte positive integer (lead byte, then a byte below 0x80) \"name\": \"json\",6E 61 6D 65 FF 6A 73 6F 6E FFkey: UTF-8 bytes; 0xFF terminates the string as another string follows; value: UTF-8 bytes; terminated as a string key follows \"pi\": 3.14,70 69 8F 40 09 1E B8 51 EB 85 1Fkey: UTF-8 bytes; value: binary64 (IEEE 754, big-endian); its marker also ends \"pi\" \"tags\": [74 61 67 73 82key: UTF-8 bytes; value: array with 2 elements; its marker also ends \"tags\" \"a\",61 FFUTF-8 bytes; terminated as a string follows \"b\"62 FFUTF-8 bytes; terminated as nothing follows ]no end marker: the element count was given up front }no end marker: the member count was given up front"},{"location":"features/binary_formats/bon8/#serialization","title":"Serialization","text":"

The library uses the following mapping from JSON values types to BON8 types according to the BON8 specification:

JSON value type value/range BON8 type first byte null null null 0xFA boolean true true 0xF9 boolean false false 0xF8 number_integer -9223372036854775808..-2147483649 int64 0x8D number_integer -2147483648..-33818507 int32 0x8C number_integer -33818506..-264075 4-byte negative integer 0xF0..0xF7 number_integer -264074..-1931 3-byte negative integer 0xE0..0xEF number_integer -1930..-11 2-byte negative integer 0xC2..0xDF number_integer -10..-1 1-byte negative integer 0xB8..0xC1 number_integer 0..39 1-byte positive integer 0x90..0xB7 number_integer 40..3879 2-byte positive integer 0xC2..0xDF number_integer 3880..528167 3-byte positive integer 0xE0..0xEF number_integer 528168..67637031 4-byte positive integer 0xF0..0xF7 number_integer 67637032..2147483647 int32 0x8C number_integer 2147483648..9223372036854775807 int64 0x8D number_unsigned 0..39 1-byte positive integer 0x90..0xB7 number_unsigned 40..3879 2-byte positive integer 0xC2..0xDF number_unsigned 3880..528167 3-byte positive integer 0xE0..0xEF number_unsigned 528168..67637031 4-byte positive integer 0xF0..0xF7 number_unsigned 67637032..2147483647 int32 0x8C number_unsigned 2147483648..9223372036854775807 int64 0x8D number_float -1.0 -1.0 0xFB number_float 0.0 0.0 0xFC number_float 1.0 1.0 0xFD number_float any other value representable by a float binary32 0x8E number_float any value NOT representable by a float binary64 0x8F string empty end of string 0xFF string non-empty UTF-8 string 0x00..0x7F, 0xC2..0xF4 array size: 0..4 array with count 0x80..0x84 array size: 5 or more array (terminated by 0xFE) 0x85 object size: 0..4 object with count 0x86..0x8A object size: 5 or more object (terminated by 0xFE) 0x8B binary size: 0..4 array with count 0x80..0x84 binary size: 5 or more array (terminated by 0xFE) 0x85

An integer that takes 2 to 4 bytes starts with a UTF-8 lead byte (0xC2..0xF7) that is followed by a byte that cannot continue a UTF-8 character: 0x00..0x7F for positive and 0xC0..0xFF for negative integers. A string is terminated by 0xFF only if it is empty, if another string follows it, or if nothing follows it in the message; otherwise, the byte after it ends it: the first byte of the next value, or the 0xFE that ends an array or object. For example, [\"e\"] is serialized as 0x81 0x65 0xFF, but [1,2,3,4,\"e\"] as 0x85 0x91 0x92 0x93 0x94 0x65 0xFE.

Complete mapping

Except for the values listed below, any JSON value can be converted to a BON8 value.

Any BON8 output created by to_bon8 can be successfully parsed by from_bon8.

Unsupported values

The following values can not be converted to a BON8 value:

  • integers outside the int64 range (unsigned integers above 9223372036854775807 and, for number types wider than 64 bits, any larger or smaller integer), because BON8 integers are limited to int64 (out_of_range.407)
  • strings that are not valid UTF-8, because the end of a string is determined from its encoding (type_error.316)

NaN/infinity handling

-0.0, Infinity, and -Infinity are serialized as binary32 (type 0x8E, 5 bytes total). NaN is serialized as the binary32 value 0x7F800001 that the specification recommends. This is in contrast to the dump function which serializes NaN or Infinity to null.

Binary values

BON8 has no binary type. Binary values are serialized as arrays of integers (0..255), so they are read back as arrays. The subtype is not serialized.

Canonical representation

The output follows the specification's canonical representation rules: every value uses the shortest encoding, floating-point numbers use binary32 whenever that loses no precision, and object keys are sorted by their UTF-8 code units. There are two exceptions:

  • Strings are not normalized to Unicode Normalization Form C (NFC).
  • Object keys are written in the order of the object type, which is sorted for json, but not for ordered_json.
Example: serialize a JSON value to BON8
#include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\nusing namespace nlohmann::literals;\n\nint main()\n{\n    // create a JSON value\n    json j = R\"({\"compact\": true, \"format\": \"BON8\", \"schema\": 0})\"_json;\n\n    // serialize it to BON8\n    std::vector<std::uint8_t> v = json::to_bon8(j);\n\n    // print the vector content\n    for (auto& byte : v)\n    {\n        std::cout << \"0x\" << std::hex << std::setw(2) << std::setfill('0') << static_cast<int>(byte) << \" \";\n    }\n    std::cout << '\\n';\n}\n

Output:

0x89 0x63 0x6f 0x6d 0x70 0x61 0x63 0x74 0xf9 0x66 0x6f 0x72 0x6d 0x61 0x74 0xff 0x42 0x4f 0x4e 0x38 0xff 0x73 0x63 0x68 0x65 0x6d 0x61 0x90 \n
"},{"location":"features/binary_formats/bon8/#deserialization","title":"Deserialization","text":"

The library maps BON8 types to JSON value types as follows:

BON8 type JSON value type first byte UTF-8 string string 0x00..0x7F array with count array 0x80..0x84 array (terminated by 0xFE) array 0x85 object with count object 0x86..0x8A object (terminated by 0xFE) object 0x8B int32 number_unsigned or number_integer 0x8C int64 number_unsigned or number_integer 0x8D binary32 number_float 0x8E binary64 number_float 0x8F 1-byte positive integer number_unsigned 0x90..0xB7 1-byte negative integer number_integer 0xB8..0xC1 UTF-8 string string 0xC2..0xF4, followed by 0x80..0xBF 2- to 4-byte positive integer number_unsigned 0xC2..0xF7, followed by 0x00..0x7F 2- to 4-byte negative integer number_integer 0xC2..0xF7, followed by 0xC0..0xFF false false 0xF8 true true 0xF9 null null 0xFA -1.0 number_float 0xFB 0.0 number_float 0xFC 1.0 number_float 0xFD empty string string 0xFF

Non-negative integers are read as number_unsigned, negative integers as number_integer.

A byte 0xF5..0xF7 followed by 0x80..0xBF is neither a string nor an integer and is rejected with parse_error.112 (invalid UTF-8 byte). The same error is reported for any other invalid byte (such as a stray 0xFE), for ill-formed UTF-8, and for an object key that is not a string. Input that ends prematurely, trailing data after the value, and a missing final 0xFF after a string at the end of the message are reported as parse_error.110.

Non-canonical input

Values that do not use the canonical representation, such as integers with a longer encoding than necessary, arrays and objects with up to four elements that are terminated by 0xFE, unsorted object keys, or a 0xFF after a string that would also end without it, are accepted. A second 0xFF is not a terminator but an empty string.

Strings must be valid UTF-8, and a string at the very end of a message must be terminated by 0xFF.

Duplicate object keys are accepted; the last value wins (ordered_json keeps the position of the first occurrence). The specification does not say how to treat them; the HikoGUI reference decoder keeps the first value.

Round trips

Any BON8 output created by to_bon8 can be successfully parsed by from_bon8.

Example: deserialize a JSON value from BON8
#include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create byte vector\n    std::vector<std::uint8_t> v = {0x89, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x63, 0x74,\n                                   0xf9, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0xff,\n                                   0x42, 0x4f, 0x4e, 0x38, 0xff, 0x73, 0x63, 0x68,\n                                   0x65, 0x6d, 0x61, 0x90\n                                  };\n\n    // deserialize it with BON8\n    json j = json::from_bon8(v);\n\n    // print the deserialized JSON value\n    std::cout << std::setw(2) << j << '\\n';\n}\n

Output:

{\n  \"compact\": true,\n  \"format\": \"BON8\",\n  \"schema\": 0\n}\n
"},{"location":"features/binary_formats/bon8/#see-also","title":"See also","text":"
  • Binary formats - overview and comparison of the supported binary formats
  • Binary values - how binary values and subtypes map to BON8
  • to_bon8 - serialize a JSON value to BON8
  • from_bon8 - parse a JSON value from BON8
  • JSON_STRICT_BINARY_UTF8 - reject ill-formed UTF-8 in strings
  • SAX interface - decode binary formats without building a value
"},{"location":"features/binary_formats/bson/","title":"BSON","text":"

BSON, short for Binary JSON, is a binary-encoded serialization of JSON-like documents. Like JSON, BSON supports the embedding of documents and arrays within other documents and arrays. BSON also contains extensions that allow representation of data types that are not part of the JSON spec. For example, BSON has a Date type and a BinData type.

References

  • BSON Website - the main source on BSON
  • BSON Specification - the specification
"},{"location":"features/binary_formats/bson/#byte-layout","title":"Byte layout","text":"

A BSON document is a length-prefixed sequence of elements. The first four bytes hold the total size of the document (little-endian int32), followed by the elements, and a final 0x00 byte ends the document. Each element starts with a one-byte type, followed by its key as a NUL-terminated string and the value, whose encoding depends on the type. Arrays are documents whose keys are the decimal indices \"0\", \"1\", ...; nesting is expressed by embedding documents. Because every document announces its size, a reader can skip over it without parsing its content. The top level of a BSON value is always a document, which is why only JSON objects can be serialized.

Consider the following JSON value (shown formatted for readability):

{\n  \"id\": 300,\n  \"name\": \"json\",\n  \"pi\": 3.14,\n  \"tags\": [\n    \"a\",\n    \"b\"\n  ]\n}\n

to_bson encodes it to 69 bytes (shown in hexadecimal; the encoding contains no whitespace). The colors mark the role of each byte: type/marker length/count/size data.

JSONBytesMeaning {45 00 00 00document size: 69 bytes (int32, little-endian) \"id\": 300,10 69 64 00 2C 01 00 00int32 element; key as NUL-terminated string; value (little-endian) \"name\": \"json\",02 6E 61 6D 65 00 05 00 00 00 6A 73 6F 6E 00string element; key; length incl. NUL (int32); NUL-terminated UTF-8 bytes \"pi\": 3.14,01 70 69 00 1F 85 EB 51 B8 1E 09 40double element; key; value (little-endian) \"tags\": [04 74 61 67 73 00 17 00 00 00array element; key; embedded document of 23 bytes (keys are the indices) \"a\",02 30 00 02 00 00 00 61 00string element; key \"0\"; length 2; a + NUL \"b\"02 31 00 02 00 00 00 62 00string element; key \"1\"; length 2; b + NUL ]00end of the array document }00end of the document"},{"location":"features/binary_formats/bson/#serialization","title":"Serialization","text":"

The library uses the following mapping from JSON values types to BSON types:

JSON value type value/range BSON type marker null null null 0x0A boolean true, false boolean 0x08 number_integer -9223372036854775808..-2147483649 int64 0x12 number_integer -2147483648..2147483647 int32 0x10 number_integer 2147483648..9223372036854775807 int64 0x12 number_unsigned 0..2147483647 int32 0x10 number_unsigned 2147483648..9223372036854775807 int64 0x12 number_unsigned 9223372036854775808..18446744073709551615 uint64 0x11 number_float any value double 0x01 string any value string 0x02 array any value document 0x04 object any value document 0x03 binary any value binary 0x05

Incomplete mapping

The mapping is incomplete, since only JSON-objects (and things contained therein) can be serialized to BSON. Also, keys may not contain U+0000, since they are serialized as zero-terminated C strings.

Order of object members

The members of an object are written in the order in which iteration visits them: sorted by key for json, in insertion order for ordered_json.

BSON type 0x11 interoperability

The BSON specification defines type 0x11 as a Timestamp. This library uses marker 0x11 when serializing number_unsigned values in the range 9223372036854775808..18446744073709551615. Other BSON implementations may therefore interpret these values as Timestamps instead of unsigned integers.

Binary values without a subtype

BSON requires every binary value to have a subtype. If a binary value has no subtype, this library serializes it with the generic subtype 0x00. After deserialization, has_subtype() returns true and subtype() returns 0. As a result, serializing and deserializing a JSON object containing such a value produces a different JSON object, even though the binary data is unchanged.

Binary subtype 0x02 (old binary)

The BSON specification defines the payload of the \"binary (old)\" subtype 0x02 as an int32 followed by that many bytes, so the value is preceded by two lengths: the length of the binary element and, as the first four bytes of the payload, the number of bytes that follow. A binary value with subtype 2 is therefore written with the outer length 4 bytes larger than its size and the size as inner length: binary({1, 2, 3}, 2) becomes 07 00 00 00 02 03 00 00 00 01 02 03. When reading, the inner length is checked and removed, so the value contains only the bytes that follow it. from_bson() throws parse_error.112 if the outer length is less than 4 or the inner length is not the outer length minus 4. Versions before 3.13.0 did not write the inner length and returned it as part of the payload; BSON data written by those versions with subtype 2 is not readable any more and must be written again.

Example: serialize a JSON value to BSON
#include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\nusing namespace nlohmann::literals;\n\nint main()\n{\n    // create a JSON value\n    json j = R\"({\"compact\": true, \"schema\": 0})\"_json;\n\n    // serialize it to BSON\n    std::vector<std::uint8_t> v = json::to_bson(j);\n\n    // print the vector content\n    for (auto& byte : v)\n    {\n        std::cout << \"0x\" << std::hex << std::setw(2) << std::setfill('0') << static_cast<int>(byte) << \" \";\n    }\n    std::cout << '\\n';\n}\n

Output:

0x1b 0x00 0x00 0x00 0x08 0x63 0x6f 0x6d 0x70 0x61 0x63 0x74 0x00 0x01 0x10 0x73 0x63 0x68 0x65 0x6d 0x61 0x00 0x00 0x00 0x00 0x00 0x00 \n
"},{"location":"features/binary_formats/bson/#deserialization","title":"Deserialization","text":"

The library maps BSON record types to JSON value types as follows:

BSON type BSON marker byte JSON value type double 0x01 number_float string 0x02 string document 0x03 object array 0x04 array binary 0x05 binary undefined 0x06 unsupported ObjectId 0x07 unsupported boolean 0x08 boolean UTC Date-Time 0x09 unsupported null 0x0A null Regular Expr. 0x0B unsupported DB Pointer 0x0C unsupported JavaScript Code 0x0D unsupported Symbol 0x0E unsupported JavaScript Code w/ scope 0x0F unsupported int32 0x10 number_integer uint64(Timestamp) 0x11 number_unsigned int64 0x12 number_integer 128-bit decimal float 0x13 unsupported Max Key 0x7F unsupported Min Key 0xFF unsupported

Incomplete mapping

The mapping is incomplete. The unsupported mappings are indicated in the table above.

Handling of BSON type 0x11

This library deserializes BSON type 0x11 (Timestamp) as a number_unsigned value. The 64-bit value is preserved, but the Timestamp type information is not.

Lenient BSON input handling

The BSON reader is lenient in a few areas where the BSON specification is more restrictive:

  • array element keys are not checked against the required decimal sequence (0, 1, 2, ...),
  • any non-zero byte is accepted as true for the boolean type,
  • the payloads of the binary subtypes 0x03 (UUID, old), 0x04 (UUID), and 0x05 (MD5) are not checked to have 16 bytes,
  • duplicate keys within a document are accepted; the last value wins ({\"a\": 1, \"a\": 2} is read as {\"a\": 2}), while a SAX handler receives every occurrence,
  • a string value may contain embedded 0x00 bytes, and
  • with strict set to false, bytes after the end of the document are ignored.

If BSON input must be validated for strict specification compliance, validate it separately before passing it to from_bson().

Document size

Every document starts with its size. from_bson() rejects a document with parse_error.112 if the size is less than 5 (the size prefix and the terminator), if an embedded document does not end before the end of the document that contains it, if the elements do not fit into the declared size, or if the size does not match the number of bytes read when the terminating 0x00 byte is reached. A size that is too small is detected before an element is read whose type byte and name no longer fit; an element that starts inside the declared size but extends past it is read, and reported to a SAX handler, before the mismatch is found at the terminator. A size that is too large is likewise found only at the terminator. Passing strict as false skips only the check for bytes after the end of the document (parse_error.110), not the document size checks.

Ill-formed UTF-8 in string values

The BSON specification requires string values (type 0x02) to be valid UTF-8, but this is not required of a decoder, so checking is opt-in: with the error_handler parameter left at keep (the default), from_bson() accepts a string value whose bytes are not valid UTF-8 and hands them back unchanged. Passing error_handler_t::strict makes from_bson() check and throw parse_error.113 for ill-formed UTF-8, and replace/ignore sanitize the string instead of keeping it. However, dump() still requires valid UTF-8 and throws type_error.316 for a value read with the default keep handler, unless an error handler is passed that replaces or ignores the ill-formed bytes. to_bson()'s own error_handler parameter defaults to keep, so such a string value or element (key) name is written unchanged; with strict (the default if JSON_STRICT_BINARY_UTF8 is enabled), it throws the same exception instead. Element (key) names are treated like string values: with keep they are read unchanged, with strict, replace, or ignore they are checked and handled in the same way. binary values (type 0x05) are unaffected, since they are not required to hold text.

Example: deserialize a JSON value from BSON
#include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create byte vector\n    std::vector<std::uint8_t> v = {0x1b, 0x00, 0x00, 0x00, 0x08, 0x63, 0x6f, 0x6d,\n                                   0x70, 0x61, 0x63, 0x74, 0x00, 0x01, 0x10, 0x73,\n                                   0x63, 0x68, 0x65, 0x6d, 0x61, 0x00, 0x00, 0x00,\n                                   0x00, 0x00, 0x00\n                                  };\n\n    // deserialize it with BSON\n    json j = json::from_bson(v);\n\n    // print the deserialized JSON value\n    std::cout << std::setw(2) << j << '\\n';\n}\n

Output:

{\n  \"compact\": true,\n  \"schema\": 0\n}\n
"},{"location":"features/binary_formats/bson/#see-also","title":"See also","text":"
  • Binary formats - overview and comparison of the supported binary formats
  • Binary values - how binary values and subtypes map to BSON
  • to_bson - serialize a JSON value to BSON
  • from_bson - parse a JSON value from BSON
  • JSON_STRICT_BINARY_UTF8 - reject ill-formed UTF-8 in strings
  • SAX interface - decode binary formats without building a value
"},{"location":"features/binary_formats/cbor/","title":"CBOR","text":"

The Concise Binary Object Representation (CBOR) is a data format whose design goals include the possibility of extremely small code sizes, fairly small message size, and extensibility without the need for version negotiation.

References

  • CBOR Website - the main source on CBOR
  • CBOR Playground - an interactive webpage to translate between JSON and CBOR
  • RFC 8949 - the CBOR specification
"},{"location":"features/binary_formats/cbor/#byte-layout","title":"Byte layout","text":"

CBOR encodes every data item as a head followed by optional content. The first byte of the head holds the major type in its upper three bits (unsigned integer, negative integer, byte string, text string, array, map, tag, or simple/float) and an additional information value in its lower five bits. Additional information below 24 is the argument itself (for example, a small integer or a short length); the values 24 to 27 announce that the argument follows in 1, 2, 4, or 8 big-endian bytes. Strings, arrays, and maps are prefixed with their length (or count of elements/pairs), and content follows directly. A reader of definite-length items knows how many items to expect without a terminator; indefinite-length items (additional information 31) are instead closed by the \"break\" byte 0xFF, which from_cbor reads but to_cbor never writes.

Consider the following JSON value (shown formatted for readability):

{\n  \"id\": 300,\n  \"name\": \"json\",\n  \"pi\": 3.14,\n  \"tags\": [\n    \"a\",\n    \"b\"\n  ]\n}\n

to_cbor encodes it to 39 bytes (shown in hexadecimal; the encoding contains no whitespace). The colors mark the role of each byte: type/marker data.

JSONBytesMeaning {A4map with 4 key/value pairs \"id\": 300,62 69 64 19 01 2Ckey: text string of length 2, then its UTF-8 bytes; value: unsigned integer, 2 bytes follow (big-endian) \"name\": \"json\",64 6E 61 6D 65 64 6A 73 6F 6Ekey: text string of length 4; value: text string of length 4 \"pi\": 3.14,62 70 69 FB 40 09 1E B8 51 EB 85 1Fkey: text string of length 2; value: double-precision float (IEEE 754, big-endian) \"tags\": [64 74 61 67 73 82key: text string of length 4; value: array with 2 elements \"a\",61 61text string of length 1 \"b\"61 62text string of length 1 ]no end marker: the element count was given up front }no end marker: the member count was given up front"},{"location":"features/binary_formats/cbor/#serialization","title":"Serialization","text":"

The library uses the following mapping from JSON values types to CBOR types according to the CBOR specification (RFC 8949):

JSON value type value/range CBOR type first byte null null Null 0xF6 boolean true True 0xF5 boolean false False 0xF4 number_integer -9223372036854775808..-4294967297 Negative integer (8 bytes follow) 0x3B number_integer -4294967296..-65537 Negative integer (4 bytes follow) 0x3A number_integer -65536..-257 Negative integer (2 bytes follow) 0x39 number_integer -256..-25 Negative integer (1 byte follow) 0x38 number_integer -24..-1 Negative integer 0x20..0x37 number_integer 0..23 Integer 0x00..0x17 number_integer 24..255 Unsigned integer (1 byte follow) 0x18 number_integer 256..65535 Unsigned integer (2 bytes follow) 0x19 number_integer 65536..4294967295 Unsigned integer (4 bytes follow) 0x1A number_integer 4294967296..9223372036854775807 Unsigned integer (8 bytes follow) 0x1B number_unsigned 0..23 Integer 0x00..0x17 number_unsigned 24..255 Unsigned integer (1 byte follow) 0x18 number_unsigned 256..65535 Unsigned integer (2 bytes follow) 0x19 number_unsigned 65536..4294967295 Unsigned integer (4 bytes follow) 0x1A number_unsigned 4294967296..18446744073709551615 Unsigned integer (8 bytes follow) 0x1B number_float any value representable by a float Single-Precision Float 0xFA number_float any value NOT representable by a float Double-Precision Float 0xFB string length: 0..23 UTF-8 string 0x60..0x77 string length: 24..255 UTF-8 string (1 byte follow) 0x78 string length: 256..65535 UTF-8 string (2 bytes follow) 0x79 string length: 65536..4294967295 UTF-8 string (4 bytes follow) 0x7A string length: 4294967296..18446744073709551615 UTF-8 string (8 bytes follow) 0x7B array size: 0..23 array 0x80..0x97 array size: 24..255 array (1 byte follow) 0x98 array size: 256..65535 array (2 bytes follow) 0x99 array size: 65536..4294967295 array (4 bytes follow) 0x9A array size: 4294967296..18446744073709551615 array (8 bytes follow) 0x9B object size: 0..23 map 0xA0..0xB7 object size: 24..255 map (1 byte follow) 0xB8 object size: 256..65535 map (2 bytes follow) 0xB9 object size: 65536..4294967295 map (4 bytes follow) 0xBA object size: 4294967296..18446744073709551615 map (8 bytes follow) 0xBB binary size: 0..23 byte string 0x40..0x57 binary size: 24..255 byte string (1 byte follow) 0x58 binary size: 256..65535 byte string (2 bytes follow) 0x59 binary size: 65536..4294967295 byte string (4 bytes follow) 0x5A binary size: 4294967296..18446744073709551615 byte string (8 bytes follow) 0x5B

Binary values with subtype are mapped to tagged values (0xD8..0xDB) depending on the subtype, followed by a byte string, see \"binary\" cells in the table above.

Complete mapping

The mapping is complete in the sense that any JSON value type can be converted to a CBOR value, with one exception: an integer outside the range of CBOR integers (only possible with a number type wider than 64 bits) throws out_of_range.407.

Not a deterministic encoding

to_cbor does not produce the deterministic encoding of RFC 8949, Section 4.2.1, and not always the preferred serialization of Section 4.1:

  • floating-point numbers are written as single precision (0xFA) when that is exact and as double precision (0xFB) otherwise; half precision (0xF9) is used only for NaN and Infinity/-Infinity (1.0 is fa 3f 80 00 00);
  • a binary subtype 0..23 is written as d8 xx instead of the one-byte tag 0xC0..0xD7 (d8 01 41 01);
  • object members are written in the order of object_t (for the default std::map: sorted by the key string, not by the encoded key bytes).

Integers and lengths use the shortest form, and indefinite-length items are never written. Decoders must accept all of this; the RFC does not require the preferred serialization.

NaN/infinity handling

NaN, Infinity, and -Infinity are serialized as a CBOR half-precision float (type 0xF9, 3 bytes total): NaN as 0xF9 0x7E 0x00, Infinity as 0xF9 0x7C 0x00, and -Infinity as 0xF9 0xFC 0x00. This behavior differs from the normal JSON serialization which serializes NaN or Infinity to null.

Note

Prior to version 3.8.0, NaN and Infinity were instead serialized as a CBOR double-precision float (type 0xFB, 9 bytes total).

Unused CBOR types

The following CBOR types are not used in the conversion:

  • UTF-8 strings terminated by \"break\" (0x7F)
  • arrays terminated by \"break\" (0x9F)
  • maps terminated by \"break\" (0xBF)
  • byte strings terminated by \"break\" (0x5F)
  • date/time (0xC0..0xC1)
  • bignum (0xC2..0xC3)
  • decimal fraction (0xC4)
  • bigfloat (0xC5)
  • expected conversions (0xD5..0xD7)
  • simple values (0xE0..0xF3, 0xF8)
  • undefined (0xF7)
  • break (0xFF)

Tagged items

Binary subtypes will be serialized as tagged items. See binary values for an example.

Example: serialize a JSON value to CBOR
#include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\nusing namespace nlohmann::literals;\n\nint main()\n{\n    // create a JSON value\n    json j = R\"({\"compact\": true, \"schema\": 0})\"_json;\n\n    // serialize it to CBOR\n    std::vector<std::uint8_t> v = json::to_cbor(j);\n\n    // print the vector content\n    for (auto& byte : v)\n    {\n        std::cout << \"0x\" << std::hex << std::setw(2) << std::setfill('0') << static_cast<int>(byte) << \" \";\n    }\n    std::cout << '\\n';\n}\n

Output:

0xa2 0x67 0x63 0x6f 0x6d 0x70 0x61 0x63 0x74 0xf5 0x66 0x73 0x63 0x68 0x65 0x6d 0x61 0x00 \n
"},{"location":"features/binary_formats/cbor/#deserialization","title":"Deserialization","text":"

The library maps CBOR types to JSON value types as follows:

CBOR type JSON value type first byte Integer number_unsigned 0x00..0x17 Unsigned integer number_unsigned 0x18 Unsigned integer number_unsigned 0x19 Unsigned integer number_unsigned 0x1A Unsigned integer number_unsigned 0x1B Negative integer number_integer 0x20..0x37 Negative integer number_integer 0x38 Negative integer number_integer 0x39 Negative integer number_integer 0x3A Negative integer number_integer 0x3B Byte string binary 0x40..0x57 Byte string binary 0x58 Byte string binary 0x59 Byte string binary 0x5A Byte string binary 0x5B Byte string binary 0x5F UTF-8 string string 0x60..0x77 UTF-8 string string 0x78 UTF-8 string string 0x79 UTF-8 string string 0x7A UTF-8 string string 0x7B UTF-8 string string 0x7F array array 0x80..0x97 array array 0x98 array array 0x99 array array 0x9A array array 0x9B array array 0x9F map object 0xA0..0xB7 map object 0xB8 map object 0xB9 map object 0xBA map object 0xBB map object 0xBF False false 0xF4 True true 0xF5 Null null 0xF6 Half-Precision Float number_float 0xF9 Single-Precision Float number_float 0xFA Double-Precision Float number_float 0xFB

Indefinite-length UTF-8 strings (0x7F) and byte strings (0x5F) are supported. Each chunk must be a definite-length string of the same major type, as required by RFC 8949, Section 3.2.3.

Incomplete mapping

The mapping is incomplete in the sense that not all CBOR types can be converted to a JSON value. The following CBOR types are not supported and will yield parse errors:

  • simple values (0xE0..0xF3, 0xF8)
  • undefined (0xF7)

Tagged items (0xC0..0xDB) are not interpreted either; see the note on tagged items below.

Negative integer overflow

CBOR negative integers (major type 1) are decoded as -1 - n. If the encoded magnitude n is too large for the result to fit into number_integer_t (std::int64_t by default), the result is stored as number_float_t, like a too small integer in JSON text. For example, -18446744073709551616 (0x3B followed by eight 0xFF bytes) is stored as -1.8446744073709552e+19.

Object keys

CBOR allows map keys of any type, whereas JSON only allows strings as keys in object values. Therefore, CBOR maps with keys other than text strings (major type 3) are rejected with a parse_error.113 exception (or, with allow_exceptions set to false, a discarded value) naming the type of the key that was found, for instance:

[json.exception.parse_error.113] parse error at byte 2: syntax error while parsing CBOR object key: only string keys are supported, but found an unsigned integer; last byte: 0x01\n

This applies to the SAX interface as well, as the key is read before it is passed on. This is a deliberate restriction of the library's JSON value model, not an oversight: formats built on CBOR maps with integer keys, such as COSE (RFC 9052) or CWT (RFC 8392), cannot be read with this library and need a general-purpose CBOR library instead.

A tag in front of a text string key is handled like a tag in front of a value: it is skipped with cbor_tag_handler_t::ignore or cbor_tag_handler_t::store and rejected with the default error. A tag does not turn a key of another type into a text string.

A map with duplicate keys is well-formed, but invalid under RFC 8949, Section 5.3.1. from_cbor accepts it and the last value wins; the SAX interface reports every occurrence.

Ill-formed UTF-8 in text strings

RFC 8949, Section 3.1 requires CBOR text strings (major type 3) to be valid UTF-8 (a string with ill-formed UTF-8 is \"well-formed but invalid\"), and Section 5.3.1 leaves it up to the decoder whether to verify this, so checking is opt-in: with the error_handler parameter left at keep (the default), from_cbor() accepts a text string (object keys included) whose bytes are not valid UTF-8 and hands them back unchanged. Passing error_handler_t::strict makes from_cbor() check and throw parse_error.113 for ill-formed UTF-8, and replace/ignore sanitize the string instead of keeping it. However, dump() still requires valid UTF-8 and throws type_error.316 for a value read with the default keep handler, unless an error handler is passed that replaces or ignores the ill-formed bytes. to_cbor()'s own error_handler parameter defaults to keep, so such a value is written back unchanged; with strict (the default if JSON_STRICT_BINARY_UTF8 is enabled), it throws the same exception instead. Byte strings (major type 2) are unaffected, since they are not required to hold text.

The chunks of an indefinite-length text string are checked one by one, as required by RFC 8949, Section 3.2.3: a code point cannot be spread over two chunks. With error_handler_t::strict such a string throws parse_error.113; replace and ignore sanitize each chunk on its own.

Tagged items

Tagged items (0xC0..0xDB) will throw a parse error by default. They can be ignored by passing cbor_tag_handler_t::ignore to function from_cbor, in which case the tag is skipped and the enclosed data item is parsed on its own. Passing cbor_tag_handler_t::store to function from_cbor stores tagged byte strings (for bytes 0xd8..0xdb) as binary values with the tag as subtype; other tagged values are read as if the tag were ignored. If several tags precede a byte string, only the tag directly in front of it is stored, and only when it has the form 0xD8..0xDB (a tag 0..23 written as 0xC0..0xD7 is skipped); for example, D8 05 C1 41 AA yields subtype null, whereas C1 D8 05 41 AA yields 5. Tags in front of a text string map key are skipped as well. Note that no tag is ever interpreted: for instance, a text string tagged with tag 0 (date/time) stays a string.

Example: deserialize a JSON value from CBOR
#include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create byte vector\n    std::vector<std::uint8_t> v = {0xa2, 0x67, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x63,\n                                   0x74, 0xf5, 0x66, 0x73, 0x63, 0x68, 0x65, 0x6d,\n                                   0x61, 0x00\n                                  };\n\n    // deserialize it with CBOR\n    json j = json::from_cbor(v);\n\n    // print the deserialized JSON value\n    std::cout << std::setw(2) << j << '\\n';\n}\n

Output:

{\n  \"compact\": true,\n  \"schema\": 0\n}\n
"},{"location":"features/binary_formats/cbor/#see-also","title":"See also","text":"
  • Binary formats - overview and comparison of the supported binary formats
  • Binary values - how binary values and subtypes map to CBOR
  • to_cbor - serialize a JSON value to CBOR
  • from_cbor - parse a JSON value from CBOR
  • JSON_STRICT_BINARY_UTF8 - reject ill-formed UTF-8 in strings
  • SAX interface - decode binary formats without building a value
  • cbor_tag_handler_t - how CBOR tags are handled when parsing
"},{"location":"features/binary_formats/messagepack/","title":"MessagePack","text":"

MessagePack is an efficient binary serialization format. It lets you exchange data among multiple languages like JSON. But it's faster and smaller. Small integers are encoded into a single byte, and typical short strings require only one extra byte in addition to the strings themselves.

References

  • MessagePack website
  • MessagePack specification
"},{"location":"features/binary_formats/messagepack/#byte-layout","title":"Byte layout","text":"

MessagePack encodes each value as a one-byte format marker, optionally followed by a length or the payload. The marker range is partitioned to keep common values small: small non-negative integers (0 to 127) and small negative integers (-32 to -1) are the marker byte itself; short strings, arrays, and maps (up to 31 bytes for strings and up to 15 elements for arrays and maps) hide their length in the marker's lower bits. Larger values use dedicated markers that announce the width (8, 16, 32, or 64 bits) of the length or number that follows, in big-endian byte order. Like CBOR, containers are length-prefixed, so no terminator is needed.

Consider the following JSON value (shown formatted for readability):

{\n  \"id\": 300,\n  \"name\": \"json\",\n  \"pi\": 3.14,\n  \"tags\": [\n    \"a\",\n    \"b\"\n  ]\n}\n

to_msgpack encodes it to 39 bytes (shown in hexadecimal; the encoding contains no whitespace). The colors mark the role of each byte: type/marker data.

JSONBytesMeaning {84map with 4 key/value pairs \"id\": 300,A2 69 64 CD 01 2Ckey: fixstr of length 2, then its UTF-8 bytes; value: uint 16 (big-endian) \"name\": \"json\",A4 6E 61 6D 65 A4 6A 73 6F 6Ekey: fixstr of length 4; value: fixstr of length 4 \"pi\": 3.14,A2 70 69 CB 40 09 1E B8 51 EB 85 1Fkey: fixstr of length 2; value: float 64 (IEEE 754, big-endian) \"tags\": [A4 74 61 67 73 92key: fixstr of length 4; value: fixarray with 2 elements \"a\",A1 61fixstr of length 1 \"b\"A1 62fixstr of length 1 ]no end marker: the element count was given up front }no end marker: the member count was given up front"},{"location":"features/binary_formats/messagepack/#serialization","title":"Serialization","text":"

The library uses the following mapping from JSON values types to MessagePack types according to the MessagePack specification:

JSON value type value/range MessagePack type first byte null null nil 0xC0 boolean true true 0xC3 boolean false false 0xC2 number_integer -9223372036854775808..-2147483649 int64 0xD3 number_integer -2147483648..-32769 int32 0xD2 number_integer -32768..-129 int16 0xD1 number_integer -128..-33 int8 0xD0 number_integer -32..-1 negative fixint 0xE0..0xFF number_integer 0..127 positive fixint 0x00..0x7F number_integer 128..255 uint 8 0xCC number_integer 256..65535 uint 16 0xCD number_integer 65536..4294967295 uint 32 0xCE number_integer 4294967296..18446744073709551615 uint 64 0xCF number_unsigned 0..127 positive fixint 0x00..0x7F number_unsigned 128..255 uint 8 0xCC number_unsigned 256..65535 uint 16 0xCD number_unsigned 65536..4294967295 uint 32 0xCE number_unsigned 4294967296..18446744073709551615 uint 64 0xCF number_float any value representable by a float float 32 0xCA number_float any value NOT representable by a float float 64 0xCB string length: 0..31 fixstr 0xA0..0xBF string length: 32..255 str 8 0xD9 string length: 256..65535 str 16 0xDA string length: 65536..4294967295 str 32 0xDB array size: 0..15 fixarray 0x90..0x9F array size: 16..65535 array 16 0xDC array size: 65536..4294967295 array 32 0xDD object size: 0..15 fix map 0x80..0x8F object size: 16..65535 map 16 0xDE object size: 65536..4294967295 map 32 0xDF binary size: 0..255 bin 8 0xC4 binary size: 256..65535 bin 16 0xC5 binary size: 65536..4294967295 bin 32 0xC6

Complete mapping

The mapping is complete in the sense that any JSON value type can be converted to a MessagePack value.

Any MessagePack output created by to_msgpack can be successfully parsed by from_msgpack.

Size constraints

The following values can not be converted to a MessagePack value:

  • strings with more than 4294967295 bytes
  • byte strings with more than 4294967295 bytes
  • arrays with more than 4294967295 elements
  • objects with more than 4294967295 elements

Serializing such a value throws out_of_range.412.

NaN/infinity handling

NaN, Infinity, and -Infinity are serialized as a MessagePack float 32 (type 0xCA, 5 bytes total), regardless of magnitude, in contrast to the dump function which serializes NaN or Infinity to null.

Note

Prior to version 3.13.0 unreleased, NaN and Infinity were instead serialized as a MessagePack float 64 (type 0xCB, 9 bytes total), because the check used to select the smaller float 32 encoding failed for NaN (all comparisons are false) and for Infinity and -Infinity (outside the float range checked against std::numeric_limits<float>::lowest() and max()), so the float 32 path was skipped.

Example: serialize a JSON value to MessagePack
#include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\nusing namespace nlohmann::literals;\n\nint main()\n{\n    // create a JSON value\n    json j = R\"({\"compact\": true, \"schema\": 0})\"_json;\n\n    // serialize it to MessagePack\n    std::vector<std::uint8_t> v = json::to_msgpack(j);\n\n    // print the vector content\n    for (auto& byte : v)\n    {\n        std::cout << \"0x\" << std::hex << std::setw(2) << std::setfill('0') << static_cast<int>(byte) << \" \";\n    }\n    std::cout << '\\n';\n}\n

Output:

0x82 0xa7 0x63 0x6f 0x6d 0x70 0x61 0x63 0x74 0xc3 0xa6 0x73 0x63 0x68 0x65 0x6d 0x61 0x00 \n
"},{"location":"features/binary_formats/messagepack/#deserialization","title":"Deserialization","text":"

The library maps MessagePack types to JSON value types as follows:

MessagePack type JSON value type first byte positive fixint number_unsigned 0x00..0x7F fixmap object 0x80..0x8F fixarray array 0x90..0x9F fixstr string 0xA0..0xBF nil null 0xC0 (never used) \u2013 0xC1 false false 0xC2 true true 0xC3 float 32 number_float 0xCA float 64 number_float 0xCB uint 8 number_unsigned 0xCC uint 16 number_unsigned 0xCD uint 32 number_unsigned 0xCE uint 64 number_unsigned 0xCF int 8 number_integer 0xD0 int 16 number_integer 0xD1 int 32 number_integer 0xD2 int 64 number_integer 0xD3 str 8 string 0xD9 str 16 string 0xDA str 32 string 0xDB array 16 array 0xDC array 32 array 0xDD map 16 object 0xDE map 32 object 0xDF bin 8 binary 0xC4 bin 16 binary 0xC5 bin 32 binary 0xC6 ext 8 binary 0xC7 ext 16 binary 0xC8 ext 32 binary 0xC9 fixext 1 binary 0xD4 fixext 2 binary 0xD5 fixext 4 binary 0xD6 fixext 8 binary 0xD7 fixext 16 binary 0xD8 negative fixint number_integer 0xE0-0xFF

The byte 0xC1 is reserved as \"never used\" by the specification. As a value it is rejected with parse_error.112 (invalid byte: 0xC1); as a map key it is rejected with parse_error.113 and the generic \"expected length specification\" message, because the key is read as a string.

Duplicate keys in a map are accepted; the last value wins.

"},{"location":"features/binary_formats/messagepack/#extension-types-ext-fixext","title":"Extension types (ext, fixext)","text":"

MessagePack ext and fixext values are read as binary values, and the ext type byte is stored as the binary subtype. Although the specification defines the type as a signed 8-bit integer (0 to 127 for applications, -128 to -1 reserved, with -1 being the Timestamp extension), the library reads it as an unsigned byte: a negative ext type n becomes subtype 256+n, so ext type -1 is read as subtype 255 and -128 as subtype 128. The Timestamp extension is not interpreted; it is returned as binary with subtype 255. Use has_subtype() to tell a bin value (no subtype) from an ext value (subtype, even if it is 0).

When serializing, a binary value with a subtype is always written as fixext (1, 2, 4, 8, or 16 bytes) or ext, even for subtype 0 (d6 00 01 02 03 04); a binary value without a subtype is written as bin. Subtypes 128 to 255 are written as the reserved negative ext types (255 as -1), so json::binary({1,2,3,4}, 255) becomes d6 ff 01 02 03 04, which other MessagePack libraries decode as a 32-bit timestamp. A subtype above 255 throws out_of_range.415. The payload length is limited to 4294967295 bytes like all other lengths.

Info

Any MessagePack output created by to_msgpack can be successfully parsed by from_msgpack.

Object keys

MessagePack allows map keys of any type, whereas JSON only allows strings as keys in object values. Like the JSON-compatible profile sketched in the MessagePack specification, this library restricts map keys to str values. Maps with keys of any other type are rejected with a parse_error.113 exception (or, with allow_exceptions set to false, a discarded value). For most key types the message names the type that was found, for instance:

[json.exception.parse_error.113] parse error at byte 2: syntax error while parsing MessagePack object key: only string keys are supported, but found nil; last byte: 0xC0\n

This applies to the SAX interface as well, as the key is read before it is passed on. Such input needs a general-purpose MessagePack library instead.

Ill-formed UTF-8 in string values

The MessagePack specification explicitly allows a str value (fixstr, str 8, str 16, str 32) to contain a byte sequence that is not valid UTF-8, and recommends that a deserializer provide a way to obtain the original bytes. This library follows that by default: with its error_handler parameter left at keep (the default), from_msgpack() reads str bytes (object keys included) as-is, without validating them, so such a value round-trips through from_msgpack(to_msgpack(j)) byte for byte. Passing error_handler_t::strict makes from_msgpack() check anyway and throw parse_error.113 for ill-formed UTF-8, and replace/ignore sanitize the string instead of keeping it. to_msgpack() also writes str bytes as-is by default, since the specification permits it; its error_handler parameter can be set to strict to throw type_error.316 instead, or to replace/ignore to sanitize the string, for instance for a decoder that rejects ill-formed UTF-8. However, dump() still requires valid UTF-8 and throws type_error.316 for a value read this way with the default keep handler, unless an error handler is passed that replaces or ignores the ill-formed bytes.

Example: deserialize a JSON value from MessagePack
#include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create byte vector\n    std::vector<std::uint8_t> v = {0x82, 0xa7, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x63,\n                                   0x74, 0xc3, 0xa6, 0x73, 0x63, 0x68, 0x65, 0x6d,\n                                   0x61, 0x00\n                                  };\n\n    // deserialize it with MessagePack\n    json j = json::from_msgpack(v);\n\n    // print the deserialized JSON value\n    std::cout << std::setw(2) << j << '\\n';\n}\n

Output:

{\n  \"compact\": true,\n  \"schema\": 0\n}\n
"},{"location":"features/binary_formats/messagepack/#see-also","title":"See also","text":"
  • Binary formats - overview and comparison of the supported binary formats
  • Binary values - how binary values and subtypes map to MessagePack
  • to_msgpack - serialize a JSON value to MessagePack
  • from_msgpack - parse a JSON value from MessagePack
  • JSON_STRICT_BINARY_UTF8 - reject ill-formed UTF-8 in strings
  • SAX interface - decode binary formats without building a value
"},{"location":"features/binary_formats/ubjson/","title":"UBJSON","text":"

Universal Binary JSON (UBJSON) is a binary form directly imitating JSON, but requiring fewer bytes of data. It aims to achieve the generality of JSON, combined with being much easier to process than JSON.

References

  • UBJSON Website
"},{"location":"features/binary_formats/ubjson/#byte-layout","title":"Byte layout","text":"

UBJSON is built from just a one-byte, human-readable ASCII type marker (for example, i for int8, S for string, [ for array) followed by the payload of that type. Strings and the like are prefixed with their length, which is itself a UBJSON integer value including its marker. Numbers are stored in big-endian byte order. Containers can be written in two ways: as an unoptimized container that is opened with [ or { and closed with ] or }, or as an optimized container that declares a count (#) after the opening marker, optionally preceded by an element type ($); an element type is only allowed together with a count. An optimized container saves the closing marker and, with a type, the per-element markers.

Consider the following JSON value (shown formatted for readability):

{\n  \"id\": 300,\n  \"name\": \"json\",\n  \"pi\": 3.14,\n  \"tags\": [\n    \"a\",\n    \"b\"\n  ]\n}\n

to_ubjson encodes it to 51 bytes (shown in hexadecimal; the encoding contains no whitespace). The colors mark the role of each byte: type/marker length/count/size data.

JSONBytesMeaning {7Bobject start ({) \"id\": 300,69 02 69 64 49 01 2Ckey: length 2 as int8 (i), then UTF-8 bytes; value: int16 (I), big-endian \"name\": \"json\",69 04 6E 61 6D 65 53 69 04 6A 73 6F 6Ekey: length 4; value: string (S), length 4 as int8, UTF-8 bytes \"pi\": 3.14,69 02 70 69 44 40 09 1E B8 51 EB 85 1Fkey: length 2; value: float64 (D), big-endian \"tags\": [69 04 74 61 67 73 5Bkey: length 4; value: array start ([) \"a\",53 69 01 61string, length 1 \"b\"53 69 01 62string, length 1 ]5Darray end (]) }7Dobject end (})"},{"location":"features/binary_formats/ubjson/#serialization","title":"Serialization","text":"

The library uses the following mapping from JSON values types to UBJSON types according to the UBJSON specification:

JSON value type value/range UBJSON type marker null null null Z boolean true true T boolean false false F number_integer -9223372036854775808..-2147483649 int64 L number_integer -2147483648..-32769 int32 l number_integer -32768..-129 int16 I number_integer -128..127 int8 i number_integer 128..255 uint8 U number_integer 256..32767 int16 I number_integer 32768..2147483647 int32 l number_integer 2147483648..9223372036854775807 int64 L number_unsigned 0..127 int8 i number_unsigned 128..255 uint8 U number_unsigned 256..32767 int16 I number_unsigned 32768..2147483647 int32 l number_unsigned 2147483648..9223372036854775807 int64 L number_unsigned 9223372036854775808..18446744073709551615 high-precision H number_float any value float64 (float32 if number_float_t is float) D (d) string with shortest length indicator string S array see notes on optimized format array [ object see notes on optimized format object {

Complete mapping

The mapping is complete in the sense that any JSON value type can be converted to a UBJSON value.

Any UBJSON output created by to_ubjson can be successfully parsed by from_ubjson.

Size constraints

The following values can not be converted to a UBJSON value:

  • strings with more than 9223372036854775807 bytes (theoretical)

UTF-8 validation of string values and object keys

UBJSON's required string encoding is UTF-8. By default (the error_handler parameter left at keep), to_ubjson() writes the bytes of string values and object keys unchanged, even if they are not valid UTF-8. With error_handler_t::strict, it throws type_error.316 for ill-formed UTF-8 instead; replace/ignore sanitize the string. JSON_STRICT_BINARY_UTF8 makes strict the default.

Unused UBJSON markers

The following markers are not used in the conversion:

  • N: no-op values are never written (they are skipped when reading).
  • C: single-byte strings are serialized with S markers.

NaN/infinity handling

NaN and infinity are written as IEEE 754 float64 values (D) and read back unchanged. This differs from dump(), which serializes them to null, and from the UBJSON specification, which encodes infinity as null (it does not mention NaN); other UBJSON readers may therefore not accept these values.

Optimized formats

The optimized formats for containers are supported: Parameter use_size adds size information to the beginning of a container and removes the closing marker. Parameter use_type further checks whether all elements of a container have the same type and adds the type marker to the beginning of the container. The use_type parameter must only be used together with use_size = true: combining use_type with use_size = false throws other_error.502 if the value contains a non-empty array, object, or binary value.

Two elements have the same type if they are written with the same type marker. For example, [1, 2] is written with the type i, but [1, 200] (i, U), [true, false] (T, F), and [1, 2.5] (i, D) are not; an empty container is never given a $ annotation of its own (an array of empty arrays is still typed [).

Note that use_size = true alone may result in larger representations - the benefit of this parameter is that the receiving side is immediately informed on the number of elements of the container.

An array whose type marker is Z (null), T (true) or F (false) stores no payload at all, because the marker already is the value. Its declared count is therefore the only thing that decides how much memory the receiving side allocates, and a handful of bytes can describe billions of elements. from_ubjson rejects such an array with out_of_range.408 when the count exceeds 1,048,576 (1 << 20), and to_ubjson writes longer arrays of these types in the counted but untyped form: the $ type marker is dropped, the # count is kept, and every element is written with its own marker ([#l 1048577 Z Z ...), so any value it produces can be read back. Objects and untyped counted arrays are not subject to this limit.

Binary values

If the JSON data contains the binary type, the value stored is a list of integers, as suggested by the UBJSON documentation. In particular, this means that serialization and the deserialization of a JSON containing binary values into UBJSON and back will result in a different JSON object.

Example: serialize JSON values to UBJSON, with and without size/type optimization
#include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\nusing namespace nlohmann::literals;\n\n// function to print UBJSON's diagnostic format\nvoid print_byte(uint8_t byte)\n{\n    if (32 < byte and byte < 128)\n    {\n        std::cout << static_cast<char>(byte);\n    }\n    else\n    {\n        std::cout << static_cast<int>(byte);\n    }\n}\n\nint main()\n{\n    // create a JSON value\n    json j = R\"({\"compact\": true, \"schema\": false})\"_json;\n\n    // serialize it to UBJSON\n    std::vector<std::uint8_t> v = json::to_ubjson(j);\n\n    // print the vector content\n    for (auto& byte : v)\n    {\n        print_byte(byte);\n    }\n    std::cout << '\\n';\n\n    // create an array of numbers\n    json array = {1, 2, 3, 4, 5, 6, 7, 8};\n\n    // serialize it to UBJSON using default representation\n    std::vector<std::uint8_t> v_array = json::to_ubjson(array);\n    // serialize it to UBJSON using size optimization\n    std::vector<std::uint8_t> v_array_size = json::to_ubjson(array, true);\n    // serialize it to UBJSON using type optimization\n    std::vector<std::uint8_t> v_array_size_and_type = json::to_ubjson(array, true, true);\n\n    // print the vector contents\n    for (auto& byte : v_array)\n    {\n        print_byte(byte);\n    }\n    std::cout << '\\n';\n\n    for (auto& byte : v_array_size)\n    {\n        print_byte(byte);\n    }\n    std::cout << '\\n';\n\n    for (auto& byte : v_array_size_and_type)\n    {\n        print_byte(byte);\n    }\n    std::cout << '\\n';\n}\n

Output:

{i7compactTi6schemaF}\n[i1i2i3i4i5i6i7i8]\n[#i8i1i2i3i4i5i6i7i8\n[$i#i812345678\n
"},{"location":"features/binary_formats/ubjson/#deserialization","title":"Deserialization","text":"

The library maps UBJSON types to JSON value types as follows:

UBJSON type JSON value type marker no-op no value, next value is read N null null Z false false F true true T float32 number_float d float64 number_float D uint8 number_unsigned U int8 number_integer i int16 number_integer I int32 number_integer l int64 number_integer L string string S char string C high-precision number_unsigned, number_integer, or number_float H array array (optimized values are supported) [ object object (optimized values are supported) {

High-precision numbers

The payload of H is a length-prefixed string that is parsed as a JSON number (surrounding whitespace is ignored). Integer text in the range of number_unsigned_t (non-negative) or number_integer_t (negative) is stored as such; any other valid number text (larger or smaller integers, fractions, and exponents such as 1e2) is stored as number_float, so precision may be lost. Text that is not a valid JSON number raises parse_error.115, a number outside the range of number_float_t (1e999) raises out_of_range.406.

Complete mapping

Every well-formed UBJSON value can be converted to a JSON value, with these exceptions: a high-precision number outside the range of number_float_t (out_of_range.406), an optimized array of Z, T, or F with more than 1,048,576 elements, and a count that exceeds the capacity of the container (out_of_range.408). High-precision numbers that do not fit an integer type are stored as floating-point numbers and may lose precision. Ill-formed input is rejected with a parse error.

Duplicate object keys

If an object contains the same key more than once, the last value is kept (the UBJSON specification does not address duplicate keys).

Type marker of optimized containers

The type marker after $ must be one of Z, N, T, F, i, U, I, l, L, d, D, H, C, S, [, or {. It is checked even if the count is 0; any other marker raises parse_error.112. A counted object typed N ({$N#i1 ...) is not supported.

Ill-formed UTF-8 in string values and object keys

UBJSON's required string encoding is UTF-8, but checking it on read is opt-in: with the error_handler parameter left at keep (the default), from_ubjson() accepts a string value or object key whose bytes are not valid UTF-8 and hands them back unchanged. Passing error_handler_t::strict makes from_ubjson() check and throw parse_error.113 for ill-formed UTF-8, and replace/ignore sanitize the string instead of keeping it. However, dump() still requires valid UTF-8 and throws type_error.316 for a value read with the default keep handler, unless an error handler is passed that replaces or ignores the ill-formed bytes. to_ubjson()'s own error_handler parameter defaults to keep (see above), so such a value is written back unchanged.

Example: deserialize a JSON value from UBJSON
#include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create byte vector\n    std::vector<std::uint8_t> v = {0x7B, 0x69, 0x07, 0x63, 0x6F, 0x6D, 0x70, 0x61,\n                                   0x63, 0x74, 0x54, 0x69, 0x06, 0x73, 0x63, 0x68,\n                                   0x65, 0x6D, 0x61, 0x69, 0x00, 0x7D\n                                  };\n\n    // deserialize it with UBJSON\n    json j = json::from_ubjson(v);\n\n    // print the deserialized JSON value\n    std::cout << std::setw(2) << j << '\\n';\n}\n

Output:

{\n  \"compact\": true,\n  \"schema\": 0\n}\n
"},{"location":"features/binary_formats/ubjson/#see-also","title":"See also","text":"
  • Binary formats - overview and comparison of the supported binary formats
  • Binary values - how binary values and subtypes map to UBJSON
  • to_ubjson - serialize a JSON value to UBJSON
  • from_ubjson - parse a JSON value from UBJSON
  • JSON_STRICT_BINARY_UTF8 - reject ill-formed UTF-8 in strings
  • SAX interface - decode binary formats without building a value
"},{"location":"features/element_access/","title":"Element Access","text":"

There are many ways elements in a JSON value can be accessed:

  • unchecked access via operator[]
  • checked access via at
  • access with default value via value
  • iterators
  • JSON pointers

Testing whether a key or index exists before accessing it is also possible, with contains or find (which returns an iterator to the value, or end() if it is not found).

How do I get a value out? Start at the top and follow the first question that applies:

flowchart TD\n    A[\"getting a value out\"] --> P{{\"nested path such as /server/port?\"}}\n    P -->|\"yes\"| JP[\"JSON Pointer: at(ptr), value(ptr, default), contains(ptr)\"]\n    P -->|\"no, one key or index\"| T{{\"only testing whether it exists?\"}}\n    T -->|\"yes\"| CF[\"contains() / find()\"]\n    T -->|\"no\"| M{{\"may it be missing?\"}}\n    M -->|\"yes, a fallback is fine\"| V[\"value(key, default)\"]\n    M -->|\"yes, and missing is an error\"| AT[\"at(): throws out_of_range\"]\n    M -->|\"no, it exists and its type is known\"| OP[\"operator[] and get#lt;T#gt;()\"]\n    OP -.- W[\"non-const operator[] inserts null for a missing key\"]

Decision tree for reading a value: the labels on the arrows are the answers to the questions, and the boxes name the functions to use. The dashed line marks a side effect of the non-const operator[].

"},{"location":"features/element_access/#does-this-key-exist","title":"Does this key exist?","text":"

Use contains to test for a key; it does not modify the value and does not throw:

json j = {{\"name\", \"Mary\"}, {\"address\", {{\"city\", \"Berlin\"}}}};\n\nj.contains(\"name\");                   // true\nj.contains(\"age\");                    // false\nj.contains(\"city\");                   // false: contains() only looks at the top level\nj[\"address\"].contains(\"city\");        // true\nj.contains(json::json_pointer(\"/address/city\"));  // true: a JSON pointer tests a nested path in one call\n

If the value is needed afterwards, find tests and accesses with a single lookup:

if (auto it = j.find(\"name\"); it != j.end())\n{\n    std::cout << *it << '\\n';\n}\n

contains also returns true for a key whose value is null; use j.contains(\"k\") && !j[\"k\"].is_null() if a null should count as missing. To read a value with a fallback instead, see value.

operator[] inserts missing keys

Like std::map::operator[], the non-const operator[] adds a null value if the key is missing. Testing a key with it therefore changes the object:

json j = {{\"foo\", 1}};\nbool absent = j[\"bar\"].is_null();   // true, but j is now {\"bar\": null, \"foo\": 1}\n

Use contains/find to test, and at to access a value that must exist (it throws an out_of_range exception otherwise).

"},{"location":"features/element_access/#see-also","title":"See also","text":"
  • operator[] - unchecked access
  • at - checked access
  • value - access with default value
  • contains - and find - test for existence
  • front - and back - first and last element
  • items - iterate over keys and values
  • Checked access: at - access with range checking
  • Unchecked access: operator[] - access without range checking
  • Access with default value: value - fall back to a default instead of throwing
  • Iterators - visit all elements of arrays and objects
  • JSON Pointer - address nested values with a single string
  • Modifying values - add, merge and remove elements
  • basic_json - all member functions
"},{"location":"features/element_access/checked_access/","title":"Checked access: at","text":""},{"location":"features/element_access/checked_access/#overview","title":"Overview","text":"

The at member function performs checked access; that is, it returns a reference to the desired value if it exists and throws a basic_json::out_of_range exception otherwise.

Example: read access

Consider the following JSON value:

{\n    \"name\": \"Mary Smith\",\n    \"age\": 42,\n    \"hobbies\": [\"hiking\", \"reading\"]\n}\n

Assume the value is parsed to a json variable j.

expression value j {\"name\": \"Mary Smith\", \"age\": 42, \"hobbies\": [\"hiking\", \"reading\"]} j.at(\"name\") \"Mary Smith\" j.at(\"age\") 42 j.at(\"hobbies\") [\"hiking\", \"reading\"] j.at(\"hobbies\").at(0) \"hiking\" j.at(\"hobbies\").at(1) \"reading\"

The return value is a reference, so it can be used to modify the original value.

Example: write access
j.at(\"name\") = \"John Smith\";\n

This code produces the following JSON value:

{\n    \"name\": \"John Smith\",\n    \"age\": 42,\n    \"hobbies\": [\"hiking\", \"reading\"]\n}\n

When accessing an invalid index (i.e., an index greater than or equal to the array size) or the passed object key is non-existing, an exception is thrown.

Example: access via invalid index or missing key
j.at(\"hobbies\").at(3) = \"cooking\";\n

This code produces the following exception:

[json.exception.out_of_range.401] array index 3 is out of range\n

When extended diagnostic messages are enabled by defining JSON_DIAGNOSTICS, the exception further gives information where the key or index is missing or out of range.

[json.exception.out_of_range.401] (/hobbies) array index 3 is out of range\n
"},{"location":"features/element_access/checked_access/#notes","title":"Notes","text":"

Exceptions

  • at can only be used with objects (with a string argument) or with arrays (with a numeric argument). For other types, a basic_json::type_error is thrown.
  • basic_json::out_of_range exception exceptions are thrown if the provided key is not found in an object or the provided index is invalid.
"},{"location":"features/element_access/checked_access/#summary","title":"Summary","text":"scenario non-const value const value access to existing object key reference to existing value is returned const reference to existing value is returned access to valid array index reference to existing value is returned const reference to existing value is returned access to non-existing object key basic_json::out_of_range exception is thrown basic_json::out_of_range exception is thrown access to invalid array index basic_json::out_of_range exception is thrown basic_json::out_of_range exception is thrown

Result of at in each scenario, for a non-const and a const value.

"},{"location":"features/element_access/checked_access/#see-also","title":"See also","text":"
  • Element Access - overview of all ways to access elements
  • Unchecked access: operator[] - access without range checking
  • Access with default value: value - fall back to a default instead of throwing
  • at - checked access by reference
  • JSON Pointer - access nested values with at and a pointer
"},{"location":"features/element_access/default_value/","title":"Access with default value: value","text":""},{"location":"features/element_access/default_value/#overview","title":"Overview","text":"

In many situations, such as configuration files, missing values are not exceptional, but may be treated as if a default value was present. For this case, use value(key, default_value) which takes the key you want to access and a default value in case there is no value stored with that key. This is equivalent to Python's dict.get(key, default).

"},{"location":"features/element_access/default_value/#example","title":"Example","text":"Example

Consider the following JSON value:

{\n    \"logOutput\": \"result.log\",\n    \"append\": true\n}\n

Assume the value is parsed to a json variable j.

expression value j {\"logOutput\": \"result.log\", \"append\": true} j.value(\"logOutput\", \"logfile.log\") \"result.log\" j.value(\"append\", true) true j.value(\"append\", false) true j.value(\"logLevel\", \"verbose\") \"verbose\""},{"location":"features/element_access/default_value/#nested-values","title":"Nested values","text":"

To read a value deep inside a document, pass a JSON Pointer instead of a key. The default value is returned if the value at the pointer does not exist, including the case that an intermediate key is missing. There is no need to check each level with contains first.

json j = {{\"server\", {{\"port\", 8080}}}, {\"list\", {10, 20}}};\n\nint port = j.value(\"/server/port\"_json_pointer, 80);        // 8080\nint timeout = j.value(\"/server/limits/timeout\"_json_pointer, 30); // 30 (missing intermediate key)\nint second = j.value(\"/list/1\"_json_pointer, 0);            // 20 (numeric tokens index arrays)\nint third = j.value(\"/list/5\"_json_pointer, 0);             // 0 (index out of range)\n\nbool has_port = j.contains(\"/server/port\"_json_pointer);    // true\nbool has_host = j.contains(\"/server/host/name\"_json_pointer); // false\n

If the path is only available as a dotted string such as \"server.port\", do not build the pointer by concatenating \"/\" and the parts: keys containing / or ~ would be misinterpreted. Append each part as a reference token with operator/= instead. It escapes the token for you.

json::json_pointer to_pointer(const std::string& dotted)\n{\n    json::json_pointer ptr;\n    std::istringstream in(dotted);\n    for (std::string token; std::getline(in, token, '.');)\n    {\n        ptr /= token;\n    }\n    return ptr;\n}\n\nint port = j.value(to_pointer(\"server.port\"), 80);          // 8080\nint first = j.value(to_pointer(\"list.0\"), 0);               // 10\n

The key \"a/b\" yields the pointer \"/a~1b\"; the dot-splitting itself is up to the caller, so keys containing . need a different separator.

"},{"location":"features/element_access/default_value/#notes","title":"Notes","text":"

Exceptions

  • With string keys, value can only be used with objects. For other types, a basic_json::type_error is thrown.
  • With JSON Pointers, value can be used with both objects and arrays. For other types (null, boolean, number, string), a basic_json::type_error is thrown.

null and mistyped members are not missing

value returns the default value only if the key is absent. If the member exists, it is converted to the type of the default value, even if it is null. For {\"k\": null}, the call j.value(\"k\", 0) throws a basic_json::type_error, and so does a member of another type such as a string where a number is expected. The same holds for JSON Pointers.

To treat null like a missing value, check for it explicitly:

int n = (j.contains(\"k\") && !j[\"k\"].is_null()) ? j[\"k\"].get<int>() : 0;\n

With C++17, get<std::optional<T>>() maps null to an empty optional. As at throws out_of_range for an absent key, use find to cover both cases:

std::optional<int> n;                        // empty if \"k\" is absent or null\nif (const auto it = j.find(\"k\"); it != j.end())\n{\n    n = it->get<std::optional<int>>();       // still throws for a non-number such as \"text\"\n}\n

Return type

The value function is a template, and the return type of the function is determined by the type of the provided default value unless otherwise specified. This can have unexpected effects. In the example below, we store a 64-bit unsigned integer. We get exactly that value when using operator[]. However, when we call value and provide 0 as default value, then -1 is returned. This occurs, because 0 has type int which overflows when handling the value 18446744073709551615.

To address this issue, either provide a correctly typed default value or use the template parameter to specify the desired return type. Note that this issue occurs even when a value is stored at the provided key, and the default value is not used as the return value.

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    json j = json::parse(R\"({\"uint64\": 18446744073709551615})\");\n\n    std::cout << \"operator[]:                \" << j[\"uint64\"] << '\\n'\n              << \"default value (int):       \" << j.value(\"uint64\", 0) << '\\n'\n              << \"default value (uint64_t):  \" << j.value(\"uint64\", static_cast<std::uint64_t>(0)) << '\\n'\n              << \"explicit return value type: \" << j.value<std::uint64_t>(\"uint64\", 0) << '\\n';\n}\n

Output:

operator[]:                18446744073709551615\ndefault value (int):       -1\ndefault value (uint64_t):  18446744073709551615\nexplicit return value type: 18446744073709551615\n
"},{"location":"features/element_access/default_value/#see-also","title":"See also","text":"
  • value - for access with default value
  • Checked access: at - access with bounds checking
  • JSON Pointer - addressing values by path
  • contains - to check whether a key or JSON Pointer exists
  • json_pointer::operator/= - to build a pointer token by token
  • Unchecked access: operator[] - access without range checking
  • Element Access - overview of all ways to access elements
"},{"location":"features/element_access/unchecked_access/","title":"Unchecked access: operator[]","text":""},{"location":"features/element_access/unchecked_access/#overview","title":"Overview","text":"

Elements in a JSON object and a JSON array can be accessed via operator[] similar to a std::map and a std::vector, respectively.

Example: read access

Consider the following JSON value:

{\n    \"name\": \"Mary Smith\",\n    \"age\": 42,\n    \"hobbies\": [\"hiking\", \"reading\"]\n}\n

Assume the value is parsed to a json variable j.

expression value j {\"name\": \"Mary Smith\", \"age\": 42, \"hobbies\": [\"hiking\", \"reading\"]} j[\"name\"] \"Mary Smith\" j[\"age\"] 42 j[\"hobbies\"] [\"hiking\", \"reading\"] j[\"hobbies\"][0] \"hiking\" j[\"hobbies\"][1] \"reading\"

The return value is a reference, so it can modify the original value. In case the passed object key is non-existing, a null value is inserted which can immediately be overwritten.

Example: write access
j[\"name\"] = \"John Smith\";\nj[\"maidenName\"] = \"Jones\";\n

This code produces the following JSON value:

{\n    \"name\": \"John Smith\",\n    \"maidenName\": \"Jones\",\n    \"age\": 42,\n    \"hobbies\": [\"hiking\", \"reading\"]\n}\n

When accessing an invalid index (i.e., an index greater than or equal to the array size), the JSON array is resized such that the passed index is the new maximal index. Intermediate values are filled with null.

Example: filling up arrays with null values
j[\"hobbies\"][0] = \"running\";\nj[\"hobbies\"][3] = \"cooking\";\n

This code produces the following JSON value:

{\n    \"name\": \"John Smith\",\n    \"maidenName\": \"Jones\",\n    \"age\": 42,\n    \"hobbies\": [\"running\", \"reading\", null, \"cooking\"]\n}\n
"},{"location":"features/element_access/unchecked_access/#notes","title":"Notes","text":"

Design rationale

The library behaves differently to std::vector and std::map:

  • std::vector::operator[] never inserts a new element.
  • std::map::operator[] is not available for const values.

The type json wraps all JSON value types. It would be impossible to remove operator[] for const objects. At the same time, inserting elements for non-const objects is really convenient as it avoids awkward insert calls. To this end, we decided to have an inserting non-const behavior for both arrays and objects.

Info

The access is unchecked. In case the passed object key does not exist or the passed array index is invalid, no exception is thrown.

Danger

  • It is undefined behavior to access a const object with a non-existing key.
  • It is undefined behavior to access a const array with an invalid index.
  • In debug mode, an assertion will fire in both cases. You can disable assertions by defining the preprocessor symbol NDEBUG or redefine the macro JSON_ASSERT(x). See the documentation on runtime assertions for more information.

Exceptions

operator[] can only be used with objects (with a string argument) or with arrays (with a numeric argument). For other types, a basic_json::type_error is thrown.

"},{"location":"features/element_access/unchecked_access/#performance-reserving-array-capacity","title":"Performance: reserving array capacity","text":"

There is no public reserve(count) member on basic_json for pre-allocating array capacity. If you are building a large array incrementally (e.g., via repeated push_back()) and know its final size ahead of time, you can reserve capacity via get_ref() to access the underlying array_t directly:

json j = json::array();\nj.get_ref<json::array_t&>().reserve(1000);\nfor (int i = 0; i < 1000; ++i) {\n    j.push_back(i);\n}\n
"},{"location":"features/element_access/unchecked_access/#summary","title":"Summary","text":"scenario non-const value const value access to existing object key reference to existing value is returned const reference to existing value is returned access to valid array index reference to existing value is returned const reference to existing value is returned access to non-existing object key reference to newly inserted null value is returned undefined behavior; runtime assertion in debug mode access to invalid array index reference to newly inserted null value is returned; any index between previous maximal index and passed index are filled with null undefined behavior; runtime assertion in debug mode

Result of operator[] in each scenario, for a non-const and a const value.

"},{"location":"features/element_access/unchecked_access/#see-also","title":"See also","text":"
  • Element Access - overview of all ways to access elements
  • Checked access: at - access with range checking
  • Access with default value: value - fall back to a default instead of throwing
  • operator[] - unchecked access by reference
  • Runtime assertions - assertions that guard operator[] misuse
"},{"location":"features/parsing/","title":"Parsing","text":"

This library can create a JSON value from a wide range of inputs. This page gives an overview of the available parsing functions and how they behave; the linked pages go into more detail.

flowchart LR\n    I[\"JSON input\"] --> P[\"parse()\"]\n    I --> S[\"sax_parse()\"]\n    I --> A[\"accept()\"]\n    P -->|\"optional parser callback filters values\"| D[\"basic_json value (DOM)\"]\n    S --> H[\"events delivered to a user SAX handler\"]\n    A --> V[\"bool: is the input valid JSON?\"]

The three entry points for parsing: parse() builds a basic_json value, optionally filtered by a parser callback, sax_parse() delivers events to a SAX handler, and accept() only checks whether the input is valid.

"},{"location":"features/parsing/#input","title":"Input","text":"

The parse function reads a JSON value from an input. The input can be

  • a string (std::string, C string, or string literal),
  • a wide string (std::u16string, std::u32string, or std::wstring, or a wide string literal),
  • a std::istream (e.g., an std::ifstream reading from a file),
  • a FILE* pointer,
  • a pair of iterators over a contiguous range (e.g., a std::vector<std::uint8_t>), or
  • a contiguous container.
// parse from a string\njson j = json::parse(R\"({\"happy\": true, \"pi\": 3.141})\");\n\n// parse from a file\nstd::ifstream f(\"example.json\");\njson data = json::parse(f);\n

The input must be encoded in UTF-8; other encodings are not supported. The exception is wide-character input, which is read as UTF-16 or UTF-32 \u2014 depending on the character type \u2014 and converted to UTF-8; see the parse page for an example. A single input may contain only one JSON value. Inputs consisting of multiple values separated by newlines are handled by the JSON Lines format; input that arrives in chunks or contains several values is covered in Large, streamed, and partial input.

By default, the library rejects comments and trailing commas. Both can be enabled with parameters of the parse function \u2014 see comments and trailing commas.

basic_json_document::parse accepts the same inputs with the same options, but keeps the result in a document rather than in a basic_json value; see Documents and views below.

"},{"location":"features/parsing/#strictness-and-trailing-data","title":"Strictness and trailing data","text":"

parse reads a single JSON value and requires the whole input to be consumed: any non-whitespace data after the value is reported as a parse error. Use it when you want to guarantee that an input is exactly one complete JSON document.

operator>> follows relaxed std::istream semantics instead: it parses one JSON value and leaves the stream positioned right after it, without requiring the rest of the stream to be consumed. This is what makes it possible to read several concatenated values from the same stream, but it also means that \"a valid document followed by trailing bytes\" is accepted rather than rejected. If you are validating conformance, or need to reject any input that is not exactly one JSON document, prefer parse.

When using operator>> to read several concatenated values this way, a value that is a number must be followed by whitespace, because operator>> consumes the character that terminates a number, unless JSON_PRECISE_STREAM_POSITION is defined to 1 \u2014 see the operator>> notes for details and examples.

"},{"location":"features/parsing/#input-sources-and-performance","title":"Input sources and performance","text":"

All inputs produce the same values and the same exceptions, but they are read in different ways, which makes some of them faster than others:

input how it is read strings, string views, string literals, contiguous containers, pointer or iterator ranges over contiguous memory the whole input is scanned in bulk: runs of string characters, numbers, and indentation are recognized several bytes at a time std::istream (std::ifstream, std::istringstream, ...) the characters the stream buffer holds are scanned in bulk like a string; the stream buffer is asked for more when they are used up FILE* one character at a time, with the file locked once for the whole parse other iterator ranges (e.g., std::list<char>, std::istreambuf_iterator<char>), wide strings one character at a time

Parsing a file from a std::ifstream is therefore only about 10 to 20 % slower than reading the whole file into a std::string first and parsing that, and it needs no memory for a copy of the file. The stream is never read ahead: after parsing, it is positioned exactly as if every character had been read one at a time, so operator>> can still read several values from one stream (see also JSON Lines).

Two macros switch these optimizations off without changing any result: JSON_DISABLE_STREAM_BULK_SCAN for stream buffers that do not follow the usual std::streambuf contract, and JSON_DISABLE_UNLOCKED_FILE_IO for programs in which another thread must use the same FILE object while it is parsed.

Where the target has them, strings are scanned with vector instructions: SSE2 on x86-64 (and SSSE3 for UTF-8 text, when the CPU has it) and NEON on AArch64. JSON_NO_SIMD selects portable code instead, again without changing any result.

"},{"location":"features/parsing/#sax-vs-dom-parsing","title":"SAX vs. DOM parsing","text":"

The library offers two parsing models, and a third, read-only alternative:

  • DOM parsing (the default): the complete input is read and stored as an in-memory basic_json value that can be traversed and modified freely. This is what parse does, and it is the right choice for most use cases.
  • SAX parsing: instead of building a value, the parser reports events (such as \"a string was read\" or \"an object started\") to a handler that you implement. This avoids building the full value in memory and is useful for very large inputs or when you only need to extract parts of the input. See the SAX interface for details and sax_parse for the API.

  • Document and views (<nlohmann/json_view.hpp>, added in version 3.13.0 unreleased): json_document::parse reads the same JSON grammar but builds a flat, read-only index of the values instead of a basic_json tree. Strings and floating-point numbers are read from the text on demand, and only the parts you materialize() become basic_json values. This avoids most of the work when you need only a few values from a large or frequently parsed text; see Zero-copy JSON views. It is read-only, so use parse when you need to modify the value.

You can influence a DOM parse without switching to the SAX interface by passing a parser callback, which is called during parsing and can, for example, discard parts of the input.

"},{"location":"features/parsing/#documents-and-views","title":"Documents and views","text":"

A third model sits between DOM and SAX: basic_json_document::parse parses the input into a document that keeps the text and a flat index of the values in it, and basic_json_view gives read-only access to the values through that index. The whole input is validated during parsing, but only integers and strings that contain escape sequences are converted right away (the strings into a buffer owned by the document). Floating-point numbers and all other strings stay in the source text and are only converted when they are read, which is faster and uses less memory than building a tree of basic_json values when only parts of the document are needed. A document can also be modified in place, and it can be saved and loaded again without parsing it.

#include <nlohmann/json_view.hpp>\n\njson_document doc = json_document::parse(R\"({\"happy\": true, \"pi\": 3.141})\");\nstd::cout << doc.root()[\"happy\"].get<bool>() << '\\n';\n

See Zero-copy JSON views for the concept and the trade-offs.

"},{"location":"features/parsing/#exceptions","title":"Exceptions","text":"

When the input is not valid JSON, the parse function throws an exception by default. If exceptions are undesired or unavailable, the parser can instead return a discarded value, or accept can be used to only check whether an input is valid JSON. See parsing and exceptions for the available options.

"},{"location":"features/parsing/#see-also","title":"See also","text":"
  • parse - deserialize from a compatible input
  • basic_json_document::parse - deserialize into a document instead of a value
  • accept - check if the input is valid JSON
  • sax_parse - generate SAX events
  • JSON Lines - parse newline-delimited JSON
  • Large, streamed, and partial input - chunked, concatenated, and very large input
  • parser callbacks - influence the parsing by a callback function
  • SAX interface - implement a custom SAX handler
  • Zero-copy JSON views - parse into a read-only document and read it through views
  • parsing and exceptions - control error handling
  • parsing untrusted input - what to consider when parsing input from untrusted sources
  • operator>> - deserialize from stream
  • json_sax - documentation of the SAX interface
  • parse_error - exception thrown on a parse error
  • Comments - ignore // and /* */ comments while parsing
  • Trailing Commas - accept trailing commas in arrays and objects
  • Serialization - pretty-printing, UTF-8 handling, and number output
  • Working Without Exceptions - error handling when exceptions are disabled
  • Exceptions - list of exceptions and error codes
"},{"location":"features/parsing/json_lines/","title":"JSON Lines","text":"

The JSON Lines format is a text format of newline-delimited JSON. In particular:

  1. The input must be UTF-8 encoded.
  2. Every line must be a valid JSON value.
  3. The line separator must be \\n. As \\r is silently ignored, \\r\\n is also supported.
  4. The final character may be \\n, but is not required to be one.

JSON Text example

{\"name\": \"Gilbert\", \"wins\": [[\"straight\", \"7\u2663\"], [\"one pair\", \"10\u2665\"]]}\n{\"name\": \"Alexa\", \"wins\": [[\"two pair\", \"4\u2660\"], [\"two pair\", \"9\u2660\"]]}\n{\"name\": \"May\", \"wins\": []}\n{\"name\": \"Deloise\", \"wins\": [[\"three of a kind\", \"5\u2663\"]]}\n

JSON Lines input with more than one value is treated as invalid JSON by the parse or accept functions. To process it line by line, functions like std::getline can be used:

Example: Parse JSON Text input line by line

The example below demonstrates how JSON Lines can be processed.

#include <sstream>\n#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // JSON Lines (see https://jsonlines.org)\n    std::stringstream input;\n    input << R\"({\"name\": \"Gilbert\", \"wins\": [[\"straight\", \"7\u2663\"], [\"one pair\", \"10\u2665\"]]}\n{\"name\": \"Alexa\", \"wins\": [[\"two pair\", \"4\u2660\"], [\"two pair\", \"9\u2660\"]]}\n{\"name\": \"May\", \"wins\": []}\n{\"name\": \"Deloise\", \"wins\": [[\"three of a kind\", \"5\u2663\"]]}\n)\";\n\n    std::string line;\n    while (std::getline(input, line))\n    {\n        std::cout << json::parse(line) << '\\n';\n    }\n}\n

Output:

{\"name\":\"Gilbert\",\"wins\":[[\"straight\",\"7\u2663\"],[\"one pair\",\"10\u2665\"]]}\n{\"name\":\"Alexa\",\"wins\":[[\"two pair\",\"4\u2660\"],[\"two pair\",\"9\u2660\"]]}\n{\"name\":\"May\",\"wins\":[]}\n{\"name\":\"Deloise\",\"wins\":[[\"three of a kind\",\"5\u2663\"]]}\n

Note

Using operator>> like

json j;\nwhile (input >> j)\n{\n    std::cout << j << std::endl;\n}\n

with a JSON Lines input does not work, because the parser will try to parse one value after the last one and throw a parse_error.101 exception. The same happens for a stream of concatenated (non-newline-delimited) JSON values: operator>> reads them one at a time, but the loop above throws after the last value. To read either format with operator>>, check for the end of the stream before each read:

json j;\nwhile (input >> std::ws && input.peek() != std::char_traits<char>::eof())\n{\n    input >> j;\n    std::cout << j << std::endl;\n}\n

A value that is a number must be followed by whitespace \u2014 see the notes of operator>> for details.

"},{"location":"features/parsing/json_lines/#see-also","title":"See also","text":"
  • Parsing - overview of the parsing functions
  • Large, Streamed, and Partial Input - chunked, concatenated, and very large input
  • parse - deserialize from a compatible input
  • operator>> - deserialize from stream
"},{"location":"features/parsing/large_and_partial_input/","title":"Large, Streamed, and Partial Input","text":"

parse reads exactly one complete JSON value and builds it in memory. It cannot be paused and resumed, and it does not hand back a half-parsed value when the input ends early. This page shows what to do when the input does not fit that model: it arrives in pieces, it contains several values, or it is too large to hold as a json value.

flowchart TD\n    A[\"my input is...\"] --> B{\"several JSON values in one stream?\"}\n    B -->|\"yes\"| C[\"read them one at a time\"]\n    A --> D{\"arriving in chunks (socket, pipe)?\"}\n    D -->|\"yes\"| E[\"frame the messages, or buffer until complete\"]\n    A --> F{\"too large to keep in memory?\"}\n    F -->|\"yes\"| G[\"discard parts with a callback, or use SAX\"]\n    A --> H{\"only a small part is needed?\"}\n    H -->|\"yes\"| I[\"stop early with SAX, or read through a view\"]

Questions about the input and the approach this page describes for each; an input can match more than one question.

"},{"location":"features/parsing/large_and_partial_input/#several-values-in-one-stream","title":"Several values in one stream","text":"

For newline-delimited input, read line by line and parse each line, as described in JSON Lines. For values that are simply concatenated, operator>> reads one value and leaves the stream positioned after it. Check for the end of the stream before each read, because a read at the end throws:

Example: read concatenated values
#include <iostream>\n#include <sstream>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    std::istringstream input(R\"({\"a\":1} [2,3] 4 \"s\")\");\n\n    // check for the end of the stream before each read, because a read at the end throws\n    json j;\n    while (input >> std::ws && input.peek() != std::char_traits<char>::eof())\n    {\n        input >> j;\n        std::cout << j << '\\n';\n    }\n}\n

Output:

{\"a\":1}\n[2,3]\n4\n\"s\"\n

The same works for binary formats. from_cbor and its relatives accept strict = false to stop after the first value and leave the rest of the stream untouched; tellg() then reports how many bytes the value took:

Example: read one CBOR value and find out how many bytes it used
#include <iostream>\n#include <sstream>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    // a CBOR value followed by other data\n    const std::vector<std::uint8_t> cbor = json::to_cbor(json{1, 2, 3});\n    std::string data(cbor.begin(), cbor.end());\n    data += \"TRAILING\";\n\n    std::istringstream input(data);\n    json j = json::from_cbor(input, false); // strict = false: stop after the first value\n\n    std::cout << \"value: \" << j << '\\n';\n    std::cout << \"bytes used: \" << input.tellg() << '\\n';\n\n    std::string rest;\n    input >> rest;\n    std::cout << \"remaining input: \" << rest << '\\n';\n}\n

Output:

value: [1,2,3]\nbytes used: 4\nremaining input: TRAILING\n
"},{"location":"features/parsing/large_and_partial_input/#input-arriving-in-chunks","title":"Input arriving in chunks","text":"

A socket, pipe, or HTTP body hands over data in pieces of arbitrary size, and a piece can end in the middle of a number, a string, or an object. The parser does not keep state between calls, so there are two ways to deal with this.

Frame the messages. The most robust approach is a protocol that says where a value ends: one value per line (JSON Lines), a length prefix, or a delimiter. Collect the bytes of one message and parse them when the frame is complete. Prefer this whenever you control the protocol.

Buffer until the value is complete. If the data has no framing, append every chunk to a buffer and try to parse it. A parse error at the very end of the buffer means that the input ended prematurely, while an error anywhere else is a real syntax error. The member byte of the parse_error exception is one past the buffer size in the first case:

Example: buffer chunks until the value is complete
#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nstd::string buffer;\n\n// call for every chunk; returns true and sets `value` once the buffer holds one complete JSON value\nbool push(const std::string& chunk, json& value)\n{\n    buffer += chunk;\n    try\n    {\n        value = json::parse(buffer);\n        buffer.clear();\n        return true;\n    }\n    catch (const json::parse_error& e)\n    {\n        if (e.byte == buffer.size() + 1)\n        {\n            return false; // the input ends prematurely: wait for more data\n        }\n        throw; // a real syntax error\n    }\n}\n\nint main()\n{\n    json value;\n    const auto chunks = {\"{\\\"na\", \"me\\\": \\\"Ma\", \"ry\\\", \\\"l\", \"ist\\\": [1, 2\", \", 3]}\"};\n    for (const std::string chunk : chunks)\n    {\n        std::cout << \"chunk \" << chunk << \" -> \" << (push(chunk, value) ? \"complete\" : \"incomplete\") << '\\n';\n    }\n    std::cout << value << '\\n';\n\n    // a syntax error in the middle is not mistaken for missing data\n    try\n    {\n        push(\"[1, ]\", value);\n    }\n    catch (const json::parse_error& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n}\n

Output:

chunk {\"na -> incomplete\nchunk me\": \"Ma -> incomplete\nchunk ry\", \"l -> incomplete\nchunk ist\": [1, 2 -> incomplete\nchunk , 3]} -> complete\n{\"list\":[1,2,3],\"name\":\"Mary\"}\n[json.exception.parse_error.101] parse error at line 1, column 5: syntax error while parsing value - unexpected ']'; expected '[', '{', or a literal\n

The example feeds a document in five chunks. The first four are reported as incomplete, and a syntax error is reported as such, not as missing data.

The chunks of the example, and the bytes each attempt parses again:

Buffering chunks until the value is complete: five chunks of {\"name\": \"Mary\", \"list\": [1, 2, 3]} appended to a buffer. After chunks 1 to 4 the buffer has 4, 12, 19, and 30 bytes, and parsing it fails at byte 5, 13, 20, and 31: one past the end, so the input is incomplete and the program waits for more. After chunk 5 the buffer of 35 bytes parses as one complete value. For the input [1, ] of 5 bytes the error is at byte 5, before the end, so it is a real syntax error. Every attempt parses the buffer from byte 1, so 4 + 12 + 19 + 30 + 35 = 100 bytes are parsed for a 35-byte value, and the work grows quadratically. chunk buffer, parsed from byte 1 each time result chunk 1 {\"na error at byte 5 = size + 1 incomplete: wait for more chunk 2 {\"name\": \"Ma error at byte 13 = size + 1 incomplete: wait for more chunk 3 {\"name\": \"Mary\", \"l error at byte 20 = size + 1 incomplete: wait for more chunk 4 {\"name\": \"Mary\", \"list\": [1, 2 error at byte 31 = size + 1 incomplete: wait for more chunk 5 {\"name\": \"Mary\", \"list\": [1, 2, 3]} parsed, size 35 complete: one value other input [1, ] error at byte 5, size 5 before the end: a real error Bytes parsed: 4 + 12 + 19 + 30 + 35 = 100 for a value of 35 bytes. Every attempt starts again at byte 1, so the total work grows quadratically with the size of the value.

Each row is one parse attempt on the growing buffer: an error at the byte after the end of the buffer means the value is incomplete, an error before the end is a real syntax error. The last line adds up the bytes parsed over all attempts.

Limits of buffering

  • The buffer must contain exactly one value. Data that belongs to the next value is a syntax error. Use framing if values follow each other without a separator.
  • A number at the end of the buffer is a complete value, even if more digits are still to come (12 may be the start of 123). Buffering cannot detect this; use framing for top-level numbers.
  • Every attempt parses the buffer from the beginning, so the total work grows quadratically with the size of the value. Limit the size of the buffer for input you do not trust (see untrusted input).
"},{"location":"features/parsing/large_and_partial_input/#input-too-large-for-memory","title":"Input too large for memory","text":"

The input does not have to become one huge json value. The two tools below process it piece by piece.

How the memory use develops while a large array of records is parsed (illustrative, not a measurement):

Illustrative memory use over time while a large array of records is parsed, not a measurement. Four curves. D\u200bOM, parse(): rises steadily until the whole tree is in memory. json_document: starts at about the size of the text, which it keeps, and grows a little while its index is built. Parser callback that discards every record: stays flat at the size of one record. S\u200bAX: stays flat and lowest, because no value is built and only what the handler keeps is in memory. memory time: records parsed illustrative, not a measurement D\u200bOM: parse() the whole tree json_document the text plus its index callback, discard one record at a time S\u200bAX only what the handler keeps

Memory use over the number of records parsed: parse() keeps the whole tree, json_document the text plus its index, a discarding callback one record at a time, and SAX only what the handler keeps.

"},{"location":"features/parsing/large_and_partial_input/#handle-and-discard-elements-with-a-callback","title":"Handle and discard elements with a callback","text":"

A parser callback is called for every finished value. If it returns false, the value is discarded and its memory is released at once. For a file that consists of one huge array (or one huge object) of records, handle each record at depth 1 and discard it:

Example: handle and discard each record of a large array
#include <iostream>\n#include <sstream>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nvoid handle(const json& record)\n{\n    std::cout << \"handling \" << record << '\\n';\n}\n\nint main()\n{\n    std::istringstream file(R\"([{\"id\": 1}, {\"id\": 2}, {\"id\": 3}])\");\n\n    json result = json::parse(file, [](int depth, json::parse_event_t event, json & record)\n    {\n        if (depth == 1 && event == json::parse_event_t::object_end)\n        {\n            handle(record);\n            return false; // discard the record\n        }\n        return true;\n    });\n\n    std::cout << \"result: \" << result << '\\n';\n}\n

Output:

handling {\"id\":1}\nhandling {\"id\":2}\nhandling {\"id\":3}\nresult: []\n

Only one record is in memory at any time. The same recipe, with more detail, is in the parser callbacks page. To skip entire members you do not need, discard them when their key is read; see the example for parse_event_t::key.

"},{"location":"features/parsing/large_and_partial_input/#extract-a-few-values-and-stop-with-sax","title":"Extract a few values and stop with SAX","text":"

With the SAX interface, no value is built at all, and returning false from any handler function stops the parser. sax_parse then returns false, and the rest of the input is not read. The example finds the first id in a document without parsing the remainder:

Example: stop parsing as soon as a value is found
#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nstruct find_id : nlohmann::json_sax<json>\n{\n    bool next_is_id = false;\n    json::number_unsigned_t id = 0;\n\n    bool key(std::string& name) override\n    {\n        next_is_id = (name == \"id\");\n        return true;\n    }\n\n    bool number_unsigned(json::number_unsigned_t value) override\n    {\n        if (next_is_id)\n        {\n            id = value;\n            return false; // found: stop parsing\n        }\n        return true;\n    }\n\n    bool null() override\n    {\n        return true;\n    }\n    bool boolean(bool /*val*/) override\n    {\n        return true;\n    }\n    bool number_integer(json::number_integer_t /*val*/) override\n    {\n        return true;\n    }\n    bool number_float(json::number_float_t /*val*/, const std::string& /*s*/) override\n    {\n        return true;\n    }\n    bool string(std::string& /*val*/) override\n    {\n        return true;\n    }\n    bool binary(json::binary_t& /*val*/) override\n    {\n        return true;\n    }\n    bool start_object(std::size_t /*elements*/) override\n    {\n        return true;\n    }\n    bool end_object() override\n    {\n        return true;\n    }\n    bool start_array(std::size_t /*elements*/) override\n    {\n        return true;\n    }\n    bool end_array() override\n    {\n        return true;\n    }\n    bool parse_error(std::size_t /*position*/, const std::string& /*last_token*/, const json::exception& /*ex*/) override\n    {\n        return false;\n    }\n};\n\nint main()\n{\n    find_id handler;\n    const bool completed = json::sax_parse(R\"({\"x\": [1, 2, 3], \"id\": 42, \"rest\": [4, 5, 6]})\", &handler);\n\n    std::cout << std::boolalpha;\n    std::cout << \"parse completed: \" << completed << '\\n';\n    std::cout << \"id: \" << handler.id << '\\n';\n}\n

Output:

parse completed: false\nid: 42\n

Note that sax_parse returns false both when a handler stopped the parse and when the input is invalid, so record the reason in the handler (here: id) if you need to tell the two apart.

"},{"location":"features/parsing/large_and_partial_input/#read-parts-of-a-large-document-with-a-view","title":"Read parts of a large document with a view","text":"

If the whole text is available and you only need to read some of it, a json_document from <nlohmann/json_view.hpp> (added in version 3.13.0 unreleased) avoids the basic_json tree altogether: it keeps the text, builds a flat index of the values, and gives read-only views of the parts you look at. Only what you materialize() becomes a basic_json value. See Zero-copy JSON views for details and for the lifetime rules.

"},{"location":"features/parsing/large_and_partial_input/#see-also","title":"See also","text":"
  • Parsing - overview of the parsing functions
  • JSON Lines - newline-delimited JSON
  • Parser callbacks - discard values while parsing
  • SAX interface - event-based parsing
  • Zero-copy JSON views - read parts of a large document without building a tree
  • Untrusted input - limits for input you do not control
  • operator>> - deserialize from stream
  • parse - deserialize from a compatible input
  • sax_parse - generate SAX events
  • JSON_PRECISE_STREAM_POSITION - leave the stream positioned right after a parsed number
  • JSON_DISABLE_STREAM_BULK_SCAN - read a std::istream one character at a time
"},{"location":"features/parsing/parse_exceptions/","title":"Parsing and Exceptions","text":"

When the input is not valid JSON, an exception of type parse_error is thrown. This exception contains the position in the input where the error occurred, together with a diagnostic message and the last read input token. The exceptions page contains a list of examples for parse error exceptions. In case you process untrusted input, always enclose your code with a try/catch block, like

json j;\ntry\n{\n    j = json::parse(my_input);\n}\ncatch (json::parse_error& ex)\n{\n    std::cerr << \"parse error at byte \" << ex.byte << std::endl;\n}\n

In case exceptions are undesired or not supported by the environment, there are different ways to proceed:

Tip

Working without exceptions also covers accessing values and converting to your own types.

"},{"location":"features/parsing/parse_exceptions/#switch-off-exceptions","title":"Switch off exceptions","text":"

The parse() function accepts a bool parameter allow_exceptions which controls whether an exception is thrown when a parse error occurs (true, default) or whether a discarded value should be returned (false).

json j = json::parse(my_input, nullptr, false);\nif (j.is_discarded())\n{\n    std::cerr << \"parse error\" << std::endl;\n}\n

Note there is no diagnostic information available in this scenario.

"},{"location":"features/parsing/parse_exceptions/#use-accept-function","title":"Use accept() function","text":"

Alternatively, function accept() can be used which does not return a json value, but a bool indicating whether the input is valid JSON.

if (!json::accept(my_input))\n{\n    std::cerr << \"parse error\" << std::endl;\n}\n

Again, there is no diagnostic information available.

"},{"location":"features/parsing/parse_exceptions/#user-defined-sax-interface","title":"User-defined SAX interface","text":"

Finally, you can implement the SAX interface and decide what should happen in case of a parse error.

This function has the following interface:

bool parse_error(std::size_t position,\n                 const std::string& last_token,\n                 const json::exception& ex);\n

The return value indicates whether the parsing should continue, so the function should usually return false.

Example: report parse errors without exceptions

The example derives from the library's DOM parser and overrides parse_error to print the error instead of throwing. Note the DOM parser is an implementation detail (nlohmann::detail) and may change between releases; see Do not use the detail namespace.

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\n// a DOM parser that reports parse errors instead of throwing\nclass sax_no_exception : public nlohmann::detail::json_sax_dom_parser<json, nlohmann::detail::string_input_adapter_type>\n{\n  public:\n    explicit sax_no_exception(json& j)\n        : nlohmann::detail::json_sax_dom_parser<json, nlohmann::detail::string_input_adapter_type>(j, false)\n    {}\n\n    bool parse_error(std::size_t position,\n                     const std::string& last_token,\n                     const json::exception& ex)\n    {\n        std::cout << \"parse error at input byte \" << position << \"\\n\"\n                  << ex.what() << \"\\n\"\n                  << \"last read: \\\"\" << last_token << \"\\\"\"\n                  << '\\n';\n        return false;\n    }\n};\n\nint main()\n{\n    std::string myinput = \"[1,2,3,]\";\n\n    json result;\n    sax_no_exception sax(result);\n\n    bool parse_result = json::sax_parse(myinput, &sax);\n    if (!parse_result)\n    {\n        std::cout << \"parsing unsuccessful!\" << '\\n';\n    }\n\n    std::cout << \"parsed value: \" << result << '\\n';\n}\n

Output:

parse error at input byte 8\n[json.exception.parse_error.101] parse error at line 1, column 8: syntax error while parsing value - unexpected ']'; expected '[', '{', or a literal\nlast read: \"3,]\"\nparsing unsuccessful!\nparsed value: [1,2,3]\n
"},{"location":"features/parsing/parse_exceptions/#where-did-the-error-occur","title":"Where did the error occur?","text":"

The message of a parse_error for JSON text contains the line and column of the error:

[json.exception.parse_error.101] parse error at line 3, column 8: syntax error while parsing value - unexpected ']'; expected '[', '{', or a literal\n

The exception object itself only stores the byte index of the last read character in the member byte (the first byte of the input has index 1). The same index is passed to parse_error in the SAX interface. If you need the line and column as numbers, for example to show them in an editor, compute them from the input:

Example: compute line and column of a parse error
#include <iostream>\n#include <utility>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\n// line and column (both starting at 1) of a byte index in a text\nstd::pair<std::size_t, std::size_t> line_column(const std::string& input, std::size_t byte)\n{\n    std::size_t line = 1;\n    std::size_t column = 1;\n    for (std::size_t i = 0; i + 1 < byte && i < input.size(); ++i)\n    {\n        if (input[i] == '\\n')\n        {\n            ++line;\n            column = 1;\n        }\n        else\n        {\n            ++column;\n        }\n    }\n    return {line, column};\n}\n\nint main()\n{\n    const std::string input = \"{\\n  \\\"a\\\": 1,\\n  \\\"b\\\": ]\\n}\";\n\n    try\n    {\n        const json j = json::parse(input);\n        std::cout << j << '\\n';\n    }\n    catch (const json::parse_error& e)\n    {\n        const auto position = line_column(input, e.byte);\n        std::cout << e.what() << '\\n';\n        std::cout << \"byte \" << e.byte << \" = line \" << position.first << \", column \" << position.second << '\\n';\n    }\n}\n

Output:

[json.exception.parse_error.101] parse error at line 3, column 8: syntax error while parsing value - unexpected ']'; expected '[', '{', or a literal\nbyte 20 = line 3, column 8\n

Columns count bytes, so a line with multi-byte UTF-8 characters before the error may differ from the column your editor shows.

"},{"location":"features/parsing/parse_exceptions/#where-is-the-value-that-caused-a-later-error","title":"Where is the value that caused a later error?","text":"

A parse_error is raised while the text is read. Many mistakes show up later: the text is valid JSON, but a value has the wrong type when you convert it (type_error.302), or a key is missing (out_of_range.403). The exception then says what is wrong, but not where in the input the value was. Define JSON_DIAGNOSTIC_POSITIONS before including the library to add the byte range of the offending value to such messages (since version 3.12.0), and to query the range of any value with start_pos() and end_pos():

Example: locate a value with diagnostic positions
#define JSON_DIAGNOSTIC_POSITIONS 1\n#include <iostream>\n#include <utility>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\n// line and column (both starting at 1) of a byte index in a text\nstd::pair<std::size_t, std::size_t> line_column(const std::string& input, std::size_t byte)\n{\n    std::size_t line = 1;\n    std::size_t column = 1;\n    for (std::size_t i = 0; i + 1 < byte && i < input.size(); ++i)\n    {\n        if (input[i] == '\\n')\n        {\n            ++line;\n            column = 1;\n        }\n        else\n        {\n            ++column;\n        }\n    }\n    return {line, column};\n}\n\nint main()\n{\n    const std::string input = \"{\\n  \\\"name\\\": \\\"Mary\\\",\\n  \\\"age\\\": \\\"forty-two\\\"\\n}\";\n    const json j = json::parse(input); // the input is valid JSON ...\n\n    try\n    {\n        const int age = j[\"age\"]; // ... but the value has the wrong type\n        std::cout << age << '\\n';\n    }\n    catch (const json::exception& e)\n    {\n        std::cout << e.what() << '\\n';\n\n        // start_pos() is a 0-based index into the input; the helper expects a 1-based byte index\n        const auto position = line_column(input, j[\"age\"].start_pos() + 1);\n        std::cout << \"the value starts at line \" << position.first << \", column \" << position.second << '\\n';\n    }\n}\n

Output:

[json.exception.type_error.302] (bytes 29-40) type must be number, but is string\nthe value starts at line 3, column 10\n

Positions are only available for values created by parse, they are not updated when a value is changed, and the macro makes every value 16 bytes larger on 64-bit platforms, so use it where the cost is acceptable, for example for configuration files. Note that start_pos() is a 0-based index into the input, whereas byte of a parse_error starts at 1.

For binary formats such as CBOR, there are no lines; byte is the position in the byte sequence. To find out how many bytes a successfully parsed value used, see Several values in one stream.

"},{"location":"features/parsing/parse_exceptions/#see-also","title":"See also","text":"
  • parse - deserialize from a compatible input
  • accept - check if the input is valid JSON
  • sax_parse - generate SAX events
  • parse_error - exception thrown on a parse error
  • JSON_DIAGNOSTIC_POSITIONS - record start and end positions of parsed values
  • Working Without Exceptions - error handling when exceptions are disabled
  • Exceptions - list of exceptions and error codes
  • Parsing Untrusted Input - limits and checks for input you do not control
"},{"location":"features/parsing/parser_callbacks/","title":"Parser Callbacks","text":""},{"location":"features/parsing/parser_callbacks/#overview","title":"Overview","text":"

With a parser callback function, the result of parsing a JSON text can be influenced. When passed to parse, it is called on certain events (passed as parse_event_t via parameter event) with a set recursion depth depth and context JSON value parsed. The return value of the callback function is a boolean indicating whether the element that emitted the callback shall be kept or not.

The type of the callback function is:

template<typename BasicJsonType>\nusing parser_callback_t =\n    std::function<bool(int depth, parse_event_t event, BasicJsonType& parsed)>;\n
"},{"location":"features/parsing/parser_callbacks/#callback-event-types","title":"Callback event types","text":"

We distinguish six scenarios (determined by the event type) in which the callback function can be called. The following table describes the values of the parameters depth, event, and parsed.

parameter event description parameter depth parameter parsed parse_event_t::object_start the parser read { and started to process a JSON object depth of the parent of the JSON object a JSON value with type discarded parse_event_t::key the parser read a key of a value in an object depth of the currently parsed JSON object a JSON string containing the key parse_event_t::object_end the parser read } and finished processing a JSON object depth of the parent of the JSON object the parsed JSON object parse_event_t::array_start the parser read [ and started to process a JSON array depth of the parent of the JSON array a JSON value with type discarded parse_event_t::array_end the parser read ] and finished processing a JSON array depth of the parent of the JSON array the parsed JSON array parse_event_t::value the parser finished reading a JSON value depth of the value the parsed JSON value

Example of the parse events a callback sees for the J\u200bSON text {\"name\": \"Berlin\", \"location\": [52.519444, 13.406667]}: object_start after the opening brace, key after each key, array_start after the opening bracket, value after each value, array_end after the closing bracket, and object_end after the closing brace. Every array and object also produces a value event when it is complete. J\u200bSON to parse callback events { \"name\" : \"Berlin\" , \"location\" : [ 52.519444 , 13.406667 ] } object_start key object_end array_start array_end value

Each coloured dot marks where the parser reports a parse_event_t event while reading the JSON text on the left; the legend on the right names the event per colour.

Example: sequence of callback events

When parsing the following JSON text,

{\n    \"name\": \"Berlin\",\n    \"location\": [\n        52.519444,\n        13.406667\n    ]\n}\n

these calls are made to the callback function:

event depth parsed object_start 0 discarded key 1 \"name\" value 1 \"Berlin\" key 1 \"location\" array_start 1 discarded value 2 52.519444 value 2 13.406667 array_end 1 [52.519444,13.406667] object_end 0 {\"location\":[52.519444,13.406667],\"name\":\"Berlin\"}

No built-in nesting depth limit

The library has no built-in limit on recursion/nesting depth while parsing. A parser callback can only discard content it has already parsed (by returning false); it cannot make parsing fail once a nesting limit is exceeded partway through reading a deeply nested value. If you need to reject over-deep untrusted input outright, track depth in a callback and throw from it once your limit is exceeded (a thrown exception propagates out of parse() as usual).

"},{"location":"features/parsing/parser_callbacks/#return-value","title":"Return value","text":"

Discarding a value (i.e., returning false) has different effects depending on the context in which the function was called:

  • Discarded values in structured types are skipped. That is, the parser will behave as if the discarded value was never read.
  • In case a value outside a structured type is skipped, it is replaced with null. This case happens if the top-level element is skipped.
Example: skip an object key while parsing

The example below demonstrates the parse() function with and without callback function.

#include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // a JSON text\n    const auto* text = R\"(\n    {\n        \"Image\": {\n            \"Width\":  800,\n            \"Height\": 600,\n            \"Title\":  \"View from 15th Floor\",\n            \"Thumbnail\": {\n                \"Url\":    \"http://www.example.com/image/481989943\",\n                \"Height\": 125,\n                \"Width\":  100\n            },\n            \"Animated\" : false,\n            \"IDs\": [116, 943, 234, 38793]\n        }\n    }\n    )\";\n\n    // parse and serialize JSON\n    json j_complete = json::parse(text);\n    std::cout << std::setw(4) << j_complete << \"\\n\\n\";\n\n    // define parser callback\n    json::parser_callback_t cb = [](int depth, json::parse_event_t event, json & parsed)\n    {\n        // skip object elements with key \"Thumbnail\"\n        if (event == json::parse_event_t::key and parsed == json(\"Thumbnail\"))\n        {\n            return false;\n        }\n        else\n        {\n            return true;\n        }\n    };\n\n    // parse (with callback) and serialize JSON\n    json j_filtered = json::parse(text, cb);\n    std::cout << std::setw(4) << j_filtered << '\\n';\n}\n

Output:

{\n    \"Image\": {\n        \"Animated\": false,\n        \"Height\": 600,\n        \"IDs\": [\n            116,\n            943,\n            234,\n            38793\n        ],\n        \"Thumbnail\": {\n            \"Height\": 125,\n            \"Url\": \"http://www.example.com/image/481989943\",\n            \"Width\": 100\n        },\n        \"Title\": \"View from 15th Floor\",\n        \"Width\": 800\n    }\n}\n\n{\n    \"Image\": {\n        \"Animated\": false,\n        \"Height\": 600,\n        \"IDs\": [\n            116,\n            943,\n            234,\n            38793\n        ],\n        \"Title\": \"View from 15th Floor\",\n        \"Width\": 800\n    }\n}\n
"},{"location":"features/parsing/parser_callbacks/#recipe-rejecting-duplicate-object-keys","title":"Recipe: rejecting duplicate object keys","text":"

The JSON specification leaves the handling of objects with repeated keys up to the implementation. As described in object_t, it is unspecified which value for a repeated key ends up in the resulting json value \u2014 once parsing has produced that value, the duplicate is already gone, because object storage maps each key to a single value. If duplicate keys should instead be treated as an error, a parser callback can detect them while the object is still being read, before that ambiguity ever applies.

Example: reject duplicate object keys
#include <iostream>\n#include <nlohmann/json.hpp>\n#include <stdexcept>\n#include <string>\n#include <unordered_set>\n#include <vector>\n\nusing nlohmann::json;\n\njson parse_strict(const std::string& input)\n{\n    // one key set per nesting depth, reused across sibling objects\n    std::vector<std::unordered_set<std::string>> keys;\n\n    auto reject_duplicate_keys = [&](int depth, json::parse_event_t event, json & parsed)\n    {\n        if (event == json::parse_event_t::object_start)\n        {\n            // keys of this object are reported at depth+1 (see the event table above)\n            const auto child_depth = static_cast<std::size_t>(depth) + 1;\n            if (keys.size() <= child_depth)\n            {\n                keys.resize(child_depth + 1);\n            }\n            keys[child_depth].clear();\n            return true;\n        }\n\n        if (event == json::parse_event_t::key)\n        {\n            auto& seen = keys[static_cast<std::size_t>(depth)];\n            const auto& key = parsed.get_ref<const std::string&>();\n            if (!seen.insert(key).second)\n            {\n                throw std::runtime_error(\"duplicate JSON object key: \" + key);\n            }\n            return true;\n        }\n\n        return true;\n    };\n\n    return json::parse(input, reject_duplicate_keys);\n}\n\nint main()\n{\n    // parsing succeeds when all keys are unique\n    json j = parse_strict(R\"({\"one\": 1, \"two\": 2})\");\n    std::cout << j << '\\n';\n\n    // parsing throws when a key is repeated\n    try\n    {\n        parse_strict(R\"({\"one\": 1, \"one\": 2})\");\n    }\n    catch (const std::exception& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n}\n

Output:

{\"one\":1,\"two\":2}\nduplicate JSON object key: one\n

This approach has three limitations:

  • The depth-indexed bookkeeping must account for the fact that object_start reports the depth of the parent of the object, while the key events inside that object are reported one depth deeper (see the event table above); it is easy to get this off by one for nested objects.
  • The thrown exception cannot carry a parse_error-style byte offset, because position tracking only exists inside the parser and lexer, not at the callback layer.
  • The exception only names the repeated key, not where it occurs in the document. Reporting its full path requires maintaining a stack of the enclosing keys and array indices in the callback as well.

A SAX interface does not lift the position limitation: its key function receives no position either \u2014 only parse_error is passed the byte position.

"},{"location":"features/parsing/parser_callbacks/#recipe-streaming-a-large-homogeneous-array","title":"Recipe: streaming a large homogeneous array","text":"

A common use case is a huge top-level array of many similarly-shaped objects, too large to hold entirely in memory as a json value. A parser callback can hand off each completed element to a user function and then discard it, so memory usage stays bounded by a single element (plus the not-yet-parsed tail of the input) rather than the whole document. Since the top-level array's array_start/array_end are reported at depth == 0 (its parent is the document root), the object elements it contains are reported at depth == 1:

Example: stream a large top-level array
std::ifstream input(\"large_array.json\");\n\nauto callback = [](int depth, json::parse_event_t event, json& parsed) -> bool {\n    if (depth == 1 && event == json::parse_event_t::object_end) {\n        handle_element(parsed); // process the element, e.g. write it elsewhere\n        return false;           // discard it -- frees its memory before the next one is parsed\n    }\n    return true; // keep everything else, including the (by then empty) top-level array\n};\n\njson::parse(input, callback);\n

If the array's elements are scalars or nested arrays instead of objects, check for parse_event_t::value or parse_event_t::array_end at depth == 1 instead. The same approach works for a top-level object of many homogeneous values by checking object_end/value events at depth == 1 there too.

"},{"location":"features/parsing/parser_callbacks/#recipe-max-nesting-depth-via-a-callback","title":"Recipe: max nesting depth via a callback","text":"

Since there is no built-in nesting-depth limit (see the note above), a callback can enforce one manually by tracking the maximum depth seen and throwing once it is exceeded:

Example: limit the nesting depth
constexpr int max_depth = 32;\n\nauto callback = [](int depth, json::parse_event_t /*event*/, json& /*parsed*/) -> bool {\n    if (depth > max_depth) {\n        throw std::runtime_error(\"maximum nesting depth exceeded\");\n    }\n    return true;\n};\n\njson::parse(input, callback);\n
"},{"location":"features/parsing/parser_callbacks/#see-also","title":"See also","text":"
  • Parsing - overview of the parsing functions
  • SAX Interface - guide to event-based parsing
  • parse - deserialize from a compatible input
  • parser_callback_t - callback function type for the parser
  • parse_event_t - enumeration of parser events
"},{"location":"features/parsing/sax_interface/","title":"SAX Interface","text":"

The library uses a SAX-like interface with the following functions:

classDiagram\n\nclass sax_t [\"json::sax_t\"] {\n    <<interface>>\n    +bool null()*\n\n    +bool boolean(bool val)*\n\n    +bool number_integer(number_integer_t val)*\n    +bool number_unsigned(number_unsigned_t val)*\n\n    +bool number_float(number_float_t val, const string_t& s)*\n\n    +bool string(string_t& val)*\n    +bool binary(binary_t& val)*\n\n    +bool start_object(std::size_t elements)*\n    +bool end_object()*\n    +bool start_array(std::size_t elements)*\n    +bool end_array()*\n    +bool key(string_t& val)*\n\n    +bool parse_error(std::size_t position, const std::string& last_token, const json::exception& ex)*\n}

The interface json::sax_t: one function per event, each returning bool; the functions marked with * are pure virtual.

// called when null is parsed\nbool null();\n\n// called when a boolean is parsed; value is passed\nbool boolean(bool val);\n\n// called when a signed or unsigned integer number is parsed; value is passed\nbool number_integer(number_integer_t val);\nbool number_unsigned(number_unsigned_t val);\n\n// called when a floating-point number is parsed; value and original string is passed\nbool number_float(number_float_t val, const string_t& s);\n\n// called when a string is parsed; value is passed and can be safely moved away\nbool string(string_t& val);\n// called when a binary value is parsed; value is passed and can be safely moved away\nbool binary(binary_t& val);\n\n// called when an object or array begins or ends, resp. The number of elements is passed (or -1 if not known)\nbool start_object(std::size_t elements);\nbool end_object();\nbool start_array(std::size_t elements);\nbool end_array();\n// called when an object key is parsed; value is passed and can be safely moved away\nbool key(string_t& val);\n\n// called when a parse error occurs; byte position, the last token, and an exception is passed\nbool parse_error(std::size_t position, const std::string& last_token, const json::exception& ex);\n

The return value of each function determines whether parsing should proceed.

"},{"location":"features/parsing/sax_interface/#stepping-through-the-events","title":"Stepping through the events","text":"

The events for a small input, step by step, and what two different handlers do with them. Press Play or step with Next:

input

{\"a\":[1,true],\"b\":\"x\"}

events, in the order the parser calls them

  1. start_object(-1)
  2. key(\"a\")
  3. start_array(-1)
  4. number_unsigned(1)
  5. boolean(true)
  6. end_array()
  7. key(\"b\")
  8. string(\"x\")
  9. end_object()

handler: build a value tree, as parse does

{\n  \"a\": [\n    1,\n    true\n  ],\n  \"b\": \"x\"\n}

After end_object() the tree is complete and no container is open. The number of elements is passed as -1: the parser does not know it in advance.

The three lanes show the input consumed so far, the events called so far, and the state of the selected handler (build a tree or keep only /b). Check return false at this event to stop the parse at the current event and see which events are no longer called.

To implement your own SAX handler, proceed as follows:

  1. Implement the SAX interface in a class. You can use class nlohmann::json_sax<json> as base class, but you can also use any class where the functions described above are implemented and public.
  2. Create an object of your SAX interface class, e.g. my_sax.
  3. Call bool json::sax_parse(input, &my_sax); where the first parameter can be any input like a string or an input stream and the second parameter is a pointer to your SAX interface.

Note the sax_parse function only returns a bool indicating the result of the last executed SAX event. It does not return json value - it is up to you to decide what to do with the SAX events. Furthermore, no exceptions are thrown in case of a parse error - it is up to you what to do with the exception object passed to your parse_error implementation. Internally, the SAX interface is used for the DOM parser (class json_sax_dom_parser) as well as the acceptor (json_sax_acceptor), see file json_sax.hpp.

"},{"location":"features/parsing/sax_interface/#see-also","title":"See also","text":"
  • json_sax - documentation of the SAX interface
  • sax_parse - SAX parser
  • Parsing - overview of the parsing functions
  • Parsing and Exceptions - handling parse errors and locating them in the input
  • parse - deserialize from a compatible input
  • Binary Formats - CBOR, MessagePack, BSON, and other formats
"},{"location":"features/parsing/untrusted_input/","title":"Parsing Untrusted Input","text":"

This page is for applications that parse JSON \u2014 or one of the supported binary formats (BJData, BON8, BSON, CBOR, MessagePack, UBJSON) \u2014 from a source they do not fully control, such as a network connection, an uploaded file, or another process. It summarizes what the library already does for such input and what remains the caller's responsibility, linking to the pages that cover each aspect in detail rather than repeating them.

For the project's threat model and the countermeasures behind these behaviors, see the assurance case; to report a vulnerability, see the security policy.

"},{"location":"features/parsing/untrusted_input/#errors-without-exceptions","title":"Errors without exceptions","text":"

By default, parse() throws a parse_error (for instance parse_error.101 for a syntax error) when the input is not valid. If your environment cannot use exceptions for untrusted input, the library offers several alternatives; see Parsing and exceptions for the full comparison:

  • Pass false as the third argument to parse() to get a discarded value (checked with is_discarded()) instead of a thrown exception, with no diagnostic information.
  • Use accept() to only check whether the input is valid JSON, without building a value.
  • Implement the SAX interface and override parse_error() to react to an error yourself, with the byte position and the exception that would otherwise have been thrown; see the example that overrides it to print instead of throw.

If exceptions are unavailable entirely (-fno-exceptions, or JSON_NOEXCEPTION defined), every throw in the library becomes a call to std::abort(). The alternatives above do not throw, so parse() with allow_exceptions set to false (and likewise accept() and the from_* functions with allow_exceptions set to false) can still reject invalid input in that configuration; a plain parse() call aborts on invalid input. See Working without exceptions and Switch off exceptions for the details and for overriding the abort with JSON_THROW_USER.

"},{"location":"features/parsing/untrusted_input/#nesting-depth","title":"Nesting depth","text":"

The JSON parser and the binary readers are iterative: they keep the containers they are currently inside of on a heap-allocated stack instead of calling themselves once per nesting level, so the native call stack does not grow with the nesting depth of the input. A deeply nested document is therefore bounded by available memory, not by the call stack, however deeply it is nested.

No built-in depth limit while parsing

Neither the parser nor the binary readers impose a limit on how deep the input may nest. An attacker can still exhaust memory (though not the call stack) with a sufficiently deep document. If you need to reject over-deep untrusted input outright, track the depth yourself, either with a parser callback for the JSON parser, or by counting start_object/start_array and end_object/end_array calls in a SAX handler (for the JSON parser or a binary format alike) and throwing once your limit is exceeded.

Once a value has been parsed, operations that walk it recursively \u2014 serializing it with dump, hashing it, copying it, comparing two values with ==, <, or (in C++20) <=>, merging with update, applying a merge_patch, creating a patch with diff or merge_diff, flatten, and the binary writers (to_cbor, to_msgpack, ...) \u2014 descend at most 128 levels on the call stack and continue below that with an explicit stack instead, so none of them can exhaust the stack either, however deeply the value is nested. Destroying a value (its destructor) never recurses at all, regardless of nesting depth, for the same reason.

"},{"location":"features/parsing/untrusted_input/#input-size","title":"Input size","text":"

The library does not limit the overall size of a JSON text; a value nested or wide enough will use memory proportional to the input. If you parse untrusted input of unbounded size, check the size of the file or stream yourself before \u2014 or while \u2014 handing it to parse().

For the binary formats, an announced size is never trusted outright:

  • Reading a string or binary value copies the input in bounded 4096-byte chunks and grows the result as bytes are actually consumed, rather than allocating the announced length up front \u2014 a truncated input runs out of bytes (reported as a parse error) instead of triggering an oversized allocation.
  • When an array announces its number of elements and the array container supports reserve() (as std::vector, the default, does), the library reserves storage for at most 16384 of them upfront, regardless of how large the announced count is; further elements still grow the container normally as they are read.
  • An announced array or object size that exceeds what the target container could ever hold (its max_size()) is rejected immediately as out_of_range.408, without attempting to allocate anything.
"},{"location":"features/parsing/untrusted_input/#strings","title":"Strings","text":"

Invalid UTF-8 is rejected while parsing, not just while serializing:

  • In JSON text, an ill-formed UTF-8 byte in a string is a parse_error.101 (\"invalid string: ill-formed UTF-8 byte\").
  • In UTF-16 or UTF-32 input, an ill-formed sequence is a parse_error.101 as well: a lone surrogate, a high surrogate that is not followed by its low surrogate, and a code point above U+10FFFF are all rejected.
  • In a binary format, a string that is not valid UTF-8 is a parse_error.113.

A '\\0' (NUL) byte inside a quoted JSON string is always rejected (it must be escaped as \\u0000). A NUL byte outside of a string is different: by default it is silently treated as the end of the input, so trailing bytes after it \u2014 including further, otherwise well-formed JSON \u2014 are silently ignored rather than rejected. Since untrusted input that happens to embed a NUL is a way to make part of it disappear without a parse error, see the FAQ entry and consider defining JSON_STRICT_NUL_HANDLING to 1 to reject a NUL byte like any other unexpected byte instead.

Parsing is not the only place invalid UTF-8 matters: a string that reached a json value some other way (for example, constructed by application code, or, before JSON_STRICT_NUL_HANDLING existed, read from a binary format that does not validate strings) still has to round-trip back to JSON text. By default, dump() throws type_error.316 if the string is not valid UTF-8; passing error_handler_t::replace or error_handler_t::ignore avoids the exception instead of crashing an application that forgot to catch it. See Handling invalid UTF-8 for the options and an example.

"},{"location":"features/parsing/untrusted_input/#duplicate-object-keys","title":"Duplicate object keys","text":"

The JSON specification leaves the handling of repeated keys in an object up to the implementation, and this library does too: as described in object_t, it is unspecified which of the values for a repeated key ends up in the parsed object. If your application must reject duplicate keys instead of silently resolving them one way or another, see the parser callback recipe for rejecting duplicate keys.

"},{"location":"features/parsing/untrusted_input/#numbers","title":"Numbers","text":"

A number whose value cannot be represented \u2014 for instance 1E1000, which overflows double \u2014 is rejected while parsing as out_of_range.406 rather than silently becoming infinity. An integer that is syntactically valid but does not fit the 64-bit integer types is not rejected; it is instead stored as a double, which may lose precision for very large values. See number limits for the exact ranges and an example.

"},{"location":"features/parsing/untrusted_input/#comments-and-trailing-commas","title":"Comments and trailing commas","text":"

Both comments and trailing commas are rejected by default, matching the JSON specification; they must be explicitly enabled per call with the ignore_comments and ignore_trailing_commas parameters of parse() or accept(). Do not enable either for input whose conformance you cannot otherwise control, since interoperability with strictly conforming JSON consumers is exactly what the default rejects.

"},{"location":"features/parsing/untrusted_input/#checklist","title":"Checklist","text":"
  • Wrap parsing in a try/catch block, or use allow_exceptions=false/accept() if your environment cannot use exceptions; never let JSON_NOEXCEPTION's abort() be the first time you think about error handling.
  • If the input's nesting depth matters to you, enforce your own limit with a parser callback or a SAX handler; the library bounds the call stack but not memory use.
  • Bound the size of the input itself before parsing, independent of the library's own bounded allocations for binary format lengths.
  • Decide up front how you want a string with invalid UTF-8 \u2014 from any source, not only parsing \u2014 to be serialized (strict, replace, or ignore), rather than discovering it from an uncaught type_error.316.
  • If a stray NUL byte silently truncating trailing input is a problem for your input format, define JSON_STRICT_NUL_HANDLING.
  • Decide whether duplicate object keys should be an error for your application, and add a callback if so.
  • Do not enable ignore_comments or ignore_trailing_commas for input that must be strictly conforming JSON.

For the broader design rationale and how it is tested (fuzzing, sanitizers, static analysis), see the assurance case and quality assurance. To report a security issue in the library itself, follow the security policy.

"},{"location":"features/parsing/untrusted_input/#see-also","title":"See also","text":"
  • Parsing - overview of the parsing functions
  • Parsing and exceptions - error handling without exceptions
  • Parser callbacks - depth limits, duplicate-key rejection, and streaming recipes
  • SAX interface - implement a custom handler with access to parse errors and positions
  • Serialization - handling invalid UTF-8 when dumping
  • Number handling - number ranges and overflow behavior
  • Assurance case - the library's threat model and countermeasures
  • Security policy - how to report a vulnerability
  • parse - deserialize from a compatible input
  • accept - check if the input is valid JSON
  • sax_parse - generate SAX events
  • parser_callback_t - callback function type for the parser
  • JSON_STRICT_NUL_HANDLING - opt in to rejecting a NUL byte in the input
  • JSON_DIAGNOSTIC_POSITIONS - record start and end positions of parsed values
"},{"location":"features/types/","title":"Types","text":"

This page gives an overview of how JSON values are stored and how this can be configured.

"},{"location":"features/types/#overview","title":"Overview","text":"

By default, JSON values are stored as follows:

JSON type C++ type object std::map<std::string, basic_json> array std::vector<basic_json> null std::nullptr_t string std::string boolean bool number std::int64_t, std::uint64_t, and double

Note there are three different types for numbers - when parsing JSON text, the best fitting type is chosen.

"},{"location":"features/types/#storage","title":"Storage","text":"
classDiagram\n\nclass value_t {\n    <<enumeration>>\n    null\n    object\n    array\n    string\n    boolean\n    number_integer\n    number_unsigned\n    number_float\n    binary\n    discarded\n}\n\nclass json_value {\n    <<union>>\n    object_t* object\n    array_t* array\n    string_t* string\n    binary_t* binary\n    boolean_t boolean\n    number_integer_t number_integer\n    number_unsigned_t number_unsigned\n    number_float_t number_float\n}\n\nclass basic_json {\n    -value_t m_type\n    -json_value m_value\n    +typedef object_t\n    +typedef array_t\n    +typedef binary_t\n    +typedef boolean_t\n    +typedef number_integer_t\n    +typedef number_unsigned_t\n    +typedef number_float_t\n}\n\nbasic_json .. json_value\nbasic_json .. value_t

Storage of a basic_json value: the enumeration value_t holds the type, and the union json_value holds the value, as a pointer for objects, arrays, strings, and binary values and directly for booleans and numbers.

"},{"location":"features/types/#template-arguments","title":"Template arguments","text":"

The data types to store a JSON value are derived from the template arguments passed to class basic_json:

template<\n    template<typename U, typename V, typename... Args> class ObjectType = std::map,\n    template<typename U, typename... Args> class ArrayType = std::vector,\n    class StringType = std::string,\n    class BooleanType = bool,\n    class NumberIntegerType = std::int64_t,\n    class NumberUnsignedType = std::uint64_t,\n    class NumberFloatType = double,\n    template<typename U> class AllocatorType = std::allocator,\n    template<typename T, typename SFINAE = void> class JSONSerializer = adl_serializer,\n    class BinaryType = std::vector<std::uint8_t>,\n    class CustomBaseClass = void\n>\nclass basic_json;\n

Type json is an alias for basic_json<> and uses the default types.

From the template arguments, the following types are derived:

using object_comparator_t = std::less<>;\nusing object_t = ObjectType<StringType, basic_json, object_comparator_t,\n                   AllocatorType<std::pair<const StringType, basic_json>>>;\n\nusing array_t = ArrayType<basic_json, AllocatorType<basic_json>>;\n\nusing string_t = StringType;\n\nusing boolean_t = BooleanType;\n\nusing number_integer_t = NumberIntegerType;\nusing number_unsigned_t = NumberUnsignedType;\nusing number_float_t = NumberFloatType;\n\nusing binary_t = nlohmann::byte_container_with_subtype<BinaryType>;\n

Not every type can be passed for these template arguments: the library uses the resulting types in ways that imply a number of requirements, for instance that StringType is char-based or that ArrayType is vector-like. These requirements are collected in Template Parameter Requirements.

"},{"location":"features/types/#objects","title":"Objects","text":"

RFC 8259 describes JSON objects as follows:

An object is an unordered collection of zero or more name/value pairs, where a name is a string and a value is a string, number, boolean, null, object, or array.

"},{"location":"features/types/#default-type","title":"Default type","text":"

With the default values for ObjectType (std::map), StringType (std::string), and AllocatorType (std::allocator), the default type for object_t is:

std::map<\n  std::string, // key_type\n  basic_json, // value_type\n  std::less<>, // key_compare\n  std::allocator<std::pair<const std::string, basic_json>> // allocator_type\n>\n
"},{"location":"features/types/#behavior","title":"Behavior","text":"

The choice of object_t influences the behavior of the JSON class. With the default type, objects have the following behavior:

  • When all names are unique, objects will be interoperable in the sense that all software implementations receiving that object will agree on the name-value mappings.
  • When the names within an object are not unique, it is unspecified which one of the values for a given key will be chosen. For instance, {\"key\": 2, \"key\": 1} could be equal to either {\"key\": 1} or {\"key\": 2}. To reject duplicate keys instead of silently resolving them one way or another, see this parsing recipe.
  • Internally, name/value pairs are stored in lexicographical order of the names. Objects will also be serialized (see dump) in this order. For instance, both {\"b\": 1, \"a\": 2} and {\"a\": 2, \"b\": 1} will be stored and serialized as {\"a\": 2, \"b\": 1}.
  • When comparing objects, the order of the name/value pairs is irrelevant. This makes objects interoperable in the sense that they will not be affected by these differences. For instance, {\"b\": 1, \"a\": 2} and {\"a\": 2, \"b\": 1} will be treated as equal.
"},{"location":"features/types/#key-order","title":"Key order","text":"

The order in which name/value pairs are added to the object is 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 alphabetical order as std::map with std::less is used by default. Please note this behavior conforms to RFC 8259, because any order implements the specified \"unordered\" nature of JSON objects.

"},{"location":"features/types/#limits","title":"Limits","text":"

RFC 8259 specifies:

An implementation may set limits on the maximum depth of nesting.

In this class, the object's limit of nesting is not explicitly constrained. However, a maximum depth of nesting may be introduced by the compiler or runtime environment. A theoretical limit can be queried by calling the max_size function of a JSON object.

"},{"location":"features/types/#storage_1","title":"Storage","text":"

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.

"},{"location":"features/types/#converting-maps-with-non-string-keys","title":"Converting maps with non-string keys","text":"

A std::map/std::unordered_map whose key type is not string-like (e.g., std::map<int, std::string>) is converted to a JSON array of 2-element [key, value] arrays rather than a JSON object, because JSON object keys must be strings:

std::map<int, std::string> m{{1, \"one\"}, {2, \"two\"}};\njson j = m;\n// j is [[1,\"one\"],[2,\"two\"]], not {\"1\":\"one\",\"2\":\"two\"}\n
"},{"location":"features/types/#arrays","title":"Arrays","text":"

RFC 8259 describes JSON arrays as follows:

An array is an ordered sequence of zero or more values.

"},{"location":"features/types/#default-type_1","title":"Default type","text":"

With the default values for ArrayType (std::vector) and AllocatorType (std::allocator), the default type for array_t is:

std::vector<\n  basic_json, // value_type\n  std::allocator<basic_json> // allocator_type\n>\n
"},{"location":"features/types/#limits_1","title":"Limits","text":"

RFC 8259 specifies:

An implementation may set limits on the maximum depth of nesting.

In this class, the array's limit of nesting is not explicitly constrained. However, a maximum depth of nesting may be introduced by the compiler or runtime environment. A theoretical limit can be queried by calling the max_size function of a JSON array.

"},{"location":"features/types/#storage_2","title":"Storage","text":"

Arrays are stored as pointers in a basic_json type. That is, for any access to array values, a pointer of type array_t* must be dereferenced.

"},{"location":"features/types/#strings","title":"Strings","text":"

RFC 8259 describes JSON strings as follows:

A string is a sequence of zero or more Unicode characters.

Unicode values are split by the JSON class into byte-sized characters during deserialization.

"},{"location":"features/types/#default-type_2","title":"Default type","text":"

With the default values for StringType (std::string), the default type for string_t is std::string.

"},{"location":"features/types/#encoding","title":"Encoding","text":"

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.

"},{"location":"features/types/#string-comparison","title":"String comparison","text":"

RFC 8259 states:

Software implementations are typically required to test names of object members for equality. Implementations that transform the textual representation into sequences of Unicode code units and then perform the comparison numerically, code unit by code unit are interoperable in the sense that implementations will agree in all cases on equality or inequality of two strings. For example, implementations that compare strings with escaped characters unconverted may incorrectly find that \"a\\\\b\" and \"a\\u005Cb\" are not equal.

This implementation is interoperable as it does compare strings code unit by code unit.

"},{"location":"features/types/#storage_3","title":"Storage","text":"

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.

"},{"location":"features/types/#booleans","title":"Booleans","text":"

RFC 8259 implicitly describes a boolean as a type which differentiates the two literals true and false.

"},{"location":"features/types/#default-type_3","title":"Default type","text":"

With the default values for BooleanType (bool), the default type for boolean_t is bool.

"},{"location":"features/types/#storage_4","title":"Storage","text":"

Boolean values are stored directly inside a basic_json type.

"},{"location":"features/types/#numbers","title":"Numbers","text":"

See the number handling article for a detailed discussion on how numbers are handled by this library.

RFC 8259 describes numbers as follows:

The representation of numbers is similar to that used in most programming languages. A number is represented in base 10 using decimal digits. It contains an integer component that may be prefixed with an optional minus sign, which may be followed by a fraction part and/or an exponent part. Leading zeros are not allowed. (...) Numeric values that cannot be represented in the grammar below (such as Infinity and NaN) are not permitted.

This description includes both integer and floating-point numbers. However, C++ allows more precise storage if it is known whether the number is a signed integer, an unsigned integer, or a floating-point number. Therefore, three different types, number_integer_t, number_unsigned_t, and number_float_t are used.

"},{"location":"features/types/#default-types","title":"Default types","text":"

With the default values for NumberIntegerType (std::int64_t), the default type for number_integer_t is std::int64_t. With the default values for NumberUnsignedType (std::uint64_t), the default type for number_unsigned_t is std::uint64_t. With the default values for NumberFloatType (double), the default type for number_float_t is double.

"},{"location":"features/types/#default-behavior","title":"Default behavior","text":"
  • 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.
  • Not-a-number (NaN) values will be serialized to null.
"},{"location":"features/types/#limits_2","title":"Limits","text":"

RFC 8259 specifies:

An implementation may set limits on the range and precision of numbers.

When the default type is used, the maximal integer number that can be stored is 9223372036854775807 (INT64_MAX) and the minimal integer number that can be stored is -9223372036854775808 (INT64_MIN). Integer numbers that are out of range will yield over/underflow when used in a constructor. During deserialization, too large or small integer numbers will automatically be stored as number_unsigned_t or number_float_t.

When the default type is used, the maximal unsigned integer number that can be stored is 18446744073709551615 (UINT64_MAX) and the minimal integer number that can be stored is 0. Integer numbers that are out of range will yield over/underflow when used in a constructor. During deserialization, too large or small integer numbers will automatically be stored as number_integer_t or number_float_t.

RFC 8259 further states:

Note that when such software is used, numbers that are integers and are in the range [-253+1, 253-1] are interoperable in the sense that implementations will agree exactly on their numeric values.

As this range is a subrange of the exactly supported range [INT64_MIN, INT64_MAX], this class's integer type is interoperable.

RFC 8259 states:

This specification allows implementations to set limits on the range and precision of numbers accepted. Since software that implements IEEE 754-2008 binary64 (double precision) numbers is generally available and widely used, good interoperability can be achieved by implementations that expect no more precision or range than these provide, in the sense that implementations will approximate JSON numbers within the expected precision.

This implementation does exactly follow this approach, as it uses double precision floating-point numbers by default (see NumberFloatType above). Note that with the default double, numbers smaller than -1.79769313486232e+308 or greater than 1.79769313486232e+308 are rejected during parsing with out_of_range.406. Non-finite values (NaN and infinity) can only be stored by assigning them directly and are serialized to null.

"},{"location":"features/types/#storage_5","title":"Storage","text":"

Integer number values, unsigned integer number values, and floating-point number values are stored directly inside a basic_json type.

"},{"location":"features/types/#see-also","title":"See also","text":"
  • Number handling - how numbers are stored and converted
  • Template parameter requirements - what the template parameters of basic_json must provide
  • basic_json - the class template and its member types
  • type - and value_t - query the type of a value
  • object_t, array_t, string_t, number_integer_t, number_float_t - the underlying types
  • Object order - how object keys are ordered
  • json - the default JSON type
  • boolean_t - the underlying boolean type
  • number_unsigned_t - the underlying unsigned integer type
  • is_primitive - and the other is_* functions query the type
  • is_structured - true for objects and arrays
  • Converting values - convert JSON values to and from C++ types
  • Creating JSON values - build JSON values
"},{"location":"features/types/number_handling/","title":"Number Handling","text":"

This document describes how the library is handling numbers.

"},{"location":"features/types/number_handling/#background","title":"Background","text":"

This section briefly summarizes how the JSON specification describes how numbers should be handled.

"},{"location":"features/types/number_handling/#json-number-syntax","title":"JSON number syntax","text":"

JSON defines the syntax of numbers as follows:

RFC 8259, Section 6

The representation of numbers is similar to that used in most programming languages. A number is represented in base 10 using decimal digits. It contains an integer component that may be prefixed with an optional minus sign, which may be followed by a fraction part and/or an exponent part. Leading zeros are not allowed.

A fraction part is a decimal point followed by one or more digits.

An exponent part begins with the letter E in uppercase or lowercase, which may be followed by a plus or minus sign. The E and optional sign are followed by one or more digits.

The following railroad diagram from json.org visualizes the number syntax:

Railroad diagram of the J\u200bSON number syntax: optional minus, then 0 or a digit from 1 to 9 followed by digits, then an optional fraction (a dot and digits) and an optional exponent (e or E, an optional sign, and digits). \u2212 0 digit 1\u20139 digit . digit e E \u2212 + digit number fraction exponent

Read the diagram from left to right: every path along the lines spells a valid number, made of an optional minus sign, an integer part, an optional fraction, and an optional exponent.

"},{"location":"features/types/number_handling/#number-interoperability","title":"Number interoperability","text":"

On number interoperability, the following remarks are made:

RFC 8259, Section 6

This specification allows implementations to set limits on the range and precision of numbers accepted. Since software that implements IEEE 754 binary64 (double precision) numbers [IEEE754] is generally available and widely used, good interoperability can be achieved by implementations that expect no more precision or range than these provide, in the sense that implementations will approximate JSON numbers within the expected precision. A JSON number such as 1E400 or 3.141592653589793238462643383279 may indicate potential interoperability problems, since it suggests that the software that created it expects receiving software to have greater capabilities for numeric magnitude and precision than is widely available.

Note that when such software is used, numbers that are integers and are in the range [-253+1, 253-1] are interoperable in the sense that implementations will agree exactly on their numeric values.

"},{"location":"features/types/number_handling/#library-implementation","title":"Library implementation","text":"

This section describes how this library implements the above number specification.

"},{"location":"features/types/number_handling/#number-storage","title":"Number storage","text":"

In the default json type, numbers are stored as std::uint64_t, std::int64_t, and double, respectively. Thereby, std::uint64_t and std::int64_t are used only if they can store the number without loss of precision. If this is impossible (e.g., if the number is too large), the number is stored as double.

Positive integers are stored as std::uint64_t, while negative integers are stored as std::int64_t. This distinction is determined at parse time: if the JSON number has a leading minus sign, it uses signed integer storage; otherwise, it uses unsigned integer storage.

flowchart TD\n    A[\"number literal\"] --> B{{\"has a fraction (.) or exponent (e/E)?\"}}\n    B -->|\"yes\"| F[\"number_float_t\"]\n    B -->|\"no\"| C{{\"has a leading minus sign?\"}}\n    C -->|\"yes\"| D[\"try number_integer_t\"]\n    C -->|\"no\"| E[\"try number_unsigned_t\"]\n    D -->|\"overflow\"| F\n    E -->|\"overflow\"| F

How the parser picks the storage type of a number literal: a fraction or exponent always gives number_float_t; otherwise the sign selects the signed or unsigned integer type, and a value that overflows it is stored as number_float_t.

Notes

  • Numbers with a decimal digit or scientific notation are always stored as double.
  • The number types can be changed, see Template number types.
  • The library converts integers and floating-point numbers itself, independent of the locale. Floating-point numbers are correctly rounded (to nearest, ties to even). Only a long double that is not IEEE 754 binary64 (e.g., the 80-bit x87 format) is converted with std::from_chars where available, or else with std::strtold. For that call, the library temporarily replaces the . with the decimal point of the current locale (which may be longer than one byte, e.g., in fa_IR.UTF-8), so the result does not depend on the locale either. Changing the locale in another thread during parsing is undefined behavior of the C library, though. Before version 3.13.0 unreleased, the conversion was realized by std::strtoull, std::strtoll, and std::strtod, respectively.

Examples

  • Integer -12345678912345789123456789 is smaller than INT64_MIN and will be stored as floating-point number -1.2345678912345788e+25.
  • Integer 1E3 will be stored as floating-point number 1000.0.
"},{"location":"features/types/number_handling/#number-limits","title":"Number limits","text":"
  • Any 64-bit signed or unsigned integer can be stored without loss of precision.
  • Numbers exceeding the limits of double (i.e., numbers whose rounded value is not satisfying std::isfinite such as 1E400) will throw exception json.exception.out_of_range.406 during parsing. Numbers too small for double (such as 1E-400) become zero, with the sign of the number.
  • Floating-point numbers are rounded to the next number representable as double. For instance 3.141592653589793238462643383279 is stored as 0x400921fb54442d18. This is the same behavior as the code double x = 3.141592653589793238462643383279;.

Interoperability

  • The library is interoperable with respect to the specification, because its supported range [-263, 264-1] is larger than the described range [-253+1, 253-1].
  • All integers outside the range [-263, 264-1], as well as floating-point numbers are stored as double. This also concurs with the specification above.
"},{"location":"features/types/number_handling/#zeros","title":"Zeros","text":"

The JSON number grammar allows for different ways to express zero, and this library will store zeros differently:

Literal Stored value and type Serialization 0 std::uint64_t(0) 0 -0 std::int64_t(0) 0 0.0 double(0.0) 0.0 -0.0 double(-0.0) -0.0 0E0 double(0.0) 0.0 -0E0 double(-0.0) -0.0

That is, -0 is stored as a signed integer, but the serialization does not reproduce the -.

The literals mentioned on this page, parsed with json::parse and serialized with dump() (checked against the library; pick one or type it to see the row):

Literal Stored as (type()) dump() 0 number_unsigned (std::uint64_t) 0 -0 number_integer (std::int64_t) 0 -0.0 number_float (double) -0.0 1E3 number_float (double) 1000.0 -12345678912345789123456789 number_float (double) -1.2345678912345788e+25 18446744073709551615 number_unsigned (std::uint64_t) 18446744073709551615 18446744073709551616 number_float (double) 1.8446744073709552e+19 -9223372036854775808 number_integer (std::int64_t) -9223372036854775808 1E400 exception out_of_range.406 (nothing, parsing fails) 1E-400 number_float (double) 0.0 3.141592653589793238462643383279 number_float (double) 3.141592653589793 2555.5599999999999 number_float (double) 2555.56 0.0000972439793401814 number_float (double) 9.72439793401814e-05 12345E-5 number_float (double) 0.12345

Each row shows how a literal is stored and how dump() writes it back. The explorer only knows the literals in this list; other input is reported as not in the verified list.

"},{"location":"features/types/number_handling/#number-serialization","title":"Number serialization","text":"
  • Integer numbers are serialized as is; that is, no scientific notation is used.
  • Floating-point numbers are serialized with the fewest digits that read back as the same value (the closest such digits if there are several), in the layout of the %g printf modifier: 1.5, 100.0, 1e+100. Doubles are converted with the algorithm of \u017bmij, floats with Grisu2, which can write more digits than necessary.

Notes regarding precision of floating-point numbers

As described above, floating-point numbers are rounded to the nearest double and serialized with the shortest representation to allow round-tripping. This can yield confusing examples:

  • The serialization can have fewer decimal places than the input: 2555.5599999999999 will be serialized as 2555.56. The reverse can also be true.
  • The serialization can be in scientific notation even if the input is not: 0.0000972439793401814 will be serialized as 9.72439793401814e-05. The reverse can also be true: 12345E-5 will be serialized as 0.12345.
  • Conversions from float to double can also introduce rounding errors:
    float f = 0.3;\njson j = f;\nstd::cout << j << '\\n';\n
    yields 0.30000001192092896.

All examples here can be reproduced by passing the original double value to

std::printf(\"%.*g\\n\", std::numeric_limits<double>::max_digits10, double_value);\n
"},{"location":"features/types/number_handling/#nan-handling","title":"NaN handling","text":"

NaN (not-a-number) cannot be expressed with the number syntax described above and are in fact explicitly excluded:

RFC 8259, Section 6

Numeric values that cannot be represented in the grammar below (such as Infinity and NaN) are not permitted.

That is, there is no way to parse a NaN value. However, assignments can store NaN values in a JSON value.

This library serializes NaN values as null. This corresponds to the behavior of JavaScript's JSON.stringify function.

Example

The following example shows how a NaN value is stored in a json value.

int main()\n{\n    double val = std::numeric_limits<double>::quiet_NaN();\n    std::cout << \"val=\" << val << std::endl;\n    json j = val;\n    std::cout << \"j=\" << j.dump() << std::endl;\n    val = j;\n    std::cout << \"val=\" << val << std::endl;\n}\n

output:

val=nan\nj=null\nval=nan\n
"},{"location":"features/types/number_handling/#number-comparison","title":"Number comparison","text":"

Floating-point numbers inside JSON values are compared with json::number_float_t::operator== which is double::operator== by default.

Alternative comparison functions

To compare floating-point while respecting an epsilon, an alternative comparison function could be used, for instance

template<typename T, typename = typename std::enable_if<std::is_floating_point<T>::value, T>::type>\ninline bool is_same(T a, T b, T epsilon = std::numeric_limits<T>::epsilon()) noexcept\n{\n    return std::abs(a - b) <= epsilon;\n}\n
Or you can self-define an operator equal function like this:

bool my_equal(const_reference lhs, const_reference rhs)\n{\n    const auto lhs_type = lhs.type();\n    const auto rhs_type = rhs.type();\n    if (lhs_type == rhs_type)\n    {\n        switch(lhs_type)\n        {\n            // self_defined case\n            case value_t::number_float:\n                return std::abs(lhs - rhs) <= std::numeric_limits<float>::epsilon();\n\n            // other cases remain the same with the original\n            ...\n        }\n    }\n    ...\n}\n

(see #703 for more information.)

Note

NaN values never compare equal to themselves or to other NaN values. See #514.

"},{"location":"features/types/number_handling/#number-conversion","title":"Number conversion","text":"

Just like the C++ language itself, the get family of functions allows conversions between unsigned and signed integers, and between integers and floating-point values. This behavior may be surprising.

Unconditional number conversions

double d = 42.3;                          // non-integer double value 42.3\njson jd = d;                              // stores double value 42.3\nstd::int64_t i = jd.get<std::int64_t>();  // now i==42; no warning or error is produced\n

Note the last line with throw a json.exception.type_error.302 exception if jd is not a numerical type, for instance a string.

Numeric conversions are performed according to the corresponding C++ conversion rules. The library does not perform range checks when converting between numeric types.

In particular, conversions from floating-point values to integer types, or conversions to integer types with a smaller range than the stored value, may produce implementation-defined or undefined behavior if the source value cannot be represented by the target type.

Applications requiring checked conversions should inspect the stored number type with is_number_float(), is_number_integer(), is_number_unsigned(), or type(), and perform explicit range checks before converting to a narrower type.

The rationale is twofold:

  1. JSON does not define a number type or precision (see above).
  2. C++ also allows silently converting between number types.

Conditional number conversion

The code above can be solved by explicitly checking the nature of the value with members such as is_number_integer() or is_number_unsigned():

// check if jd is really integer-valued\nif (jd.is_number_integer())\n{\n    // if so, do the conversion and use i\n    std::int64_t i = jd.get<std::int64_t>();\n    // ...\n}\nelse\n{\n    // otherwise, take appropriate action\n    // ...\n}\n

Note this approach also has the advantage that it can react on non-numerical JSON value types such as strings.

(Example taken from #777.)

"},{"location":"features/types/number_handling/#determine-number-types","title":"Determine number types","text":"

As the example in Number conversion shows, there are different functions to determine the type of the stored number:

  • is_number() returns true for any number type
  • is_number_integer() returns true for signed and unsigned integers
  • is_number_unsigned() returns true for unsigned integers only
  • is_number_float() returns true for floating-point numbers
  • type_name() returns \"number\" for any number type
  • type() returns a different enumerator of value_t for all number types
function unsigned integer signed integer floating-point string is_number() true true true false is_number_integer() true true false false is_number_unsigned() true false false false is_number_float() false false true false type_name() \"number\" \"number\" \"number\" \"string\" type() number_unsigned number_integer number_float string

Return value of each function for a value that stores an unsigned integer, a signed integer, or a floating-point number, and for a string for comparison.

"},{"location":"features/types/number_handling/#template-number-types","title":"Template number types","text":"

The number types can be changed with template parameters.

position number type default type possible values 5 signed integers std::int64_t std::int32_t, std::int16_t, etc. 6 unsigned integers std::uint64_t std::uint32_t, std::uint16_t, etc. 7 floating-point double float, long double

Constraints on number types

  • The type for signed integers must be convertible from long long. The type for floating-point numbers is used in case of overflow.
  • The type for unsigned integers must be convertible from unsigned long long. The type for floating-point numbers is used in case of overflow.
  • The type for unsigned integers can also be the same signed type as the type for signed integers (e.g., std::int64_t for both). Then every integer is stored as a signed integer, and is_number_unsigned() is always false, see Template Parameter Requirements.
  • The type for floating-point numbers must be distinct from the integer types.
  • Only double, float, and long double are supported for floating-point numbers.

Example

A basic_json type that uses long double as floating-point type.

using json_ld = nlohmann::json::with_float_t<long double>;\n

Note values should then be parsed with json_ld::parse rather than json::parse as the latter would parse floating-point values to double before then converting them to long double.

"},{"location":"features/types/number_handling/#see-also","title":"See also","text":"
  • Types - how all value types are stored
  • Converting values - convert numbers to C++ types
  • number_integer_t - the signed integer type
  • number_unsigned_t - the unsigned integer type
  • number_float_t - the floating-point type
  • is_number - check for a number of any kind
"},{"location":"features/types/template_parameters/","title":"Template Parameter Requirements","text":"

Class basic_json is configurable through eleven template parameters. The library never formally states what a type passed for one of these parameters has to provide \u2014 the requirements are implied by the way the library uses the resulting object_t, array_t, string_t, etc. This page collects these requirements so they do not have to be discovered by trial and error. Each section lists the concrete types that are known to work for that parameter and the ones that do not, checked against Boost 1.83, Abseil 20250127.0, Folly, EASTL 3.21, ankerl::unordered_dense, phmap, gtl, robin_hood, tsl::ordered_map, and Qt 6.

To change a single template parameter and keep the others, use the member alias templates with_*_t; for instance, nlohmann::json::with_float_t<long double> is json with long double as number_float_t.

"},{"location":"features/types/template_parameters/#how-to-read-this-page","title":"How to read this page","text":"

Requirements are split into two groups:

  • Always required \u2014 needed to instantiate basic_json at all, or needed by functions that virtually every program uses (construction, element access, dump).
  • Required for ... \u2014 only needed when a particular part of the API is instantiated. Member function templates are only instantiated when they are used, so a type may be perfectly usable even though it does not satisfy these requirements, as long as the corresponding functions are never called.

Requirements are not checked

Three requirements are checked with a static_assert: the array iterator category, the width of BinaryType's value_type, and NumberUnsignedType being at least as wide as NumberIntegerType. The rest are not diagnosed with dedicated error messages, and violating most of them results in a compiler error somewhere inside the library. Four violations are not caught at compile time at all:

  • A StringType whose data() is not null-terminated compiles and silently misparses numbers stored as a long double that is not IEEE 754 binary64 (e.g., the 80-bit x87 format), because the lexer hands the buffer to std::strtold.
  • A stateful AllocatorType compiles and silently ignores its state: allocation, deallocation, and get_allocator() each use a different default-constructed instance.
  • The two cross-specialization conversions below. These abort on an assertion in a normal build, and only fail silently under NDEBUG.
"},{"location":"features/types/template_parameters/#overview","title":"Overview","text":"Template parameter Default Notable substitutes ObjectType std::map nlohmann::ordered_map, Abseil hash maps ArrayType std::vector std::deque StringType std::string std::string-like types over char BooleanType bool none worth using NumberIntegerType std::int64_t any signed integer type NumberUnsignedType std::uint64_t any unsigned integer type at least as wide as NumberIntegerType, or NumberIntegerType itself NumberFloatType double float (long double: no binary formats) AllocatorType std::allocator stateless allocators JSONSerializer adl_serializer serializers with the same interface BinaryType std::vector<std::uint8_t> std::vector<char> CustomBaseClass void any default-constructible class

Third-party containers and incomplete types

object_t is instantiated inside the definition of basic_json \u2014 it is probed for a key_compare member to form object_comparator_t \u2014 i.e. while basic_json is still an incomplete type. std::map is required by the standard to support incomplete mapped types; most third-party maps are not, and inspecting the mapped type at class scope (for instance with std::is_trivially_move_assignable) makes them unusable as ObjectType, no matter how their template arguments are adapted. This rules out absl::btree_map, phmap::btree_map, gtl::btree_map, robin_hood::unordered_node_map, folly::F14FastMap, and eastl::hash_map.

array_t is only named in the class definition and is not instantiated until basic_json is complete, so an ArrayType that inspects its value type at class scope is generally fine \u2014 boost::container::small_vector and static_vector both reject incomplete value types yet work here. absl::InlinedVector is the exception: the std::is_trivially_move_assignable<basic_json> it evaluates while instantiating itself re-enters the library's own trait machinery mid-instantiation.

Folly requires C++20

Folly's headers use consteval and std::type_identity, so any basic_json specialization that names a Folly type has to be compiled as C++20 or later, whatever the rest of the library supports.

"},{"location":"features/types/template_parameters/#objecttype","title":"ObjectType","text":"

ObjectType is instantiated as

using object_t = ObjectType<StringType,                                    // key_type\n                            basic_json,                                    // mapped_type\n                            default_object_comparator_t,                   // key_compare\n                            AllocatorType<std::pair<const StringType,\n                                                    basic_json>>>;         // allocator_type\n

i.e., the template arguments follow the order and meaning of std::map.

"},{"location":"features/types/template_parameters/#always-required","title":"Always required","text":"
  • The template must be usable with four type arguments in the order shown above. The third argument is a comparator; containers that expect something else in this position (e.g., a hash function) need an alias template or wrapper \u2014 see Notes.
  • An optional member type key_compare. If it is present it becomes object_comparator_t; otherwise default_object_comparator_t is used.
  • Member types key_type, mapped_type, value_type, and iterator.
  • value_type must behave like std::pair<const key_type, mapped_type>; the library accesses .first and .second on it.
  • iterator must be default-constructible and satisfy LegacyBidirectionalIterator. The type returned by cbegin()/cend() must satisfy the same requirements.
  • Constructors: default, copy, move, and from an iterator range (first, last).
  • Member functions begin(), end(), cbegin(), cend(), empty(), size(), max_size(), clear(), find(key), count(key), emplace(key, value), insert(value_type), insert(first, last), operator[](key), erase(iterator), and erase(first, last). erase(iterator) may return the following iterator or void; in the latter case the library computes the successor itself, before erasing.
  • erase(key) is optional: if the container does not provide one, the library falls back to find(key) followed by erase(iterator).
  • at(key) is required only by to_ubjson and to_bjdata, but every container tried here provides it.
  • emplace and insert(value_type) must return std::pair<iterator, bool> and must have unique-key semantics; multimaps cannot be used.
  • The type must be swappable (via std::swap or an ADL swap).
  • The comparison operators == and <; !=, <=, >, and >= are derived from them. Where the library uses three-way comparison (C++20), == and <=> are required instead \u2014 the six two-way operators do not satisfy it. They implement basic_json's comparison operators.
"},{"location":"features/types/template_parameters/#required-for-heterogeneous-key-lookup","title":"Required for heterogeneous key lookup","text":"

The overloads of at, operator[], find, contains, count, erase, and value that accept a key type other than object_t::key_type require

  • a transparent comparator, i.e. object_comparator_t has a member type is_transparent (this is why the default comparator is std::less<> since C++14), and
  • corresponding heterogeneous find, count, erase, and operator[] overloads on the container.
"},{"location":"features/types/template_parameters/#notes","title":"Notes","text":""},{"location":"features/types/template_parameters/#stdunordered_map-needs-an-adapter","title":"std::unordered_map needs an adapter","text":"

std::unordered_map cannot be passed directly: its third template parameter is a hash function, but basic_json passes a comparator in that position. An alias template or wrapper that restores the expected argument order makes it usable:

template<class Key, class T, class IgnoredCompare, class Allocator>\nstruct unordered_map_object\n    : std::unordered_map<Key, T, std::hash<Key>, std::equal_to<Key>, Allocator>\n{\n    using base_t = std::unordered_map<Key, T, std::hash<Key>, std::equal_to<Key>, Allocator>;\n    using base_t::base_t;\n};\n\nusing unordered_json = nlohmann::json::with_object_t<unordered_map_object>;\n

Whether std::unordered_map can be instantiated at all depends on the standard library: object_t is formed while basic_json is still incomplete (see the warning above), and libstdc++ 9 needs the size of the mapped type to instantiate the hash map's node type, so the adapter does not compile there. Newer libstdc++ versions, and the hash maps listed below, do not have that problem.

The adapter above works verbatim for Abseil's, Boost's, phmap's and gtl's hash maps, which all place the hash function third and take a std::pair<const Key, T> allocator fifth. Two need a different adapter:

  • ankerl::unordered_dense expects an allocator over std::pair<Key, T> (non-const key), so the allocator has to be rebound to that or dropped.
  • robin_hood's fifth parameter is the non-type MaxLoadFactor100, so its adapter must drop the allocator entirely.

None of these hash maps defines key_compare, so all of them additionally rely on object_comparator_t falling back to default_object_comparator_t; see object_comparator_t.

"},{"location":"features/types/template_parameters/#abseil-hash-maps","title":"Abseil hash maps","text":"

absl::flat_hash_map and absl::node_hash_map tolerate an incomplete value type, but they take a hash function as their third template argument. The same adapter as for std::unordered_map makes them usable:

template<class Key, class T, class IgnoredCompare, class Allocator>\nstruct flat_hash_object\n    : absl::flat_hash_map<Key, T, absl::Hash<Key>, std::equal_to<Key>, Allocator>\n{\n    using base_t = absl::flat_hash_map<Key, T, absl::Hash<Key>, std::equal_to<Key>, Allocator>;\n    using base_t::base_t;\n};\n\nusing flat_hash_json = nlohmann::json::with_object_t<flat_hash_object>;\n

absl::node_hash_map keeps references to the mapped values valid across insertions; absl::flat_hash_map does not, which makes it behave like ordered_json with respect to iterator invalidation. Both expose a capacity() member function, so JSON_DIAGNOSTICS treats them conservatively and keeps the parent pointers correct either way.

"},{"location":"features/types/template_parameters/#iteration-order","title":"Iteration order","text":"

The library never relies on the container's iteration order for correctness; it does determine the order in which object keys are serialized by dump and visited by items. See Object Order.

"},{"location":"features/types/template_parameters/#capacity-marks-a-container-as-insertion-ordered","title":"capacity() marks a container as insertion-ordered","text":"

With JSON_DIAGNOSTICS enabled, the library detects insertion-ordered maps by probing for a capacity() member function (nlohmann::ordered_map inherits it from std::vector) and refreshes all parent pointers after every insertion. An ObjectType that happens to have a capacity() member is therefore treated conservatively \u2014 this is correct, but slower.

"},{"location":"features/types/template_parameters/#key-order-and-duplicate-keys","title":"Key order and duplicate keys","text":"

The library does not sort or de-duplicate keys itself; the behavior described in object_t is entirely the behavior of the chosen container.

Reference implementation

docs/mkdocs/docs/examples/custom_object_type.hpp wraps a private std::map and satisfies every requirement above. It does not define key_compare, so object_comparator_t falls back to default_object_comparator_t \u2014 a good starting point for a custom ObjectType.

#pragma once\n\n#include <map>\n#include <utility>\n\n// A minimal, self-contained ObjectType built around a private std::map.\n// key_compare is deliberately not exposed: when an ObjectType has no\n// key_compare member, the library falls back to its own default comparator.\n// See https://json.nlohmann.me/features/types/template_parameters/#objecttype\ntemplate<class Key, class T, class Compare, class Allocator>\nclass custom_object_type\n{\n    using map_t = std::map<Key, T, Compare, Allocator>;\n    map_t data_;\n\n  public:\n    using key_type = typename map_t::key_type;\n    using mapped_type = typename map_t::mapped_type;\n    using value_type = typename map_t::value_type;\n    using size_type = typename map_t::size_type;\n    using iterator = typename map_t::iterator;\n    using const_iterator = typename map_t::const_iterator;\n\n    custom_object_type() = default;\n    custom_object_type(const custom_object_type&) = default;\n    custom_object_type(custom_object_type&&) = default;\n    custom_object_type& operator=(const custom_object_type&) = default;\n    custom_object_type& operator=(custom_object_type&&) = default;\n\n    template<class InputIt>\n    custom_object_type(InputIt first, InputIt last) : data_(first, last) {}\n\n    iterator begin()\n    {\n        return data_.begin();\n    }\n    iterator end()\n    {\n        return data_.end();\n    }\n    const_iterator begin() const\n    {\n        return data_.begin();\n    }\n    const_iterator end() const\n    {\n        return data_.end();\n    }\n    const_iterator cbegin() const\n    {\n        return data_.cbegin();\n    }\n    const_iterator cend() const\n    {\n        return data_.cend();\n    }\n\n    bool empty() const\n    {\n        return data_.empty();\n    }\n    size_type size() const\n    {\n        return data_.size();\n    }\n    size_type max_size() const\n    {\n        return data_.max_size();\n    }\n    void clear()\n    {\n        data_.clear();\n    }\n\n    iterator find(const key_type& key)\n    {\n        return data_.find(key);\n    }\n    const_iterator find(const key_type& key) const\n    {\n        return data_.find(key);\n    }\n    size_type count(const key_type& key) const\n    {\n        return data_.count(key);\n    }\n\n    std::pair<iterator, bool> emplace(const key_type& key, const mapped_type& value)\n    {\n        return data_.emplace(key, value);\n    }\n\n    std::pair<iterator, bool> insert(const value_type& value)\n    {\n        return data_.insert(value);\n    }\n\n    template<class InputIt>\n    void insert(InputIt first, InputIt last)\n    {\n        data_.insert(first, last);\n    }\n\n    mapped_type& operator[](const key_type& key)\n    {\n        return data_[key];\n    }\n\n    mapped_type& at(const key_type& key)\n    {\n        return data_.at(key);\n    }\n    const mapped_type& at(const key_type& key) const\n    {\n        return data_.at(key);\n    }\n\n    iterator erase(iterator pos)\n    {\n        return data_.erase(pos);\n    }\n    iterator erase(iterator first, iterator last)\n    {\n        return data_.erase(first, last);\n    }\n    size_type erase(const key_type& key)\n    {\n        return data_.erase(key);\n    }\n\n    void swap(custom_object_type& other)\n    {\n        data_.swap(other.data_);\n    }\n\n    friend bool operator==(const custom_object_type& lhs, const custom_object_type& rhs)\n    {\n        return lhs.data_ == rhs.data_;\n    }\n    friend bool operator<(const custom_object_type& lhs, const custom_object_type& rhs)\n    {\n        return lhs.data_ < rhs.data_;\n    }\n};\n
Example: use the custom ObjectType
#include <iostream>\n#include <type_traits>\n\n#include <nlohmann/json.hpp>\n\n#include \"custom_object_type.hpp\"\n\nusing custom_json = nlohmann::json::with_object_t<custom_object_type>;\n\nint main()\n{\n    custom_json j;\n    j[\"pi\"] = 3.141;\n    j[\"happy\"] = true;\n    j[\"list\"] = {1, 2, 3};\n\n    std::cout << j.dump(2) << '\\n';\n    std::cout << std::boolalpha << (custom_json::parse(j.dump()) == j) << '\\n';\n\n    // custom_object_type has no key_compare member, so object_comparator_t\n    // falls back to its default\n    std::cout << std::boolalpha\n              << std::is_same<custom_json::object_comparator_t, custom_json::default_object_comparator_t>::value\n              << '\\n';\n}\n

Output:

{\n  \"happy\": true,\n  \"list\": [\n    1,\n    2,\n    3\n  ],\n  \"pi\": 3.141\n}\ntrue\ntrue\n
"},{"location":"features/types/template_parameters/#compatible-containers","title":"Compatible containers","text":"Container Notes std::map (default) nlohmann::ordered_map used by ordered_json; keeps insertion order nlohmann::fifo_map keeps insertion order; adapter puts fifo_map_compare in the comparator slot boost::container::map, boost::container::flat_map no adapter needed std::unordered_map through the adapter above; not with libstdc++ 9, see the note boost::unordered_map, boost::unordered_flat_map, boost::unordered_node_map through the adapter above absl::flat_hash_map, absl::node_hash_map through the adapter above; flat_hash_map moves mapped values on rehash phmap::flat_hash_map, phmap::node_hash_map, gtl::flat_hash_map through the adapter above ankerl::unordered_dense::map and segmented_map adapter must rebind or drop the allocator robin_hood::unordered_flat_map adapter must drop the allocator folly::F14NodeMap through the adapter above; requires C++20, see the note above folly::sorted_vector_map alias must drop the allocator, whose value type it disagrees on"},{"location":"features/types/template_parameters/#containers-that-cannot-be-used","title":"Containers that cannot be used","text":"Container Reason absl::btree_map, phmap::btree_map, gtl::btree_map require a complete mapped type robin_hood::unordered_node_map, folly::F14FastMap, eastl::hash_map require a complete mapped type eastl::map EASTL iterators do not work with std::iterator_traits tsl::ordered_map its iterators expose the mapped value as const QMap no value_type member type QHash its value_type is the mapped type rather than a key/value pair, and its iterators dereference to the mapped value std::multimap, std::unordered_multimap emplace does not return std::pair<iterator, bool>"},{"location":"features/types/template_parameters/#arraytype","title":"ArrayType","text":"

ArrayType is instantiated as

using array_t = ArrayType<basic_json, AllocatorType<basic_json>>;\n
"},{"location":"features/types/template_parameters/#always-required_1","title":"Always required","text":"
  • The template must be usable with two type arguments (value type and allocator).
  • Member types value_type and iterator.
  • Constructors: default, copy, and move; and from an iterator range (first, last).
  • Member functions begin(), end(), cbegin(), cend(), empty(), size(), max_size(), clear(), operator[](size_type), back(), push_back(), emplace_back(), pop_back(), resize(), insert() (single element, count, and range), erase(pos), and erase(first, last). basic_json::insert(pos, initializer_list) goes through the range overload, so no initializer-list insert is needed. at(size_type) is not required: basic_json::at(size_type) checks the index itself and then uses operator[].
  • iterator must be default-constructible, and it as well as the type returned by cbegin()/cend() must satisfy LegacyRandomAccessIterator. A static_assert only checks for LegacyBidirectionalIterator, but dump (cend() - 1), erase(idx) (begin() + idx), and the random-access operations of basic_json::iterator require random access.
  • The comparison operators, as for ObjectType: == and <, or == and <=> under C++20.
"},{"location":"features/types/template_parameters/#required-for-individual-functions","title":"Required for individual functions","text":"
  • A member type value_type, for to_bson of an array.
  • A constructor from (count, value), for basic_json(size_type, const basic_json&).
  • Swappability, via std::swap or an ADL swap, for swap(array_t&).

capacity() is optional

With JSON_DIAGNOSTICS enabled, the library reads array_t::capacity() to find out whether adding an element reallocated the array and moved its elements, which would invalidate the parent pointers. An array type without a capacity() member function is handled conservatively: the parent pointers of all elements are refreshed after every insertion, which makes adding n elements cost O(*n*\u00b2). Only diagnostics builds pay this; without them capacity() is never called.

Reference implementation

docs/mkdocs/docs/examples/custom_array_type.hpp wraps a private std::vector and satisfies every requirement above \u2014 a good starting point for a custom ArrayType.

#pragma once\n\n#include <memory>\n#include <utility>\n#include <vector>\n\n// A minimal, self-contained ArrayType built around a private std::vector.\n// See https://json.nlohmann.me/features/types/template_parameters/#arraytype\ntemplate<class T, class Allocator = std::allocator<T>>\nclass custom_array_type\n{\n    using vector_t = std::vector<T, Allocator>;\n    vector_t data_;\n\n  public:\n    using value_type = typename vector_t::value_type;\n    using size_type = typename vector_t::size_type;\n    using iterator = typename vector_t::iterator;\n    using const_iterator = typename vector_t::const_iterator;\n\n    custom_array_type() = default;\n    custom_array_type(const custom_array_type&) = default;\n    custom_array_type(custom_array_type&&) = default;\n    custom_array_type& operator=(const custom_array_type&) = default;\n    custom_array_type& operator=(custom_array_type&&) = default;\n\n    template<class InputIt>\n    custom_array_type(InputIt first, InputIt last) : data_(first, last) {}\n\n    custom_array_type(size_type count, const T& value) : data_(count, value) {}\n\n    iterator begin()\n    {\n        return data_.begin();\n    }\n    iterator end()\n    {\n        return data_.end();\n    }\n    const_iterator begin() const\n    {\n        return data_.begin();\n    }\n    const_iterator end() const\n    {\n        return data_.end();\n    }\n    const_iterator cbegin() const\n    {\n        return data_.cbegin();\n    }\n    const_iterator cend() const\n    {\n        return data_.cend();\n    }\n\n    bool empty() const\n    {\n        return data_.empty();\n    }\n    size_type size() const\n    {\n        return data_.size();\n    }\n    size_type max_size() const\n    {\n        return data_.max_size();\n    }\n    void clear()\n    {\n        data_.clear();\n    }\n    void resize(size_type n)\n    {\n        data_.resize(n);\n    }\n\n    T& operator[](size_type pos)\n    {\n        return data_[pos];\n    }\n    const T& operator[](size_type pos) const\n    {\n        return data_[pos];\n    }\n\n    T& back()\n    {\n        return data_.back();\n    }\n    const T& back() const\n    {\n        return data_.back();\n    }\n\n    void push_back(const T& value)\n    {\n        data_.push_back(value);\n    }\n    void push_back(T&& value)\n    {\n        data_.push_back(std::move(value));\n    }\n\n    template<class... Args>\n    void emplace_back(Args&& ... args)\n    {\n        data_.emplace_back(std::forward<Args>(args)...);\n    }\n\n    void pop_back()\n    {\n        data_.pop_back();\n    }\n\n    iterator insert(const_iterator pos, const T& value)\n    {\n        return data_.insert(pos, value);\n    }\n    iterator insert(const_iterator pos, size_type count, const T& value)\n    {\n        return data_.insert(pos, count, value);\n    }\n    template<class InputIt>\n    iterator insert(const_iterator pos, InputIt first, InputIt last)\n    {\n        return data_.insert(pos, first, last);\n    }\n\n    iterator erase(const_iterator pos)\n    {\n        return data_.erase(pos);\n    }\n    iterator erase(const_iterator first, const_iterator last)\n    {\n        return data_.erase(first, last);\n    }\n\n    void swap(custom_array_type& other)\n    {\n        data_.swap(other.data_);\n    }\n\n    friend bool operator==(const custom_array_type& lhs, const custom_array_type& rhs)\n    {\n        return lhs.data_ == rhs.data_;\n    }\n    friend bool operator<(const custom_array_type& lhs, const custom_array_type& rhs)\n    {\n        return lhs.data_ < rhs.data_;\n    }\n};\n
Example: use the custom ArrayType
#include <iostream>\n\n#include <nlohmann/json.hpp>\n\n#include \"custom_array_type.hpp\"\n\nusing custom_json = nlohmann::json::with_array_t<custom_array_type>;\n\nint main()\n{\n    custom_json j = custom_json::array();\n    j.push_back(1);\n    j.push_back(2);\n    j.push_back(3);\n\n    std::cout << j.dump() << '\\n';\n    std::cout << std::boolalpha << (custom_json::parse(j.dump()) == j) << '\\n';\n}\n

Output:

[1,2,3]\ntrue\n
"},{"location":"features/types/template_parameters/#compatible-containers_1","title":"Compatible containers","text":"Container Notes std::vector (default) std::deque references survive appends, but not insertions elsewhere; see the capacity() note above std::pmr::vector through an alias, as the allocator comes from AllocatorType instead boost::container::vector, deque, devector boost::container::stable_vector the only one tried that keeps references valid across every insertion boost::container::small_vector, folly::small_vector through an alias that fixes the inline capacity boost::container::static_vector through the same kind of alias, for arrays that stay within the fixed capacity folly::fbvector requires C++20, see the note above"},{"location":"features/types/template_parameters/#containers-that-cannot-be-used_1","title":"Containers that cannot be used","text":"Container Reason std::list no operator[], and no random-access iterators eastl::vector, QList, QVector no max_size(); they handle the incomplete value type fine absl::InlinedVector requires a complete value type, see the note above absl::FixedArray the size is fixed at construction, so resize, push_back, insert and erase are missing"},{"location":"features/types/template_parameters/#stringtype","title":"StringType","text":"

StringType is used both for JSON string values and for the keys of JSON objects (string_t and object_t::key_type).

"},{"location":"features/types/template_parameters/#always-required_2","title":"Always required","text":"
  • A member type value_type that is one byte wide and char-compatible. The library stores and processes UTF-8 encoded char data and passes data() to functions that take a const char*, such as std::strtold (only used to parse a long double that is not IEEE 754 binary64, see NumberFloatType). std::wstring, std::u16string, and std::u32string are not valid choices; see the FAQ on wide string handling.
  • Constructors: default, copy, move, from const char* (which must not be explicit), from (const char*, size_type), and from (size_type, char); and copy or move assignment.
  • Member functions size(), clear(), resize(n, c), data(), push_back(char), and operator[] (const and non-const, returning references). c_str() and back() are not required.
  • data() must return a pointer to a contiguous, null-terminated buffer. float, double, and a long double that is IEEE 754 binary64 are converted by the library itself and do not depend on this. For any other NumberFloatType (a long double of another format), the parser falls back to std::strtold when std::from_chars is not available or declines the token, and std::strtold reads up to the null character. A type whose data() is not null-terminated does not fail to compile; with such a NumberFloatType it can silently misparse floating-point numbers.
  • append(const char*, size_type), used by dump and by the binary readers. The library's internal string concatenation additionally has to append a char and a const char*; for each it selects between append(arg), operator+=, append(first, last), and append(data, size).
  • The comparison operator == against another StringType, and < for use as a key of the chosen ObjectType (with the default comparator, std::less<> must be able to compare two StringType values, and a StringType with the key types used for lookup). != is never applied to a StringType, and == against const char* is resolved by the implicit const char* constructor.
"},{"location":"features/types/template_parameters/#required-for-the-binary-formats","title":"Required for the binary formats","text":"
  • resize(n), used by the readers to make room for a block of bytes.
  • Non-const operator[], into which the readers std::memcpy those bytes. A non-const data() would serve just as well, but std::string has only had one since C++17, and the library still supports C++11.
"},{"location":"features/types/template_parameters/#required-for-json-pointer-flatten-and-diff","title":"Required for JSON Pointer, flatten, and diff","text":"
  • A static member npos and the member function find_first_of(char, size_type) \u2014 together with data(), reserve(n), and append(const char*, size_type) they implement the escaping and unescaping of reference tokens described in RFC 6901. Neither find(const StringType&, size_type), nor substr(pos, count), nor replace(pos, count, const StringType&) is required.
  • empty().
  • resize(n) (one argument) \u2014 used by to_string to size the result before the reference tokens are copied into it.
  • begin() and end() \u2014 used by operator[](const json_pointer&) to decide whether a reference token denotes an array index.
"},{"location":"features/types/template_parameters/#required-for-other-functionality","title":"Required for other functionality","text":"Functionality Additional requirement diff, items, std::hash conversion of a std::size_t to StringType: either assignability from the result of std::to_string, or an ADL overload void int_to_string(StringType&, std::size_t) operator/(std::size_t) the same conversion of a std::size_t to StringType as diff, items, and std::hash above std::hash<basic_json> additionally a specialization of std::hash<StringType> to_bson find(value_type) and npos parse from a string_t the input adapters must accept it; otherwise pass a character range operator<<(std::ostream&, const json_pointer&) streamability to std::ostream to_string conversion of StringType to std::string (the function returns a std::string) exception messages data() and size(), or begin() and end()"},{"location":"features/types/template_parameters/#compatible-types","title":"Compatible types","text":"Type Notes std::string (default) std::basic_string with a custom stateless allocator std::pmr::string see the warning below before relying on the memory resource boost::container::string needs a user-supplied std::hash specialization (Boost provides boost::hash instead) folly::fbstring requires C++20, see the note above eastl::string needs a user-supplied std::hash and an ADL int_to_string (it is not assignable from a std::string); parse does not accept it directly \u2014 pass a character range or a std::string a custom string class in a user-defined namespace if the requirements above are met"},{"location":"features/types/template_parameters/#types-that-cannot-be-used","title":"Types that cannot be used","text":"Type Reason std::wstring, std::u16string, std::u32string the character type is not one byte wide std::u8string one byte wide, but char8_t is not char-compatible absl::Cord no value_type, and the storage is not contiguous QString no append(const char*, size_type); its QChar is also two bytes wide, though that is never diagnosed

A std::pmr::string mostly does not use the memory resource you choose

basic_json cannot be given an allocator or a memory resource. AllocatorType is default-constructed at every allocation and has to be stateless (see AllocatorType), and string values the library creates are constructed with their own default allocator. So:

  • Every string the library itself produces \u2014 from parse, from dump, or by default construction \u2014 allocates from std::pmr::get_default_resource().
  • Copying an arena-backed string into a value silently drops its memory resource: the copy lands on the default resource, because std::pmr::polymorphic_allocator does not propagate on copy construction. Nothing warns about this.
  • Moving one in does keep it, and later growth still allocates from that arena \u2014 but it does not survive a copy of the enclosing basic_json.
  • Passing std::pmr::polymorphic_allocator as AllocatorType does not work around any of this; it does not compile.

Apart from moving a string in, the only way to redirect these allocations is the process-global std::pmr::set_default_resource().

Reference implementation

docs/mkdocs/docs/examples/custom_string_type.hpp wraps a private std::string and satisfies every requirement above \u2014 a good starting point for a custom StringType. The unit test tests/src/unit-alt-string.cpp contains a more thorough variant, alt_string, exercised against a larger part of the API.

#pragma once\n\n#include <cstddef>\n#include <ostream>\n#include <string>\n\n// A minimal, self-contained StringType built around a private std::string.\n// Wraps rather than inherits, so it exposes exactly what the library needs\n// and nothing more of std::string's interface.\n//\n// Covers the \"Always required\" members, the extras needed for the binary\n// formats, JSON Pointer / flatten / unflatten, and the int_to_string overload\n// needed for diff and items. Extending it further (e.g. for\n// std::hash<basic_json> or to_bson) is a matter of adding the extra members\n// listed in the \"Required for other functionality\" table.\n//\n// See https://json.nlohmann.me/features/types/template_parameters/#stringtype\nclass custom_string_type\n{\n    std::string data_;\n\n  public:\n    using value_type = char;\n    using size_type = std::string::size_type;\n    using iterator = std::string::iterator;\n    using const_iterator = std::string::const_iterator;\n\n    static constexpr size_type npos = std::string::npos;\n\n    custom_string_type() = default;\n    custom_string_type(const custom_string_type&) = default;\n    custom_string_type(custom_string_type&&) = default;\n    custom_string_type& operator=(const custom_string_type&) = default;\n    custom_string_type& operator=(custom_string_type&&) = default;\n\n    // not explicit: the library relies on being able to hand it a string literal\n    custom_string_type(const char* s) : data_(s) {}\n    custom_string_type(const char* s, size_type count) : data_(s, count) {}\n    custom_string_type(size_type count, char ch) : data_(count, ch) {}\n\n    size_type size() const\n    {\n        return data_.size();\n    }\n    bool empty() const\n    {\n        return data_.empty();\n    }\n    void clear()\n    {\n        data_.clear();\n    }\n    void resize(size_type n)\n    {\n        data_.resize(n);\n    }\n    void resize(size_type n, char c)\n    {\n        data_.resize(n, c);\n    }\n    void reserve(size_type n)\n    {\n        data_.reserve(n);\n    }\n\n    // must stay null-terminated -- the parser hands this to std::strtoull &\n    // friends; std::string::data() has guaranteed that since C++11\n    const char* data() const\n    {\n        return data_.data();\n    }\n\n    void push_back(char c)\n    {\n        data_.push_back(c);\n    }\n\n    char& operator[](size_type pos)\n    {\n        return data_[pos];\n    }\n    char operator[](size_type pos) const\n    {\n        return data_[pos];\n    }\n\n    custom_string_type& append(const char* s, size_type count)\n    {\n        data_.append(s, count);\n        return *this;\n    }\n    custom_string_type& append(const custom_string_type& other)\n    {\n        data_.append(other.data_);\n        return *this;\n    }\n    custom_string_type& operator+=(char c)\n    {\n        data_.push_back(c);\n        return *this;\n    }\n\n    size_type find_first_of(char c, size_type pos = 0) const\n    {\n        return data_.find_first_of(c, pos);\n    }\n\n    iterator begin()\n    {\n        return data_.begin();\n    }\n    iterator end()\n    {\n        return data_.end();\n    }\n    const_iterator begin() const\n    {\n        return data_.begin();\n    }\n    const_iterator end() const\n    {\n        return data_.end();\n    }\n\n    // found by ADL; converts array indices to keys in diff and items\n    friend void int_to_string(custom_string_type& target, std::size_t value)\n    {\n        target.data_ = std::to_string(value);\n    }\n\n    friend bool operator==(const custom_string_type& lhs, const custom_string_type& rhs)\n    {\n        return lhs.data_ == rhs.data_;\n    }\n    friend bool operator<(const custom_string_type& lhs, const custom_string_type& rhs)\n    {\n        return lhs.data_ < rhs.data_;\n    }\n\n    // not required by the library itself, but dump() returns a custom_string_type\n    // and this makes `std::cout << j.dump()` work as expected\n    friend std::ostream& operator<<(std::ostream& os, const custom_string_type& s)\n    {\n        return os << s.data_;\n    }\n};\n
Example: use the custom StringType
#include <iostream>\n\n#include <nlohmann/json.hpp>\n\n#include \"custom_string_type.hpp\"\n\nusing custom_json = nlohmann::json::with_string_t<custom_string_type>;\n\nint main()\n{\n    custom_json j;\n    j[\"pi\"] = 3.141;\n    j[\"happy\"] = true;\n    j[\"list\"] = {1, 2, 3};\n\n    std::cout << j.dump(2) << '\\n';\n    std::cout << std::boolalpha << (custom_json::parse(j.dump()) == j) << '\\n';\n}\n

Output:

{\n  \"happy\": true,\n  \"list\": [\n    1,\n    2,\n    3\n  ],\n  \"pi\": 3.141\n}\ntrue\n
"},{"location":"features/types/template_parameters/#booleantype","title":"BooleanType","text":"

boolean_t is stored directly inside basic_json, as a member of an anonymous union.

"},{"location":"features/types/template_parameters/#always-required_3","title":"Always required","text":"
  • A literal type that is trivially default-constructible, trivially copyable, and trivially destructible; otherwise the union's special member functions are deleted.
  • Implicitly convertible from bool \u2014 an explicit constructor is not enough, because the to_json overload for a custom BooleanType is constrained on std::is_convertible \u2014 and contextually convertible to bool (here an explicit operator bool is fine).
  • Comparison operators ==, !=, <, <=, >, >= (or <=>).
  • Convertible from and to bool through the serializer, because get<bool>() is used internally.

There is little reason to use anything other than bool here.

"},{"location":"features/types/template_parameters/#compatible-types_1","title":"Compatible types","text":"

bool is the only usable choice. Another trivially copyable type that is implicitly convertible to and from bool \u2014 std::uint8_t, say \u2014 does compile, and JSON booleans still round-trip, but the type then serves as both boolean_t and an ordinary integer: basic_json can no longer be constructed or assigned from a std::uint8_t at all (the boolean and unsigned-integer to_json overloads become ambiguous), and get<std::uint8_t>() on a number throws type_error.302 instead of returning the value.

"},{"location":"features/types/template_parameters/#numberintegertype-and-numberunsignedtype","title":"NumberIntegerType and NumberUnsignedType","text":"

Both types are stored directly inside basic_json's union.

"},{"location":"features/types/template_parameters/#always-required_4","title":"Always required","text":"
  • std::is_integral must be satisfied: NumberIntegerType must be a signed integer type, NumberUnsignedType an unsigned integer type or the same type as NumberIntegerType (see below). Class types are not supported \u2014 among others, the constructors taking integer values are constrained on std::is_integral.
  • Trivially default-constructible, trivially copyable, and trivially destructible (union member).
  • std::numeric_limits must be specialized for both types.
  • An unsigned NumberUnsignedType must be able to represent the absolute value of every NumberIntegerType value; serialization of negative numbers converts the value to NumberUnsignedType. A static_assert requires it to be at least as wide as NumberIntegerType, which is what that amounts to for the standard integer types.
  • Both types must fit into the internal 64-character number buffer used by dump, which is the case for all standard integer types.
  • std::hash<basic_json> additionally requires std::hash specializations.
"},{"location":"features/types/template_parameters/#notes_1","title":"Notes","text":"

The number types influence what the parser accepts: an integer literal that does not round-trip through the chosen type is stored as number_float_t instead. Choosing types narrower than 64 bits therefore silently changes parse results rather than raising an error. See Number Handling for details.

"},{"location":"features/types/template_parameters/#same-type-for-both","title":"Same type for both","text":"

NumberUnsignedType may be the same type as NumberIntegerType, e.g. nlohmann::json::with_integers_t<std::int64_t, std::int64_t> (see with_integers_t), for code that only wants to handle one integer type. Such a basic_json stores every integer as number_integer_t:

  • is_number_unsigned() is always false, and type() never returns value_t::number_unsigned. Constructing a value from value_t::number_unsigned gives a value_t::number_integer value.
  • Values of unsigned C++ types (e.g., 5u) are converted to NumberIntegerType, so values above its maximum wrap around, as values outside the range of a narrower NumberIntegerType already do.
  • The parsers store a non-negative integer above the maximum of NumberIntegerType (e.g., 18446744073709551615 for std::int64_t) as number_float_t, like any other integer that does not fit.
  • Converting from a basic_json with distinct types turns its unsigned values into number_integer_t values.
"},{"location":"features/types/template_parameters/#compatible-types_2","title":"Compatible types","text":"Type pair Support std::int64_t / std::uint64_t (default) full std::int32_t / std::uint32_t, long long / unsigned long long full; narrower types change which literals the parser can represent any other pair of standard signed/unsigned integer types full the same signed integer type for both, e.g. std::int64_t / std::int64_t full; every integer is stored as number_integer_t, see above class types, enumerations not usable; std::is_integral must hold bool, number_float_t, or the type of another member of the union not usable; std::is_integral<bool> is in fact true, but the get_impl_ptr overloads for boolean_t, number_integer_t, number_unsigned_t and number_float_t would collide"},{"location":"features/types/template_parameters/#numberfloattype","title":"NumberFloatType","text":"

number_float_t is stored directly inside basic_json's union.

"},{"location":"features/types/template_parameters/#always-required_5","title":"Always required","text":"
  • Trivially default-constructible, trivially copyable, and trivially destructible (union member).
  • std::numeric_limits must be specialized; max_digits10 is used to size the conversion.
  • std::isfinite must be applicable to the type.
"},{"location":"features/types/template_parameters/#required-for-parsing-and-serialization","title":"Required for parsing and serialization","text":"

NumberFloatType must be one of float, double, or long double:

  • The parser converts number literals to float, double, and a long double that is IEEE 754 binary64 itself; other long double formats are converted with std::from_chars where available, or with std::strtold. The library provides overloads for exactly these three types.
  • dump falls back to std::snprintf with the %g and %Lg conversion specifiers, for which the library likewise provides only double and long double overloads (float is promoted to double).

If std::numeric_limits<NumberFloatType> describes an IEEE 754 binary64 number, dump uses the algorithm of \u017bmij, which produces the shortest representation that round-trips. For IEEE 754 binary32 numbers, it uses Grisu2, which produces a short representation that round-trips. Otherwise the snprintf fallback with max_digits10 digits is used.

"},{"location":"features/types/template_parameters/#required-for-the-binary-formats_1","title":"Required for the binary formats","text":"

NumberFloatType must be float or double. The writers for CBOR, MessagePack, UBJSON, BJData, BON8, and BSON map a floating-point value onto an IEEE 754 binary32 or binary64 field and have no encoding for long double.

"},{"location":"features/types/template_parameters/#compatible-types_3","title":"Compatible types","text":"Type Support double (default) full; shortest round-trip output through \u017bmij float full; short round-trip output through Grisu2 long double dump and parse only; the binary format writers do not compile, as they only handle IEEE 754 binary32 and binary64 any other type not usable"},{"location":"features/types/template_parameters/#allocatortype","title":"AllocatorType","text":"

AllocatorType is instantiated with one argument, for each of object_t, array_t, string_t, binary_t, basic_json, std::pair<const StringType, basic_json>, and std::pair<StringType, basic_json>.

AllocatorType is not the only allocator a basic_json uses. It allocates the JSON values themselves, but most temporary storage is allocated with std::allocator. This includes the parser's stacks and the stacks that process deeply nested values without recursion.

"},{"location":"features/types/template_parameters/#always-required_6","title":"Always required","text":"
  • The template must be usable with exactly one type argument. The library instantiates AllocatorType<T> directly and never uses std::allocator_traits<...>::rebind_alloc.
  • It must satisfy the Allocator named requirement so that std::allocator_traits can be used with it.
  • It must be default-constructible and stateless. Objects are allocated with a default-constructed allocator and deallocated with a different default-constructed allocator, and get_allocator() returns a default-constructed instance. Allocators carrying state are not supported, so there is no way to tell a basic_json where to allocate from; see the note under StringType for what that means in practice. A stateful allocator is not diagnosed: it compiles and silently ignores the state.
  • It must support incomplete types: AllocatorType<basic_json> is instantiated inside the definition of basic_json itself.
  • std::allocator_traits<AllocatorType<basic_json>>::pointer becomes basic_json::pointer, and iterators are constructed from raw basic_json* values. The pointer type must therefore be a plain pointer; fancy pointers are not supported.
"},{"location":"features/types/template_parameters/#compatible-types_4","title":"Compatible types","text":"Type Support std::allocator (default) full a custom stateless allocator template full stateful allocators, e.g. std::pmr::polymorphic_allocator not usable; see the requirements above"},{"location":"features/types/template_parameters/#jsonserializer","title":"JSONSerializer","text":"

JSONSerializer is instantiated as JSONSerializer<T, void> and defaults to adl_serializer.

"},{"location":"features/types/template_parameters/#always-required_7","title":"Always required","text":"
  • The template must accept two type arguments. It does not have to give the second one a default \u2014 basic_json declares the parameter as template<typename T, typename SFINAE = void> class JSONSerializer, so uses such as JSONSerializer<T> inside the library supply void themselves. The second parameter exists so that partial specializations can be constrained by SFINAE.
  • For every type T that is converted to a JSON value, a static member function static void to_json(basic_json&, T) must exist.
  • For every type T that is converted from a JSON value, either static void from_json(const basic_json&, T&) or static T from_json(const basic_json&) must exist. The latter form is required for types that are not default-constructible; see Arbitrary Types Conversions.
  • To support the converting constructor between different basic_json specializations, to_json must be available for boolean_t, number_integer_t, number_unsigned_t, number_float_t, string_t, object_t, array_t, and binary_t of the source specialization.
"},{"location":"features/types/template_parameters/#compatible-types_5","title":"Compatible types","text":"Type Support nlohmann::adl_serializer (default) full a class template deriving from adl_serializer full; the usual way to change behavior while keeping the defaults an unrelated template with the same interface full, but it has to handle every type the library converts"},{"location":"features/types/template_parameters/#binarytype","title":"BinaryType","text":"

BinaryType is not a JSON type; it is used for the byte strings of the binary formats. It is wrapped as

using binary_t = nlohmann::byte_container_with_subtype<BinaryType>;\n
"},{"location":"features/types/template_parameters/#always-required_8","title":"Always required","text":"
  • A non-final class type \u2014 byte_container_with_subtype derives from it publicly.
  • A member type value_type that is exactly one byte wide (e.g., std::uint8_t, char, or std::byte). Readers and writers reinterpret the container's storage as raw bytes, so a wider value_type is rejected with a static_assert.
  • Contiguous storage: the binary readers std::memcpy into &binary[n], the writers reinterpret_cast data(). data() + n would do for the readers too, but they share one helper with StringType, whose non-const data() is C++17 and later only.
  • Default-constructible, copy-constructible, and move-constructible.
  • Member functions size(), empty(), data(), resize(), operator[], back(), begin(), end(), cbegin(), and cend() with random-access iterators. push_back() is not required.
  • Comparison operators: == is used by byte_container_with_subtype, the relational operators by basic_json's comparison operators.
"},{"location":"features/types/template_parameters/#required-for-individual-functions_1","title":"Required for individual functions","text":"
  • clear(), for basic_json::clear().

max_size(), at(), reserve(), erase(), pop_back(), and emplace_back() are not used at all.

See binary_t for how a non-default BinaryType changes the meaning of assigning such a container to a basic_json value.

Reference implementation

docs/mkdocs/docs/examples/custom_binary_type.hpp wraps a private std::vector<std::uint8_t> and satisfies every requirement above \u2014 a good starting point for a custom BinaryType.

#pragma once\n\n#include <cstdint>\n#include <initializer_list>\n#include <vector>\n\n// A minimal, self-contained BinaryType built around a private std::vector.\n// See https://json.nlohmann.me/features/types/template_parameters/#binarytype\nclass custom_binary_type\n{\n    using vector_t = std::vector<std::uint8_t>;\n    vector_t data_;\n\n  public:\n    using value_type = vector_t::value_type;\n    using size_type = vector_t::size_type;\n    using iterator = vector_t::iterator;\n    using const_iterator = vector_t::const_iterator;\n\n    custom_binary_type() = default;\n    custom_binary_type(const custom_binary_type&) = default;\n    custom_binary_type(custom_binary_type&&) = default;\n    custom_binary_type& operator=(const custom_binary_type&) = default;\n    custom_binary_type& operator=(custom_binary_type&&) = default;\n\n    template<class InputIt>\n    custom_binary_type(InputIt first, InputIt last) : data_(first, last) {}\n\n    // so basic_json::binary({0x01, 0x02}) can build one directly\n    custom_binary_type(std::initializer_list<std::uint8_t> init) : data_(init) {}\n\n    size_type size() const\n    {\n        return data_.size();\n    }\n    bool empty() const\n    {\n        return data_.empty();\n    }\n    void clear()\n    {\n        data_.clear();\n    }\n    void resize(size_type n)\n    {\n        data_.resize(n);\n    }\n\n    // read-only is enough: the writers only ever read from a binary value\n    const std::uint8_t* data() const\n    {\n        return data_.data();\n    }\n\n    std::uint8_t& operator[](size_type pos)\n    {\n        return data_[pos];\n    }\n    std::uint8_t operator[](size_type pos) const\n    {\n        return data_[pos];\n    }\n\n    std::uint8_t& back()\n    {\n        return data_.back();\n    }\n    std::uint8_t back() const\n    {\n        return data_.back();\n    }\n\n    iterator begin()\n    {\n        return data_.begin();\n    }\n    iterator end()\n    {\n        return data_.end();\n    }\n    const_iterator begin() const\n    {\n        return data_.begin();\n    }\n    const_iterator end() const\n    {\n        return data_.end();\n    }\n    const_iterator cbegin() const\n    {\n        return data_.cbegin();\n    }\n    const_iterator cend() const\n    {\n        return data_.cend();\n    }\n\n    template<class InputIt>\n    iterator insert(const_iterator pos, InputIt first, InputIt last)\n    {\n        return data_.insert(pos, first, last);\n    }\n\n    friend bool operator==(const custom_binary_type& lhs, const custom_binary_type& rhs)\n    {\n        return lhs.data_ == rhs.data_;\n    }\n    friend bool operator<(const custom_binary_type& lhs, const custom_binary_type& rhs)\n    {\n        return lhs.data_ < rhs.data_;\n    }\n};\n
Example: use the custom BinaryType
#include <iostream>\n\n#include <nlohmann/json.hpp>\n\n#include \"custom_binary_type.hpp\"\n\nusing custom_json = nlohmann::json::with_binary_t<custom_binary_type>;\n\nint main()\n{\n    const auto j = custom_json::binary({0x01, 0x02, 0x03});\n\n    std::cout << j.dump() << '\\n';\n    std::cout << std::boolalpha << (custom_json::from_cbor(custom_json::to_cbor(j)) == j) << '\\n';\n}\n

Output:

{\"bytes\":[1,2,3],\"subtype\":null}\ntrue\n
"},{"location":"features/types/template_parameters/#compatible-containers_2","title":"Compatible containers","text":"Container Notes std::vector<std::uint8_t> (default) std::vector<char>, std::vector<std::byte> dump() writes the bytes as 0..255 whichever is used boost::container::vector<std::uint8_t>, boost::container::small_vector<std::uint8_t, N> absl::InlinedVector<std::uint8_t, N> usable here, unlike as an ArrayType, because the value type is complete eastl::vector<std::uint8_t> usable here, unlike as an ArrayType, because max_size() is not needed folly::fbvector<std::uint8_t> requires C++20, see the note above"},{"location":"features/types/template_parameters/#containers-that-cannot-be-used_2","title":"Containers that cannot be used","text":"Container Reason QByteArray no empty() (it spells that isEmpty()); its insert takes an index rather than an iterator; and it converts to string_t, which makes to_json ambiguous between a string and a binary value std::string binary_t::container_type and string_t would be the same type, so the two swap overloads collide and basic_json cannot be instantiated at all std::deque<std::uint8_t> storage is not contiguous, so there is no data() containers whose value_type is wider than one byte see above \u2014 accepted by the compiler, wrong at runtime"},{"location":"features/types/template_parameters/#custombaseclass","title":"CustomBaseClass","text":"

CustomBaseClass is an extension point: unless it is void (the default, which selects the empty nlohmann::json_default_base), basic_json publicly derives from it.

"},{"location":"features/types/template_parameters/#always-required_9","title":"Always required","text":"
  • A non-final, default-constructible class type.
  • basic_json is copy-/move-constructible and copy-/move-assignable only if CustomBaseClass is.
"},{"location":"features/types/template_parameters/#notes_2","title":"Notes","text":"

basic_json is documented to be a StandardLayoutType. Because basic_json has non-static data members of its own, a CustomBaseClass with non-static data members forfeits this guarantee.

Note the namespace of CustomBaseClass becomes an associated namespace of basic_json for the purpose of argument-dependent lookup.

See json_base_class_t for an example.

"},{"location":"features/types/template_parameters/#compatible-types_6","title":"Compatible types","text":"Type Support void (default) an empty base class is used; no effect on basic_json any default-constructible, non-final class full; see json_base_class_t"},{"location":"features/types/template_parameters/#cross-specialization-conversions","title":"Cross-specialization conversions","text":"

Converting a value from one basic_json specialization into another (see the converting constructor) imposes two additional requirements that are not diagnosed at compile time. With assertions enabled they abort on the JSON_ASSERT at the end of the converting constructor; under NDEBUG they fail silently at runtime:

  • The target string_t must be directly constructible from the source string_t. Otherwise the string is converted to an array of character codes.
  • The target object_t::key_type must be directly constructible from the source object's key type. Otherwise the object is converted to an array of key/value pairs.

See issue #3425, string_t, and object_t.

"},{"location":"features/types/template_parameters/#see-also","title":"See also","text":"
  • Types - overview of how JSON values are stored
  • Number Handling - how the number types affect parsing and serialization
  • Object Order - using an insertion-ordered ObjectType
  • basic_json - API documentation of the class template
  • object_t - the ObjectType in use
  • array_t - the ArrayType in use
  • string_t - the StringType in use
  • json_serializer - the JSONSerializer in use
  • json_base_class_t - the CustomBaseClass in use
  • with_t - derive a specialization with one parameter replaced
  • get_allocator - the allocator in use
"},{"location":"home/architecture/","title":"Architecture","text":"

This page gives a high-level overview of the library's architecture. It should help new contributors to get an idea of the used concepts and where to make changes.

"},{"location":"home/architecture/#overview","title":"Overview","text":"

The library is built around a single class template, nlohmann::basic_json. A basic_json value is a node in a tree of JSON values. All other components either create such a tree from an input (parsing), write a tree to an output (serialization), or give access to it (iterators, JSON Pointer, conversions).

flowchart LR\n    input[/\"input<br>(string, stream,<br>iterator range, file)\"/]\n    ia[\"input adapter\"]\n    lexer[\"lexer\"]\n    parser[\"parser\"]\n    breader[\"binary_reader\"]\n    sax[\"SAX interface\"]\n    value[(\"basic_json<br>value tree\")]\n    serializer[\"serializer\"]\n    bwriter[\"binary_writer\"]\n    oa[\"output adapter\"]\n    output[/\"output<br>(string, stream,<br>vector)\"/]\n\n    input --> ia\n    ia --> lexer --> parser --> sax\n    ia --> breader --> sax\n    sax --> value\n    value --> serializer --> oa\n    value --> bwriter --> oa\n    oa --> output

Data flow through the library: input runs left to right through an input adapter and the lexer and parser (JSON text) or the binary_reader (binary formats) into SAX events, which build the value tree; the serializer or the binary_writer writes the tree to an output adapter.

  • JSON text is read by an input adapter, tokenized by the lexer, and turned into SAX events by the parser.
  • Binary formats (BJData, BON8, BSON, CBOR, MessagePack, UBJSON) are read by an input adapter and turned into the same SAX events by the binary_reader.
  • A SAX consumer receives the events. The one used by parse builds a basic_json value tree.
  • The serializer (JSON text) or the binary_writer (binary formats) writes a value tree to an output adapter.
"},{"location":"home/architecture/#source-layout","title":"Source layout","text":"

The public headers are in include/nlohmann:

  • json.hpp defines class basic_json.
  • json_fwd.hpp contains forward declarations.
  • adl_serializer.hpp, byte_container_with_subtype.hpp, and ordered_map.hpp define adl_serializer, byte_container_with_subtype, and ordered_map.
  • json_view.hpp is a separate, optional header that defines basic_json_document and basic_json_view, a flat-index, read-only, non-owning way to look at a parsed JSON text; see Zero-copy JSON views. It builds on json.hpp internals (it requires the same library version) and has its own detail/view/ subdirectory.

Everything else lives in detail/ and namespace nlohmann::detail, which is not part of the public API. Paths below are relative to include/nlohmann.

Component Location Value type enumeration detail/value_t.hpp Input adapters detail/input/input_adapters.hpp Lexer detail/input/lexer.hpp, detail/input/number_parse.hpp, detail/input/string_scan.hpp, detail/input/simd_scan.hpp Parser detail/input/parser.hpp SAX interface and DOM builders detail/input/json_sax.hpp Binary format readers detail/input/binary_reader.hpp JSON serializer detail/output/serializer.hpp, detail/conversions/to_chars.hpp Binary format writers detail/output/binary_writer.hpp Output adapters detail/output/output_adapters.hpp Iterators detail/iterators/ Conversions from/to arbitrary types detail/conversions/from_json.hpp, detail/conversions/to_json.hpp JSON Pointer detail/json_pointer.hpp Exceptions detail/exceptions.hpp Type traits and C++ feature backports detail/meta/ Macros detail/macro_scope.hpp, detail/macro_unscope.hpp, detail/abi_macros.hpp

The single-header version single_include/nlohmann/json.hpp is generated from these files with make amalgamate and must not be edited by hand. The same command also generates single_include/nlohmann/json_view.hpp from json_view.hpp and detail/view/.

"},{"location":"home/architecture/#template-parameters","title":"Template parameters","text":"

basic_json is parameterized by the types it uses to store values and to convert from and to other types:

Template parameter Default Used for ObjectType std::map objects, see object_t ArrayType std::vector arrays, see array_t StringType std::string strings and object keys, see string_t BooleanType bool Booleans, see boolean_t NumberIntegerType std::int64_t signed integers, see number_integer_t NumberUnsignedType std::uint64_t unsigned integers, see number_unsigned_t NumberFloatType double floating-point numbers, see number_float_t AllocatorType std::allocator allocating objects, arrays, strings, and binary values JSONSerializer adl_serializer conversions from/to other types, see adl_serializer BinaryType std::vector<std::uint8_t> binary values, see binary_t CustomBaseClass void an optional base class, see json_base_class_t

The library provides two specializations:

  • json uses all default template arguments.
  • ordered_json uses ordered_map as ObjectType to keep the insertion order of object keys.

The requirements on the template arguments are listed in Template Parameter Requirements.

"},{"location":"home/architecture/#value-storage","title":"Value storage","text":"

Each basic_json value stores its content as a tagged union: an enumeration value_t names the type of the value, and a union json_value holds the value itself. Both are members of the nested struct data, which is the only data member m_data of basic_json:

struct data\n{\n    /// the type of the current element\n    value_t m_type = value_t::null;\n\n    /// the value of the current element\n    json_value m_value = {};\n};\n\ndata m_data = {};\n

with

enum class value_t : std::uint8_t\n{\n    null,             ///< null value\n    object,           ///< object (unordered set of name/value pairs)\n    array,            ///< array (ordered collection of values)\n    string,           ///< string value\n    boolean,          ///< boolean value\n    number_integer,   ///< number value (signed integer)\n    number_unsigned,  ///< number value (unsigned integer)\n    number_float,     ///< number value (floating-point)\n    binary,           ///< binary array (ordered collection of bytes)\n    discarded         ///< discarded by the parser callback function\n};\n\nunion json_value {\n  /// object (stored with pointer to save storage)\n  object_t *object;\n  /// array (stored with pointer to save storage)\n  array_t *array;\n  /// string (stored with pointer to save storage)\n  string_t *string;\n  /// binary (stored with pointer to save storage)\n  binary_t *binary;\n  /// boolean\n  boolean_t boolean;\n  /// number (integer)\n  number_integer_t number_integer;\n  /// number (unsigned integer)\n  number_unsigned_t number_unsigned;\n  /// number (floating-point)\n  number_float_t number_float;\n};\n

Objects, arrays, strings, and binary values are allocated on the heap with AllocatorType, and the union only stores a pointer to them. This keeps a basic_json value small: one pointer-sized union and one byte for the type. The class maintains the invariant that the pointer matching m_type is never null; assert_invariant() checks it with runtime assertions.

"},{"location":"home/architecture/#node-index-of-json-views","title":"Node index of JSON views","text":"

A basic_json_document (see Zero-copy JSON views) does not build a tree of values. Its parser (detail/view/builder.hpp) writes a flat array of 16-byte nodes, one per value and one per object key, in document order. A basic_json_view is a pointer to the document and a pointer to one node. The layout is struct node in detail/view/node.hpp (the numbers are bit offsets, 32 bits per row):

packet-beta\n  0-7: \"kind\"\n  8-15: \"flags\"\n  16-31: \"extra\"\n  32-63: \"off\"\n  64-95: \"len\"\n  96-127: \"next\"

Layout of one 16-byte node of a JSON view index. Each row is 32 bits wide, and the numbers are the bit offsets of the fields kind, flags, extra, off, len, and next.

Bytes Field Type Contents 0 kind uint8_t the type, numbered as value_t: 0 null, 1 object, 2 array, 3 string, 4 boolean, 5 signed integer, 6 unsigned integer, 7 float; 10 for a link (see below). There is no node for a discarded value: a discarded view has none 1 flags uint8_t bits 0-1: where a string's bytes (or a number's token) are (0: the source text, 1: the buffer of decoded strings, for strings with escapes, 2: the edit buffer); bit 2: the value of a boolean; bit 3: moved, bit 4: new, bit 5: linked (see below) 2-3 extra uint16_t numbers: the number of integer digits (low byte) and fraction digits (high byte), 255 for more; objects: the number of their key hash index (1-based), or 0; otherwise 0 4-7 off uint32_t where the value starts: the first byte after a string's opening quote (or its position in the buffer of decoded strings), the first byte of a number or literal, the bracket of an array or object 8-11 len uint32_t strings: the length after decoding; floats and literals: the length of the token; arrays and objects: the number of elements 12-15 next uint32_t arrays and objects: the number of nodes of the subtree, including the node itself

Fields of a node, by their byte offset within the 16-byte node. Integers use bytes 8-15 differently, see below.

  • Integers keep their converted value in bytes 8-15 instead of len and next; the length of their token follows from the number of digits in extra (and the sign). Non-negative integers are unsigned integers, as with parse.
  • Floats keep only their token. The digit layout in extra lets the conversion read the digits without scanning the token again, and only when the value is read.
  • Object members are the node of the key (a string) followed by the nodes of the value.
  • Navigation needs no pointers: the elements of an array or object follow its node, and the node after a value's subtree is next nodes further for an array or object, and the next node otherwise (document_data::after). Views step from element to element this way and skip whole subtrees in constant time.
  • Offsets are 32 bits wide, so a document is limited to 4294967279 bytes, 4 GiB minus 16 bytes (a margin below 2^32 for positions one scanner step past the end of the text; out_of_range.416).
  • Large objects (128 members or more) get a hash index for their keys after parsing (detail/view/object_index.hpp): an open-addressing table whose slots hold the distance from the object's node to a key's node, so that a lookup does not compare every key. Of duplicate keys the table leads to the first, as a linear search does. The object's extra holds the number of its table. Only 65,535 tables fit into extra; objects beyond them are searched linearly.

For example, {\"a\": [1, 2.5]} becomes five nodes. Each node's elements follow it, and next leads from an array or object past its subtree:

flowchart LR\n    n0[\"0: object<br>len 1, next 5\"]\n    n1[\"1: key a\"]\n    n2[\"2: array<br>len 2, next 3\"]\n    n3[\"3: unsigned integer 1\"]\n    n4[\"4: float 2.5\"]\n    e([\"end\"])\n    n0 --> n1 --> n2 --> n3 --> n4 --> e\n    n0 -. next .-> e\n    n2 -. next .-> e

The five nodes of {\"a\": [1, 2.5]} in document order. Solid arrows lead from each node to the one after it; dotted arrows show where next leads from the object and the array, past their subtrees.

Node kind extra off len next 0 1 (object) 0 0 1 5 1 3 (string) 0 2 1 0 2 2 (array) 0 6 2 3 3 6 (unsigned integer) 0x0001 7 - - 4 7 (float) 0x0101 10 3 0

Fields of the five nodes of {\"a\": [1, 2.5]}. off is the byte offset in the text, and - marks the bytes 8-15 that hold the integer's value instead of len and next.

All flags are 0. The integer's bytes 8-15 hold its value, 1; its extra says it has one digit. The float's extra says it has one integer and one fraction digit, and its len is that of the token 2.5.

Editable documents (json_editable_document, detail/view/edit.hpp and detail/view/edit_storage.hpp) never write the source text and never move or resize the parsed index, so views stay valid while the document is edited:

  • A new scalar is written over its node. Its text (a string, or the token of a number as dump() writes it) goes to the edit buffer, which flags bits 0-1 then name.
  • An array or object whose elements change gets the flag moved (bit 3): its elements then live in a separate sequence (a header node, then the entries), whose number is in off. The entries are links (kind 10), whose bytes 8-15 hold the address of the value's node, so values never move.
  • A node written by an edit gets the flag new (bit 4): it has no position in the source text.
  • A value that an entry of such a sequence links to gets the flag linked (bit 5): its extent in the parsed layout (next) no longer matters, so a scalar can replace an array or object there in place.
  • Views of read-only documents compile without any of this: how views walk the index is a template parameter (navigation<Editable>).

Images (save and load, detail/view/image.hpp) store the nodes as they are: a 64-byte header (the magic bytes NJVI, a format version, the sizes, and reserved bytes that must be zero), the nodes, the text, and the decoded strings. An edited document is first written in document order, as the parser would have written it (without links), and the numbers of the hash indexes are cleared, since load rebuilds the indexes. So a change of the node layout is a change of the image format: it must raise image_version, and load then rejects images of other versions (parse_error.116) instead of misreading them.

"},{"location":"home/architecture/#input-adapters","title":"Input adapters","text":"

Input is read via input adapters that abstract a source. Every input adapter provides this interface:

/// the type of the characters in the input\nusing char_type = ...;\n\n/// read a single character; returns std::char_traits<char_type>::eof() at the end of the input\ntypename std::char_traits<char_type>::int_type get_character();\n\n/// read up to count * sizeof(T) bytes into dest and return the number of bytes read\n/// (used by the binary readers)\ntemplate<class T>\nstd::size_t get_elements(T* dest, std::size_t count = 1);\n

The lexer detects two optional extensions at compile time. iterator_input_adapter provides both, and only for random-access input of single-byte characters. input_stream_adapter provides the second one (as a window onto the streambuf's buffer) unless JSON_DISABLE_STREAM_BULK_SCAN is defined:

  • supports_seek, get_consumed_count(), and copy_consumed_range() let the lexer reconstruct already consumed input for error messages instead of copying every character it reads. With get_read_count() and count_consumed_lines(), the lexer also derives the read position from the adapter and counts lines only when an error needs them, instead of counting characters and lines on every read.
  • supports_bulk_scan, bulk_data(), bulk_remaining(), and bulk_skip() let the lexer scan strings directly in contiguous memory, several bytes at a time, and skip the spaces that indent a line in 8-byte steps.

The function input_adapter picks the right adapter for the argument passed to parse, accept, sax_parse, or the from_* functions:

  • iterator_input_adapter reads from an iterator range, which also covers strings, containers, and pointers.
  • wide_string_input_adapter reads from ranges of wchar_t, char16_t, or char32_t and converts them to UTF-8. It cannot be used for binary formats; its get_elements() throws.
  • input_stream_adapter reads from a std::istream.
  • file_input_adapter reads from a std::FILE*.

The adapters have no common base class: the lexer and the parser are templates on the adapter type, and wide_string_input_adapter wraps an iterator_input_adapter:

classDiagram\n    class input_adapter [\"input adapter\"] {\n        <<concept>>\n        +char_type\n        +get_character() int_type\n        +get_elements(T* dest, size_t count) size_t\n    }\n    class iterator_input_adapter {\n        -IteratorType current\n        -SentinelType end\n    }\n    class wide_string_input_adapter {\n        -BaseInputAdapter base_adapter\n    }\n    class input_stream_adapter {\n        -std::istream* is\n        -std::streambuf* sb\n    }\n    class file_input_adapter {\n        -std::FILE* m_file\n    }\n    input_adapter <|.. iterator_input_adapter\n    input_adapter <|.. wide_string_input_adapter\n    input_adapter <|.. input_stream_adapter\n    input_adapter <|.. file_input_adapter\n    wide_string_input_adapter o-- iterator_input_adapter : converts to UTF-8

The input adapters as a class diagram. The dotted arrows mean that each adapter implements the input adapter concept; the diamond shows that wide_string_input_adapter holds an iterator_input_adapter.

"},{"location":"home/architecture/#sax-interface","title":"SAX interface","text":"

The parser does not build values itself. It reports what it reads as events to a SAX consumer, which implements the interface json_sax: null, boolean, number_integer, number_unsigned, number_float, string, binary, start_object, key, end_object, start_array, end_array, and parse_error.

The library comes with two consumers in detail/input/json_sax.hpp:

  • json_sax_dom_parser builds a basic_json value tree. parse uses it.
  • json_sax_dom_callback_parser does the same, but calls a parser callback for each event, which can skip values. parse uses it when a callback is given.

The binary_reader emits the same events for binary formats, so sax_parse works with a user-defined consumer for JSON and for all binary formats alike. The SAX event stepper shows the events for a small input.

"},{"location":"home/architecture/#output-adapters","title":"Output adapters","text":"

Output is written via output adapters:

void write_character(CharType c);\n\nvoid write_characters(const CharType* s, std::size_t length);\n

The serializer (used by dump and operator<<) and the binary_writer (used by the to_* functions) write to one of these adapters:

  • output_vector_adapter appends to a std::vector.
  • output_stream_adapter writes to a std::ostream.
  • output_string_adapter appends to a string.

They implement the abstract class output_adapter_protocol. The class output_adapter creates the one that matches its argument and holds it in a std::shared_ptr (output_adapter_t):

classDiagram\n    class output_adapter_protocol~CharType~ {\n        <<interface>>\n        +write_character(CharType c)*\n        +write_characters(const CharType* s, size_t length)*\n    }\n    class output_vector_adapter {\n        -std::vector& v\n    }\n    class output_stream_adapter {\n        -std::basic_ostream& stream\n    }\n    class output_string_adapter {\n        -StringType& str\n    }\n    class output_adapter {\n        -output_adapter_t oa\n    }\n    output_adapter_protocol <|-- output_vector_adapter\n    output_adapter_protocol <|-- output_stream_adapter\n    output_adapter_protocol <|-- output_string_adapter\n    output_adapter o-- output_adapter_protocol : shared_ptr

The output adapters as a class diagram. The three adapters derive from output_adapter_protocol (solid arrows), and output_adapter holds one of them through a shared_ptr (diamond).

The binary_writer does not call an adapter for every byte. The to_* functions that return a std::vector write into the vector through a sink (output_vector_sink) that is not virtual. The functions that take an output adapter write through a sink (output_adapter_sink) that collects the output in a buffer of one kibibyte and passes it to the adapter in blocks, so that the adapter is called (and a stream locked) once per block instead of once per value.

"},{"location":"home/architecture/#value-conversion","title":"Value conversion","text":"

Values are converted from and to other types with the JSONSerializer template parameter. The default, adl_serializer, calls the free functions

template<class T>\nvoid to_json(basic_json& j, const T& t);\n\ntemplate<class T>\nvoid from_json(const basic_json& j, T& t);\n

found by argument-dependent lookup. The library defines them for standard types in detail/conversions; users add them for their own types, see Arbitrary Type Conversions. The serialization macros generate these functions.

"},{"location":"home/architecture/#additional-features","title":"Additional features","text":"
  • JSON Pointer (class json_pointer) addresses values inside a tree. It is also the basis of JSON Patch.
  • Binary formats are read by binary_reader and written by binary_writer.
  • A custom base class can add members to every basic_json value.
  • Serialization macros generate to_json and from_json functions for user-defined types.
"},{"location":"home/architecture/#details-namespace","title":"Details namespace","text":"

Namespace nlohmann::detail contains all implementation details. It is not part of the public API and may change in any release. Besides the components above, it contains:

  • type traits to detect the capabilities of user-defined types (detail/meta/type_traits.hpp),
  • backports of C++14/17 features to C++11 (detail/meta/cpp_future.hpp), and
  • helpers such as string_concat and string_escape.
"},{"location":"home/architecture/#see-also","title":"See also","text":"
  • basic_json - the main class and all its member functions
  • adl_serializer - customization point for type conversions
  • json_sax - interface of the SAX parser events
  • SAX Interface - how to consume parser events without building a DOM
  • Zero-copy JSON views - the flat node index that backs views and documents
  • Template Parameter Requirements - the template parameters of basic_json
  • Serialization - the output side of the library
  • nlohmann Namespace - how the library namespace is structured
"},{"location":"home/customers/","title":"Customers","text":"

The library is used in multiple projects, applications, operating systems, etc. The list below is not exhaustive, but the result of an internet search. If you know further customers of the library, please let me know.

"},{"location":"home/customers/#space-exploration","title":"Space Exploration","text":"
  • Peregrine Lunar Lander Flight 01 - The library was used for payload management in the Peregrine Moon Lander, developed by Astrobotic Technology and launched as part of NASA's Commercial Lunar Payload Services (CLPS) program. After six days in orbit, the spacecraft was intentionally redirected into Earth's atmosphere, where it burned up over the Pacific Ocean on January 18, 2024.
  • NASA Unsteady Pressure-Sensitive Paint Processing, NASA software for processing high-speed video recordings of wind tunnel tests on launch vehicle and aircraft models
  • Terma TEMU, an emulator of spacecraft on-board computers used to develop and validate flight software for European space missions
"},{"location":"home/customers/#automotive","title":"Automotive","text":"
  • Alexa Auto SDK, a software development kit enabling the integration of Alexa into automotive systems
  • Apollo, a framework for building autonomous driving systems
  • Automotive Grade Linux (AGL), a collaborative open-source platform for automotive software development
  • Autoware, an open-source software stack for autonomous driving built on ROS 2
  • Eclipse S-CORE, an open-source software platform for the software-defined vehicle backed by major automotive manufacturers and suppliers
  • Genesis Motor (infotainment), a luxury automotive brand
  • Hyundai (infotainment), a global automotive brand
  • Kia (infotainment), a global automotive brand
  • Mercedes-Benz Operating System (MB.OS), a core component of the vehicle software ecosystem from Mercedes-Benz
  • NVIDIA DRIVE OS, the operating system and DriveWorks SDK powering NVIDIA's platform for autonomous vehicles
  • Rivian (infotainment), an electric vehicle manufacturer
  • Suzuki (infotainment), a global automotive and motorcycle manufacturer
"},{"location":"home/customers/#gaming-and-entertainment","title":"Gaming and Entertainment","text":"
  • Anno 117: Pax Romana, a city-building strategy game set in the Roman Empire
  • Assassin's Creed: Mirage, a stealth-action game set in the Middle East, focusing on the journey of a young assassin with classic parkour and stealth mechanics
  • Battlefield 6, a military first-person shooter known for its large-scale multiplayer battles
  • Battlefield: REDSEC, a free-to-play battle royale experience set in the Battlefield universe
  • BioMenace: Remastered, a remaster of the classic side-scrolling platform shooter
  • Chasm: The Rift, a first-person shooter blending horror and adventure, where players navigate dark realms and battle monsters
  • College Football 25, a college football simulation game featuring gameplay that mimics real-life college teams and competitions
  • College Football 26, a college football simulation game featuring licensed teams and stadiums
  • College Football 27, the latest installment of the college football simulation series
  • Concepts, a digital sketching app designed for creative professionals, offering flexible drawing tools for illustration, design, and brainstorming
  • Depthkit, a tool for creating and capturing volumetric video, enabling immersive 3D experiences and interactive content
  • Dune: Awakening, an open-world survival MMO set on the desert planet Arrakis
  • EA Sports FC 25, an association football simulation with club, career, and online modes
  • EA Sports FC 26, the latest installment of the association football simulation series
  • EA Sports UFC 6, a mixed martial arts fighting simulation
  • FiveM, a modification framework for Grand Theft Auto V that powers custom multiplayer servers
  • FLUX:: Immersive, a suite of professional audio processing and immersive mixing plugins used in music and post-production
  • IMG.LY, a platform offering creative tools and SDKs for integrating advanced image and video editing in applications
  • immersivetech, a technology company focused on immersive experiences, providing tools and solutions for virtual and augmented reality applications
  • Kodi, a home theater and media center application
  • LOOT, a tool for optimizing the load order of game plugins, commonly used in The Elder Scrolls and Fallout series
  • LunaTranslator, a real-time translation tool for visual novels
  • MaaAssistantArknights, an automation assistant for the mobile game Arknights
  • Madden NFL 25, a sports simulation game capturing the excitement of American football with realistic gameplay and team management features
  • Madden NFL 26, an American football simulation with franchise and team management modes
  • Madden NFL 27, the latest installment of the American football simulation series
  • Marne, an unofficial private server platform for hosting custom Battlefield 1 game experiences
  • Minecraft, a popular sandbox video game
  • Mumble, a low-latency, open-source voice chat application widely used by gaming communities
  • NHL 22, a hockey simulation game offering realistic gameplay, team management, and various modes to enhance the hockey experience
  • OBS Studio, a free and open-source suite for video recording and live streaming
  • OpenRCT2, an open source re-implementation of RollerCoaster Tycoon 2
  • Pixelpart, a 2D animation and video compositing software that allows users to create animated graphics and visual effects with a focus on simplicity and ease of use
  • Razer Cortex, a gaming performance optimizer and system booster designed to enhance the gaming experience
  • Red Dead Redemption II, an open-world action-adventure game following an outlaw's story in the late 1800s, emphasizing deep storytelling and immersive gameplay
  • RetroArch, a frontend for emulators, game engines, and media players built on the libretro API
  • shadPS4, a PlayStation 4 emulator for Windows, Linux and macOS
  • skate., a free-to-play skateboarding game set in an open world
  • Snapchat, a multimedia messaging and augmented reality app for communication and entertainment
  • Steel Century Groove, an action game released in 2026
  • Sunshine, a self-hosted game streaming host compatible with Moonlight clients
  • Tactics Ogre: Reborn, a tactical role-playing game featuring strategic battles and deep storytelling elements
  • Throne and Liberty, an MMORPG that offers an expansive fantasy world with dynamic gameplay and immersive storytelling
  • Unity Vivox, a communication service that enables voice and text chat functionality in multiplayer games developed with Unity
  • xemu, an emulator of the original Xbox console
  • Zool: Redimensioned, a modern reimagining of the classic platformer featuring fast-paced gameplay and vibrant environments
"},{"location":"home/customers/#consumer-electronics","title":"Consumer Electronics","text":"
  • Audinate, a provider of networked audio solutions specializing in Dante technology, which facilitates high-quality digital audio transport over IP networks
  • Canon CanoScan LIDE, a series of flatbed scanners offering high-resolution image scanning for home and office use
  • Canon PIXMA Printers, a line of all-in-one inkjet printers known for high-quality printing and wireless connectivity
  • Cisco Webex Desk Camera, a video camera designed for professional-quality video conferencing and remote collaboration
  • DJI Edge SDK, the reference applications for DJI's Edge SDK, used to build edge computing services on DJI drone docks
  • Elgato Stream Deck, a family of programmable control surfaces for content creators and their plugin ecosystem
  • Instagrid, a manufacturer of portable, high-performance battery systems for professional mobile power supply
  • iRobot, a manufacturer of autonomous home robots including the Roomba vacuum cleaner range
  • Logitech Logi Bolt, the management application for Logitech's secure wireless connectivity technology
  • Novitus, a manufacturer of fiscal cash registers and point-of-sale devices
  • Philips Hue Personal Wireless Lighting, a smart lighting system for customizable and wireless home illumination
  • Ray-Ban Meta Smart glasses, a pair of smart glasses designed for capturing photos and videos with integrated connectivity and social features
  • Razer Synapse, a unified configuration software enabling hardware customization for Razer devices
  • Sharp Professional Displays, a range of large-format interactive displays for business and education
  • Siemens SINEMA Remote Connect, a remote connectivity solution for monitoring and managing industrial networks and devices securely
  • Skydio, a manufacturer of autonomous drones for inspection, public safety, and defense applications
  • Sony PlayStation 4, a gaming console developed by Sony that offers a wide range of games and multimedia entertainment features
  • Sony Spatial Reality Display, a glasses-free stereoscopic 3D display and its plugins for Blender, 3ds Max, and ZBrush
  • Sony Virtual Webcam Driver for Remote Camera, a software driver that enables the use of Sony cameras as virtual webcams for video conferencing and streaming
  • Yamaha Clavinova, a series of digital pianos combining acoustic piano feel with digital sound technology
"},{"location":"home/customers/#operating-systems-and-platforms","title":"Operating Systems and Platforms","text":"
  • Apple iOS and macOS, a family of operating systems developed by Apple, including iOS for mobile devices and macOS for desktop computers
  • Chromium, the open-source browser project that Google Chrome, Microsoft Edge, and many other browsers are built on, where the library is used as data container for on-device model execution
  • Google Fuchsia, an open-source operating system developed by Google, designed to be secure, updatable, and adaptable across various devices
  • LG webOS, a Linux-based operating system used in LG smart TVs, signage, and embedded devices
  • Microsoft Azure Linux, a Linux distribution developed by Microsoft for Azure infrastructure and edge workloads
  • OpenHarmony, an open-source operating system for smart devices and the foundation of HarmonyOS
  • SerenityOS, an open-source operating system that aims to provide a simple and beautiful user experience with a focus on simplicity and elegance
  • Windows Subsystem for Linux, a compatibility layer that runs Linux environments natively on Windows
  • Yocto, a Linux-based build system for creating custom operating systems and software distributions, tailored for embedded devices and IoT applications
"},{"location":"home/customers/#development-tools-and-ides","title":"Development Tools and IDEs","text":"
  • Accentize SpectralBalance, an adaptive speech analysis tool designed to enhance audio quality by optimizing frequency balance in recordings
  • Airbus Ghidralligator, a Ghidra-based emulator from Airbus CyberSecurity used to fuzz and analyse embedded firmware
  • Apache brpc, an industrial-grade remote procedure call framework for C++
  • Arm Compiler for Linux, a software development toolchain for compiling and optimizing applications on Arm-based Linux systems
  • BBEdit, a professional text and code editor for macOS
  • CoderPad, a collaborative coding platform that enables real-time code interviews and assessments for developers; the library is included in every CoderPad instance and can be accessed with a simple #include \"json.hpp\"
  • Codon, an ahead-of-time compiler for a Python-like language
  • Compiler Explorer, a web-based tool that allows users to write, compile, and visualize the assembly output of code in various programming languages; the library is readily available and accessible with the directive #include <nlohmann/json.hpp>.
  • Flutter, a UI toolkit for building natively compiled applications for mobile, web, and desktop from a single codebase
  • Fraunhofer VVenC, a fast and efficient encoder for the Versatile Video Coding (H.266/VVC) standard
  • GitHub CodeQL, a code analysis tool used for identifying security vulnerabilities and bugs in software through semantic queries
  • GoPro ngfx, a low-level graphics abstraction and profiling framework developed by GoPro
  • gRPC, a high-performance universal remote procedure call framework
  • Hex-Rays, a reverse engineering toolset for analyzing and decompiling binaries, primarily used for security research and vulnerability analysis
  • ImHex, a hex editor designed for reverse engineering, providing advanced features for data analysis and manipulation
  • Intel GITS, a tool for capturing and replaying graphics API calls for debugging and performance analysis
  • Intel GPA Framework, a suite of cross-platform tools for capturing, analyzing, and optimizing graphics applications across different APIs
  • Intopix, a provider of advanced image processing and compression solutions used in software development and AV workflows
  • Java SE, the core Java platform that provides the libraries and runtime needed to build and run general-purpose Java applications
  • Meta Yoga, a layout engine that facilitates flexible and efficient user interface design across multiple platforms
  • MKVToolNix, a set of tools for creating, editing, and inspecting MKV (Matroska) multimedia container files
  • MRTech IFF SDK, an image processing SDK for machine vision applications with GPU-accelerated pipelines
  • Nix, a purely functional package manager
  • Notepad++, a free source code editor that supports various programming languages
  • NVIDIA Nsight Compute, a performance analysis tool for CUDA applications that provides detailed insights into GPU performance metrics
  • openFrameworks, a community-developed C++ toolkit for creative coding
  • OpenRGB, an open source RGB lighting control that doesn't depend on manufacturer software
  • OpenTelemetry C++, a library for collecting and exporting observability data in C++, enabling developers to implement distributed tracing and metrics in their application
  • Oracle GraalVM, a high-performance JDK distribution with ahead-of-time compilation and polyglot runtime support
  • Philips amp-cucumber-cpp-runner, a behaviour-driven development test runner for embedded C++ software developed at Philips
  • Qt Creator, an IDE for developing applications using the Qt application framework
  • Qt for MCUs, a graphics framework for building fluid user interfaces on microcontrollers
  • React Native, a framework for building native mobile applications using React
  • Scanbot SDK, a software development kit (SDK) that provides tools for integrating advanced document scanning and barcode scanning capabilities into applications
  • STMicroelectronics TouchGFX, a graphical user interface framework shipped with STM32 microcontrollers for building embedded HMIs
  • swagger-codegen, a template-driven engine that generates API clients and server stubs from an OpenAPI specification
  • Swoole, a coroutine-based concurrency engine for PHP
  • Tracy Profiler, a real-time frame profiler for games and other applications
  • WasmEdge, a lightweight WebAssembly runtime for edge and cloud workloads
  • x64dbg, an open source user mode debugger for Windows, aimed at reverse engineering and malware analysis
"},{"location":"home/customers/#machine-learning-and-ai","title":"Machine Learning and AI","text":"
  • Alibaba MNN, a lightweight deep learning inference engine for mobile and embedded devices
  • AMD Gaia, an open-source framework for running generative AI applications locally on AMD hardware
  • AMD Vitis AI (VAIP), the execution provider stack that runs AI models on AMD Ryzen AI and adaptive computing devices
  • Apple Core ML Tools, a set of tools for converting and configuring machine learning models for deployment in Apple's Core ML framework
  • Avular Mobile Robotics, a platform for developing and deploying mobile robotics solutions
  • FunASR, a speech recognition toolkit for training and deploying end-to-end models
  • Google gemma.cpp, a lightweight C++ inference engine designed for running AI models from the Gemma family
  • Google Magenta The Infinite Crate, an open-source generative AI plugin for digital audio workstations from Google's Magenta research team
  • GPT4All, a desktop application for running local large language models on consumer hardware
  • Huawei MindSpore, a deep learning framework for training and inference across device, edge, and cloud
  • KTransformers, a framework for heterogeneous large language model inference
  • llama.cpp, a C++ library designed for efficient inference of large language models (LLMs), enabling streamlined integration into applications
  • LocalAI, a self-hosted inference engine that exposes local models through an OpenAI-compatible API
  • MLX, an array framework for machine learning on Apple Silicon
  • Mozilla llamafile, a tool designed for distributing and executing large language models (LLMs) efficiently using a single file format
  • NVIDIA ACE, a suite of real-time AI solutions designed for the development of interactive avatars and digital human applications, enabling scalable and sophisticated user interactions
  • NVIDIA Instant NGP, an implementation of instant neural graphics primitives for rapid scene reconstruction
  • NVIDIA TensorRT, an SDK for high-performance deep learning inference, including its TensorRT-LLM extension for large language models
  • NVIDIA TensorRT-LLM, a toolkit for optimizing and serving large language model inference on GPUs
  • ONNX Runtime, a cross-platform inference and training accelerator for machine learning models
  • OpenVINO, Intel's toolkit for optimizing and deploying deep learning inference across CPUs, GPUs, and NPUs
  • PaddleOCR, an optical character recognition toolkit that turns documents and images into structured data
  • PaddlePaddle, a deep learning framework for distributed training and inference
  • Peer, a platform offering personalized AI assistants for interactive learning and creative collaboration
  • PyTorch, a machine learning framework for building and training neural networks, widely used in research and production
  • Qualcomm AI Engine Direct, a toolchain for building and running generative AI applications on Snapdragon devices
  • sherpa-onnx, a speech toolkit for on-device recognition, synthesis and speaker diarization
  • stable-diffusion.cpp, a C++ implementation of the Stable Diffusion image generation model
  • TanvasTouch, a software development kit (SDK) that enables developers to create tactile experiences on touchscreens, allowing users to feel textures and physical sensations in a digital environment
  • TensorFlow, a machine learning framework that facilitates the development and training of models, supporting data serialization and efficient data exchange between components
  • whisper.cpp, a C++ implementation of OpenAI's Whisper automatic speech recognition model
"},{"location":"home/customers/#scientific-research-and-analysis","title":"Scientific Research and Analysis","text":"
  • BLACK, a bounded linear temporal logic (LTL) satisfiability checker
  • CERN ALICE O2, the online-offline computing framework of the ALICE heavy-ion experiment at the Large Hadron Collider
  • CERN Atlas Athena, a software framework used in the ATLAS experiment at the Large Hadron Collider (LHC) for performance monitoring
  • CERN CMSSW, the offline software framework of the CMS experiment at the Large Hadron Collider
  • CERN Gaudi, the event-processing framework used by the LHCb and ATLAS experiments at the Large Hadron Collider
  • ICU, the International Components for Unicode, a mature library for software globalization and multilingual support
  • KAMERA, a platform for synchronized data collection and real-time deep learning to map marine species like polar bears and seals, aiding Arctic ecosystem research
  • KiCad, a free and open-source software suite for electronic design automation
  • LLNL ROSE, a compiler infrastructure from Lawrence Livermore National Laboratory for building source-to-source program analysis and transformation tools
  • Maple, a symbolic and numeric computing environment for advanced mathematical modeling and analysis
  • MeVisLab, a software framework for medical image processing and visualization.
  • MITK, the Medical Imaging Interaction Toolkit, a framework for developing interactive medical image processing software
  • OpenPMD API, a versatile programming interface for accessing and managing scientific data, designed to facilitate the efficient storage, retrieval, and sharing of simulation data across various applications and platforms
  • ORNL DataFed, a federated scientific data management system developed at Oak Ridge National Laboratory
  • ParaView, an open-source tool for large-scale data visualization and analysis across various scientific domains
  • QGIS, a free and open-source geographic information system (GIS) application that allows users to create, edit, visualize, and analyze geospatial data across a variety of formats
  • Sandia InterSpec, spectral radiation analysis software from Sandia National Laboratories for identifying radioactive isotopes
  • VolView, a lightweight application for interactive visualization and analysis of 3D medical imaging data.
  • VTK, a software library for 3D computer graphics, image processing, and visualization
"},{"location":"home/customers/#business-and-productivity-software","title":"Business and Productivity Software","text":"
  • ArcGIS PRO, a desktop geographic information system (GIS) application developed by Esri for mapping and spatial analysis
  • Autodesk Desktop, a software platform developed by Autodesk for creating and managing desktop applications and services
  • Check Point, a cybersecurity company specializing in threat prevention and network security solutions, offering a range of products designed to protect enterprises from cyber threats and ensure data integrity
  • EasyEffects, an audio effects processor for PipeWire offering limiting, compression and equalization
  • espanso, a cross-platform text expander
  • Karabiner-Elements, a keyboard customizer for macOS
  • MacType, a font rendering engine for Windows
  • magicplan, a mobile application for creating floor plans and interior designs using augmented reality
  • Microsoft Office for Mac, a suite of productivity applications developed by Microsoft for macOS, including tools for word processing, spreadsheets, and presentations
  • Microsoft Teams, a team collaboration application offering workspace chat and video conferencing, file storage, and integration of proprietary and third-party applications and services
  • MuseScore, a free and open-source music notation and composition application
  • NanaZip, a 7-Zip derivative built for modern Windows
  • Nexthink Infinity, a digital employee experience management platform for monitoring and improving IT performance
  • Sophos Connect Client, a secure VPN client from Sophos that allows remote users to connect to their corporate network, ensuring secure access to resources and data
  • Stonebranch, a cloud-based cybersecurity solution that integrates backup, disaster recovery, and cybersecurity features to protect data and ensure business continuity for organizations
  • Tablecruncher, a data analysis tool that allows users to import, analyze, and visualize spreadsheet data, offering interactive features for better insights and decision-making
  • VNote, a Markdown-based note-taking application written in C++
"},{"location":"home/customers/#databases-and-big-data","title":"Databases and Big Data","text":"
  • ADIOS2, a data management framework designed for high-performance input and output operations
  • Apache Doris, a real-time analytical database for high-concurrency queries
  • Claris FileMaker Server, the server platform hosting FileMaker custom apps and databases, developed by Apple subsidiary Claris
  • ClickHouse, a column-oriented database management system for real-time analytical queries
  • Cribl Stream, a real-time data processing platform that enables organizations to collect, route, and transform observability data, enhancing visibility and insights into their systems
  • DB Browser for SQLite, a visual open-source tool for creating, designing, and editing SQLite database files
  • Manticore Search, a database for search, offering full-text and vector queries
  • Milvus, a cloud-native vector database built for embedding similarity search
  • MongoDB, a general-purpose document database
  • MySQL Connector/C++, a C++ library for connecting and interacting with MySQL databases
  • MySQL NDB Cluster, a distributed database system that provides high availability and scalability for MySQL databases
  • MySQL Shell, an advanced client and code editor for interacting with MySQL servers, supporting SQL, Python, and JavaScript
  • PrestoDB, a distributed SQL query engine designed for large-scale data analytics, originally developed by Facebook
  • ROOT Data Analysis Framework, an open-source data analysis framework widely used in high-energy physics and other fields for data processing and visualization
  • Typesense, an open source typo-tolerant search engine
  • Vearch, a distributed vector database developed at JD.com for similarity search and retrieval-augmented generation
  • WiredTiger, a high-performance storage engine for databases, offering support for compression, concurrency, and checkpointing
"},{"location":"home/customers/#simulation-and-modeling","title":"Simulation and Modeling","text":"
  • Adobe Lagrange, a geometry processing library developed by Adobe for mesh manipulation and analysis
  • Arcturus HoloSuite, a software toolset for capturing, editing, and streaming volumetric video, featuring advanced compression technologies for high-quality 3D content creation
  • azul, a fast and efficient 3D city model viewer designed for visualizing urban environments and spatial data
  • Bambu Studio, a slicing and print management application for Bambu Lab 3D printers
  • Blender, a free and open-source 3D creation suite for modeling, animation, rendering, and more
  • cpplot, a library for creating interactive graphs and charts in C++, which can be viewed in web browsers
  • Foundry Nuke, a powerful node-based digital compositing and visual effects application used in film and television post-production
  • FreeCAD, a free and open-source parametric 3D CAD modeler for product design and engineering
  • GAMS, a high-performance mathematical modeling system for optimization and decision support
  • Keysight WirelessPro, a simulation platform for 5G, 5G-Advanced, and 6G cellular network research
  • Kitware SMTK, a software toolkit for managing simulation models and workflows in scientific and engineering applications
  • M-Star, a computational fluid dynamics software for simulating and analyzing fluid flow
  • MapleSim CAD Toolbox, a software extension for MapleSim that integrates CAD models, allowing users to import, manipulate, and analyze 3D CAD data within the MapleSim environment for enhanced modeling and simulation
  • Microsoft AirSim, a simulator for autonomous vehicles and drones built on Unreal Engine
  • NVIDIA Omniverse, a platform for 3D content creation and collaboration that enables real-time simulations and interactive experiences across various industries
  • OpenSCAD, a script-driven solid 3D CAD modeller
  • OrcaSlicer, an open-source slicer supporting a wide range of consumer 3D printers
  • Pixar Renderman, a photorealistic 3D rendering software developed by Pixar, widely used in the film industry for creating high-quality visual effects and animations
  • PrusaSlicer, the slicing software developed by Prusa Research for its 3D printers
  • ROS - Robot Operating System, a set of software libraries and tools that assist in developing robot applications
  • UBS, a multinational financial services and banking company
"},{"location":"home/customers/#enterprise-and-cloud-applications","title":"Enterprise and Cloud Applications","text":"
  • Acronis Cyber Protect Cloud, an all-in-one data protection solution that combines backup, disaster recovery, and cybersecurity to safeguard business data from threats like ransomware
  • Baereos, a backup solution that provides data protection and recovery options for various environments, including physical and virtual systems
  • Bitdefender Home Scanner, a tool from Bitdefender that scans devices for malware and security threats, providing a safeguard against potential online dangers
  • Cisco MLS++, an implementation of the Messaging Layer Security protocol for end-to-end encrypted group messaging
  • Citrix Provisioning, a solution that streamlines the delivery of virtual desktops and applications by allowing administrators to manage and provision resources efficiently across multiple environments
  • Citrix Virtual Apps and Desktops, a solution from Citrix that delivers virtual apps and desktops
  • CyberArk, a security solution that specializes in privileged access management, enabling organizations to control and monitor access to critical systems and data, thereby enhancing overall cybersecurity posture
  • Deutsche Telekom sysrepo-plugins, a collection of YANG datastore plugins used to manage network devices
  • Egnyte Desktop, a secure cloud storage solution designed for businesses, enabling file sharing, collaboration, and data management across teams while ensuring compliance and data protection
  • Elster, a digital platform developed by German tax authorities for secure and efficient electronic tax filing and management using secunet protect4use
  • Envoy, a cloud-native edge and service proxy that forms the data plane of many service meshes
  • Ethereum Solidity, a high-level, object-oriented programming language designed for implementing smart contracts on the Ethereum platform
  • gVisor, an application kernel that provides a secure sandbox for running untrusted containers
  • IBM Storage Virtualize, the software powering IBM FlashSystem enterprise storage arrays
  • Inciga, a monitoring tool for IT infrastructure, designed to provide insights into system performance and availability through customizable dashboards and alerts
  • Intel Accelerator Management Daemon for VMware ESXi, a management tool designed for monitoring and controlling Intel hardware accelerators within VMware ESXi environments, optimizing performance and resource allocation
  • Juniper Identity Management Service
  • Meta FBOSS, the software stack that controls the network switches in Meta's data centers
  • Microsoft Azure IoT SDK, a collection of tools and libraries to help developers connect, build, and deploy Internet of Things (IoT) solutions on the Azure cloud platform
  • Microsoft Confidential Consortium Framework, a framework for building secure, highly available applications on trusted execution environments
  • Microsoft WinGet, a command-line utility included in the Windows Package Manager
  • Mitsubishi Electric SECS/GEM, the semiconductor equipment communication software running on Mitsubishi Electric C Controller and C intelligent function modules
  • Moxa, a provider of industrial networking, computing, and automation infrastructure
  • plexusAV, a high-performance AV-over-IP transceiver device capable of video encoding and decoding using the IPMX standard
  • Pointr, a platform for indoor positioning and navigation solutions, offering tools and SDKs for developers to create location-based applications
  • secunet protect4use, a secure, passwordless multifactor authentication solution that transforms smartphones into digital keyrings, ensuring high security for online services and digital identities
  • Sencore MRD 7000, a professional multi-channel receiver and decoder supporting UHD and HD stream decoding
  • Siemens SINEC, a family of network management and infrastructure services for industrial networks
  • Toshiba Industrial Servers, the FS20000R series of industrial servers for factory automation and control systems
  • Wazuh, a security platform for threat detection, integrity monitoring and incident response
  • ZeroTier, a software-defined networking service that creates virtual Ethernet networks
"},{"location":"home/debugging/","title":"Debugging","text":"

This page collects the library's built-in debugger integrations and other debugging-related features. They are not covered by any single page elsewhere in the docs, so they are collected here.

"},{"location":"home/debugging/#visual-studio-natvis","title":"Visual Studio (natvis)","text":"

The repository ships nlohmann_json.natvis at its root, a Natvis file that gives json/ordered_json values a friendly, key/value debugger view instead of showing raw internal fields, when debugging with the MSVC debug engine (cppvsdbg) in Visual Studio or VS Code.

The checked-in visualizers cover namespace variants with zero, one, or two ABI tags. Configurations with three or more ABI tags are not covered and may show raw internal fields instead. To generate a Natvis file for such a configuration:

  1. Check out the release tag of the library version you use.
  2. List the ABI tags and the macros that enable them:

    make natvis NATVIS_ARGS=\"--list-tags\"\n
  3. Generate a Natvis file with the tags of your configuration, for example for JSON_DIAGNOSTICS, JSON_DIAGNOSTIC_POSITIONS, and JSON_NO_SIMD:

    make natvis NATVIS_ARGS=\"--abi-tags _diag,_dp,_ns --output my_nlohmann_json.natvis\"\n
  4. Use the generated file instead of nlohmann_json.natvis.

--abi-tags can be repeated for several configurations, and --all generates every combination (about 60 MB for 12 ABI tags, doubling with each further tag). See tools/generate_natvis for all options.

Debug engines that wrap LLDB instead of the MSVC debug engine (for example, codelldb in VS Code) only have partial/experimental Natvis support, and commonly fall back to showing raw internal fields even with the .natvis file present. Switching to cppvsdbg where available, or checking your debug extension's own Natvis support/version, are the next things to try if this happens. There is currently no bundled LLDB-native pretty-printer script in this repository.

"},{"location":"home/debugging/#gdb","title":"GDB","text":"

The repository ships a GDB Python pretty printer under tools/gdb_pretty_printer, with its own usage instructions in that directory's README.md.

"},{"location":"home/debugging/#extended-exception-diagnostics","title":"Extended exception diagnostics","text":"

Defining JSON_DIAGNOSTICS before including the library augments type_error/out_of_range-style exceptions with a JSON Pointer to the offending value, which can help pinpoint where in a large document a runtime error occurred. This only applies to exceptions thrown after a value exists (e.g. during element access); parse errors, which happen before any value exists to point at, are not covered by this mechanism \u2014 see Parsing and exceptions for how parse errors report their own location instead.

"},{"location":"home/debugging/#see-also","title":"See also","text":"
  • JSON_DIAGNOSTICS - extended exception messages with the path of the failing value
  • JSON_DIAGNOSTIC_POSITIONS - record byte positions of values for error messages
  • Exceptions - all exceptions and their error codes
  • exception - base class of all exceptions thrown by the library
"},{"location":"home/design_goals/","title":"Design goals","text":"

There are myriads of JSON libraries out there, and each may even have its reason to exist. Our class had these design goals:

  • Intuitive syntax. In languages such as Python, JSON feels like a first-class data type. We used all the operator magic of modern C++ to achieve the same feeling in your code.

  • Trivial integration. Our whole code consists of a single header file json.hpp. That's it. No library, no subproject, no dependencies, no complex build system. The class is written in vanilla C++11. All in all, everything should require no adjustment of your compiler flags or project settings.

  • Serious testing. Our class is heavily unit-tested and covers 100% of the code, including all exceptional behavior. Furthermore, we checked with Valgrind and the Clang Sanitizers that there are no memory leaks. Google OSS-Fuzz additionally runs fuzz tests against all parsers 24/7, effectively executing billions of tests so far. To maintain high quality, the project is following the OpenSSF Best Practices.

Other aspects were not so important to us:

  • Memory efficiency. Each JSON object has an overhead of one pointer (the maximal size of a union) and one enumeration element (1 byte). The default generalization uses the following C++ data types: std::string for strings, int64_t, uint64_t or double for numbers, std::map for objects, std::vector for arrays, and bool for Booleans. However, you can template the generalized class basic_json to your needs.

  • Speed. There are certainly faster JSON libraries out there. However, if your goal is to speed up your development by adding JSON support with a single header, then this library is the way to go. If you know how to use a std::vector or std::map, you are already set.

See the contribution guidelines for more information.

"},{"location":"home/design_goals/#see-also","title":"See also","text":"
  • basic_json - the main class and all its member functions
  • Macros - reference of all macros
  • Performance - how the library performs and what is not optimized
  • Architecture - how the library is put together
"},{"location":"home/exceptions/","title":"Exceptions","text":""},{"location":"home/exceptions/#overview","title":"Overview","text":""},{"location":"home/exceptions/#base-type","title":"Base type","text":"

All exceptions inherit from class json::exception (which in turn inherits from std::exception). It is used as the base class for all exceptions thrown by the basic_json class. This class can hence be used as \"wildcard\" to catch exceptions.

The map shows the class tree and every exception id documented on this page; click an id to jump to its section.

Exception id map Class tree: std::exception is the base of json::exception, which is the base of the five exception families parse_error (ids 1xx), invalid_iterator (2xx), type_error (3xx), out_of_range (4xx) and other_error (5xx). Each family lists the ids documented on this page, 68 in total; every id links to its section. std::exceptionC++ standard library base json::exceptionid, what() \u00b7 catch-all json::parse_error1xx \u00b7 15 ids \u00b7 adds member byte 101 102 103 104 105 106 107 108 109 110 112 113 114 115 116 json::invalid_iterator2xx \u00b7 14 ids 201 202 203 204 205 206 207 208 209 210 211 212 213 214 json::type_error3xx \u00b7 21 ids 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 json::out_of_range4xx \u00b7 16 ids 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 json::other_error5xx \u00b7 2 ids 501 502 Exception id map Class tree: std::exception is the base of json::exception, which is the base of the five exception families parse_error (ids 1xx), invalid_iterator (2xx), type_error (3xx), out_of_range (4xx) and other_error (5xx). Each family lists the ids documented on this page, 68 in total; every id links to its section. std::exceptionC++ standard library base json::exceptionid, what() \u00b7 catch-all json::parse_error1xx \u00b7 15 ids \u00b7 adds member byte 101 102 103 104 105 106 107 108 109 110 112 113 114 115 116 json::invalid_iterator2xx \u00b7 14 ids 201 202 203 204 205 206 207 208 209 210 211 212 213 214 json::type_error3xx \u00b7 21 ids 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 json::out_of_range4xx \u00b7 16 ids 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 json::other_error5xx \u00b7 2 ids 501 502

The exception classes from std::exception down to the five families, each with the ids it can throw. Every id chip links to the section that describes it.

Which exception an element access throws depends on the function and on the type of the value:

flowchart LR\n    S{{\"which call?\"}} -->|\"at(key)\"| A{{\"j is\"}}\n    A -->|\"object, key missing\"| A1[\"out_of_range.403\"]\n    A -->|\"array or null\"| A2[\"type_error.304\"]\n    S -->|\"at(index)\"| B{{\"j is\"}}\n    B -->|\"array, index >= size()\"| B1[\"out_of_range.401\"]\n    B -->|\"object or null\"| B2[\"type_error.304\"]\n    S -->|\"non-const operator[](key)\"| C{{\"j is\"}}\n    C -->|\"object or null\"| C1[\"no exception: a missing key is inserted as null\"]\n    C -->|\"array\"| C2[\"type_error.305\"]\n    S -->|\"value(key, default)\"| D{{\"j is\"}}\n    D -->|\"object, key missing\"| D1[\"no exception: returns the default\"]\n    D -->|\"object, incompatible value type\"| D2[\"type_error.302\"]\n    D -->|\"array or null\"| D3[\"type_error.306\"]

Exceptions thrown by element access. Start at the call on the left, follow the edge that matches the type of j, and read the exception id (or \"no exception\") in the box at the end.

"},{"location":"home/exceptions/#switch-off-exceptions","title":"Switch off exceptions","text":"

Exceptions are used widely within the library. They can, however, be switched off with either using the compiler flag -fno-exceptions or by defining the symbol JSON_NOEXCEPTION. In this case, exceptions are replaced by abort() calls. You can further control this behavior by defining JSON_THROW_USER (overriding throw), JSON_TRY_USER (overriding try), and JSON_CATCH_USER (overriding catch).

See Working without exceptions for the functions that report errors without throwing.

Note that JSON_THROW_USER should leave the current scope (e.g., by throwing or aborting), as continuing after it may yield undefined behavior.

Example: switch off exceptions and log errors before aborting

The code below switches off exceptions and creates a log entry with a detailed error message in case of errors.

#include <iostream>\n\n#define JSON_TRY_USER if(true)\n#define JSON_CATCH_USER(exception) if(false)\n#define JSON_THROW_USER(exception)                           \\\n    {std::clog << \"Error in \" << __FILE__ << \":\" << __LINE__ \\\n               << \" (function \" << __FUNCTION__ << \") - \"    \\\n               << (exception).what() << std::endl;           \\\n     std::abort();}\n\n#include <nlohmann/json.hpp>\n

Note the explanatory what() string of exceptions is not available for MSVC if exceptions are disabled, see #2824.

See documentation of JSON_TRY_USER, JSON_CATCH_USER and JSON_THROW_USER for more information.

"},{"location":"home/exceptions/#extended-diagnostic-messages","title":"Extended diagnostic messages","text":"

Exceptions in the library are thrown in the local context of the JSON value they are detected. This makes detailed diagnostics messages, and hence debugging, difficult.

Example: standard diagnostic message
#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    json j;\n    j[\"address\"][\"street\"] = \"Fake Street\";\n    j[\"address\"][\"housenumber\"] = \"12\";\n\n    try\n    {\n        int housenumber = j[\"address\"][\"housenumber\"];\n    }\n    catch (const json::exception& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n}\n

Output:

[json.exception.type_error.302] type must be number, but is string\n

This exception can be hard to debug if storing the value \"12\" and accessing it is further apart.

To create better diagnostics messages, each JSON value needs a pointer to its parent value such that a global context (i.e., a path from the root value to the value that led to the exception) can be created. That global context is provided as JSON Pointer.

As this global context comes at the price of storing one additional pointer per JSON value and runtime overhead to maintain the parent relation, extended diagnostics are disabled by default. They can, however, be enabled by defining the preprocessor symbol JSON_DIAGNOSTICS to 1 before including json.hpp.

Example: extended diagnostic message with JSON_DIAGNOSTICS
#include <iostream>\n\n# define JSON_DIAGNOSTICS 1\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    json j;\n    j[\"address\"][\"street\"] = \"Fake Street\";\n    j[\"address\"][\"housenumber\"] = \"12\";\n\n    try\n    {\n        int housenumber = j[\"address\"][\"housenumber\"];\n    }\n    catch (const json::exception& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n}\n

Output:

[json.exception.type_error.302] (/address/housenumber) type must be number, but is string\n

Now the exception message contains a JSON Pointer /address/housenumber that indicates which value has the wrong type.

See documentation of JSON_DIAGNOSTICS for more information, and Debugging for the debugger integrations of the library.

"},{"location":"home/exceptions/#parse-errors","title":"Parse errors","text":"

The library throws this exception when a parse error occurs. Parse errors can occur during the deserialization of JSON text or of one of the binary formats (BJData, BON8, BSON, CBOR, MessagePack, UBJSON), as well as when using JSON Patch.

Exceptions have ids 1xx.

Byte index

Member byte holds the byte index of the last read character in the input file.

For an input with n bytes, 1 is the index of the first character and n+1 is the index of the terminating null byte or the end of file. This also holds true when reading a byte vector (CBOR or MessagePack).

Example: catch a parse_error exception

The following code shows how a parse_error exception can be caught.

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    try\n    {\n        // parsing input with a syntax error\n        json j = json::parse(\"[1,2,3,]\");\n    }\n    catch (const json::parse_error& e)\n    {\n        // output exception information\n        std::cout << \"message: \" << e.what() << '\\n'\n                  << \"exception id: \" << e.id << '\\n'\n                  << \"byte position of error: \" << e.byte << '\\n';\n    }\n}\n

Output:

message: [json.exception.parse_error.101] parse error at line 1, column 8: syntax error while parsing value - unexpected ']'; expected '[', '{', or a literal\nexception id: 101\nbyte position of error: 8\n
"},{"location":"home/exceptions/#jsonexceptionparse_error101","title":"json.exception.parse_error.101","text":"

This error indicates a syntax error while deserializing a JSON text. The error message describes that an unexpected token (character) was encountered, and the member byte indicates the error position.

Example message

Input ended prematurely:

[json.exception.parse_error.101] parse error at 2: unexpected end of input; expected string literal\n

No input:

[json.exception.parse_error.101] parse error at line 1, column 1: attempting to parse an empty input; check that your input string or stream contains the expected JSON\n

Control character was not escaped:

[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: control character U+0009 (HT) must be escaped to \\u0009 or \\\\; last read: '\"<U+0009>'\"\n

String was not closed:

[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: missing closing quote; last read: '\"'\n

Invalid number format:

[json.exception.parse_error.101] parse error at line 1, column 3: syntax error while parsing value - invalid number; expected '+', '-', or digit after exponent; last read: '1E'\n

\\u was not be followed by four hex digits:

[json.exception.parse_error.101] parse error at line 1, column 6: syntax error while parsing value - invalid string: '\\u' must be followed by 4 hex digits; last read: '\"\\u01\"'\n

Invalid UTF-8 surrogate pair:

[json.exception.parse_error.101] parse error at line 1, column 13: syntax error while parsing value - invalid string: surrogate U+DC00..U+DFFF must follow U+D800..U+DBFF; last read: '\"\\uD7FF\\uDC00'\"\n

Invalid UTF-8 byte:

[json.exception.parse_error.101] parse error at line 3, column 24: syntax error while parsing value - invalid string: ill-formed UTF-8 byte; last read: '\"vous \\352t'\n

Tip

  • Make sure the input is correctly read. Try to write the input to standard output to check if, for instance, the input file was successfully opened.
  • Paste the input to a JSON validator like https://jsonlint.com or a tool like jq.
Parsing a file fails at line 1, column 1 (unexpected end of input)

The messages attempting to parse an empty input (since version 3.11.3) and unexpected end of input (also the message of earlier versions for an empty input) at the very start of the input mean that the parser did not see a single character. The library only reads from the stream it is given: it does not open files and cannot tell a missing file from an empty one. The usual causes are:

  • The file was not opened. A relative path is resolved against the working directory of the running program, not against the source file or the project. IDEs and build tools often start the program in a build directory (for example build/ or cmake-build-debug/), so \"example.json\" may need to be \"../example.json\". Use an absolute path to rule this out.
  • The file is empty, or a previous run truncated it (for example when it was opened for writing).
  • The stream was already read. A stream whose content has been consumed (by printing it with std::cout << file.rdbuf(), or by an earlier accept/parse/>>) is at its end. Parse it once, or rewind it with seekg(0) after clearing the state with clear().

Check the stream before parsing it:

std::ifstream f(\"example.json\");\nif (!f.is_open())\n{\n    std::cerr << \"cannot open example.json\\n\";\n    return 1;\n}\njson data = json::parse(f);\n
"},{"location":"home/exceptions/#jsonexceptionparse_error102","title":"json.exception.parse_error.102","text":"

JSON uses the \\uxxxx format to describe Unicode characters. Code points above 0xFFFF are split into two \\uxxxx entries (\"surrogate pairs\"). This error indicates that the surrogate pair is incomplete or contains an invalid code point.

Example message

[json.exception.parse_error.102] parse error at 14: missing or wrong low surrogate\n

Note

This exception is not used any more. Instead json.exception.parse_error.101 with a more detailed description is used.

"},{"location":"home/exceptions/#jsonexceptionparse_error103","title":"json.exception.parse_error.103","text":"

Unicode supports code points up to 0x10FFFF. Code points above 0x10FFFF are invalid.

Example message

[json.exception.parse_error.103] parse error: code points above 0x10FFFF are invalid\n

Note

This exception is not used any more. Instead json.exception.parse_error.101 with a more detailed description is used.

"},{"location":"home/exceptions/#jsonexceptionparse_error104","title":"json.exception.parse_error.104","text":"

RFC 6902 requires a JSON Patch document to be a JSON document that represents an array of objects.

Example message

[json.exception.parse_error.104] parse error: JSON patch must be an array of objects\n
"},{"location":"home/exceptions/#jsonexceptionparse_error105","title":"json.exception.parse_error.105","text":"

An operation of a JSON Patch document must contain exactly one \"op\" member, whose value indicates the operation to perform. Its value must be one of \"add\", \"remove\", \"replace\", \"move\", \"copy\", or \"test\"; other values are errors.

Example message

[json.exception.parse_error.105] parse error: operation 'add' must have member 'value'\n
[json.exception.parse_error.105] parse error: operation 'copy' must have string member 'from'\n
[json.exception.parse_error.105] parse error: operation value 'foo' is invalid\n

"},{"location":"home/exceptions/#jsonexceptionparse_error106","title":"json.exception.parse_error.106","text":"

An array index in a JSON Pointer (RFC 6901) may be 0 or any number without a leading 0.

Example message

[json.exception.parse_error.106] parse error: array index '01' must not begin with '0'\n
"},{"location":"home/exceptions/#jsonexceptionparse_error107","title":"json.exception.parse_error.107","text":"

A JSON Pointer must be a Unicode string containing a sequence of zero or more reference tokens, each prefixed by a / character.

Example message

[json.exception.parse_error.107] parse error at byte 1: JSON pointer must be empty or begin with '/' - was: 'foo'\n
"},{"location":"home/exceptions/#jsonexceptionparse_error108","title":"json.exception.parse_error.108","text":"

In a JSON Pointer, only ~0 and ~1 are valid escape sequences.

Example message

[json.exception.parse_error.108] parse error: escape character '~' must be followed with '0' or '1'\n
"},{"location":"home/exceptions/#jsonexceptionparse_error109","title":"json.exception.parse_error.109","text":"

A JSON Pointer array index must be a number. This exception is thrown for an array index that does not begin with a digit, except for - and the empty reference token, which throw out_of_range.404 where they cannot be resolved.

Example messages

[json.exception.parse_error.109] parse error: array index 'one' is not a number\n
[json.exception.parse_error.109] parse error: array index '+1' is not a number\n

Note

Before version 3.13.0 unreleased, a one-character array index that is not a digit (e.g., x) threw out_of_range.404 instead.

"},{"location":"home/exceptions/#jsonexceptionparse_error110","title":"json.exception.parse_error.110","text":"

When parsing a binary format, the byte vector ends before the complete value has been read, or (with strict = true) further bytes follow the value.

Example messages

[json.exception.parse_error.110] parse error at byte 5: syntax error while parsing CBOR string: unexpected end of input\n
[json.exception.parse_error.110] parse error at byte 2: syntax error while parsing UBJSON value: expected end of input; last byte: 0x5A\n
[json.exception.parse_error.110] parse error at byte 8: syntax error while parsing BSON number: unexpected end of input\n

"},{"location":"home/exceptions/#jsonexceptionparse_error112","title":"json.exception.parse_error.112","text":"

An unexpected byte was read in a binary format or length information is invalid (BSON). In BON8, this exception is also thrown for a key that is not a string and for ill-formed UTF-8.

Example messages

[json.exception.parse_error.112] parse error at byte 1: syntax error while parsing CBOR value: invalid byte: 0x1C\n
[json.exception.parse_error.112] parse error at byte 1: syntax error while parsing MessagePack value: invalid byte: 0xC1\n
[json.exception.parse_error.112] parse error at byte 4: syntax error while parsing BJData size: expected '#' after type information; last byte: 0x02\n
[json.exception.parse_error.112] parse error at byte 4: syntax error while parsing UBJSON size: expected '#' after type information; last byte: 0x02\n
[json.exception.parse_error.112] parse error at byte 10: syntax error while parsing BSON string: string length must be at least 1, is -2147483648\n
[json.exception.parse_error.112] parse error at byte 15: syntax error while parsing BSON binary: byte array length cannot be negative, is -1\n
[json.exception.parse_error.112] parse error at byte 5: syntax error while parsing BSON document: document size 6 does not match the number of bytes read (5)\n
[json.exception.parse_error.112] parse error at byte 2: syntax error while parsing BON8 string: invalid UTF-8 byte: 0x80\n

"},{"location":"home/exceptions/#jsonexceptionparse_error113","title":"json.exception.parse_error.113","text":"

A string could not be read from a binary format: either a value that is not a string was read where one was required (for instance as a map key), the string's length specification is invalid, or the string's bytes are not valid UTF-8 and the error_handler parameter of the corresponding from_* function is set to strict. By default (error_handler_t::keep), the bytes of a string are not checked for valid UTF-8 on read. This applies to the from_* functions that have an error_handler parameter; from_bon8 does not have one. See the ill-formed UTF-8 notes on the individual binary format pages for how such a string is handled depending on error_handler. from_bon8() never throws this exception: BON8 non-string keys and ill-formed UTF-8 are reported as parse_error.112.

CBOR and MessagePack allow map keys of any type, but JSON object keys are always strings. Maps with keys of any other type (for instance integers or null) are therefore not supported; see the notes on CBOR and MessagePack.

Example messages

[json.exception.parse_error.113] parse error at byte 2: syntax error while parsing CBOR object key: only string keys are supported, but found an unsigned integer; last byte: 0x01\n
[json.exception.parse_error.113] parse error at byte 2: syntax error while parsing MessagePack object key: only string keys are supported, but found nil; last byte: 0xC0\n
[json.exception.parse_error.113] parse error at byte 2: syntax error while parsing CBOR string: expected length specification (0x60-0x7B) or indefinite string type (0x7F); last byte: 0x7C\n
[json.exception.parse_error.113] parse error at byte 2: syntax error while parsing UBJSON char: byte after 'C' must be in range 0x00..0x7F; last byte: 0x82\n
[json.exception.parse_error.113] parse error at byte 3: syntax error while parsing BJData string: string length must not be negative\n
[json.exception.parse_error.113] parse error at byte 3: syntax error while parsing CBOR string: invalid string: ill-formed UTF-8 byte\n

"},{"location":"home/exceptions/#jsonexceptionparse_error114","title":"json.exception.parse_error.114","text":"

The parsing of the corresponding BSON record type is not implemented (yet).

Example message

[json.exception.parse_error.114] parse error at byte 5: Unsupported BSON record type 0xFF\n
"},{"location":"home/exceptions/#jsonexceptionparse_error115","title":"json.exception.parse_error.115","text":"

A UBJSON or BJData high-precision number could not be parsed.

Example messages

[json.exception.parse_error.115] parse error at byte 5: syntax error while parsing UBJSON high-precision number: invalid number text: 1A\n
[json.exception.parse_error.115] parse error at byte 5: syntax error while parsing BJData high-precision number: invalid number text: 1A\n

"},{"location":"home/exceptions/#jsonexceptionparse_error116","title":"json.exception.parse_error.116","text":"

basic_json_document::load() rejected an image: either the bytes are not one save() could have written (too short, an unknown magic number or format version, or sizes that do not fit the buffer), or they are, but fail the requested image_check.

Example message

[json.exception.parse_error.116] parse error: invalid json_document image: the check failed\n

Note

This exception was added in version 3.13.0 unreleased, together with images.

"},{"location":"home/exceptions/#iterator-errors","title":"Iterator errors","text":"

This exception is thrown if iterators passed to a library function do not match the expected semantics.

Exceptions have ids 2xx.

Example: catch an invalid_iterator exception

The following code shows how an invalid_iterator exception can be caught.

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    try\n    {\n        // calling iterator::key() on non-object iterator\n        json j = \"string\";\n        json::iterator it = j.begin();\n        auto k = it.key();\n    }\n    catch (const json::invalid_iterator& e)\n    {\n        // output exception information\n        std::cout << \"message: \" << e.what() << '\\n'\n                  << \"exception id: \" << e.id << '\\n';\n    }\n}\n

Output:

message: [json.exception.invalid_iterator.207] cannot use key() for non-object iterators\nexception id: 207\n
"},{"location":"home/exceptions/#jsonexceptioninvalid_iterator201","title":"json.exception.invalid_iterator.201","text":"

The iterators passed to constructor basic_json(InputIT first, InputIT last) are not compatible, meaning they do not belong to the same container. Therefore, the range (first, last) is invalid.

Example message

[json.exception.invalid_iterator.201] iterators are not compatible\n
"},{"location":"home/exceptions/#jsonexceptioninvalid_iterator202","title":"json.exception.invalid_iterator.202","text":"

In the erase or insert function, the passed iterator pos does not belong to the JSON value for which the function was called. It hence does not define a valid position for the deletion/insertion.

Example messages

[json.exception.invalid_iterator.202] iterator does not fit current value\n
[json.exception.invalid_iterator.202] iterators first and last must point to objects\n

"},{"location":"home/exceptions/#jsonexceptioninvalid_iterator203","title":"json.exception.invalid_iterator.203","text":"

Either iterator passed to function erase(IteratorType first, IteratorType last) does not belong to the JSON value from which values shall be erased. It hence does not define a valid range to delete values from.

Example message

[json.exception.invalid_iterator.203] iterators do not fit current value\n
"},{"location":"home/exceptions/#jsonexceptioninvalid_iterator204","title":"json.exception.invalid_iterator.204","text":"

When an iterator range for a primitive type (number, boolean, or string) is passed to a constructor or an erase function, this range has to be exactly (begin(), end()), because this is the only way the single stored value is expressed. All other ranges are invalid.

Example message

[json.exception.invalid_iterator.204] iterators out of range\n
"},{"location":"home/exceptions/#jsonexceptioninvalid_iterator205","title":"json.exception.invalid_iterator.205","text":"

When an iterator for a primitive type (number, boolean, or string) is passed to an erase function, the iterator has to be the begin() iterator, because it is the only way to address the stored value. All other iterators are invalid.

Example message

[json.exception.invalid_iterator.205] iterator out of range\n
"},{"location":"home/exceptions/#jsonexceptioninvalid_iterator206","title":"json.exception.invalid_iterator.206","text":"

The iterators passed to constructor basic_json(InputIT first, InputIT last) belong to a JSON null value and hence to not define a valid range.

Example message

[json.exception.invalid_iterator.206] cannot construct with iterators from null\n
"},{"location":"home/exceptions/#jsonexceptioninvalid_iterator207","title":"json.exception.invalid_iterator.207","text":"

The key() member function can only be used on iterators belonging to a JSON object, because other types do not have a concept of a key.

Example message

[json.exception.invalid_iterator.207] cannot use key() for non-object iterators\n
"},{"location":"home/exceptions/#jsonexceptioninvalid_iterator208","title":"json.exception.invalid_iterator.208","text":"

The operator[] to specify a concrete offset cannot be used on iterators belonging to a JSON object, because JSON objects are unordered.

Example message

[json.exception.invalid_iterator.208] cannot use operator[] for object iterators\n
"},{"location":"home/exceptions/#jsonexceptioninvalid_iterator209","title":"json.exception.invalid_iterator.209","text":"

The offset operators (+, -, +=, -=) cannot be used on iterators belonging to a JSON object, because JSON objects are unordered.

Example message

[json.exception.invalid_iterator.209] cannot use offsets with object iterators\n
"},{"location":"home/exceptions/#jsonexceptioninvalid_iterator210","title":"json.exception.invalid_iterator.210","text":"

The iterator range passed to the insert function is not compatible, meaning they do not belong to the same container. Therefore, the range (first, last) is invalid.

Example message

[json.exception.invalid_iterator.210] iterators do not fit\n
"},{"location":"home/exceptions/#jsonexceptioninvalid_iterator211","title":"json.exception.invalid_iterator.211","text":"

The iterator range passed to the insert function must not be a subrange of the container to insert to.

Example message

[json.exception.invalid_iterator.211] passed iterators may not belong to container\n
"},{"location":"home/exceptions/#jsonexceptioninvalid_iterator212","title":"json.exception.invalid_iterator.212","text":"

When two iterators are compared, they must belong to the same container.

Example message

[json.exception.invalid_iterator.212] cannot compare iterators of different containers\n
"},{"location":"home/exceptions/#jsonexceptioninvalid_iterator213","title":"json.exception.invalid_iterator.213","text":"

The order of object iterators cannot be compared, because JSON objects are unordered.

Example message

[json.exception.invalid_iterator.213] cannot compare order of object iterators\n
"},{"location":"home/exceptions/#jsonexceptioninvalid_iterator214","title":"json.exception.invalid_iterator.214","text":"

Cannot retrieve value from iterator: The iterator either refers to a null value, or it refers to a primitive type (number, boolean, or string), but does not match the iterator returned by begin().

Example message

[json.exception.invalid_iterator.214] cannot get value\n
"},{"location":"home/exceptions/#type-errors","title":"Type errors","text":"

This exception is thrown in case of a type error; that is, a library function is executed on a JSON value whose type does not match the expected semantics.

Exceptions have ids 3xx.

Example: catch a type_error exception

The following code shows how a type_error exception can be caught.

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    try\n    {\n        // calling push_back() on a string value\n        json j = \"string\";\n        j.push_back(\"another string\");\n    }\n    catch (const json::type_error& e)\n    {\n        // output exception information\n        std::cout << \"message: \" << e.what() << '\\n'\n                  << \"exception id: \" << e.id << '\\n';\n    }\n}\n

Output:

message: [json.exception.type_error.308] cannot use push_back() with string\nexception id: 308\n
"},{"location":"home/exceptions/#jsonexceptiontype_error301","title":"json.exception.type_error.301","text":"

To create an object from an initializer list, the initializer list must consist only of a list of pairs whose first element is a string. When this constraint is violated, an array is created instead.

Example message

[json.exception.type_error.301] cannot create object from initializer list\n
"},{"location":"home/exceptions/#jsonexceptiontype_error302","title":"json.exception.type_error.302","text":"

During implicit or explicit value conversion, the JSON type must be compatible with the target type. For instance, a JSON string can only be converted into string types, but not into numbers or boolean types.

Example messages

[json.exception.type_error.302] type must be object, but is null\n
[json.exception.type_error.302] type must be string, but is object\n

This exception is also thrown with JSON_USE_OBJECTS_FOR_ENUM_KEYED_MAPS if a key of a map with enum keys is not converted to a string, for instance, because the enum is stored as an integer.

"},{"location":"home/exceptions/#jsonexceptiontype_error303","title":"json.exception.type_error.303","text":"

To retrieve a reference to a value stored in a basic_json object with get_ref, the type of the reference must match the value type. For instance, for a JSON array, the ReferenceType must be array_t &.

Example messages

[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is object\n
[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is number\"\n

"},{"location":"home/exceptions/#jsonexceptiontype_error304","title":"json.exception.type_error.304","text":"

The at() member functions can only be executed for certain JSON types.

Example messages

[json.exception.type_error.304] cannot use at() with string\n
[json.exception.type_error.304] cannot use at() with number\n

"},{"location":"home/exceptions/#jsonexceptiontype_error305","title":"json.exception.type_error.305","text":"

The operator[] member functions can only be executed for certain JSON types.

Example messages

[json.exception.type_error.305] cannot use operator[] with a string argument with array\n
[json.exception.type_error.305] cannot use operator[] with a numeric argument with object\n

"},{"location":"home/exceptions/#jsonexceptiontype_error306","title":"json.exception.type_error.306","text":"

The value() member functions can only be executed for certain JSON types.

Example message

[json.exception.type_error.306] cannot use value() with number\n
"},{"location":"home/exceptions/#jsonexceptiontype_error307","title":"json.exception.type_error.307","text":"

The erase() member functions can only be executed for certain JSON types.

Example message

[json.exception.type_error.307] cannot use erase() with string\n
"},{"location":"home/exceptions/#jsonexceptiontype_error308","title":"json.exception.type_error.308","text":"

The push_back() and operator+= member functions can only be executed for certain JSON types.

Example message

[json.exception.type_error.308] cannot use push_back() with string\n
"},{"location":"home/exceptions/#jsonexceptiontype_error309","title":"json.exception.type_error.309","text":"

The insert() member functions can only be executed for certain JSON types.

Example messages

[json.exception.type_error.309] cannot use insert() with array\n
[json.exception.type_error.309] cannot use insert() with number\n

"},{"location":"home/exceptions/#jsonexceptiontype_error310","title":"json.exception.type_error.310","text":"

The swap() member functions can only be executed for certain JSON types.

Example message

[json.exception.type_error.310] cannot use swap() with number\n
"},{"location":"home/exceptions/#jsonexceptiontype_error311","title":"json.exception.type_error.311","text":"

The emplace() and emplace_back() member functions can only be executed for certain JSON types.

Example messages

[json.exception.type_error.311] cannot use emplace() with number\n
[json.exception.type_error.311] cannot use emplace_back() with number\n

"},{"location":"home/exceptions/#jsonexceptiontype_error312","title":"json.exception.type_error.312","text":"

The update() member functions can only be executed for certain JSON types.

Example message

[json.exception.type_error.312] cannot use update() with array\n
"},{"location":"home/exceptions/#jsonexceptiontype_error313","title":"json.exception.type_error.313","text":"

The unflatten() function converts an object whose keys are JSON Pointers back into an arbitrary nested JSON value. The JSON Pointers must not overlap, because then the resulting value would not be well-defined.

Example message

[json.exception.type_error.313] invalid value to unflatten\n
"},{"location":"home/exceptions/#jsonexceptiontype_error314","title":"json.exception.type_error.314","text":"

The unflatten() function only works for an object whose keys are JSON Pointers.

Example message

Calling unflatten() on an array [1,2,3]:

[json.exception.type_error.314] only objects can be unflattened\n
"},{"location":"home/exceptions/#jsonexceptiontype_error315","title":"json.exception.type_error.315","text":"

The unflatten() function only works for an object whose keys are JSON Pointers and whose values are primitive.

Example message

Calling unflatten() on an object {\"/1\", [1,2,3]}:

[json.exception.type_error.315] values in object must be primitive\n
"},{"location":"home/exceptions/#jsonexceptiontype_error316","title":"json.exception.type_error.316","text":"

The dump() function only works with UTF-8 encoded strings; that is, if you assign a std::string to a JSON value, make sure it is UTF-8 encoded. See the FAQ entry on serializing untrusted or invalid UTF-8 for background and the recommended fix.

The binary writers to_cbor(), to_ubjson(), to_bjdata(), and to_bson() throw this exception as well for a string value or object key that is not valid UTF-8 if their error_handler is strict (the default if JSON_STRICT_BINARY_UTF8 is enabled). So does to_msgpack() if error_handler_t::strict is passed. to_bon8() always throws this exception for such a string or key, regardless of JSON_STRICT_BINARY_UTF8, because the end of a BON8 string is determined from its UTF-8 encoding.

Example message

Calling dump() on a JSON value containing an ISO 8859-1 encoded string:

[json.exception.type_error.316] invalid UTF-8 byte at index 15: 0x6F\n

Tip

  • Store the source file with UTF-8 encoding.
  • Pass an error handler as last parameter to the dump() function to avoid this exception:
    • json::error_handler_t::replace will replace invalid bytes sequences with U+FFFD
    • json::error_handler_t::ignore will silently ignore invalid byte sequences
    • json::error_handler_t::keep will copy invalid byte sequences to the output unchanged
"},{"location":"home/exceptions/#jsonexceptiontype_error317","title":"json.exception.type_error.317","text":"

The dynamic type of the object cannot be represented in the requested serialization format (e.g., a raw true or null JSON object cannot be serialized to BSON)

Example messages

Serializing null to BSON:

[json.exception.type_error.317] to serialize to BSON, top-level type must be object, but is null\n
Serializing [1,2,3] to BSON:
[json.exception.type_error.317] to serialize to BSON, top-level type must be object, but is array\n

Tip

Encapsulate the JSON value in an object. That is, instead of serializing true, serialize {\"value\": true}

"},{"location":"home/exceptions/#jsonexceptiontype_error318","title":"json.exception.type_error.318","text":"

With JSON_USE_OBJECTS_FOR_ENUM_KEYED_MAPS, a map with enum keys is stored as an object. This exception is thrown if two of its keys are converted to the same string, so one of the entries would be lost. This happens, for instance, if NLOHMANN_JSON_SERIALIZE_ENUM does not list an enumerator and it is therefore converted like the first listed one.

Example message

[json.exception.type_error.318] duplicate object key 'red'\n
"},{"location":"home/exceptions/#jsonexceptiontype_error319","title":"json.exception.type_error.319","text":"

basic_json_document::set, basic_json_document::push_back, and basic_json_document::insert can store any basic_json value except a binary one: a json_document has no representation for binary values, which only ever arise from parsing a binary format or from an explicit json::binary value, not from JSON text.

Example message

[json.exception.type_error.319] cannot store a binary value in a json_document\n

Note

This exception was added in version 3.13.0 unreleased, together with editable json_documents.

"},{"location":"home/exceptions/#jsonexceptiontype_error320","title":"json.exception.type_error.320","text":"

basic_json_document::save() cannot write an image of a discarded document.

Example messages

[json.exception.type_error.320] cannot save a discarded json_document\n

Note

This exception was added in version 3.13.0 unreleased, together with images.

"},{"location":"home/exceptions/#jsonexceptiontype_error321","title":"json.exception.type_error.321","text":"

A discarded value (one created by parse() with a callback that returns false for the value, or by default-constructing a basic_json with value_t::discarded) was passed to a binary serialization function, either directly or nested in an array or object. There is no way to represent a discarded value in CBOR, MessagePack, UBJSON, BJData, BSON, or BON8.

Example message

Serializing [1, 2] to CBOR, where the second element was discarded by a parser callback:

[json.exception.type_error.321] cannot serialize discarded value to CBOR\n

"},{"location":"home/exceptions/#out-of-range","title":"Out of range","text":"

This exception is thrown in case a library function is called on an input parameter that exceeds the expected range, for instance, in the case of array indices or nonexisting object keys.

Exceptions have ids 4xx.

Example: catch an out_of_range exception

The following code shows how an out_of_range exception can be caught.

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    try\n    {\n        // calling at() for an invalid index\n        json j = {1, 2, 3, 4};\n        j.at(4) = 10;\n    }\n    catch (const json::out_of_range& e)\n    {\n        // output exception information\n        std::cout << \"message: \" << e.what() << '\\n'\n                  << \"exception id: \" << e.id << '\\n';\n    }\n}\n

Output:

message: [json.exception.out_of_range.401] array index 4 is out of range\nexception id: 401\n
"},{"location":"home/exceptions/#jsonexceptionout_of_range401","title":"json.exception.out_of_range.401","text":"

The provided array index i is larger than size-1.

Example message

[json.exception.out_of_range.401] array index 3 is out of range\n
"},{"location":"home/exceptions/#jsonexceptionout_of_range402","title":"json.exception.out_of_range.402","text":"

The special array index - in a JSON Pointer never describes a valid element of the array, but the index past the end. That is, it can only be used to add elements at this position, but not to read it.

Example message

[json.exception.out_of_range.402] array index '-' (3) is out of range\n
"},{"location":"home/exceptions/#jsonexceptionout_of_range403","title":"json.exception.out_of_range.403","text":"

The provided key was not found in the JSON object.

Example message

[json.exception.out_of_range.403] key 'foo' not found\n
"},{"location":"home/exceptions/#jsonexceptionout_of_range404","title":"json.exception.out_of_range.404","text":"

A reference token in a JSON Pointer could not be resolved, for instance an array index that begins with a digit but contains other characters (e.g., 1a), or - where it cannot be used.

Example message

[json.exception.out_of_range.404] unresolved reference token 'foo'\n
"},{"location":"home/exceptions/#jsonexceptionout_of_range405","title":"json.exception.out_of_range.405","text":"

The JSON Patch operations 'remove' and 'move' cannot be applied to the root element of the JSON value. The exception is also thrown when the parent or a reference token of an empty JSON Pointer is requested, for instance by back or pop_back.

Example message

[json.exception.out_of_range.405] JSON pointer has no parent\n
"},{"location":"home/exceptions/#jsonexceptionout_of_range406","title":"json.exception.out_of_range.406","text":"

A parsed number could not be stored without changing it to NaN or INF. For the binary formats, this happens when a finite floating-point number does not fit into number_float_t, for example a double-precision number when number_float_t is float.

Example messages

[json.exception.out_of_range.406] number overflow parsing '10E1000'\n
[json.exception.out_of_range.406] syntax error while parsing CBOR value: number overflow\n

"},{"location":"home/exceptions/#jsonexceptionout_of_range407","title":"json.exception.out_of_range.407","text":"

An integer number cannot be represented by the binary format it is serialized to:

  • BON8 only stores integers that fit into int64, so to_bon8 throws for unsigned integers greater than 9223372036854775807 and, with a number type wider than 64 bits, for any integer outside the int64 range.
  • CBOR, MessagePack, and BSON store integers in at most 64 bits. With the default number types, every integer fits, but a number_integer_t or number_unsigned_t wider than 64 bits (e.g., __int128) can hold values outside the range of the format: [-2^64, 2^64-1] for CBOR, [-2^63, 2^64-1] for MessagePack, and the range of int64 (signed integers) or uint64 (unsigned integers) for BSON.

UBJSON and BJData never throw this exception, because they serialize integers beyond 64 bits as high-precision numbers.

Former occurrences

The UBJSON and BSON writers used to throw this exception as well:

  • Since version 3.9.0, integer numbers beyond int64 are serialized as high-precision UBJSON numbers.
  • Since version 3.12.0, integer numbers beyond int64 are serialized as uint64 BSON numbers.

Before version 3.13.0 unreleased, CBOR, MessagePack, and BSON silently truncated integers wider than 64 bits, and BJData truncated unsigned integers wider than 64 bits that were elements of ND-arrays with \"_ArrayType_\": \"uint64\".

Example messages

[json.exception.out_of_range.407] integer number 18446744073709551615 cannot be represented by BON8 as it does not fit int64\n
[json.exception.out_of_range.407] integer number 1267650600228229401496703205376 cannot be represented by CBOR as it does not fit [-2^64, 2^64-1]\n

"},{"location":"home/exceptions/#jsonexceptionout_of_range408","title":"json.exception.out_of_range.408","text":"

The size of an array or object in a binary format exceeds the maximal capacity: the size following # for UBJSON/BJData, or the encoded length for CBOR.

The exception is also thrown for a UBJSON array of a type that is encoded by its marker alone (Z, T or F) whose declared count exceeds 1,048,576 (1 << 20). Such an array has no payload, so its count alone decides how much memory is allocated, and a handful of bytes would otherwise describe billions of values. to_ubjson writes longer arrays of these types without the $ type annotation (the # count and one marker per element are kept), so any value it produces can still be read back.

Example messages

[json.exception.out_of_range.408] excessive array size: 8658170730974374167\n
[json.exception.out_of_range.408] syntax error while parsing CBOR size: excessive array size\n
[json.exception.out_of_range.408] syntax error while parsing CBOR size: excessive map size\n
[json.exception.out_of_range.408] syntax error while parsing UBJSON size: excessive array size\n

"},{"location":"home/exceptions/#jsonexceptionout_of_range409","title":"json.exception.out_of_range.409","text":"

Key identifiers to be serialized to BSON cannot contain code point U+0000, since the key is stored as zero-terminated c-string.

Example message

[json.exception.out_of_range.409] BSON key cannot contain code point U+0000 (at byte 2)\n
"},{"location":"home/exceptions/#jsonexceptionout_of_range410","title":"json.exception.out_of_range.410","text":"

This exception is thrown when an undefined value is used with NLOHMANN_JSON_SERIALIZE_ENUM_STRICT, or when an array index in a JSON pointer exceeds the range of size_type (e.g., on 32-bit platforms).

Example message

[json.exception.out_of_range.410] enum value out of range\n[json.exception.out_of_range.410] array index 18446744073709551615 exceeds size_type\n

The second message is thrown, for instance, by json::parse(\"[1, 2]\").at(\"/18446744073709551615\"_json_pointer) on a 64-bit platform, where size_type is std::size_t and this index is SIZE_MAX. An index that does not fit into 64 bits (such as 18446744073709551616) is not reported as 410 but as out_of_range.404.

"},{"location":"home/exceptions/#jsonexceptionout_of_range411","title":"json.exception.out_of_range.411","text":"

A JSON Patch add operation cannot be applied because the target location's parent is neither an object nor an array. Per RFC 6902, an add target must reference a member of an existing object or an element of an existing array; a primitive value (string, number, boolean, etc.) cannot receive a new member or element.

Example message

[json.exception.out_of_range.411] cannot add value: the JSON Patch 'add' target's parent is of type string, but must be an object or array\n

Note

This exception was added in version 3.13.0 unreleased. Before that, this situation hit an internal assertion (aborting the program in debug builds) or was silently ignored when assertions were disabled.

A null parent is rejected as well. Before version 3.13.0 unreleased, an add into a null parent silently converted it to an object (e.g., add at /foo/bar turned {\"foo\":null} into {\"foo\":{\"bar\":1}}).

"},{"location":"home/exceptions/#jsonexceptionout_of_range412","title":"json.exception.out_of_range.412","text":"

BSON stores the length of documents, arrays, strings, and binary values in a signed 32-bit integer, and MessagePack stores the length of strings, binary values, arrays, and objects in at most an unsigned 32-bit integer. This exception is thrown when a value is too large to be described by such a length field.

Example messages

[json.exception.out_of_range.412] BSON length 2147483661 exceeds maximum of 2147483647\n
[json.exception.out_of_range.412] MessagePack length 4294967296 exceeds maximum of 4294967295\n

Note

This exception was added in version 3.13.0 unreleased. Before that, the BSON length was silently truncated, and to_bson produced documents with negative length prefixes that from_bson rejected; to_msgpack wrote such a value without any length, producing output that could not be read back.

"},{"location":"home/exceptions/#jsonexceptionout_of_range413","title":"json.exception.out_of_range.413","text":"

A JSON Patch remove operation cannot be applied because the target location's parent is neither an object nor an array. Per RFC 6902, a remove target must reference a member of an existing object or an element of an existing array; a primitive value (string, number, boolean, etc.) or null has no members or elements to remove.

Example message

[json.exception.out_of_range.413] cannot remove value: the JSON Patch 'remove' target's parent is of type number, but must be an object or array\n

Note

This exception was added in version 3.13.0 unreleased. Before that, this situation was silently ignored (the remove operation had no effect).

"},{"location":"home/exceptions/#jsonexceptionout_of_range414","title":"json.exception.out_of_range.414","text":"

A JSON Patch move operation's \"from\" location is a proper prefix of its \"path\" location. Per RFC 6902 (section 4.4), a location cannot be moved into one of its own children.

Example message

[json.exception.out_of_range.414] cannot move value: 'from' path '/0' is a proper prefix of 'path' '/0/0'\n

Note

This exception was added in version 3.13.0 unreleased. Before that, this situation could succeed with a corrupted result: for an array target, removing the \"from\" element before the \"add\" step shifted subsequent indices, so \"path\" silently re-resolved to a different element than intended.

"},{"location":"home/exceptions/#jsonexceptionout_of_range415","title":"json.exception.out_of_range.415","text":"

MessagePack's ext type and BSON's binary subtype are each stored in a single byte. This exception is thrown when serializing a byte_container_with_subtype whose subtype exceeds 255, the largest value the library can store in that byte.

Example messages

[json.exception.out_of_range.415] subtype 70000 is too large for the MessagePack ext type (max 255)\n
[json.exception.out_of_range.415] subtype 70000 is too large for the BSON binary subtype (max 255)\n

Note

This exception was added in version 3.13.0 unreleased. Before that, subtypes above 255 were silently truncated modulo 256 instead of raising an error.

"},{"location":"home/exceptions/#jsonexceptionout_of_range416","title":"json.exception.out_of_range.416","text":"

basic_json_document::parse() and the other parsing functions of basic_json_document index a value's position in the source text in 32 bits, so they do not support an input of 4294967280 bytes (4 GiB minus 16 bytes) or more. The same 32-bit limit applies to an editable document's own storage: set and push_back throw this exception once the strings and number tokens written by edits reach 4 GiB in total, or once more than 4294967295 arrays/objects have had an element set or appended to them. The same limit applies to an image: save() throws it if the node count, the text, or the decoded strings it would write would individually reach 4 GiB.

Example messages

[json.exception.out_of_range.416] input of 4294967280 bytes or more is not supported by json_document\n
[json.exception.out_of_range.416] edits of 4 GiB or more are not supported by json_document\n
[json.exception.out_of_range.416] images of 4 GiB or more are not supported by json_document\n

Note

This exception was added in version 3.13.0 unreleased, together with <nlohmann/json_view.hpp>. basic_json::parse() has no such limit.

"},{"location":"home/exceptions/#further-exceptions","title":"Further exceptions","text":"

This exception is thrown in case of errors that cannot be classified with the other exception types.

Exceptions have ids 5xx.

Example: catch an other_error exception

The following code shows how an other_error exception can be caught.

#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\nusing namespace nlohmann::literals;\n\nint main()\n{\n    try\n    {\n        // executing a failing JSON Patch operation\n        json value = R\"({\n            \"best_biscuit\": {\n                \"name\": \"Oreo\"\n            }\n        })\"_json;\n        json patch = R\"([{\n            \"op\": \"test\",\n            \"path\": \"/best_biscuit/name\",\n            \"value\": \"Choco Leibniz\"\n        }])\"_json;\n        value.patch(patch);\n    }\n    catch (const json::other_error& e)\n    {\n        // output exception information\n        std::cout << \"message: \" << e.what() << '\\n'\n                  << \"exception id: \" << e.id << '\\n';\n    }\n}\n

Output:

message: [json.exception.other_error.501] unsuccessful: {\"op\":\"test\",\"path\":\"/best_biscuit/name\",\"value\":\"Choco Leibniz\"}\nexception id: 501\n
"},{"location":"home/exceptions/#jsonexceptionother_error501","title":"json.exception.other_error.501","text":"

A JSON Patch operation 'test' failed. The unsuccessful operation is also printed.

Example message

Executing {\"op\":\"test\", \"path\":\"/baz\", \"value\":\"bar\"} on {\"baz\": \"qux\"}:

[json.exception.other_error.501] unsuccessful: {\"op\":\"test\",\"path\":\"/baz\",\"value\":\"bar\"}\n
"},{"location":"home/exceptions/#jsonexceptionother_error502","title":"json.exception.other_error.502","text":"

to_ubjson and to_bjdata were called with use_type = true but use_size = false, and the value contains a non-empty array or object (or, with BJData Draft 3, any binary value). UBJSON requires a size marker (#) after a type marker ($); scalars and empty arrays or objects do not throw.

Example message

[json.exception.other_error.502] use_type requires use_size = true\n

Note

This exception was added in version 3.13.0 unreleased. Before that, debug builds aborted on an assertion and release builds wrote a $ marker without #, which from_ubjson then rejected.

"},{"location":"home/exceptions/#see-also","title":"See also","text":"
  • exception - base class of all exceptions thrown by the library
  • parse_error - exceptions indicating a parse error
  • invalid_iterator - exceptions indicating errors with iterators
  • type_error - exceptions indicating a wrong type
  • out_of_range - exceptions indicating access out of range
  • other_error - exceptions indicating other library errors
  • JSON_NOEXCEPTION - switch off exceptions
  • JSON_DIAGNOSTICS - extended exception messages with the path of the failing value
  • Working Without Exceptions - use the library without exceptions
"},{"location":"home/faq/","title":"Frequently Asked Questions (FAQ)","text":""},{"location":"home/faq/#known-bugs","title":"Known bugs","text":""},{"location":"home/faq/#brace-initialization-yields-arrays","title":"Brace initialization yields arrays","text":"

Question

Why does

json j{true};\n

and

json j(true);\n

yield different results ([true] vs. true)?

This is a known issue, and \u2014 even worse \u2014 the behavior differs between GCC and Clang. The \"culprit\" for this is the library's constructor overloads for initializer lists to allow syntax like

json array = {1, 2, 3, 4};\n

for arrays and

json object = {{\"one\", 1}, {\"two\", 2}}; \n

for objects.

Tip

To avoid any confusion and ensure portable code, do not use brace initialization with the types basic_json, json, or ordered_json unless you want to create an object or array as shown in the examples above.

To explicitly create a single-element array, use json::array({value}):

json j = json::array({true});  // [true]\n

Opt-in copy semantics (since version 3.13.0 unreleased)

If you define JSON_BRACE_INIT_COPY_SEMANTICS to 1 before including the library, single-element brace initialization is treated as copy/move instead of creating a single-element array:

#define JSON_BRACE_INIT_COPY_SEMANTICS 1\n#include <nlohmann/json.hpp>\n\njson obj = {{\"key\", \"value\"}};\njson j{obj};   // -> {\"key\":\"value\"}  (copy, not array)\n

Without the macro (default behavior), json j{obj} creates [{\"key\":\"value\"}]. This opt-in macro fixes issue #5074 while preserving backwards compatibility for existing code.

"},{"location":"home/faq/#getting-started","title":"Getting started","text":""},{"location":"home/faq/#which-file-do-i-need","title":"Which file do I need?","text":"

Question

Do I have to clone the repository or build the library?

No. The library is header-only: the single file json.hpp from the releases page is all you need, including the _json literals. Put it in a directory nlohmann on your include path. Companion headers (json_fwd.hpp, json_view.hpp, json_literals.hpp) are only needed if you use them. See Integration.

"},{"location":"home/faq/#using-cmake-or-a-package-manager","title":"Using CMake or a package manager","text":"

Question

How do I add the library with CMake, Conan, vcpkg, Homebrew, or another tool?

See CMake for find_package, add_subdirectory, and FetchContent, and Package managers for the list of supported package managers.

"},{"location":"home/faq/#the-ide-cannot-open-the-header","title":"The IDE cannot open the header","text":"

Question

The compiler finds nlohmann/json.hpp, but my IDE reports \"cannot open source file\". Why?

The compiler's include path is set correctly, but the IDE's is not. Add the same directory to the include paths of the IDE (or of its language server); the build itself is not affected.

"},{"location":"home/faq/#compile-times","title":"Compile times","text":"

Question

Including the library slows down my build. What can I do?

Include json_fwd.hpp in headers and json.hpp only in the source files that need it, instantiate basic_json once, and consider precompiled headers or C++20 modules. See Compile times.

"},{"location":"home/faq/#parsing","title":"Parsing","text":""},{"location":"home/faq/#parsing-a-file-fails-with-unexpected-end-of-input","title":"Parsing a file fails with \"unexpected end of input\"","text":"

Question

json::parse(file) throws parse_error.101 at line 1, column 1 for a file that is valid JSON. Why?

The parser did not see any character: the file was most likely not opened. A relative path is resolved against the working directory of the running program, which is often the build directory of your IDE, not the source directory. Check is_open() and try an absolute path. Other causes are an empty file and a stream that was already read. See parse_error.101.

"},{"location":"home/faq/#input-that-arrives-in-chunks","title":"Input that arrives in chunks","text":"

Question

My data comes from a socket in pieces. How do I parse it?

The parser cannot be resumed. Frame the messages (one value per line, a length prefix) and parse each complete frame, or buffer the chunks until the value is complete; a parse_error at the end of the buffer means the input ended prematurely. See Large, streamed, and partial input.

"},{"location":"home/faq/#several-values-in-one-stream","title":"Several values in one stream","text":"

Question

How do I read concatenated JSON values or one value per line?

Read newline-delimited input line by line (JSON Lines). For concatenated values, use operator>> and check for the end of the stream before each read, as shown in Several values in one stream.

"},{"location":"home/faq/#files-that-are-too-large-for-memory","title":"Files that are too large for memory","text":"

Question

How do I process a huge JSON file?

Handle and discard the records of a large array with a parser callback, stop early with the SAX interface, or read parts of the text through a json_document (added in version 3.13.0 unreleased). See Input too large for memory.

"},{"location":"home/faq/#position-of-a-parse-error","title":"Position of a parse error","text":"

Question

How do I get the line and column of a parse error?

The message contains them. The exception stores the byte index in byte, from which you can compute both; see Where did the error occur?. To locate a value that causes a later error, such as a type_error, use JSON_DIAGNOSTIC_POSITIONS.

"},{"location":"home/faq/#comments-and-trailing-commas","title":"Comments and trailing commas","text":"

Question

Can the parser read JSON with comments or trailing commas?

Yes, when asked to: see Comments and Trailing commas. Both are rejected by default.

"},{"location":"home/faq/#accessing-and-creating-values","title":"Accessing and creating values","text":""},{"location":"home/faq/#reading-a-value-into-a-variable","title":"Reading a value into a variable","text":"

Question

How do I get a C++ value out of a json value?

Use get<T>(), for example int age = j[\"age\"].get<int>();, or an implicit conversion. auto x = j[\"age\"]; is not a conversion: it copies the json value. See Converting values.

"},{"location":"home/faq/#strings-are-printed-with-quotes","title":"Strings are printed with quotes","text":"

Question

std::cout << j[\"name\"] prints \"Mary\" with quotes. How do I get the string?

The value is a json, and printing it produces JSON text. Convert it first: j[\"name\"].get<std::string>(). See Getting a string without quotes.

"},{"location":"home/faq/#testing-whether-a-key-exists","title":"Testing whether a key exists","text":"

Question

How do I check if a key exists, without changing the object?

Use contains or find. Do not test with the non-const operator[]: like std::map::operator[], it inserts a null value for a missing key. See Does this key exist?. For choosing between value, contains/find, at, operator[], and JSON Pointer, see the decision flow in Element access.

"},{"location":"home/faq/#reading-a-value-with-a-fallback","title":"Reading a value with a fallback","text":"

Question

How do I read a value that may be missing?

Use value, which returns a default for a missing key. It still throws if the key exists with a different type; see Working without exceptions.

"},{"location":"home/faq/#iterating-and-nested-values","title":"Iterating and nested values","text":"

Question

How do I loop over an array or object, or reach a nested value?

See Iterators and items() for loops, and JSON Pointer to address or test a nested value by path.

"},{"location":"home/faq/#unexpected-arrays-when-creating-values","title":"Unexpected arrays when creating values","text":"

Question

Why does json j{x} or {{\"a\", 1}, {\"b\"}} produce an array instead of what I expected?

Braces create arrays and objects based on their content, and single-element braces create a one-element array. See Brace initialization yields arrays and the table in Creating values.

"},{"location":"home/faq/#keeping-the-order-of-object-keys","title":"Keeping the order of object keys","text":"

Question

The keys of my object come out sorted. How do I keep the insertion order?

Use ordered_json, and call ordered_json::parse when reading. See Object order.

"},{"location":"home/faq/#converting-your-own-types","title":"Converting your own types","text":""},{"location":"home/faq/#structs-enums-and-optional-fields","title":"Structs, enums, and optional fields","text":"

Question

How do I convert my own types to and from JSON?

Write to_json/from_json functions or use the NLOHMANN_DEFINE_TYPE_* macros; see Arbitrary type conversions. Enums can be mapped to strings (Enum conversion), and an empty std::optional can be omitted (Omitting a field).

"},{"location":"home/faq/#smart-pointers-variants-chrono-and-class-hierarchies","title":"Smart pointers, variants, chrono, and class hierarchies","text":"

Question

Why can't I convert std::shared_ptr, std::variant, std::chrono types, or a pointer to a base class?

There is more than one sensible JSON representation for them, so the library leaves the choice to you. Recipes for common types shows one for each.

"},{"location":"home/faq/#my-to_json-is-not-found","title":"My to_json is not found","text":"

Question

I wrote to_json/from_json, but the compiler does not find them. Why?

Typical causes are a type alias of a standard type, a function in the wrong namespace, or a declaration that comes too late. See Why isn't my to_json found?.

"},{"location":"home/faq/#limitations","title":"Limitations","text":""},{"location":"home/faq/#relaxed-parsing","title":"Relaxed parsing","text":"

Question

Can you add an option to ignore trailing commas?

Yes, trailing commas in arrays and objects can be allowed by setting parameter ignore_trailing_commas of parse to true; see trailing commas. They are rejected by default, and the library never adds them when serializing.

"},{"location":"home/faq/#parse-errors-reading-non-ascii-characters","title":"Parse errors reading non-ASCII characters","text":"

Questions

  • Why is the parser complaining about a Chinese character?
  • Does the library support Unicode?
  • I get an exception [json.exception.parse_error.101] parse error at line 1, column 53: syntax error while parsing value - invalid string: ill-formed UTF-8 byte; last read: '\"Test\u00e9$')\"

The library supports Unicode input as follows:

  • UTF-8 encoded input is supported, which is the default encoding for JSON, according to RFC 8259.
  • std::u16string and std::u32string can be parsed, assuming UTF-16 and UTF-32 encoding, respectively; std::wstring works as well and is interpreted as UTF-16 or UTF-32, depending on the width of the platform's wchar_t. These encodings cannot be read from a FILE* or a std::istream, which carry bytes only.
  • Ill-formed UTF-16 or UTF-32 input is rejected: a lone surrogate, a high surrogate that is not followed by its low surrogate, and a code point above U+10FFFF all yield a parse error. The same holds for iterators over 2- or 4-byte characters.
  • Other encodings such as Latin-1 or ISO 8859-1 are not supported and will yield parse or serialization errors.
  • The library will not replace Unicode noncharacters.
  • Invalid surrogates (e.g., incomplete pairs such as \\uDEAD) will yield parse errors.
  • The strings stored in the library are UTF-8 encoded. When using the default string type (std::string), note that its length/size functions return the number of stored bytes rather than the number of characters or glyphs.
  • When you store strings with different encodings in the library, calling dump() may throw an exception unless json::error_handler_t::replace, json::error_handler_t::ignore, or json::error_handler_t::keep are used as error handlers.

In most cases, the parser is right to complain, because the input is not UTF-8 encoded. This is especially true for Microsoft Windows, where Latin-1 or ISO 8859-1 is often the standard encoding.

"},{"location":"home/faq/#nul-bytes-in-the-input","title":"NUL bytes in the input","text":"

Questions

  • Why does json::parse() silently ignore part of my input?
  • Why does a std::string/buffer with extra data after the JSON text parse without error, while a similar-looking string with extra text does not?

A '\\0' (NUL) byte anywhere in the input is treated the same as the real end of the input, rather than as an ordinary (and, outside of a string, invalid) byte. Everything from that byte onward is silently ignored, without a parse error \u2014 including further, otherwise well-formed JSON:

json::parse(std::string(\"123\") + '\\0');          // == 123, no error\njson::parse(std::string(\"123\") + '\\0' + \"true\"); // == 123, the \"true\" is silently ignored too\n

This is different from any other unexpected trailing byte, which does raise parse_error.101:

json::parse(\"123x\"); // throws parse_error.101: unexpected additional data\n

This falls out of the same convention used when no explicit input length is given at all: json::parse(const char*) already stops at the first NUL byte via strlen(), since a bare pointer has no length of its own. The library applies that same NUL-terminated-C-string convention uniformly, rather than only when a length is genuinely unavailable \u2014 so a std::string, iterator range, or container whose content happens to include a NUL byte is affected the same way a raw const char* would be.

If your input may contain a trailing or embedded NUL that is not meant to signal the end of the JSON text \u2014 for instance, a fixed-size, zero-padded buffer \u2014 trim it yourself before calling parse(), since the library will otherwise silently stop there instead of raising an error:

s.resize(s.find('\\0')); // drop everything from the first NUL onward, if any\njson::parse(s);\n

Opt-in strict handling (since version 3.13.0 unreleased)

Manually trimming every input is easy to forget. If you define JSON_STRICT_NUL_HANDLING to 1 before including the library, a '\\0' byte is instead rejected like any other unexpected byte and raises parse_error.101, instead of being treated as end of input:

#define JSON_STRICT_NUL_HANDLING 1\n#include <nlohmann/json.hpp>\n\njson::parse(std::string(\"123\") + '\\0'); // throws parse_error.101 instead of silently returning 123\n

This macro defaults to 0 (disabled, preserving the behavior described above) to avoid breaking existing code that may depend on it, even unknowingly; it is planned to become the default in version 4.0.0. See its documentation for details, including how it also affects char arrays such as string literals.

Note that this is unrelated to an unescaped NUL byte occurring inside a quoted JSON string, which is a different, already-invalid case and is correctly rejected either way:

json::parse(std::string(\"\\\"\") + '\\0' + \"\\\"\"); // throws parse_error.101: control character U+0000 (NUL) must be escaped to \\u0000\n
"},{"location":"home/faq/#wide-string-handling","title":"Wide string handling","text":"

Question

Why are wide strings (e.g., std::wstring) dumped as arrays of numbers?

As described above, the library stores its strings as UTF-8. To store a wide string as a string, convert it to a UTF-8 encoded std::string first, as in the example below.

Example

#include <codecvt> // codecvt_utf8\n#include <locale>  // wstring_convert\n\n// encoding function\nstd::string to_utf8(std::wstring& wide_string)\n{\n    static std::wstring_convert<std::codecvt_utf8<wchar_t>> utf8_conv;\n    return utf8_conv.to_bytes(wide_string);\n}\n\njson j;\nstd::wstring ws = L\"\u8ecaB1234 \u3053\u3093\u306b\u3061\u306f\";\n\nj[\"original\"] = ws;\nj[\"encoded\"] = to_utf8(ws);\n\nstd::cout << j << std::endl;\n

The result is:

{\n  \"encoded\": \"\u8ecaB1234 \u3053\u3093\u306b\u3061\u306f\",\n  \"original\": [36554, 66, 49, 50, 51, 52, 32, 12371, 12435, 12395, 12385, 12399]\n}\n
"},{"location":"home/faq/#usage","title":"Usage","text":""},{"location":"home/faq/#thread-safety","title":"Thread safety","text":"

Question

Is basic_json thread-safe?

No. basic_json provides no built-in synchronization, the same as std::map or std::vector. Concurrent reads of the same value from multiple threads are safe, as are concurrent (non-overlapping) accesses to independent json objects. However, any concurrent write to a json object \u2014 or a concurrent read while another thread writes to the same object \u2014 is a data race and requires external synchronization (e.g., a std::mutex) by the caller.

"},{"location":"home/faq/#schema-validation","title":"Schema validation","text":"

Question

Does this library support JSON Schema validation?

Not directly, but the companion project json-schema-validator builds JSON Schema (draft 7; draft 4 in its older, now-superseded 1.x releases) validation on top of this library and is a common recommendation for this use case.

"},{"location":"home/faq/#memory-use","title":"Memory use","text":"

Question

Does the library leak memory? My process stays large after I free a json value.

Destroying a value frees everything it owns. Freed memory is returned to the allocator, which does not necessarily give it back to the operating system, so a high resident size alone is not a leak. Copies are deep, and clear() keeps the capacity of an array. See Memory, and use Valgrind or the sanitizers to tell a leak from retained memory.

"},{"location":"home/faq/#reproducible-builds","title":"Reproducible builds","text":"

Question

The header path ends up in my binary. How do I get path-independent builds?

The runtime assertions embed __FILE__. Define NDEBUG (the default for release builds) or map the path prefix; see Notes for builds and distribution.

"},{"location":"home/faq/#slow-debug-builds","title":"Slow debug builds","text":"

Question

Parsing a large file is very slow in my debug build. Can I compile the library with optimizations?

The library is header-only, so there is no separate source file. Keep the code that uses json in its own source file and compile that file with optimizations; see Notes for builds and distribution.

"},{"location":"home/faq/#exceptions","title":"Exceptions","text":""},{"location":"home/faq/#parsing-without-exceptions","title":"Parsing without exceptions","text":"

Question

Is it possible to indicate a parse error without throwing an exception?

Yes, see Parsing and exceptions and Working without exceptions.

"},{"location":"home/faq/#key-name-in-exceptions","title":"Key name in exceptions","text":"

Question

Can I get the key of the object item that caused an exception?

Yes, you can. Please define the symbol JSON_DIAGNOSTICS to get extended diagnostics messages.

"},{"location":"home/faq/#serialization-issues","title":"Serialization issues","text":""},{"location":"home/faq/#number-precision","title":"Number precision","text":"

Question

  • It seems that precision is lost when serializing a double.
  • Can I change the precision for floating-point serialization?

The library serializes floating-point numbers with the shortest representation that parses back to the same value, using at most std::numeric_limits<number_float_t>::max_digits10 (17 for IEEE doubles) significant digits. This guarantees that value -> string -> value round-trips. The reverse direction, string -> value -> string, is only guaranteed for numbers with at most std::numeric_limits<number_float_t>::digits10 (15 for IEEE doubles) significant digits; a number with more digits may not be representable exactly and is then serialized as the closest double.

cppreference.com

The value of std::numeric_limits<T>::max_digits10 is the number of base-10 digits that are necessary to uniquely represent all distinct values of the type T, such as necessary for serialization/deserialization to text.

Tip

The website https://float.exposed gives a good insight into the internal storage of floating-point numbers.

See this section on the library's number handling for more information.

"},{"location":"home/faq/#serializing-untrusted-or-invalid-utf-8","title":"Serializing untrusted or invalid UTF-8","text":"

Questions

  • Why does dump() throw when I serialize data that came from the network?
  • Is CVE-2024-34363 a vulnerability in this library?

Crashes reported against this library that stem from an uncaught type_error.316 while serializing unvalidated input (e.g., CVE-2024-34363) are a usage issue, not a library vulnerability: dump() throws in its default strict mode because RFC 8259 requires JSON text to be valid UTF-8.

The recommended pattern is to pass a non-strict error_handler or to handle the exception:

// replace invalid sequences with U+FFFD instead of throwing\nconst auto s = j.dump(-1, ' ', false, json::error_handler_t::replace);\n
"},{"location":"home/faq/#using-json-values-with-stdformat-or-fmt","title":"Using JSON values with std::format or fmt","text":"

Question

  • Can I use std::format(\"{}\", j) on a JSON value?
  • Can I use fmt::format(\"{}\", j) or fmt::print(\"{}\", j) (the {fmt} library) on a JSON value?

std::format works out of the box since version 3.13.0 unreleased, as long as the standard library provides <format> (see JSON_HAS_STD_FORMAT); see std::formatter<basic_json> for details, including the \"{:#}\" pretty-print spec, indent widths (\"{:2}\"), and custom indent characters (\"{:.>#}\").

For fmt, the library ships format_as, a small customization point fmt looks for via argument-dependent lookup. It only has an effect on fmt 10.0.0 through 11.0.2 \u2014 from fmt 11.1.0 onwards, fmt no longer picks up a format_as overload that returns a std::string. On such versions (or any version, if you also want the same \"{:#}\"/width/fill-and-align spec support that std::formatter<basic_json> has), define your own fmt::formatter specialization; see format_as for a recipe that mirrors it.

If you get ambiguous-overload errors when passing a JSON value to fmt::format/fmt::print without any fmt::formatter<json> specialization in scope, that's fmt picking up basic_json's implicit operator ValueType() conversion operator (see #964 and #958); disabling it via JSON_USE_IMPLICIT_CONVERSIONS 0 avoids the ambiguity.

"},{"location":"home/faq/#compilation-issues","title":"Compilation issues","text":""},{"location":"home/faq/#android-sdk","title":"Android SDK","text":"

Question

Why does the code not compile with Android SDK?

Since NDK r18 (2018), GCC and the gnustl/stlport C++ libraries have been removed from the Android NDK; Clang and libc++ are now the only compiler and C++ library, and they support C++11 and later out of the box. With a current NDK, no special configuration is needed to use this library.

Only very old NDKs (before r18), which defaulted to GCC and gnustl, lacked C++11 library features such as std::to_string. If you run into this, update to a current NDK.

"},{"location":"home/faq/#incomplete-detector-type-with-gcc-11","title":"Incomplete detector type with GCC < 11","text":"

Question

Why does GCC 10 or older fail with invalid use of incomplete type 'struct nlohmann::detail::detector<..., to_json_function, ...>' for a type that holds an optional member?

This happens with GCC 10 and older in C++11/C++14 mode when all of these hold:

  • a class Holder has an optional<Dummy> member (e.g., boost::optional),
  • Dummy has a constructor taking a json value, and
  • to_json for Holder is a free function in the namespace of Dummy.
class Dummy {\n  public:\n    explicit Dummy(const nlohmann::json& j);\n};\n\nclass Holder {\n    boost::optional<Dummy> d;\n};\n\nvoid to_json(nlohmann::json& j, const Holder& h);  // triggers the error\n

To decide whether Dummy is copyable, the compiler checks whether a Dummy can be converted to json. That check looks up to_json via argument-dependent lookup, finds the unrelated to_json for Holder, and eventually asks again whether Dummy is copyable. GCC before version 11 turns this cycle into a hard error; GCC 11 and later, Clang, and C++17 mode compile the code. The same error shows up without this library whenever a constrained converting constructor is involved, so the library can't avoid it.

To work around this, define to_json (and from_json) as a hidden friend inside the class. That way, argument-dependent lookup only finds it for Holder:

class Holder {\n    boost::optional<Dummy> d;\n\n    friend void to_json(nlohmann::json& j, const Holder& h) { /* ... */ }\n};\n

The NLOHMANN_DEFINE_TYPE_INTRUSIVE macros define hidden friends as well. See #3669 for details.

"},{"location":"home/faq/#missing-stl-function","title":"Missing STL function","text":"

Questions

  • Why do I get a compilation error 'to_string' is not a member of 'std' (or similarly, for strtod or strtof)?
  • Why does the code not compile with MinGW or Android SDK?

This is not an issue with the code, but rather with the compiler itself. On Android, use a current NDK (see above). For MinGW, please refer to this site and this discussion for information on how to fix this bug.

"},{"location":"home/faq/#see-also","title":"See also","text":"
  • basic_json - the main class and all its member functions
  • Macros - reference of all macros
  • Exceptions - all exceptions and their error codes
  • Features - overview of all features
"},{"location":"home/license/","title":"License","text":"

The class is licensed under the MIT License:

Copyright \u00a9 2013-2026 Niels Lohmann

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \u201cSoftware\u201d), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED \u201cAS IS\u201d, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

The class contains the UTF-8 Decoder from Bjoern Hoehrmann which is licensed under the MIT License (see above). Copyright \u00a9 2008-2009 Bj\u00f6rn Hoehrmann bjoern@hoehrmann.de

The class contains a slightly modified version of the Grisu2 algorithm from Florian Loitsch which is licensed under the MIT License (see above). Copyright \u00a9 2009 Florian Loitsch

The class contains a port of the shortest double-to-decimal conversion of \u017bmij by Victor Zverovich, including the conversion of the digits to text by Xiang JunBo and the SIMD instruction sequence of Dougall Johnson, which is licensed under the MIT License (see above). Copyright \u00a9 2025 Victor Zverovich

The class contains a copy of Hedley from Evan Nemerson which is licensed as CC0-1.0.

The class contains an adapted version of the Eisel-Lemire algorithm, its table of powers of five, and its digit comparison for long numbers from fast_float by Daniel Lemire and contributors, which is available under the MIT License (used here), the Apache 2.0 License, and the Boost Software License. Copyright \u00a9 2021 The fast_float authors

The view's parser (<nlohmann/json_view.hpp>) contains techniques and code adapted from yyjson by YaoYuan, which is licensed under the MIT License (see above): table-driven decoding of \\u escapes and fixed-offset unrolled checks.

The view's parser (<nlohmann/json_view.hpp>) validates non-ASCII strings with the vector UTF-8 check of simdjson by Daniel Lemire, Geoff Langdale, John Keiser, and contributors (its \"lookup4\" algorithm and tables, after J. Keiser and D. Lemire, \"Validating UTF-8 In Less Than One Instruction Per Byte\", 2021), which is available under the MIT License (used here) and the Apache 2.0 License. Copyright \u00a9 2018-2025 The simdjson authors

"},{"location":"home/sponsors/","title":"Sponsors","text":"

You can sponsor this library at GitHub Sponsors. Thanks to everyone who supports the project!

"},{"location":"home/sponsors/#priority-sponsors","title":"Priority Sponsors","text":"
  • Mercedes-Benz
  • FastNetMon
"},{"location":"home/sponsors/#named-sponsors","title":"Named Sponsors","text":"
  • Paul Harrington
  • Steve Wagner
  • mccaffers
  • jambolo
"},{"location":"home/sponsors/#further-sponsors","title":"Further Sponsors","text":"
  • Grisha Kirilin
  • zimmerman-dev
  • WAAutoMaton
  • F3D
  • David Alvarez Rosa
  • Alex Kong
  • Mark Oates
  • Martti Laine
  • Michael Hartmann
  • Stefan Hagen
  • Steve Sperandeo
  • Robert Jefe Lindst\u00e4dt
"},{"location":"home/releases/","title":"Releases","text":"

This section summarizes the notable changes of every release and links to the relevant documentation. The complete release notes \u2014 including all changes, the download files, and their checksums \u2014 are published on the GitHub releases page.

Unreleased changes

This documentation is built from the develop branch and may describe changes that are not part of a release yet. Their version numbers are followed by an unreleased badge.

Every release has its own page with a summary of its notable changes and an overview of the API that was added or changed in it. The API overview is generated from the \"Version history\" section of the API pages; it is not a change log, but helps to see whether a feature is available in the version you use.

All releases at a glance (hover a marker for its version and date):

Timeline from the first commit (2013-07-04) and the 44 releases from v1.0.0 (2015-12-28) to v3.12.0 (2025-04-11): 17 minor or major releases, drawn as filled dots with their version above the axis, and 27 patch releases, drawn as rings. The first commit is drawn as a diamond. 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 1.x 2.x 3.x first commit 1.0 1.1 2.0 2.1 3.0 3.1 3.2 3.3 3.4 3.5 3.6 3.7 3.8 3.9 3.10 3.11 3.12 First commit 2013-07-04 v2.0.1 released 2016-06-28 v2.0.2 released 2016-07-31 v2.0.3 released 2016-08-31 v2.0.4 released 2016-09-11 v2.0.5 released 2016-09-14 v2.0.6 released 2016-10-15 v2.0.7 released 2016-11-02 v2.0.8 released 2016-12-02 v2.0.9 released 2016-12-16 v2.0.10 released 2017-01-02 v2.1.1 released 2017-02-25 v3.0.1 released 2017-12-29 v3.1.1 released 2018-02-13 v3.1.2 released 2018-03-14 v3.7.1 released 2019-11-06 v3.7.2 released 2019-11-10 v3.7.3 released 2019-11-17 v3.9.1 released 2020-08-06 v3.10.1 released 2021-08-24 v3.10.2 released 2021-08-26 v3.10.3 released 2021-10-08 v3.10.4 released 2021-10-16 v3.10.5 released 2022-01-03 v3.11.2 released 2022-08-12 v3.11.3 released 2023-11-28 v1.0.0 released 2015-12-28 v1.1.0 released 2016-01-24 v2.0.0 released 2016-06-24 v2.1.0 released 2017-01-28 v3.0.0 released 2017-12-17 v3.1.0 released 2018-02-01 v3.2.0 released 2018-08-20 v3.3.0 released 2018-10-05 v3.4.0 released 2018-10-30 v3.5.0 released 2018-12-22 v3.6.0, v3.6.1 released 2019-03-20 v3.7.0 released 2019-07-28 v3.8.0 released 2020-06-14 v3.9.0 released 2020-07-27 v3.10.0 released 2021-08-17 v3.11.0, v3.11.1 released 2022-08-01 v3.12.0 released 2025-04-11

From the first commit (diamond) in 2013 to the latest release, on a time axis by year. Filled dots with a version label are minor or major releases, rings are patch releases.

"},{"location":"home/releases/#unreleased","title":"Unreleased","text":"Release Date Summary Unreleased Changes on the develop branch that are not part of a release yet."},{"location":"home/releases/#version-312x","title":"Version 3.12.x","text":"Release Date Summary v3.12.0 2025-04-11 Fixes bugs found in 3.11.3 and adds several features. No public API was removed or renamed. Highlights: diagnostic byte positions (start_pos/end_pos); templated conversion macros and NLOHMANN_DEFINE_DERIVED_TYPE; std::optional support."},{"location":"home/releases/#version-311x","title":"Version 3.11.x","text":"Release Date Summary v3.11.3 2023-11-28 Adds features and fixes bugs found in 3.11.2. All changes are backward-compatible. Highlights: custom base class for basic_json; serialization-only conversion macros; Bazel and Swift Package Manager support. v3.11.2 2022-08-12 Fixes bugs found in 3.11.1 and restructures the namespace. All changes are backward-compatible. Highlights: fixes value for strings and size types; restores json_pointer as associative-container key; restructured inline namespace. v3.11.1 2022-08-01 Fixes a regression from 3.11.0. All changes are backward-compatible. Highlights: restores the global _json and _json_pointer literals. v3.11.0 2022-08-01 One of the largest releases ever. All changes are backward-compatible. Highlights: std::string_view keys; BJData binary format; C++20 support including operator<=>."},{"location":"home/releases/#version-310x","title":"Version 3.10.x","text":"Release Date Summary v3.10.5 2022-01-03 Bug-fix release. All changes are backward-compatible. Highlights: guards the std::filesystem conversions with JSON_HAS_FILESYSTEM. v3.10.4 2021-10-16 Fixes regressions introduced in 3.10.0. All changes are backward-compatible. Highlights: fixes the std::filesystem::path conversion; fixes types with explicit defaulted constructors; fixes std::find/std::remove return values. v3.10.3 2021-10-08 Fixes more regressions from 3.10.0. All changes are backward-compatible. Highlights: fixes extended-diagnostics assertions in update and array insertion; custom allocators for binary output; conversion from begin()/end()-only types. v3.10.2 2021-08-26 Re-release of 3.10.1, whose Git tag pointed at the wrong commit due to a bug in the release script. All changes are backward-compatible. Highlights: re-release of 3.10.1 with the correct Git tag. v3.10.1 2021-08-24 Fixes a regression from 3.10.0. All changes are backward-compatible. Highlights: fixes an extended-diagnostics assertion with ordered_json; hardens the GDB pretty-printer. v3.10.0 2021-08-17 Feature release. All changes are backward-compatible. Highlights: extended diagnostic messages (JSON_DIAGNOSTICS); GDB pretty-printer; CBOR tag storage."},{"location":"home/releases/#version-39x","title":"Version 3.9.x","text":"Release Date Summary v3.9.1 2020-08-06 Fixes two regressions from 3.9.0. All changes are backward-compatible. Highlights: accepts consecutive comments; completes the ordered_json interface. v3.9.0 2020-07-27 Feature release adding four long-requested features. All changes are backward-compatible. Highlights: comment parsing; ordered_json; switch to disable implicit conversions."},{"location":"home/releases/#version-38x","title":"Version 3.8.x","text":"Release Date Summary v3.8.0 2020-06-14 Feature release. All changes are backward-compatible. Highlights: binary value type for CBOR, BSON, and MessagePack; input adapters for any LegacyInputIterator container; fixes contains for JSON pointers."},{"location":"home/releases/#version-37x","title":"Version 3.7.x","text":"Release Date Summary v3.7.3 2019-11-17 Fixes a regression from 3.7.2 that could yield quadratic complexity in destructor calls. All changes are backward-compatible. Highlights: fixes quadratic complexity in destructor calls. v3.7.2 2019-11-10 Fixes a stack overflow for deeply nested input by making the destructor iterative; parsing of JSON text is now bounded only by available memory (the binary-format parsers still recurse). All changes are backward-compatible. Highlights: iterative destructor fixes a stack overflow on deeply nested input. v3.7.1 2019-11-06 Bug-fix release. All changes are backward-compatible. Highlights: fixes a crash when serializing the minimum std::int64_t; fixes contains for JSON pointers; items with custom string types. v3.7.0 2019-07-28 Convenience features and house-keeping. All changes are backward-compatible. Highlights: contains overload for JSON pointers; generic to_string; return value for emplace_back."},{"location":"home/releases/#version-36x","title":"Version 3.6.x","text":"Release Date Summary v3.6.1 2019-03-20 Fixes a regression (GCC 7/8 compilation) and a <Windows.h> build error introduced in 3.6.0. All changes are backward-compatible. Highlights: fixes a GCC 7/8 compilation regression; fixes a <Windows.h> build error. v3.6.0 2019-03-20 Feature release. All changes are backward-compatible. Highlights: reworked JSON pointer interface; contains function; faster integer serialization."},{"location":"home/releases/#version-35x","title":"Version 3.5.x","text":"Release Date Summary v3.5.0 2018-12-22 Feature release. All changes are backward-compatible. Highlights: structured bindings via items; reading from FILE*; fixes eofbit handling on streams."},{"location":"home/releases/#version-34x","title":"Version 3.4.x","text":"Release Date Summary v3.4.0 2018-10-30 Feature release. All changes are backward-compatible. Highlights: BSON support; Unicode error handlers for dump; NLOHMANN_JSON_SERIALIZE_ENUM."},{"location":"home/releases/#version-33x","title":"Version 3.3.x","text":"Release Date Summary v3.3.0 2018-10-05 Feature release. All changes are backward-compatible. Highlights: GCC 4.8 support; get_to; overhauled CMake integration."},{"location":"home/releases/#version-32x","title":"Version 3.2.x","text":"Release Date Summary v3.2.0 2018-08-20 Feature release. All changes are backward-compatible. Highlights: SAX interface and non-recursive parser; parsing from wide strings; conversion to std::string_view."},{"location":"home/releases/#version-31x","title":"Version 3.1.x","text":"Release Date Summary v3.1.2 2018-03-14 Bug-fix release. All changes are backward-compatible. Highlights: fixes a memory leak in the parser callback; user-defined string types in parser and serializer. v3.1.1 2018-02-13 Bug-fix release. All changes are backward-compatible. Highlights: fixes parsing of indefinite-length CBOR strings; fixes a user-defined conversion to vector types; fixes UBJSON overflow detection. v3.1.0 2018-02-01 Feature release. All changes are backward-compatible. Highlights: UBJSON support; JSON Merge Patch; Grisu2 floating-point output."},{"location":"home/releases/#version-30x","title":"Version 3.0.x","text":"Release Date Summary v3.0.1 2017-12-29 Fixes small issues in the JSON Pointer and JSON Patch implementations (invalid \"copy\" targets and non-integer array indices). All changes are backward-compatible. Highlights: fixes invalid JSON Patch \"copy\" targets; fixes non-integer array indices in JSON Pointer. v3.0.0 2017-12-17 First 3.x release \u2014 a major release with breaking changes (see the migration guide). Highlights: user-defined exceptions with identifiers; non-throwing accept and allow_exceptions; update to merge objects."},{"location":"home/releases/#version-21x","title":"Version 2.1.x","text":"Release Date Summary v2.1.1 2017-02-25 Bug-fix release. All changes are backward-compatible. Highlights: locale-independent number parsing and serialization; correct floating-point round-tripping; GPG-signed commits and files. v2.1.0 2017-01-28 Feature release. All changes are backward-compatible. Highlights: conversions from and to arbitrary user-defined types; meta function; JSON_NOEXCEPTION."},{"location":"home/releases/#version-20x","title":"Version 2.0.x","text":"Release Date Summary v2.0.10 2017-01-02 Fixes several security-relevant bugs in the CBOR and MessagePack parsers found by OSS-Fuzz. All changes are backward-compatible. Highlights: fixes security-relevant bugs in the CBOR parser; fixes security-relevant bugs in the MessagePack parser. v2.0.9 2016-12-16 Adds the CBOR and MessagePack binary formats. All changes are backward-compatible. Highlights: CBOR support; MessagePack support. v2.0.8 2016-12-02 Adds the emplace and emplace_back functions and improves parsing and serialization performance. All changes are backward-compatible. Highlights: emplace and emplace_back; faster parsing; faster serialization. v2.0.7 2016-11-02 Fixes several parser bugs found through the \"Parsing JSON is a Minefield\" study (short files, encoding detection, surrogate pairs). All changes are backward-compatible. Highlights: fixes short-file handling; fixes encoding detection; fixes surrogate pairs. v2.0.6 2016-10-15 Fixes operator[] for JSON pointers so that it creates missing values like the other overloads. All changes are backward-compatible. Highlights: operator[] creates missing values for JSON pointers. v2.0.5 2016-09-14 Fixes a remaining stream end-of-file detection bug in the parser. All changes are backward-compatible. Highlights: fixes a remaining stream end-of-file bug. v2.0.4 2016-09-11 Fixes stream end-of-file detection in the parser. All changes are backward-compatible. Highlights: fixes stream end-of-file detection. v2.0.3 2016-08-31 Generalizes the parser to accept any contiguous sequence of one-byte elements and deprecates the input-stream constructor in favor of the parse function. All changes are backward-compatible. Highlights: parser accepts any contiguous sequence of one-byte elements; deprecates the input-stream constructor in favor of parse. v2.0.2 2016-07-31 Overhauls the parser (now rejecting unescaped control characters), tightens the class invariants, and cleans up the code. All changes are backward-compatible. Highlights: overhauled parser rejecting unescaped control characters; tighter class invariants; code cleanup. v2.0.1 2016-06-28 Fixes a performance regression in the dump function by adjusting the stream locale once per serialization. All changes are backward-compatible. Highlights: fixes a performance regression in dump. v2.0.0 2016-06-24 Feature release with a minor (potentially non-backward-compatible) API change from added noexcept and constexpr specifiers. Highlights: JSON Pointer support in at and operator[], plus flatten and unflatten; JSON Patch via diff and patch; unsigned 64-bit integers."},{"location":"home/releases/#version-11x","title":"Version 1.1.x","text":"Release Date Summary v1.1.0 2016-01-24 Bug-fix and feature release. All changes are backward-compatible. Highlights: improved floating-point round-tripping; get_ref; runtime assertions."},{"location":"home/releases/#version-10x","title":"Version 1.0.x","text":"Release Date Summary v1.0.0 2015-12-28 First official release."},{"location":"home/releases/#see-also","title":"See also","text":"
  • Migration Guide \u2014 how to future-proof your code for the next major version and replace deprecated functions.
  • Roadmap: Version 4.0 \u2014 what the next major version will change and how to try it today.
"},{"location":"home/releases/unreleased/","title":"Unreleased","text":"

These changes are part of the develop branch, but not of a release yet.

  • Converting an rvalue container to JSON (json j = std::move(vec);, json j = std::map<std::string, std::string>{...};) now moves the elements instead of copying them (e.g., std::vector<std::string> with 100,000 strings: 4.7 ms to 2.3 ms). Two consequences: the source container is left in a valid but unspecified (moved-from) state, and if an exception is thrown during the conversion, the source may be partially moved-from, so the strong exception guarantee no longer holds for the source of an rvalue conversion (the JSON value itself is unaffected). Lvalues and const objects are still copied. See basic_json.
"},{"location":"home/releases/unreleased/#api-changes","title":"API changes","text":"

Added (88 pages):

  • basic_json: as_base_class, format_as(basic_json), from_bon8, merge_diff, basic_json>, to_bon8, with_t
  • basic_json_document: (overview), accept, basic_json_document, erase, insert, is_discarded, load, memory_usage, node_count, owns_source, parse, parse_copy, push_back, read, root, save, set, shrink_to_fit, source
  • basic_json_view: (overview), at, back, basic_json_view, begin, cbegin, cend, contains, count, dump, empty, end, find, front, get, get_string, get_to, is_array, is_binary, is_boolean, is_discarded, is_null, is_number, is_number_float, is_number_integer, is_number_unsigned, is_object, is_primitive, is_string, is_structured, items, materialize, number_format, number_token, operator[], operator==, operator<<, operator!=, size, source_offset, type, type_name, value
  • json_pointer: front, pop_front, push_front
  • macros: JSON_BRACE_INIT_COPY_SEMANTICS, JSON_DELETE_DEPRECATED_FUNCTIONS, JSON_DISABLE_STREAM_BULK_SCAN, JSON_DISABLE_TUPLE_REFERENCE_CONVERSION, JSON_DISABLE_UNLOCKED_FILE_IO, JSON_HAS_RANGE_VIEW_CONVERSION, JSON_HAS_STD_FORMAT, JSON_NO_AUTOMATIC_UDLS, JSON_NO_SIMD, JSON_NO_THREAD_LOCAL, JSON_PRECISE_STREAM_POSITION, JSON_STRICT_BINARY_UTF8, JSON_STRICT_NUL_HANDLING, JSON_USE_OBJECTS_FOR_ENUM_KEYED_MAPS, JSON_USE_SIMDUTF, nlohmann_define_type_with_names

Changed:

  • operator>>(basic_json): Fixed a null pointer dereference for an std::istream without a stream buffer (now throws parse_error.101), and a crash (std::terminate) when i has eofbit in its exception mask, in version 3.13.0 unreleased.
  • operator>>(basic_json): Changed to the strong exception safety guarantee in version 3.13.0 unreleased: j is no longer left with a partially parsed value if parsing throws.
  • operator>>(basic_json): Scans the characters in the stream buffer of i in bulk in version 3.13.0 unreleased; the position of i after the call is unchanged (JSON_DISABLE_STREAM_BULK_SCAN restores reading one character at a time).
  • operator\"\"_json: Added char8_t* overload in version 3.13.0 unreleased.
  • operator\"\"_json_pointer: Added char8_t* overload in version 3.13.0 unreleased.
  • ordered_map: Changed in version 3.13.0 unreleased: growing the storage moves the mapped values instead of copying them.
  • basic_json::accept: Added ignore_trailing_commas in version 3.13.0 unreleased.
  • basic_json::accept: Extended container support (1) to include types with lvalue-only ADL begin/end (matching std::begin/std::end semantics) in version 3.13.0 unreleased.
  • basic_json::accept: Extended overload (2) to accept heterogeneous iterator+sentinel pairs (C++20 ranges support) in version 3.13.0 unreleased.
  • basic_json::accept: Parsing from an std::istream scans the characters in its stream buffer in bulk in version 3.13.0 unreleased (JSON_DISABLE_STREAM_BULK_SCAN).
  • basic_json::accept: Parsing from a FILE* locks the file once instead of once per character in version 3.13.0 unreleased (JSON_DISABLE_UNLOCKED_FILE_IO).
  • basic_json::accept: Ill-formed UTF-16 and UTF-32 input (a lone surrogate, a high surrogate that is not followed by its low surrogate, or a code point above U+10FFFF) is rejected in version 3.13.0 unreleased; before that, some such sequences were accepted or ended the input silently.
  • basic_json::array_t: Made capacity() optional, so that array types such as std::deque can be used, in version 3.13.0 unreleased.
  • basic_json::at: Overload 3: Support for keys convertible to std::string_view added in version 3.13.0 unreleased, consistently across the lookup functions.
  • basic_json::basic_json: Overload 4: Explicit for different string types if JSON_USE_IMPLICIT_CONVERSIONS is 0 since version 3.13.0 unreleased.
  • basic_json::basic_json: Overload 7: Fixed in version 3.13.0 unreleased 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.
  • basic_json::binary_t: Fixed dump, std::hash, and to_ubjson for byte types that are not integers (e.g., std::byte) in version 3.13.0 unreleased.
  • basic_json::clear: Fixed in version 3.13.0 unreleased to also clear the subtype of a binary value; before, the subtype was left unchanged.
  • basic_json::contains: Overload 2: Support for keys convertible to std::string_view added in version 3.13.0 unreleased, consistently across the lookup functions.
  • basic_json::contains: Overload 4: Deleted overloads for integral key types added in version 3.13.0 unreleased to reject such calls at compile time instead of causing undefined behavior at runtime.
  • basic_json::count: Overload 2: Support for keys convertible to std::string_view added in version 3.13.0 unreleased, consistently across the lookup functions.
  • basic_json::count: Overload 3: Deleted overload for integral key types added in version 3.13.0 unreleased to reject such calls at compile time instead of causing undefined behavior at runtime.
  • basic_json::dump: Error handler keep added in version 3.13.0 unreleased.
  • basic_json::dump: Doubles are written with the shortest digits (\u017bmij instead of Grisu2) since version 3.13.0 unreleased; about 0.1% of doubles are written differently, most of them with fewer digits.
  • basic_json::emplace: Fixed in version 3.13.0 unreleased: for ordered_json, the value could previously only be passed as an rvalue; it can now also be passed as an lvalue or a const lvalue, matching the behavior of json.
  • basic_json::erase: Overload 4: Support for keys convertible to std::string_view added in version 3.13.0 unreleased, consistently across the lookup functions.
  • basic_json::error_handler_t: Added keep, and made this enumeration apply to the binary readers and writers in addition to dump, in version 3.13.0 unreleased.
  • basic_json::find: Overload 2: Support for keys convertible to std::string_view added in version 3.13.0 unreleased, consistently across the lookup functions.
  • basic_json::find: Overload 3: Deleted overloads for integral key types added in version 3.13.0 unreleased to reject such calls at compile time instead of causing undefined behavior at runtime.
  • basic_json::from_bjdata: Extended container support (1) to include types with lvalue-only ADL begin/end (matching std::begin/std::end semantics) in version 3.13.0 unreleased.
  • basic_json::from_bjdata: Extended overload (2) to accept heterogeneous iterator+sentinel pairs (C++20 ranges support) in version 3.13.0 unreleased.
  • basic_json::from_bjdata: Added error_handler parameter in version 3.13.0 unreleased.
  • basic_json::from_bson: Extended container support (1) to include types with lvalue-only ADL begin/end (matching std::begin/std::end semantics) in version 3.13.0 unreleased.
  • basic_json::from_bson: Extended overload (2) to accept heterogeneous iterator+sentinel pairs (C++20 ranges support) in version 3.13.0 unreleased.
  • basic_json::from_bson: Added error_handler parameter in version 3.13.0 unreleased.
  • basic_json::from_cbor: Extended container support (1) to include types with lvalue-only ADL begin/end (matching std::begin/std::end semantics) in version 3.13.0 unreleased.
  • basic_json::from_cbor: Extended overload (2) to accept heterogeneous iterator+sentinel pairs (C++20 ranges support) in version 3.13.0 unreleased.
  • basic_json::from_cbor: Added error_handler parameter in version 3.13.0 unreleased.
  • basic_json::from_msgpack: Extended container support (1) to include types with lvalue-only ADL begin/end (matching std::begin/std::end semantics) in version 3.13.0 unreleased.
  • basic_json::from_msgpack: Extended overload (2) to accept heterogeneous iterator+sentinel pairs (C++20 ranges support) in version 3.13.0 unreleased.
  • basic_json::from_msgpack: Added error_handler parameter in version 3.13.0 unreleased.
  • basic_json::from_ubjson: Extended container support (1) to include types with lvalue-only ADL begin/end (matching std::begin/std::end semantics) in version 3.13.0 unreleased.
  • basic_json::from_ubjson: Extended overload (2) to accept heterogeneous iterator+sentinel pairs (C++20 ranges support) in version 3.13.0 unreleased.
  • basic_json::from_ubjson: Added error_handler parameter in version 3.13.0 unreleased.
  • basic_json::get_to: Added a static_assert with a clear message for const arguments in version 3.13.0 unreleased.
  • basic_json::insert: Overload 4: Fixed in version 3.13.0 unreleased 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.
  • basic_json::json_base_class_t: Made a public member type in version 3.13.0 unreleased; it was private before, so it could not be named outside the class.
  • basic_json::merge_patch: Fixed use of freed or relocated memory when apply_patch is *this or refers to a value contained in *this, in version 3.13.0 unreleased.
  • basic_json::number_unsigned_t: Can be the same type as number_integer_t since version 3.13.0 unreleased.
  • basic_json::object_comparator_t: Fixed the fallback to default_object_comparator_t, which previously failed to compile for object types without a key_compare member type, in version 3.13.0 unreleased.
  • basic_json::object_t: Allowed object types whose erase(iterator) returns void in version 3.13.0 unreleased.
  • basic_json::operator[]: Overload 1: Fixed in version 3.13.0 unreleased to throw std::length_error instead of emptying the array and accessing it out of bounds when idx equals the maximum value of size_type.
  • basic_json::operator[]: Overload 1: A missing index in the const version is guarded by a runtime assertion since version 3.13.0 unreleased.
  • basic_json::operator[]: Overload 3: Support for keys convertible to std::string_view added in version 3.13.0 unreleased, consistently across the lookup functions.
  • basic_json::operator[]: Overload 4: A missing array index in the const version is guarded by a runtime assertion since version 3.13.0 unreleased.
  • basic_json::operator==: Overload 2: Made conditionally noexcept in version 3.13.0 unreleased; before, a throwing conversion called std::terminate.
  • basic_json::operator>=: Overload 2: Made conditionally noexcept in version 3.13.0 unreleased; before, a throwing conversion called std::terminate.
  • basic_json::operator>: Overload 2: Made conditionally noexcept in version 3.13.0 unreleased; before, a throwing conversion called std::terminate.
  • basic_json::operator<=: Overload 2: Made conditionally noexcept in version 3.13.0 unreleased; before, a throwing conversion called std::terminate.
  • basic_json::operator<: Overload 2: Made conditionally noexcept in version 3.13.0 unreleased; before, a throwing conversion called std::terminate.
  • basic_json::operator!=: Overload 1: Changed in version 3.13.0 unreleased to remove special-casing for NaN and discarded values; operator!= now consistently means !(a == b).
  • basic_json::operator!=: Overload 1: Removed the C++20 member function in version 3.13.0 unreleased; since C++20, the compiler rewrites a != b using operator==.
  • basic_json::operator!=: Overload 2: Changed in version 3.13.0 unreleased to remove special-casing for NaN and discarded values; operator!= now consistently means !(a == b).
  • basic_json::operator!=: Overload 2: Made conditionally noexcept in version 3.13.0 unreleased; before, a throwing conversion called std::terminate.
  • basic_json::operator<=>: Overload 2: Made conditionally noexcept in version 3.13.0 unreleased; before, a throwing conversion called std::terminate.
  • basic_json::parse: Added ignore_trailing_commas in version 3.13.0 unreleased.
  • basic_json::parse: Extended container support (1) to include types with lvalue-only ADL begin/end (matching std::begin/std::end semantics) in version 3.13.0 unreleased.
  • basic_json::parse: Extended overload (2) to accept heterogeneous iterator+sentinel pairs (C++20 ranges support) in version 3.13.0 unreleased.
  • basic_json::parse: 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 unreleased.
  • basic_json::parse: Parsing from an std::istream scans the characters in its stream buffer in bulk in version 3.13.0 unreleased (JSON_DISABLE_STREAM_BULK_SCAN restores reading one character at a time).
  • basic_json::parse: Parsing from a FILE* locks the file once instead of once per character in version 3.13.0 unreleased (JSON_DISABLE_UNLOCKED_FILE_IO restores std::fgetc).
  • basic_json::parse: Ill-formed UTF-16 and UTF-32 input (a lone surrogate, a high surrogate that is not followed by its low surrogate, or a code point above U+10FFFF) is rejected with parse_error.101 in version 3.13.0 unreleased; before that, some such sequences were accepted or ended the input silently.
  • basic_json::parser_callback_t: Fixed in version 3.13.0 unreleased 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.
  • basic_json::parser_callback_t: Fixed in version 3.13.0 unreleased 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.
  • basic_json::patch: Added out_of_range.411 and stopped relying on an internal assertion when an \"add\" operation's target location has a non-object/non-array parent in version 3.13.0 unreleased.
  • basic_json::patch: This includes a null parent, which was previously silently converted to an object, in version 3.13.0 unreleased.
  • basic_json::patch: Added out_of_range.413 and stopped silently ignoring a \"remove\" operation whose target location has a non-object/non-array parent in version 3.13.0 unreleased.
  • basic_json::patch: Added out_of_range.414 and rejected a \"move\" operation whose \"from\" location is a proper prefix of its \"path\" location instead of silently producing a corrupted result in version 3.13.0 unreleased.
  • basic_json::patch: Throws parse_error.109 instead of out_of_range.404 for a one-character array index that is not a digit (e.g., /x) in version 3.13.0 unreleased, as it already did for longer ones.
  • basic_json::patch_inplace: Added out_of_range.411 and stopped relying on an internal assertion when an \"add\" operation's target location has a non-object/non-array parent in version 3.13.0 unreleased.
  • basic_json::patch_inplace: This includes a null parent, which was previously silently converted to an object, in version 3.13.0 unreleased.
  • basic_json::patch_inplace: Added out_of_range.413 and stopped silently ignoring a \"remove\" operation whose target location has a non-object/non-array parent in version 3.13.0 unreleased.
  • basic_json::patch_inplace: Added out_of_range.414 and rejected a \"move\" operation whose \"from\" location is a proper prefix of its \"path\" location instead of silently producing a corrupted result in version 3.13.0 unreleased.
  • basic_json::patch_inplace: Throws parse_error.109 instead of out_of_range.404 for a one-character array index that is not a digit (e.g., /x) in version 3.13.0 unreleased, as it already did for longer ones.
  • basic_json::sax_parse: Added ignore_trailing_commas in version 3.13.0 unreleased.
  • basic_json::sax_parse: Added tag_handler in version 3.13.0 unreleased.
  • basic_json::sax_parse: Extended container support (1) to include types with lvalue-only ADL begin/end (matching std::begin/std::end semantics) in version 3.13.0 unreleased.
  • basic_json::sax_parse: Extended overload (2) to accept heterogeneous iterator+sentinel pairs (C++20 ranges support) in version 3.13.0 unreleased.
  • basic_json::sax_parse: JSON_PRECISE_STREAM_POSITION added in version 3.13.0 unreleased to optionally leave a std::istream positioned right after the parsed value when strict is false.
  • basic_json::sax_parse: Parsing from an std::istream scans the characters in its stream buffer in bulk in version 3.13.0 unreleased (JSON_DISABLE_STREAM_BULK_SCAN).
  • basic_json::sax_parse: Parsing from a FILE* locks the file once instead of once per character in version 3.13.0 unreleased (JSON_DISABLE_UNLOCKED_FILE_IO).
  • basic_json::sax_parse: Ill-formed UTF-16 and UTF-32 input (a lone surrogate, a high surrogate that is not followed by its low surrogate, or a code point above U+10FFFF) is rejected with parse_error.101 in version 3.13.0 unreleased; before that, some such sequences were accepted or ended the input silently.
  • std::hash<nlohmann::basic_json>: Numbers that compare equal hash equally since version 3.13.0 unreleased; before, 0, 0U, and 0.0 had different hash values.
  • basic_json::string_t: Removed the requirement that string_t be implicitly convertible from std::string, which the BSON writer and the UBJSON reader relied on, in version 3.13.0 unreleased.
  • basic_json::swap: Overload 1: Exchanges the json_base_class_t subobject along with the value since version 3.13.0 unreleased.
  • basic_json::swap: Overload 2: Exchanges the json_base_class_t subobject along with the value since version 3.13.0 unreleased.
  • basic_json::to_bjdata: Added error_handler parameter in version 3.13.0 unreleased.
  • basic_json::to_bjdata: Throws type_error.321 for a discarded value since version 3.13.0 unreleased; previously, a discarded value nested in an array or object was silently skipped, producing invalid BJData.
  • basic_json::to_bson: Throws out_of_range.412 and out_of_range.415 since version 3.13.0 unreleased.
  • basic_json::to_bson: Linear in the size of j, and no longer limited by the call stack for deeply nested values, since version 3.13.0 unreleased.
  • basic_json::to_bson: out_of_range.415 is now detected before anything is written, like the other exceptions above, since version 3.13.0 unreleased.
  • basic_json::to_bson: Throws type_error.321 for a discarded value nested in j since version 3.13.0 unreleased; previously, it was silently skipped, producing a document whose declared size did not match what was actually written.
  • basic_json::to_bson: Added error_handler parameter in version 3.13.0 unreleased.
  • basic_json::to_bson: Throws out_of_range.407 for integers that do not fit 64 bits since version 3.13.0 unreleased; previously, integers of a number type wider than 64 bits were silently truncated.
  • basic_json::to_cbor: Added error_handler parameter in version 3.13.0 unreleased.
  • basic_json::to_cbor: Throws type_error.321 for a discarded value since version 3.13.0 unreleased; previously, a discarded value nested in an array or object was silently skipped, producing invalid CBOR.
  • basic_json::to_cbor: Throws out_of_range.407 for integers that do not fit 64 bits since version 3.13.0 unreleased; previously, integers of a number type wider than 64 bits were silently truncated.
  • basic_json::to_msgpack: Throws out_of_range.412 and out_of_range.415 since version 3.13.0 unreleased.
  • basic_json::to_msgpack: Added error_handler parameter in version 3.13.0 unreleased.
  • basic_json::to_msgpack: Fixed in version 3.13.0 unreleased 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.
  • basic_json::to_msgpack: Throws type_error.321 for a discarded value since version 3.13.0 unreleased; previously, a discarded value nested in an array or object was silently skipped, producing invalid MessagePack.
  • basic_json::to_msgpack: Throws out_of_range.407 for integers that do not fit 64 bits since version 3.13.0 unreleased; previously, integers of a number type wider than 64 bits were silently truncated.
  • basic_json::to_ubjson: Added error_handler parameter in version 3.13.0 unreleased.
  • basic_json::to_ubjson: Throws type_error.321 for a discarded value since version 3.13.0 unreleased; previously, a discarded value nested in an array or object was silently skipped, producing invalid UBJSON.
  • basic_json::type_name: Added \"invalid\" return value for corrupted JSON values in version 3.13.0 unreleased.
  • basic_json::unflatten: Made the array/object decision independent of the object's iteration order in version 3.13.0 unreleased.
  • basic_json::unflatten: Throws parse_error.109 instead of out_of_range.404 for a one-character array index that is not a digit (e.g., /x) in version 3.13.0 unreleased, as it already did for longer ones.
  • basic_json::update: Fixed use of freed or relocated memory when the argument is *this or refers to a value contained in *this, in version 3.13.0 unreleased.
  • basic_json::value: Overload 1: Deleted overload for integral key types added in version 3.13.0 unreleased to reject such calls at compile time instead of causing undefined behavior at runtime.
  • basic_json::value: Overload 2: Support for keys convertible to std::string_view added in version 3.13.0 unreleased, consistently across the lookup functions.
  • basic_json::value: Overload 3: Extended to work with arrays in version 3.13.0 unreleased.
  • basic_json::value: Overload 3: Throws parse_error.109 instead of returning default_value for a one-character array index that is not a digit (e.g., /x) in version 3.13.0 unreleased, as it already did for longer ones.
  • JSON_HAS_CPP_11, JSON_HAS_CPP_14, JSON_HAS_CPP_17, JSON_HAS_CPP_20, JSON_HAS_CPP_23, JSON_HAS_CPP_26: Added JSON_HAS_CPP_26 in version 3.13.0 unreleased.
  • JSON_HAS_RANGES: Added the exclusions for libstdc++ < 11, Clang < 16 with libstdc++, libc++ < 16, and nvcc (CUDA) 12.0.x and 12.1.x in version 3.13.0 unreleased.
  • JSON_USE_IMPLICIT_CONVERSIONS: Also affects the conversion between basic_json specializations with different string types since version 3.13.0 unreleased.
  • JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON: Fixed in version 3.13.0 unreleased so <= and >= also emulate the legacy behavior in C++20 when the JSON value is the right-hand operand of a scalar comparison; before, only the 3-way-comparison-rewritten candidate was found, which yielded false instead of true.
"},{"location":"home/releases/v1.0.0/","title":"v1.0.0","text":"

Released on 2015-12-28.

First official release. Full release notes.

"},{"location":"home/releases/v1.0.0/#api-changes","title":"API changes","text":"

Added (70 pages):

  • operator>>(basic_json)
  • operator\"\"_json
  • operator<<(basic_json), nlohmann::operator<<(json_pointer)
  • basic_json: (overview), array, array_t, at, back, basic_json, begin, boolean_t, cbegin, cend, clear, count, crbegin, crend, dump, empty, end, erase, find, front, get, get_allocator, get_ptr, insert, is_array, is_boolean, is_discarded, is_null, is_number, is_number_float, is_number_integer, is_object, is_primitive, is_string, is_structured, max_size, number_float_t, number_integer_t, object, object_t, operator+=, operator=, operator[], operator ValueType, operator==, operator>=, operator>, operator<=, operator<, operator!=, operator value_t, parse, parse_event_t, parser_callback_t, push_back, rbegin, rend, size, basic_json>, swap<basic_json>, string_t, swap, type, type_name, value, value_t, ~basic_json
"},{"location":"home/releases/v1.1.0/","title":"v1.1.0","text":"

Released on 2016-01-24.

Bug-fix and feature release. All changes are backward-compatible.

  • Improves floating-point round-tripping, adds a get_ref accessor for stored values, and introduces runtime assertions.

Full release notes.

"},{"location":"home/releases/v1.1.0/#api-changes","title":"API changes","text":"

Added (1 pages):

  • basic_json: get_ref

Changed:

  • basic_json::operator[]: Overload 2: Added overloads for T* key in version 1.1.0.
"},{"location":"home/releases/v2.0.0/","title":"v2.0.0","text":"

Released on 2016-06-24.

Feature release with a minor (potentially non-backward-compatible) API change from added noexcept and constexpr specifiers.

  • Adds JSON Pointer support in at and operator[], plus flatten and unflatten.
  • Adds JSON Patch via diff and patch, unsigned 64-bit integer support, and locale-independent serialization.

Full release notes.

"},{"location":"home/releases/v2.0.0/#api-changes","title":"API changes","text":"

Added (11 pages):

  • operator\"\"_json_pointer
  • basic_json: diff, flatten, is_number_unsigned, number_unsigned_t, patch, unflatten
  • json_pointer: (overview), json_pointer, operator string_t, to_string

Changed:

  • basic_json::at: Overload 4 added.
  • basic_json::is_number: Extended to also return true for unsigned integers in 2.0.0.
  • basic_json::is_number_integer: Extended to also return true for unsigned integers in 2.0.0.
  • basic_json::operator+=: Overload 3 added.
  • basic_json::operator[]: Overload 4 added.
  • basic_json::operator value_t: Added unsigned integer type in version 2.0.0.
  • basic_json::push_back: Overload 3 added.
  • basic_json::type: Added unsigned integer type in version 2.0.0.
  • basic_json::value_t: Added unsigned integer type in version 2.0.0.
"},{"location":"home/releases/v2.0.1/","title":"v2.0.1","text":"

Released on 2016-06-28.

Fixes a performance regression in the dump function by adjusting the stream locale once per serialization. All changes are backward-compatible. Full release notes.

"},{"location":"home/releases/v2.0.1/#api-changes","title":"API changes","text":"

No documented API changes.

"},{"location":"home/releases/v2.0.10/","title":"v2.0.10","text":"

Released on 2017-01-02.

Fixes several security-relevant bugs in the CBOR and MessagePack parsers found by OSS-Fuzz. All changes are backward-compatible. Full release notes.

"},{"location":"home/releases/v2.0.10/#api-changes","title":"API changes","text":"

No documented API changes.

"},{"location":"home/releases/v2.0.2/","title":"v2.0.2","text":"

Released on 2016-07-31.

Overhauls the parser (now rejecting unescaped control characters), tightens the class invariants, and cleans up the code. All changes are backward-compatible. Full release notes.

"},{"location":"home/releases/v2.0.2/#api-changes","title":"API changes","text":"

Changed:

  • basic_json::value: Overload 3 added.
"},{"location":"home/releases/v2.0.3/","title":"v2.0.3","text":"

Released on 2016-08-31.

Generalizes the parser to accept any contiguous sequence of one-byte elements and deprecates the input-stream constructor in favor of the parse function. All changes are backward-compatible. Full release notes.

"},{"location":"home/releases/v2.0.3/#api-changes","title":"API changes","text":"

Changed:

  • basic_json::parse: Overload for contiguous containers (1) added in version 2.0.3.
"},{"location":"home/releases/v2.0.4/","title":"v2.0.4","text":"

Released on 2016-09-11.

Fixes stream end-of-file detection in the parser. All changes are backward-compatible. Full release notes.

"},{"location":"home/releases/v2.0.4/#api-changes","title":"API changes","text":"

No documented API changes.

"},{"location":"home/releases/v2.0.5/","title":"v2.0.5","text":"

Released on 2016-09-14.

Fixes a remaining stream end-of-file detection bug in the parser. All changes are backward-compatible. Full release notes.

"},{"location":"home/releases/v2.0.5/#api-changes","title":"API changes","text":"

No documented API changes.

"},{"location":"home/releases/v2.0.6/","title":"v2.0.6","text":"

Released on 2016-10-15.

Fixes operator[] for JSON pointers so that it creates missing values like the other overloads. All changes are backward-compatible. Full release notes.

"},{"location":"home/releases/v2.0.6/#api-changes","title":"API changes","text":"

No documented API changes.

"},{"location":"home/releases/v2.0.7/","title":"v2.0.7","text":"

Released on 2016-11-02.

Fixes several parser bugs found through the \"Parsing JSON is a Minefield\" study (short files, encoding detection, surrogate pairs). All changes are backward-compatible. Full release notes.

"},{"location":"home/releases/v2.0.7/#api-changes","title":"API changes","text":"

No documented API changes.

"},{"location":"home/releases/v2.0.8/","title":"v2.0.8","text":"

Released on 2016-12-02.

Adds the emplace and emplace_back functions and improves parsing and serialization performance. All changes are backward-compatible. Full release notes.

"},{"location":"home/releases/v2.0.8/#api-changes","title":"API changes","text":"

Added (2 pages):

  • basic_json: emplace, emplace_back
"},{"location":"home/releases/v2.0.9/","title":"v2.0.9","text":"

Released on 2016-12-16.

Adds the CBOR and MessagePack binary formats. All changes are backward-compatible. Full release notes.

"},{"location":"home/releases/v2.0.9/#api-changes","title":"API changes","text":"

Added (4 pages):

  • basic_json: from_cbor, from_msgpack, to_cbor, to_msgpack
"},{"location":"home/releases/v2.1.0/","title":"v2.1.0","text":"

Released on 2017-01-28.

Feature release. All changes are backward-compatible.

  • Adds conversions from and to arbitrary user-defined types via to_json/from_json, the meta function, and the option to switch off exceptions (JSON_NOEXCEPTION).

Full release notes.

"},{"location":"home/releases/v2.1.0/#api-changes","title":"API changes","text":"

Added (7 pages):

  • adl_serializer: (overview), from_json, to_json
  • basic_json: json_serializer, meta
  • json_pointer: operator==, operator!=

Changed:

  • basic_json::basic_json: Overload 3 added.
  • basic_json::get: Overload 1 added.
  • basic_json::get: Overload 2 added.
  • basic_json::type_name: Part of the public API version since 2.1.0.
"},{"location":"home/releases/v2.1.1/","title":"v2.1.1","text":"

Released on 2017-02-25.

Bug-fix release. All changes are backward-compatible.

  • Makes number parsing and serialization locale-independent with correct floating-point round-tripping; commits and released files are GPG-signed.

Full release notes.

"},{"location":"home/releases/v2.1.1/#api-changes","title":"API changes","text":"

Changed:

  • basic_json::from_cbor: Parameter start_index since version 2.1.1.
  • basic_json::from_msgpack: Parameter start_index since version 2.1.1.
"},{"location":"home/releases/v3.0.0/","title":"v3.0.0","text":"

Released on 2017-12-17.

First 3.x release \u2014 a major release with breaking changes (see the migration guide).

  • Introduces user-defined exceptions (json::exception and subtypes, each with an identifier).
  • Adds a non-throwing accept function and an allow_exceptions flag for parse, and an update function to merge objects.
  • Adds streaming for CBOR and MessagePack and allows storing NaN/infinity.
  • Non-UTF-8 strings now throw on serialization, and the iterator category changed to bidirectional.

Full release notes.

"},{"location":"home/releases/v3.0.0/#api-changes","title":"API changes","text":"

Added (9 pages):

  • basic_json: accept, exception, invalid_iterator, object_comparator_t, other_error, out_of_range, parse_error, type_error, update

Changed:

  • operator<<(basic_json), nlohmann::operator<<(json_pointer): Overload 1: Added support for indentation character and deprecated std::ostream& operator>>(const basic_json& j, std::ostream& o) in version 3.0.0.
  • basic_json::dump: Indentation character indent_char, option ensure_ascii and exceptions added in version 3.0.0.
  • basic_json::from_cbor: Changed to consume input adapters, removed start_index parameter, and added strict parameter in version 3.0.0.
  • basic_json::from_msgpack: Changed to consume input adapters, removed start_index parameter, and added strict parameter in version 3.0.0.
  • basic_json::insert: Overload 5 added.
  • basic_json::type_name: Changed return value to const char* and added noexcept in version 3.0.0.
"},{"location":"home/releases/v3.0.1/","title":"v3.0.1","text":"

Released on 2017-12-29.

Fixes small issues in the JSON Pointer and JSON Patch implementations (invalid \"copy\" targets and non-integer array indices). All changes are backward-compatible. Full release notes.

"},{"location":"home/releases/v3.0.1/#api-changes","title":"API changes","text":"

No documented API changes.

"},{"location":"home/releases/v3.1.0/","title":"v3.1.0","text":"

Released on 2018-02-01.

Feature release. All changes are backward-compatible.

  • Adds UBJSON read/write support and JSON Merge Patch via merge_patch.
  • Switches to the Grisu2 algorithm for short, round-trippable floating-point output, and splits the header into multiple files with a forward-declaration header.

Full release notes.

"},{"location":"home/releases/v3.1.0/#api-changes","title":"API changes","text":"

Added (6 pages):

  • basic_json: from_ubjson, items, merge_patch, to_ubjson
  • macros: JSON_CATCH_USER, JSON_THROW_USER, JSON_TRY_USER, NLOHMANN_JSON_VERSION_MAJOR, NLOHMANN_JSON_VERSION_MINOR, NLOHMANN_JSON_VERSION_PATCH
"},{"location":"home/releases/v3.1.1/","title":"v3.1.1","text":"

Released on 2018-02-13.

Bug-fix release. All changes are backward-compatible.

  • Fixes parsing of indefinite-length CBOR strings, a user-defined conversion to vector types, and overflow detection for UBJSON containers.

Full release notes.

"},{"location":"home/releases/v3.1.1/#api-changes","title":"API changes","text":"

No documented API changes.

"},{"location":"home/releases/v3.1.2/","title":"v3.1.2","text":"

Released on 2018-03-14.

Bug-fix release. All changes are backward-compatible.

  • Fixes a memory leak in the parser callback and adds user-defined string-type support to the parser and serializer.

Full release notes.

"},{"location":"home/releases/v3.1.2/#api-changes","title":"API changes","text":"

Changed:

  • basic_json::basic_json: Overload 4 added.
  • basic_json::get: Overload 2: Extended to work with other specializations of basic_json in version 3.1.2.
"},{"location":"home/releases/v3.10.0/","title":"v3.10.0","text":"

Released on 2021-08-17.

Feature release. All changes are backward-compatible.

  • Adds extended diagnostic messages (JSON_DIAGNOSTICS) that prepend a JSON pointer to exception messages to pinpoint the offending value.
  • Adds a GDB pretty-printer and a cbor_tag_handler_t store option to keep CBOR tags as binary subtypes.
  • Supports containers with non-default-constructible types and parsing from std::byte.
  • Adds JSON_NO_IO to exclude the I/O headers and the JSON_HAS_CPP_* macros to override the detected C++ standard.

Full release notes.

"},{"location":"home/releases/v3.10.0/#api-changes","title":"API changes","text":"

Added (3 pages):

  • macros: JSON_DIAGNOSTICS, JSON_HAS_CPP_11, JSON_HAS_CPP_14, JSON_HAS_CPP_17, JSON_HAS_CPP_20, JSON_HAS_CPP_23, JSON_HAS_CPP_26, JSON_NO_IO

Changed:

  • basic_json::binary: Changed the type of subtype from std::uint8_t to binary_t::subtype_type (std::uint64_t) in version 3.10.0.
  • basic_json::binary_t: Changed the type of subtype to std::uint64_t in version 3.10.0.
  • basic_json::cbor_tag_handler_t: Added value store in 3.10.0.
  • byte_container_with_subtype: Changed the type of subtypes to std::uint64_t in 3.10.0.
  • byte_container_with_subtype::subtype: Fixed return value to properly return subtype_type(-1) as documented in version 3.10.0.
"},{"location":"home/releases/v3.10.1/","title":"v3.10.1","text":"

Released on 2021-08-24.

Fixes a regression from 3.10.0. All changes are backward-compatible.

  • Fixes an extended-diagnostics assertion triggered when used with ordered_json, and hardens the GDB pretty-printer.

Full release notes.

"},{"location":"home/releases/v3.10.1/#api-changes","title":"API changes","text":"

No documented API changes.

"},{"location":"home/releases/v3.10.2/","title":"v3.10.2","text":"

Released on 2021-08-26.

Re-release of 3.10.1, whose Git tag pointed at the wrong commit due to a bug in the release script. All changes are backward-compatible. Full release notes.

"},{"location":"home/releases/v3.10.2/#api-changes","title":"API changes","text":"

No documented API changes.

"},{"location":"home/releases/v3.10.3/","title":"v3.10.3","text":"

Released on 2021-10-08.

Fixes more regressions from 3.10.0. All changes are backward-compatible.

  • Fixes extended-diagnostics assertions triggered by update and by inserting into arrays.
  • Supports custom allocators when writing binary formats into a std::vector, and allows conversion from types that only provide begin()/end().

Full release notes.

"},{"location":"home/releases/v3.10.3/#api-changes","title":"API changes","text":"

No documented API changes.

"},{"location":"home/releases/v3.10.4/","title":"v3.10.4","text":"

Released on 2021-10-16.

Fixes regressions introduced in 3.10.0. All changes are backward-compatible.

  • Fixes the std::filesystem::path conversion (which could trigger a stack overflow and broke compilation on Windows).
  • Fixes compilation for types with an explicit defaulted constructor and for code relying on the return values of std::find and std::remove.

Full release notes.

"},{"location":"home/releases/v3.10.4/#api-changes","title":"API changes","text":"

No documented API changes.

"},{"location":"home/releases/v3.10.5/","title":"v3.10.5","text":"

Released on 2022-01-03.

Bug-fix release. All changes are backward-compatible.

  • Guards the std::filesystem conversions behind compiler-support checks (JSON_HAS_FILESYSTEM), which can be set to 0 to disable them altogether.

Full release notes.

"},{"location":"home/releases/v3.10.5/#api-changes","title":"API changes","text":"

Added (1 pages):

  • macros: JSON_HAS_FILESYSTEM / JSON_HAS_EXPERIMENTAL_FILESYSTEM

Changed:

  • std::hash<nlohmann::basic_json>: Extended for arbitrary basic_json types in version 3.10.5.
  • std::swap<basic_json>: Extended for arbitrary basic_json types in version 3.10.5.
  • basic_json::update: Added merge_objects parameter in 3.10.5.
"},{"location":"home/releases/v3.11.0/","title":"v3.11.0","text":"

Released on 2022-08-01.

One of the largest releases ever. All changes are backward-compatible.

  • Allows std::string_view as object keys in at, operator[], value, erase, find, contains, and count.
  • Adds the BJData binary format (the fifth supported format).
  • Improves C++20 support, including operator<=> and <ranges>-compatible iterators.
  • Adds a versioned, ABI-tagged inline namespace (NLOHMANN_JSON_NAMESPACE) and the option to move the UDLs out of the global namespace (JSON_USE_GLOBAL_UDLS).
  • Adds patch_inplace, default values for the conversion macros, and an option to disable enum serialization (JSON_DISABLE_ENUM_SERIALIZATION).

This release introduced a UDL regression that was fixed in 3.11.1. Full release notes.

"},{"location":"home/releases/v3.11.0/#api-changes","title":"API changes","text":"

Added (14 pages):

  • basic_json: default_object_comparator_t, from_bjdata, operator<=>, patch_inplace, to_bjdata
  • json_pointer: string_t
  • macros: JSON_DISABLE_ENUM_SERIALIZATION, JSON_HAS_RANGES, JSON_HAS_THREE_WAY_COMPARISON, JSON_SKIP_LIBRARY_VERSION_CHECK, JSON_USE_GLOBAL_UDLS, JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON, NLOHMANN_JSON_NAMESPACE, NLOHMANN_JSON_NAMESPACE_BEGIN, NLOHMANN_JSON_NAMESPACE_END

Changed:

  • operator\"\"_json: Moved to namespace nlohmann::literals::json_literals in 3.11.0.
  • operator\"\"_json_pointer: Moved to namespace nlohmann::literals::json_literals in 3.11.0.
  • operator<<(basic_json), nlohmann::operator<<(json_pointer): Overload 2 added.
  • ordered_map: Added key_compare member in version 3.11.0.
  • basic_json::at: Overload 3 added.
  • basic_json::contains: Overload 1 added.
  • basic_json::contains: Overload 2: Extended template KeyType to support comparable types in version 3.11.0.
  • basic_json::count: Overload 1 added.
  • basic_json::count: Overload 2: Changed to support comparable key types in version 3.11.0.
  • basic_json::erase: Overload 4 added.
  • basic_json::find: Overload 1 added.
  • basic_json::find: Overload 2: Changed to support comparable types in version 3.11.0.
  • basic_json::object_comparator_t: Changed to be conditionally defined as typename object_t::key_compare or default_object_comparator_t in version 3.11.0.
  • basic_json::operator[]: Overload 2: The T* key overloads forward to overload 3 since version 3.11.0.
  • basic_json::operator[]: Overload 3 added.
  • basic_json::operator==: Overload 1: Added C++20 member functions in version 3.11.0.
  • basic_json::operator==: Overload 2: Added C++20 member functions in version 3.11.0.
  • basic_json::operator>=: Overload 1: Conditionally removed since C++20 in version 3.11.0.
  • basic_json::operator>=: Overload 2: Conditionally removed since C++20 in version 3.11.0.
  • basic_json::operator>: Overload 1: Conditionally removed since C++20 in version 3.11.0.
  • basic_json::operator>: Overload 2: Conditionally removed since C++20 in version 3.11.0.
  • basic_json::operator<=: Overload 1: Conditionally removed since C++20 in version 3.11.0.
  • basic_json::operator<=: Overload 2: Conditionally removed since C++20 in version 3.11.0.
  • basic_json::operator<: Overload 1: Conditionally removed since C++20 in version 3.11.0.
  • basic_json::operator<: Overload 2: Conditionally removed since C++20 in version 3.11.0.
  • basic_json::operator!=: Overload 1: Added a C++20 member function in version 3.11.0.
  • basic_json::value: Overload 1: Changed parameter default_value type from const ValueType& to ValueType&& in version 3.11.0.
  • basic_json::value: Overload 2 added.
  • json_pointer::back: Changed return type to string_t in version 3.11.0.
  • json_pointer: Changed template parameter from basic_json to string type in version 3.11.0.
  • json_pointer::json_pointer: Changed type of s to string_t in version 3.11.0.
  • json_pointer::operator/: Overload 2: Changed type of token to string_t in version 3.11.0.
  • json_pointer::operator/=: Overload 2: Changed type of token to string_t in version 3.11.0.
  • json_pointer::operator string_t: Changed type to string_t and deprecated in version 3.11.0.
  • json_pointer::push_back: Changed type of token to string_t in version 3.11.0.
  • json_pointer::to_string: Changed return type to string_t in version 3.11.0.
  • JSON_DIAGNOSTICS: As of version 3.11.0, the definition is allowed to vary between translation units.
  • NLOHMANN_DEFINE_TYPE_INTRUSIVE, NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT, NLOHMANN_DEFINE_TYPE_INTRUSIVE_ONLY_SERIALIZE: Overload 2 added.
  • NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE, NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT, NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE: Overload 2 added.
"},{"location":"home/releases/v3.11.1/","title":"v3.11.1","text":"

Released on 2022-08-01.

Fixes a regression from 3.11.0. All changes are backward-compatible.

  • Restores the global user-defined string literals operator\"\"_json and operator\"\"_json_pointer, which 3.11.0 had moved into a namespace by default.

Full release notes.

"},{"location":"home/releases/v3.11.1/#api-changes","title":"API changes","text":"

No documented API changes.

"},{"location":"home/releases/v3.11.2/","title":"v3.11.2","text":"

Released on 2022-08-12.

Fixes bugs found in 3.11.1 and restructures the namespace. All changes are backward-compatible.

  • Fixes the value function (broken for strings, size types, and nullptr in 3.11.0) and makes json_fwd.hpp self-contained.
  • Restores using json_pointer as a key in associative containers and comparing it with strings.
  • Restructures the inline namespace and allows disabling the version component, and avoids heap allocations in the BJData parser.

Full release notes.

"},{"location":"home/releases/v3.11.2/#api-changes","title":"API changes","text":"

Added (2 pages):

  • json_pointer: operator<=>
  • macros: NLOHMANN_JSON_NAMESPACE_NO_VERSION

Changed:

  • basic_json::value: Overload 2: Made ValueType the first template parameter in version 3.11.2.
  • json_pointer::operator==: Overload 1: Added C++20 member functions in version 3.11.2.
  • json_pointer::operator==: Overload 2: Added for backward compatibility and deprecated in version 3.11.2.
  • json_pointer::operator!=: Overload 2: Added for backward compatibility and deprecated in version 3.11.2.
  • NLOHMANN_JSON_NAMESPACE: Changed inline namespace name in version 3.11.2.
  • NLOHMANN_JSON_NAMESPACE_BEGIN, NLOHMANN_JSON_NAMESPACE_END: Changed inline namespace name in version 3.11.2.
"},{"location":"home/releases/v3.11.3/","title":"v3.11.3","text":"

Released on 2023-11-28.

Adds features and fixes bugs found in 3.11.2. All changes are backward-compatible.

  • Adds a custom base class as a node customization point.
  • Adds serialization-only conversion macros (NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE and NLOHMANN_DEFINE_TYPE_INTRUSIVE_ONLY_SERIALIZE) and a clearer parse error for empty input.
  • Adds Bazel and Swift Package Manager build support.
  • Fixes custom allocators, a memory leak in adl_serializer's to_json, initializer-list construction when size_type is not int, and many compiler warnings.

Full release notes.

"},{"location":"home/releases/v3.11.3/#api-changes","title":"API changes","text":"

Added (2 pages):

  • basic_json: json_base_class_t
  • macros: JSON_HAS_STATIC_RTTI

Changed:

  • NLOHMANN_DEFINE_TYPE_INTRUSIVE, NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT, NLOHMANN_DEFINE_TYPE_INTRUSIVE_ONLY_SERIALIZE: Overload 3 added.
  • NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE, NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT, NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE: Overload 3 added.
"},{"location":"home/releases/v3.12.0/","title":"v3.12.0","text":"

Released on 2025-04-11.

Fixes bugs found in 3.11.3 and adds several features. No public API was removed or renamed.

  • Adds diagnostic byte positions via JSON_DIAGNOSTIC_POSITIONS, exposed through the new start_pos and end_pos member functions.
  • Makes the conversion macros templated (so they also work with ordered_json) and adds NLOHMANN_DEFINE_DERIVED_TYPE for derived classes.
  • Adds std::optional support (C++17) and lets patch, diff, and flatten work with arbitrary string types.
  • Extends the binary formats: BJData draft 3 and unsigned 64-bit integers for BSON.
  • Adds multidimensional C-array conversion and UTF-8 encoded std::filesystem::path conversions, and raises the minimum CMake version to 3.5 and supports CMake 4.0.

Full release notes.

"},{"location":"home/releases/v3.12.0/#api-changes","title":"API changes","text":"

Added (5 pages):

  • basic_json: bjdata_version_t, end_pos, start_pos
  • macros: JSON_DIAGNOSTIC_POSITIONS, nlohmann_define_derived_type

Changed:

  • basic_json::accept: Changed runtime assertion in case of FILE* null pointers to exception in version 3.12.0.
  • basic_json::parse: Changed runtime assertion in case of FILE* null pointers to exception in version 3.12.0.
  • basic_json::to_bjdata: BJData version parameter (for draft3 binary encoding) added in version 3.12.0.
  • JSON_HAS_CPP_11, JSON_HAS_CPP_14, JSON_HAS_CPP_17, JSON_HAS_CPP_20, JSON_HAS_CPP_23, JSON_HAS_CPP_26: Added JSON_HAS_CPP_23 in version 3.12.0.
  • NLOHMANN_JSON_NAMESPACE: Added the ABI tag _dp in version 3.12.0, and the ABI tags _bics, _psp, _snul, _sbu8, _ekmo, _dsbs, _dufio, and _ns in version 3.13.0 unreleased; see nlohmann Namespace.
"},{"location":"home/releases/v3.2.0/","title":"v3.2.0","text":"

Released on 2018-08-20.

Feature release. All changes are backward-compatible.

  • Adds a SAX interface and a non-recursive parser.
  • Adds parsing from wide-string types (std::wstring, std::u16string, std::u32string), conversion to std::string_view (C++17), and round-tripping of std::map/std::unordered_map with non-string keys.

Full release notes.

"},{"location":"home/releases/v3.2.0/#api-changes","title":"API changes","text":"

Added (16 pages):

  • basic_json: input_format_t, sax_parse
  • json_sax: (overview), boolean, end_array, end_object, key, null, number_float, number_integer, number_unsigned, parse_error, start_array, start_object, string
  • macros: JSON_SKIP_UNSUPPORTED_COMPILER_CHECK

Changed:

  • basic_json::from_cbor: Added allow_exceptions parameter in version 3.2.0.
  • basic_json::from_msgpack: Added allow_exceptions parameter in version 3.2.0.
  • basic_json::from_ubjson: Added allow_exceptions parameter in version 3.2.0.
"},{"location":"home/releases/v3.3.0/","title":"v3.3.0","text":"

Released on 2018-10-05.

Feature release. All changes are backward-compatible.

  • Adds GCC 4.8 support, the get_to function, and an overhauled and documented CMake integration.

Full release notes.

"},{"location":"home/releases/v3.3.0/#api-changes","title":"API changes","text":"

Added (1 pages):

  • basic_json: get_to
"},{"location":"home/releases/v3.4.0/","title":"v3.4.0","text":"

Released on 2018-10-30.

Feature release. All changes are backward-compatible.

  • Adds BSON read/write support.
  • Adds configurable Unicode error handlers to dump (throw, replace with U+FFFD, or ignore) and the NLOHMANN_JSON_SERIALIZE_ENUM macro for enum conversion.
  • Improves parse-error messages with line/column positions and context.

Full release notes.

"},{"location":"home/releases/v3.4.0/#api-changes","title":"API changes","text":"

Added (3 pages):

  • basic_json: error_handler_t, from_bson, to_bson

Changed:

  • basic_json::dump: Error handlers added in version 3.4.0.
"},{"location":"home/releases/v3.5.0/","title":"v3.5.0","text":"

Released on 2018-12-22.

Feature release. All changes are backward-compatible.

  • Adds structured-binding support via the items function and reading from FILE* in the parse function.
  • Fixes the eofbit handling on input streams and a bug in the BSON SAX parser.

Full release notes.

"},{"location":"home/releases/v3.5.0/#api-changes","title":"API changes","text":"

Changed:

  • basic_json::items: Added structured binding support in version 3.5.0.
"},{"location":"home/releases/v3.6.0/","title":"v3.6.0","text":"

Released on 2019-03-20.

Feature release. All changes are backward-compatible.

  • Reworks the JSON pointer interface (operator/, push_back, parent_pointer, \u2026).
  • Adds a contains function to test for an object key and greatly improves the performance of integer serialization.

Full release notes.

"},{"location":"home/releases/v3.6.0/#api-changes","title":"API changes","text":"

Added (5 pages):

  • basic_json: contains
  • json_pointer: back, operator/, operator/=, push_back
"},{"location":"home/releases/v3.6.1/","title":"v3.6.1","text":"

Released on 2019-03-20.

Fixes a regression (GCC 7/8 compilation) and a <Windows.h> build error introduced in 3.6.0. All changes are backward-compatible. Full release notes.

"},{"location":"home/releases/v3.6.1/#api-changes","title":"API changes","text":"

No documented API changes.

"},{"location":"home/releases/v3.7.0/","title":"v3.7.0","text":"

Released on 2019-07-28.

Convenience features and house-keeping. All changes are backward-compatible.

  • Adds a contains overload that checks a JSON pointer without throwing, a generic to_string, and a return value for emplace_back.

Full release notes.

"},{"location":"home/releases/v3.7.0/#api-changes","title":"API changes","text":"

Changed:

  • basic_json::contains: Overload 3 added.
  • basic_json::emplace_back: Returns reference since 3.7.0.
"},{"location":"home/releases/v3.7.1/","title":"v3.7.1","text":"

Released on 2019-11-06.

Bug-fix release. All changes are backward-compatible.

  • Fixes a segmentation fault when serializing the std::int64_t minimum value and fixes contains for JSON pointers.
  • Allows items with a custom string type and makes json_pointer::back const.

Full release notes.

"},{"location":"home/releases/v3.7.1/#api-changes","title":"API changes","text":"

No documented API changes.

"},{"location":"home/releases/v3.7.2/","title":"v3.7.2","text":"

Released on 2019-11-10.

Fixes a stack overflow for deeply nested input by making the destructor iterative; parsing of JSON text is now bounded only by available memory (the binary-format parsers still recurse). All changes are backward-compatible. Full release notes.

"},{"location":"home/releases/v3.7.2/#api-changes","title":"API changes","text":"

No documented API changes.

"},{"location":"home/releases/v3.7.3/","title":"v3.7.3","text":"

Released on 2019-11-17.

Fixes a regression from 3.7.2 that could yield quadratic complexity in destructor calls. All changes are backward-compatible. Full release notes.

"},{"location":"home/releases/v3.7.3/#api-changes","title":"API changes","text":"

No documented API changes.

"},{"location":"home/releases/v3.8.0/","title":"v3.8.0","text":"

Released on 2020-06-14.

Feature release. All changes are backward-compatible.

  • Introduces a binary value type that is read from and written to CBOR, BSON, and MessagePack, and can be shared between formats.
  • Generalizes the input adapters to read from any LegacyInputIterator container (3\u201310 % faster parsing).
  • Fixes contains for JSON pointers and makes the binary from_cbor/from_msgpack/etc. functions respect allow_exceptions.

Full release notes.

"},{"location":"home/releases/v3.8.0/#api-changes","title":"API changes","text":"

Added (9 pages):

  • basic_json: binary, binary_t, get_binary, is_binary
  • byte_container_with_subtype: (overview), operator==, operator!=, subtype
  • json_sax: binary

Changed:

  • basic_json::back: Binary values are supported since version 3.8.0.
  • basic_json::clear: Added support for binary types in version 3.8.0.
  • basic_json::dump: Serialization of binary values added in version 3.8.0.
  • basic_json::empty: Extended to return false for binary types in version 3.8.0.
  • basic_json::erase: Overload 1: Added support for binary types in version 3.8.0.
  • basic_json::erase: Overload 2: Added support for binary types in version 3.8.0.
  • basic_json::front: Binary values are supported since version 3.8.0.
  • basic_json::get_ptr: Extended to binary types in version 3.8.0.
  • basic_json::get_ref: Extended to binary types in version 3.8.0.
  • basic_json::is_primitive: Extended to return true for binary types in version 3.8.0.
  • basic_json::max_size: Extended to return 1 for binary types in version 3.8.0.
  • basic_json::operator value_t: Added binary type in version 3.8.0.
  • basic_json::size: Extended to return 1 for binary types in version 3.8.0.
  • basic_json::swap: Overload 6 added.
  • basic_json::swap: Overload 7 added.
  • basic_json::to_cbor: Compact representation of floating-point numbers added in version 3.8.0.
  • basic_json::type: Added binary type in version 3.8.0.
  • basic_json::type_name: Added support for binary type in version 3.8.0.
  • basic_json::value_t: Added binary type in version 3.8.0.
  • json_sax: Support for binary values (binary_t, binary) added in version 3.8.0.
"},{"location":"home/releases/v3.9.0/","title":"v3.9.0","text":"

Released on 2020-07-27.

Feature release adding four long-requested features. All changes are backward-compatible.

  • Optional comment parsing in parse via the ignore_comments parameter.
  • ordered_json to preserve the insertion order of object keys.
  • An option to switch off implicit conversions.
  • The NLOHMANN_DEFINE_TYPE_* convenience macros, plus high-precision-number support for UBJSON and CBOR tag handling.

Full release notes.

"},{"location":"home/releases/v3.9.0/#api-changes","title":"API changes","text":"

Added (6 pages):

  • ordered_map
  • basic_json: cbor_tag_handler_t
  • macros: JSON_ASSERT, JSON_USE_IMPLICIT_CONVERSIONS, NLOHMANN_DEFINE_TYPE_INTRUSIVE, NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT, NLOHMANN_DEFINE_TYPE_INTRUSIVE_ONLY_SERIALIZE, NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE, NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT, NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE

Changed:

  • basic_json::accept: Ignoring comments via ignore_comments added in version 3.9.0.
  • basic_json::from_cbor: Added tag_handler parameter in version 3.9.0.
  • basic_json::operator ValueType: Macros JSON_EXPLICIT/JSON_USE_IMPLICIT_CONVERSIONS added in version 3.9.0.
  • basic_json::parse: Ignoring comments via ignore_comments added in version 3.9.0.
  • basic_json::sax_parse: Ignoring comments via ignore_comments added in version 3.9.0.
"},{"location":"home/releases/v3.9.1/","title":"v3.9.1","text":"

Released on 2020-08-06.

Fixes two regressions from 3.9.0. All changes are backward-compatible.

  • Accepts consecutive comments and completes the ordered_json interface (e.g. ordered_json::parse).

Full release notes.

"},{"location":"home/releases/v3.9.1/#api-changes","title":"API changes","text":"

No documented API changes.

"},{"location":"integration/","title":"Integration","text":"

There are several ways to add this header-only library to a C++ project. The following flowchart summarizes how to pick one:

flowchart TD\n    A[Add the library to a C++ project] --> B{{Using CMake?}}\n    B -- no --> C{{Package manager available?}}\n    C -- yes --> D[\"<b>Use a package manager</b><br>see Package Managers\"]\n    C -- no --> E[\"<b>Copy the single header</b><br>see Header only\"]\n    B -- yes --> F{{Already installed?}}\n    F -- yes --> G[\"<b>find_package</b><br>see CMake, External\"]\n    F -- no --> H{{CMake 3.14 or later?}}\n    H -- yes --> I[\"<b>FetchContent</b><br>see CMake, FetchContent\"]\n    H -- no --> J[\"<b>add_subdirectory</b><br>see CMake, Embedded\"]\n    G --> T[\"<code>nlohmann_json::nlohmann_json</code>\"]\n    I --> T\n    J --> T

Choosing an integration method: answer the questions in the hexagons from top to bottom to reach a method. All CMake methods end at the same target, nlohmann_json::nlohmann_json; the list below links to each method.

  • Single header: copy json.hpp into your project; no build-system integration required.
  • CMake, see CMake:
    • find_package() if the library is already installed;
    • FetchContent to download it at configure time (CMake 3.14 or later);
    • add_subdirectory() to embed a vendored copy of the source tree;
    • or support both with an option that selects installed or vendored.
  • Package managers: install the library with Homebrew, Conan, vcpkg, or one of the many others; see Package Managers for the full list.
  • pkg-config: if you use bare Makefiles instead of CMake, pkg-config supplies the include flags for an already-installed library.

Once the library is integrated, see the Migration Guide for how to keep your code future-proof across releases.

"},{"location":"integration/#header-only","title":"Header only","text":"

json.hpp is the single required file in single_include/nlohmann or released here. You need to add

#include <nlohmann/json.hpp>\n\n// for convenience\nusing nlohmann::json;\n

to the files you want to process JSON and set the necessary switches to enable C++11 (e.g., -std=c++11 for GCC and Clang).

Which file do I download?

For a project without a package manager, the library itself, including the _json literals, is one file: json.hpp from the releases page. You do not need to clone the repository, build anything, or link a library. Put the file in a directory named nlohmann that is on your include path (for example third_party/nlohmann/json.hpp with -I third_party), so that #include <nlohmann/json.hpp> works. Download the companion headers listed below only if you use them: json_view.hpp for the zero-copy views, json_fwd.hpp for forward declarations, and json_literals.hpp if you define JSON_NO_AUTOMATIC_UDLS. Keep them in the same nlohmann directory.

Do not copy only parts of the repository's include/ directory: the headers in it include each other and must be kept together. If your IDE reports \"cannot open source file\" while the compiler succeeds, the compiler's include path is set correctly but the IDE's is not; add the same directory to the IDE's include paths.

You can further use file single_include/nlohmann/json_fwd.hpp for forward declarations (see Compile times), and file single_include/nlohmann/json_literals.hpp for the user-defined string literals if you define JSON_NO_AUTOMATIC_UDLS.

For the read-only, non-owning basic_json_document/basic_json_view types, additionally include single_include/nlohmann/json_view.hpp; see Zero-copy JSON views.

"},{"location":"integration/#notes-for-builds-and-distribution","title":"Notes for builds and distribution","text":"

Reproducible and path-independent builds. The runtime assertions use assert, which embeds the name of the source file (__FILE__) in the binary. Release builds do not contain them, because they define NDEBUG. If you compile with assertions enabled and need binaries that do not depend on the build directory, either define NDEBUG or map the prefix of the path with the compiler option -ffile-prefix-map=<old>=<new> (GCC 8 and later, Clang 10 and later). See Runtime assertions.

There is no separate source file to compile. The library is header-only, so there is no .cpp that could be built with different options than the code that includes it. It is also not available as a precompiled library. To compile the library with optimizations in an otherwise unoptimized build (for example to parse large files in a debug build, which is slow because of the unoptimized code and the checks of the debug standard library), keep the code that uses json in a separate source file and set the options for that file only. Compile times shows how to instantiate basic_json once.

Debugger visualization. The Natvis file works with the Visual Studio debugger, including the cppvsdbg engine in Visual Studio Code, but not with debuggers that wrap LLDB, such as codelldb; see Debugging.

"},{"location":"integration/#see-also","title":"See also","text":"
  • CMake - integrate the library into a CMake project
  • Package managers - install the library with a package manager
  • pkg-config - generate include flags for plain Makefiles
  • Compile times - reduce the compile time overhead
  • Migration guide - upgrade from an earlier version
  • Releases - release notes of all versions
  • basic_json - the main class and all its member functions
  • Macros - reference of all macros
  • Supported Macros - configure the library with macros
  • Modules - C++20 module support
  • NLOHMANN_JSON_VERSION_MAJOR - library version macros
"},{"location":"integration/cmake/","title":"CMake","text":""},{"location":"integration/cmake/#integration","title":"Integration","text":"

You can use the nlohmann_json::nlohmann_json interface target in CMake. This target populates the appropriate usage requirements for INTERFACE_INCLUDE_DIRECTORIES to point to the appropriate include directories and INTERFACE_COMPILE_FEATURES for the necessary C++11 flags. Most package managers that provide a CMake package configuration for this library expose this same target.

All ways of adding the library described below end at this one target:

flowchart LR\n    FP[\"<b>find_package()</b><br>installed package\"] --> T\n    AS[\"<b>add_subdirectory()</b><br>embedded source tree\"] --> T\n    FC[\"<b>FetchContent</b><br>downloaded at configure time\"] --> T\n    PM[\"<b>Package manager</b><br>its CMake package\"] --> T\n    T[\"<b>nlohmann_json::nlohmann_json</b><br>one INTERFACE target\"] --> L[\"<b>target_link_libraries()</b><br>link it PRIVATE\"]

The four ways to add the library in CMake all lead to the same nlohmann_json::nlohmann_json interface target, which a project links with target_link_libraries. The CMake options below apply to add_subdirectory() and FetchContent; installed packages have their options fixed at install time.

"},{"location":"integration/cmake/#external","title":"External","text":"

To use this library from a CMake project, you can locate it directly with find_package() and use the namespaced imported target from the generated package configuration:

Example

CMakeLists.txt
cmake_minimum_required(VERSION 3.5)\nproject(ExampleProject LANGUAGES CXX)\n\nfind_package(nlohmann_json 3.12.0 REQUIRED)\n\nadd_executable(example example.cpp)\ntarget_link_libraries(example PRIVATE nlohmann_json::nlohmann_json)\n

The package configuration file, nlohmann_jsonConfig.cmake, can be used either from an install tree or directly out of the build tree.

"},{"location":"integration/cmake/#embedded","title":"Embedded","text":"

To embed the library directly into an existing CMake project, place the entire source tree in a subdirectory and call add_subdirectory() in your CMakeLists.txt file.

Example

CMakeLists.txt
cmake_minimum_required(VERSION 3.5)\nproject(ExampleProject LANGUAGES CXX)\n\n# If you only include this third party in PRIVATE source files, you do not need to install it\n# when your main project gets installed.\nset(JSON_Install OFF CACHE INTERNAL \"\")\n\nadd_subdirectory(nlohmann_json)\n\nadd_executable(example example.cpp)\ntarget_link_libraries(example PRIVATE nlohmann_json::nlohmann_json)\n

Note

Do not use include(nlohmann_json/CMakeLists.txt), since that carries with it unintended consequences that will break the build. It is generally discouraged (although not necessarily well documented as such) to use include(...) for pulling in other CMake projects anyways.

"},{"location":"integration/cmake/#supporting-both","title":"Supporting Both","text":"

To allow your project to support either an externally supplied or an embedded JSON library, you can use a pattern akin to the following.

Example

CMakeLists.txt
project(ExampleProject LANGUAGES CXX)\n\noption(EXAMPLE_USE_EXTERNAL_JSON \"Use an external JSON library\" OFF)\n\nadd_subdirectory(thirdparty)\n\nadd_executable(example example.cpp)\n\n# Note that the namespaced target will always be available regardless of the import method\ntarget_link_libraries(example PRIVATE nlohmann_json::nlohmann_json)\n
thirdparty/CMakeLists.txt
if(EXAMPLE_USE_EXTERNAL_JSON)\n    find_package(nlohmann_json 3.12.0 REQUIRED)\nelse()\n    set(JSON_BuildTests OFF CACHE INTERNAL \"\")\n    add_subdirectory(nlohmann_json)\nendif()\n

thirdparty/nlohmann_json is then a complete copy of this source tree.

"},{"location":"integration/cmake/#fetchcontent","title":"FetchContent","text":"

Since CMake v3.14, FetchContent can be used to automatically download a release as a dependency at configure time.

Example

CMakeLists.txt
cmake_minimum_required(VERSION 3.14)\nproject(ExampleProject LANGUAGES CXX)\n\ninclude(FetchContent)\n\nFetchContent_Declare(json URL https://github.com/nlohmann/json/releases/download/v3.12.0/json.tar.xz)\nFetchContent_MakeAvailable(json)\n\nadd_executable(example example.cpp)\ntarget_link_libraries(example PRIVATE nlohmann_json::nlohmann_json)\n

Note

It is recommended to use the URL approach described above which is supported as of version 3.10.0. It is also possible to pass the Git repository like

FetchContent_Declare(json\n    GIT_REPOSITORY https://github.com/nlohmann/json\n    GIT_TAG v3.12.0\n)\n

However, the repository https://github.com/nlohmann/json download size is quite large.

"},{"location":"integration/cmake/#cmake-options","title":"CMake Options","text":""},{"location":"integration/cmake/#json_buildtests","title":"JSON_BuildTests","text":"

Build the unit tests when BUILD_TESTING is enabled. This option is ON by default if the library's CMake project is the top project and the tests directory exists (the release archive json.tar.xz does not contain it). That is, when integrating the library as described above, the test suite is not built unless explicitly switched on with this option.

"},{"location":"integration/cmake/#json_ci","title":"JSON_CI","text":"

Enable CI build targets. The exact targets are used during the several CI steps and are subject to change without notice. This option is OFF by default.

"},{"location":"integration/cmake/#json_deletedeprecatedfunctions","title":"JSON_DeleteDeprecatedFunctions","text":"

Delete the deprecated functions instead of only deprecating them by defining the macro JSON_DELETE_DEPRECATED_FUNCTIONS. This option is OFF by default.

"},{"location":"integration/cmake/#json_diagnostics","title":"JSON_Diagnostics","text":"

Enable extended diagnostic messages by defining macro JSON_DIAGNOSTICS. This option is OFF by default.

Does not apply to a pre-installed package

This option only takes effect when building nlohmann/json from source as part of your own CMake project (e.g. via FetchContent or add_subdirectory). It has no effect on a package that was already built and installed elsewhere (Homebrew, vcpkg, a system package, etc.) \u2014 the resulting compile definition is baked into the exported nlohmann_jsonTargets.cmake at install time, and set(JSON_Diagnostics ON) before find_package() does not change it (verified against the Homebrew-installed package: the exported target still carries a fixed $<$<BOOL:OFF>:JSON_DIAGNOSTICS=1>, regardless of any variable set in the consuming project).

To enable extended diagnostics for a pre-installed package, override the imported target's property directly after find_package():

find_package(nlohmann_json REQUIRED)\nset_target_properties(nlohmann_json::nlohmann_json PROPERTIES\n    INTERFACE_COMPILE_DEFINITIONS \"JSON_DIAGNOSTICS=1\")\n

This only works cleanly when your project is the sole consumer of that imported target. If nlohmann_json is pulled in from more than one place in your dependency graph with different JSON_DIAGNOSTICS values, you may see a \"JSON_DIAGNOSTICS\" redefined compiler error, since conflicting -D flags can end up on the same compile command line.

"},{"location":"integration/cmake/#json_diagnostic_positions","title":"JSON_Diagnostic_Positions","text":"

Enable position diagnostics by defining macro JSON_DIAGNOSTIC_POSITIONS. This option is OFF by default.

"},{"location":"integration/cmake/#json_disableenumserialization","title":"JSON_DisableEnumSerialization","text":"

Disable default enum serialization by defining the macro JSON_DISABLE_ENUM_SERIALIZATION. This option is OFF by default.

"},{"location":"integration/cmake/#json_disabletuplereferenceconversion","title":"JSON_DisableTupleReferenceConversion","text":"

Disable the conversion from a one-element std::tuple holding a reference to a JSON value by defining the macro JSON_DISABLE_TUPLE_REFERENCE_CONVERSION. This option is OFF by default.

"},{"location":"integration/cmake/#json_fasttests","title":"JSON_FastTests","text":"

Skip expensive/slow test suites. This option is OFF by default. Depends on JSON_BuildTests.

"},{"location":"integration/cmake/#json_globaludls","title":"JSON_GlobalUDLs","text":"

Place user-defined string literals in the global namespace by defining the macro JSON_USE_GLOBAL_UDLS. This option is ON by default; see the migration guide for how to prepare code for the next major release, where the literals are removed from the global namespace.

"},{"location":"integration/cmake/#json_implicitconversions","title":"JSON_ImplicitConversions","text":"

Enable implicit conversions by defining macro JSON_USE_IMPLICIT_CONVERSIONS. This option is ON by default; see the migration guide for how to prepare code for the next major release, where implicit conversions are switched off by default.

"},{"location":"integration/cmake/#json_install","title":"JSON_Install","text":"

Install CMake targets during install step. This option is ON by default if the library's CMake project is the top project. Installing also generates a pkg-config file for tools that rely on pkg-config instead of CMake.

"},{"location":"integration/cmake/#json_legacydiscardedvaluecomparison","title":"JSON_LegacyDiscardedValueComparison","text":"

Enable the (incorrect) legacy comparison behavior of discarded JSON values by defining macro JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON. This option is OFF by default.

"},{"location":"integration/cmake/#json_multipleheaders","title":"JSON_MultipleHeaders","text":"

Use the non-amalgamated version of the library. This option is ON by default.

"},{"location":"integration/cmake/#json_systeminclude","title":"JSON_SystemInclude","text":"

Treat the library headers like system headers (i.e., adding SYSTEM to the target_include_directories call) to check for this library by tools like Clang-Tidy. This option is OFF by default.

"},{"location":"integration/cmake/#json_strictbinaryutf8","title":"JSON_StrictBinaryUTF8","text":"

Check string values and object keys for valid UTF-8 in the CBOR, UBJSON, BJData, and BSON writers, by defining the macro JSON_STRICT_BINARY_UTF8. This option is OFF by default.

"},{"location":"integration/cmake/#json_strictnulhandling","title":"JSON_StrictNulHandling","text":"

Reject a '\\0' (NUL) byte in the input instead of treating it as end of input, by defining the macro JSON_STRICT_NUL_HANDLING. This option is OFF by default.

"},{"location":"integration/cmake/#json_testsimdutf","title":"JSON_TestSimdutf","text":"

Build the unit tests against the simdutf UTF-8 validation backend by defining JSON_USE_SIMDUTF for every test target. simdutf is fetched during configuration; its version is set by the cache variable JSON_SIMDUTF_VERSION. This option is OFF by default. Depends on JSON_BuildTests.

"},{"location":"integration/cmake/#json_valgrind","title":"JSON_Valgrind","text":"

Execute the test suite with Valgrind. This option is OFF by default. Depends on JSON_BuildTests.

"},{"location":"integration/cmake/#nlohmann_json_build_modules","title":"NLOHMANN_JSON_BUILD_MODULES","text":"

Build the experimental C++ module nlohmann.json (requires CMake 3.28 or later and C++20). This option is OFF by default.

A consuming project must link the dedicated nlohmann_json_modules CMake target (not just nlohmann_json::nlohmann_json) for import nlohmann.json; to resolve:

set(NLOHMANN_JSON_BUILD_MODULES ON)\nadd_subdirectory(path/to/json)\n\nadd_executable(myproject main.cpp)\ntarget_link_libraries(myproject PRIVATE nlohmann_json_modules)\ntarget_compile_definitions(myproject PRIVATE NLOHMANN_JSON_BUILD_MODULES)\n
"},{"location":"integration/cmake/#see-also","title":"See also","text":"
  • Macros - reference of all macros
  • Supported Macros - the macros that the CMake options set
  • Modules - C++20 module support
  • nlohmann Namespace - namespace options set by CMake
"},{"location":"integration/compile_times/","title":"Compile times","text":"

The library is header-only and makes heavy use of templates, so every translation unit that includes <nlohmann/json.hpp> pays for parsing the header and instantiating what it uses. This page lists the options to reduce that cost, ordered by how much they typically save.

Measurements

The numbers below are medians of the wall-clock time of nine runs compiling a single translation unit with -std=c++17 -c against the single-header version, with Apple clang 21.0.0 (clang-2100.3.34.2) and Homebrew GCC 16.2.0 on macOS (Apple M1 Max). All configurations were run interleaved, in alternating order. They show the order of magnitude to expect; measure your own code before and after a change.

The translation units are listed below. They replace the ones used for earlier versions of this page, whose sources were not published, so the numbers differ from earlier versions.

Measured translation units

The model and parsing translation units start with #include <string>, #include <vector>, and #include <nlohmann/json.hpp>; the header-only translation unit includes only the library header.

model translation unit
struct person\n{\n    std::string name;\n    int age = 0;\n    std::vector<std::string> tags;\n};\n\nvoid to_json(nlohmann::json& j, const person& p)\n{\n    j = nlohmann::json{{\"name\", p.name}, {\"age\", p.age}, {\"tags\", p.tags}};\n}\n\nvoid from_json(const nlohmann::json& j, person& p)\n{\n    j.at(\"name\").get_to(p.name);\n    j.at(\"age\").get_to(p.age);\n    j.at(\"tags\").get_to(p.tags);\n}\n\nnlohmann::json roundtrip(const person& p)\n{\n    nlohmann::json j = p;\n    return nlohmann::json(j.get<person>());\n}\n
parsing translation unit
std::size_t parse_and_dump(const std::string& s)\n{\n    const nlohmann::json j = nlohmann::json::parse(s);\n    return j.dump(2).size();\n}\n
header-only translation unit
#include <nlohmann/json.hpp> // or <nlohmann/json_fwd.hpp>\n\nstruct person;\nvoid to_json(nlohmann::json& j, const person& p);\nvoid from_json(const nlohmann::json& j, person& p);\n

Change in compile time against the default configuration at -O0, Apple clang and G\u200bCC 16 Grouped horizontal bars, negative is faster. json_fwd.hpp instead of json.hpp on a header-only translation unit: Apple clang -62 %, G\u200bCC 16 -82 %; extern template on a parsing translation unit: Apple clang -7 %, G\u200bCC 16 -21 %; JSON_NO_AUTOMATIC_UDLS on a model translation unit: Apple clang -11 %, G\u200bCC 16 -11 %; JSON_NO_AUTOMATIC_UDLS on a parsing translation unit: Apple clang -1 %, G\u200bCC 16 -2 %; JSON_HAS_FILESYSTEM=0 + JSON_NO_IO on a model translation unit: Apple clang -8 %, G\u200bCC 16 -11 %; JSON_HAS_FILESYSTEM=0 on a model translation unit: Apple clang -5 %, G\u200bCC 16 -9 %; JSON_NO_IO on a model translation unit: Apple clang -2 %, G\u200bCC 16 -2 %; JSON_USE_GLOBAL_UDLS=0 on a model translation unit: Apple clang 0 %, G\u200bCC 16 -1 %. Apple clang G\u200bCC 16 \u221280 % \u221260 % \u221240 % \u221220 % 0 % \u2190 faster slower \u2192 json_fwd.hpp instead of json.hpp \u00b7 header-only TU json_fwd.hpp instead of json.hpp, header-only TU (Apple clang): \u221262 % \u221262 % json_fwd.hpp instead of json.hpp, header-only TU (G\u200bCC 16): \u221282 % \u221282 % extern template \u00b7 parsing TU extern template, parsing TU (Apple clang): \u22127 % \u22127 % extern template, parsing TU (G\u200bCC 16): \u221221 % \u221221 % JSON_NO_AUTOMATIC_UDLS \u00b7 model TU JSON_NO_AUTOMATIC_UDLS, model TU (Apple clang): \u221211 % \u221211 % JSON_NO_AUTOMATIC_UDLS, model TU (G\u200bCC 16): \u221211 % \u221211 % JSON_NO_AUTOMATIC_UDLS \u00b7 parsing TU JSON_NO_AUTOMATIC_UDLS, parsing TU (Apple clang): \u22121 % \u22121 % JSON_NO_AUTOMATIC_UDLS, parsing TU (G\u200bCC 16): \u22122 % \u22122 % JSON_HAS_FILESYSTEM=0 + JSON_NO_IO \u00b7 model TU JSON_HAS_FILESYSTEM=0 + JSON_NO_IO, model TU (Apple clang): \u22128 % \u22128 % JSON_HAS_FILESYSTEM=0 + JSON_NO_IO, model TU (G\u200bCC 16): \u221211 % \u221211 % JSON_HAS_FILESYSTEM=0 \u00b7 model TU JSON_HAS_FILESYSTEM=0, model TU (Apple clang): \u22125 % \u22125 % JSON_HAS_FILESYSTEM=0, model TU (G\u200bCC 16): \u22129 % \u22129 % JSON_NO_IO \u00b7 model TU* JSON_NO_IO, model TU (Apple clang): \u22122 % \u22122 % JSON_NO_IO, model TU (G\u200bCC 16): \u22122 % \u22122 % JSON_USE_GLOBAL_UDLS=0 \u00b7 model TU* JSON_USE_GLOBAL_UDLS=0, model TU (Apple clang): 0 % 0 % JSON_USE_GLOBAL_UDLS=0, model TU (G\u200bCC 16): \u22121 % \u22121 %

Change in compile time at -O0 against the default configuration of the same translation unit, taken from the tables below (medians of nine runs, see above). * computed from the milliseconds in Options without effect on compile times.

"},{"location":"integration/compile_times/#include-json_fwdhpp-in-headers","title":"Include json_fwd.hpp in headers","text":"

Header files that only need to name the json type \u2014 for function declarations, members held by pointer or reference, or friend declarations \u2014 can include <nlohmann/json_fwd.hpp> instead of <nlohmann/json.hpp>. It only forward-declares basic_json, json_pointer, adl_serializer, and ordered_map, and defines the aliases json and ordered_json. The translation units that actually use the values then include <nlohmann/json.hpp>.

person.hpp
#pragma once\n#include <nlohmann/json_fwd.hpp>\n\nstruct person;\nvoid to_json(nlohmann::json& j, const person& p);\nvoid from_json(const nlohmann::json& j, person& p);\n
person.cpp
#include \"person.hpp\"\n#include <nlohmann/json.hpp>\n\nvoid to_json(nlohmann::json& j, const person& p) { /* ... */ }\nvoid from_json(const nlohmann::json& j, person& p) { /* ... */ }\n
Compiler json.hpp (-O0) json_fwd.hpp (-O0) Change Apple clang 868 ms 332 ms \u221262% GCC 16 1164 ms 210 ms \u221282%

Compile time of the header-only translation unit at -O0 with each header, as the median wall-clock time of nine runs (see \"Measurements\" above). A negative change means a faster build.

This is the most effective option, because it avoids the full header in every translation unit that includes your headers.

"},{"location":"integration/compile_times/#opt-out-of-the-automatic-user-defined-string-literals","title":"Opt out of the automatic user-defined string literals","text":"

The user-defined string literals operator\"\"_json and operator\"\"_json_pointer are ordinary inline functions whose bodies call the parser. As <nlohmann/json.hpp> includes them by default, every translation unit instantiates the parser, even if it never parses anything itself.

Define JSON_NO_AUTOMATIC_UDLS for the whole project and include <nlohmann/json_literals.hpp> instead of <nlohmann/json.hpp> in the files that use the literals (it includes <nlohmann/json.hpp> itself):

target_compile_definitions(my_target PRIVATE JSON_NO_AUTOMATIC_UDLS)\n
#include <nlohmann/json_literals.hpp> // only where \"...\"_json is used; includes <nlohmann/json.hpp>\n

The saving applies to translation units that do not parse JSON, for example ones that define types and their conversions or only pass json values around:

Compiler Translation unit Default (-O0 / -O2) JSON_NO_AUTOMATIC_UDLS (-O0 / -O2) Change Apple clang model 1051 ms / 1300 ms 935 ms / 1170 ms \u221211% / \u221210% GCC 16 model 1801 ms / 2106 ms 1598 ms / 1983 ms \u221211% / \u22126% Apple clang parsing 1157 ms / 2016 ms 1146 ms / 2006 ms \u22121% / 0% GCC 16 parsing 2529 ms / 4087 ms 2484 ms / 4059 ms \u22122% / \u22121%

Compile time of the model and parsing translation units without and with JSON_NO_AUTOMATIC_UDLS, at -O0 and -O2.

The model translation unit saves about a tenth. Translation units that parse anyway instantiate the parser regardless and see no difference.

"},{"location":"integration/compile_times/#instantiate-basic_json-once","title":"Instantiate basic_json once","text":"

Each translation unit instantiates the member functions of nlohmann::json it uses. An explicit instantiation declaration tells the compiler that the non-template members are instantiated elsewhere, so it can skip them:

json_instance.hpp
#pragma once\n#include <nlohmann/json.hpp>\n\nextern template class nlohmann::basic_json<>;\n
json_instance.cpp
#include \"json_instance.hpp\"\n\ntemplate class nlohmann::basic_json<>;\n

Include json_instance.hpp instead of <nlohmann/json.hpp> and compile and link json_instance.cpp once.

Compiler Translation unit Default (-O0 / -O2) extern template (-O0 / -O2) Change Apple clang parsing 1157 ms / 2016 ms 1071 ms / 1844 ms \u22127% / \u22129% GCC 16 parsing 2529 ms / 4087 ms 1994 ms / 3190 ms \u221221% / \u221222% Apple clang json_instance.cpp \u2014 2573 ms / 6221 ms \u2014 GCC 16 json_instance.cpp \u2014 6489 ms / 13759 ms \u2014

Compile time of the parsing translation unit without and with the extern template declaration, at -O0 and -O2. The json_instance.cpp rows are the one-off cost of the translation unit that holds the instantiation.

Notes:

  • The saving grows with the number of translation units that use json, while the instantiation translation unit is compiled only once (and is rarely recompiled, as it does not depend on your code).
  • Member function templates (such as get<T>(), parse(InputType&&), or value(key, default)) are not covered by the explicit instantiation and are still instantiated where they are used.
  • The declaration covers exactly nlohmann::json. Add the same lines for nlohmann::ordered_json (nlohmann::basic_json<nlohmann::ordered_map>) or your own basic_json specializations if you use them.
"},{"location":"integration/compile_times/#switch-off-filesystem-support","title":"Switch off filesystem support","text":"

With C++17, the library includes <filesystem> to provide conversions from and to std::filesystem::path (see JSON_HAS_FILESYSTEM). Parsing <filesystem> is a fixed cost in every translation unit, and it also pulls in <iomanip>, <istream>, and <ostream> (and, with GCC's libstdc++, <sstream>). If you do not convert paths, switch the detection off for the whole project:

target_compile_definitions(my_target PRIVATE JSON_HAS_FILESYSTEM=0 JSON_HAS_EXPERIMENTAL_FILESYSTEM=0)\n
Compiler Translation unit Default (-O0 / -O2) Filesystem off (-O0 / -O2) Change Apple clang model 1051 ms / 1300 ms 998 ms / 1257 ms \u22125% / \u22123% GCC 16 model 1801 ms / 2106 ms 1636 ms / 2008 ms \u22129% / \u22125% Apple clang parsing 1157 ms / 2016 ms 1107 ms / 1971 ms \u22124% / \u22122% GCC 16 parsing 2529 ms / 4087 ms 2405 ms / 4029 ms \u22125% / \u22121%

Compile time with JSON_HAS_FILESYSTEM=0 and JSON_HAS_EXPERIMENTAL_FILESYSTEM=0 against the default configuration, at -O0 and -O2.

Only with filesystem support switched off does JSON_NO_IO remove the stream headers from the translation unit, so the two macros save most together:

Compiler Translation unit Default (-O0 / -O2) Filesystem off and JSON_NO_IO (-O0 / -O2) Change Apple clang model 1051 ms / 1300 ms 969 ms / 1219 ms \u22128% / \u22126% GCC 16 model 1801 ms / 2106 ms 1605 ms / 1982 ms \u221211% / \u22126% Apple clang parsing 1157 ms / 2016 ms 1083 ms / 1947 ms \u22126% / \u22123% GCC 16 parsing 2529 ms / 4087 ms 2384 ms / 3972 ms \u22126% / \u22123%

Compile time with filesystem support switched off and JSON_NO_IO defined, against the default configuration, at -O0 and -O2.

The trade-off: the library's own to_json/from_json overloads for std::filesystem::path (which store the path as UTF-8) are removed. In a test with both compilers on macOS, paths still converted through their implicit conversion from and to std::string; whether that fallback exists depends on the platform's native path string type (std::wstring on Windows), so check code that converts paths. JSON_NO_IO additionally removes all stream functions (see Options without effect).

"},{"location":"integration/compile_times/#use-c20-modules","title":"Use C++20 modules","text":"

With a toolchain that supports named modules, import nlohmann.json; compiles the library once into a module and avoids parsing the header in every translation unit. See Modules for requirements and known issues. Module support is experimental and currently depends heavily on the compiler version.

Compile time per translation unit with import nlohmann.json at -O0, and the one-off cost of the module Horizontal bars, negative is faster, medians of nine runs, -std=c++20 for both. model TU, Apple clang: -48 % (1311 ms to 680 ms); model TU, G\u200bCC 16: -47 % (2156 ms to 1153 ms); parsing TU, Apple clang: -42 % (1387 ms to 800 ms); parsing TU, G\u200bCC 16: -36 % (2838 ms to 1810 ms); one-off build, Apple clang: 1630 ms; one-off build, G\u200bCC 16: 2538 ms. Apple clang G\u200bCC 16 \u221250 % \u221225 % 0 % \u2190 faster per TU model TU \u00b7 import nlohmann.json model TU, Apple clang: 1311 ms by default, 680 ms import nlohmann.json (\u221248 %) \u221248 % model TU, G\u200bCC 16: 2156 ms by default, 1153 ms import nlohmann.json (\u221247 %) \u221247 % parsing TU \u00b7 import nlohmann.json parsing TU, Apple clang: 1387 ms by default, 800 ms import nlohmann.json (\u221242 %) \u221242 % parsing TU, G\u200bCC 16: 2838 ms by default, 1810 ms import nlohmann.json (\u221236 %) \u221236 % One-off cost \u00b7 built once, reused by every TU Apple clang: 1630 ms once, saves 587 to 631 ms per TU G\u200bCC 16: 2538 ms once, saves 1003 to 1028 ms per TU

Change in compile time per translation unit at -O0 when #include <nlohmann/json.hpp> is replaced by import nlohmann.json;, both with -std=c++20, and the one-off cost of building the module, taken from the table below.

Compiler Translation unit #include (-O0 / -O2) import nlohmann.json; (-O0 / -O2) Change Apple clang model 1311 ms / 1597 ms 680 ms / 914 ms \u221248% / \u221243% GCC 16 model 2156 ms / 2588 ms 1153 ms / 1580 ms \u221247% / \u221239% Apple clang parsing 1387 ms / 2319 ms 800 ms / 1676 ms \u221242% / \u221228% GCC 16 parsing 2838 ms / 4520 ms 1810 ms / 3476 ms \u221236% / \u221223% Apple clang json.cppm (module) \u2014 1630 ms / 1642 ms \u2014 GCC 16 json.cppm (module) \u2014 2538 ms / 2547 ms \u2014

Compile time with #include <nlohmann/json.hpp> and with import nlohmann.json;, both with -std=c++20, at -O0 and -O2. The json.cppm rows are the one-off cost of building the module.

Both columns use -std=c++20; with -std=c++17, the #include baseline is 17% to 20% faster (see the next section). The module is built once per set of compiler flags and pays for itself from about the third translation unit that imports it. Notes from the measurement:

  • Apple clang only accepts the module declarations with -fcxx-modules; without it, module; is a syntax error.
  • GCC 16 warns with -Wexpose-global-module-tu-local about internal constants of the library when building the module. With GCC 16.2, including <string> and <vector> before import nlohmann.json; works, but including them after it fails with redefinition errors (#5103).
How these numbers were measured

The model and parsing translation units are the ones listed at the top of this page, with import nlohmann.json; in place of #include <nlohmann/json.hpp> (after #include <string> and #include <vector>). Same method as for the other tables, with -std=c++20.

# Apple clang: build the module once, then import it\nclang++ -std=c++20 -fcxx-modules -O0 -I single_include -c -x c++-module src/modules/json.cppm \\\n    -fmodule-output=nlohmann.json.pcm -o json_mod.o\nclang++ -std=c++20 -fcxx-modules -O0 -fmodule-file=nlohmann.json=nlohmann.json.pcm -c model.cpp\n\n# GCC 16 (Homebrew on macOS): writes gcm.cache/nlohmann.json.gcm, found by the importing translation unit\ng++-16 --sysroot=$(xcrun --show-sdk-path) -std=c++20 -fmodules -O0 -I single_include -c src/modules/json.cppm \\\n    -o json_mod.o\ng++-16 --sysroot=$(xcrun --show-sdk-path) -std=c++20 -fmodules -O0 -c model.cpp\n

Link json_mod.o into the program.

"},{"location":"integration/compile_times/#use-precompiled-headers","title":"Use precompiled headers","text":"

Build systems can precompile <nlohmann/json.hpp> together with other stable headers, for example with CMake's target_precompile_headers:

target_precompile_headers(my_target PRIVATE <nlohmann/json.hpp>)\n

This removes the cost of parsing the header, but not of instantiating templates in each translation unit, so it combines well with the options above.

Compile time per translation unit with a precompiled json.hpp at -O0, and the one-off cost of the PCH Horizontal bars, negative is faster, medians of nine runs, -std=c++17. model TU, Apple clang: -43 % (1045 ms to 594 ms); model TU, G\u200bCC 16: -41 % (1789 ms to 1060 ms); parsing TU, Apple clang: -38 % (1148 ms to 714 ms); parsing TU, G\u200bCC 16: -25 % (2498 ms to 1884 ms); one-off build, Apple clang: 771 ms; one-off build, G\u200bCC 16: 2254 ms. Apple clang G\u200bCC 16 \u221250 % \u221225 % 0 % \u2190 faster per TU model TU \u00b7 with PCH model TU, Apple clang: 1045 ms by default, 594 ms with PCH (\u221243 %) \u221243 % model TU, G\u200bCC 16: 1789 ms by default, 1060 ms with PCH (\u221241 %) \u221241 % parsing TU \u00b7 with PCH parsing TU, Apple clang: 1148 ms by default, 714 ms with PCH (\u221238 %) \u221238 % parsing TU, G\u200bCC 16: 2498 ms by default, 1884 ms with PCH (\u221225 %) \u221225 % One-off cost \u00b7 built once, reused by every TU Apple clang: 771 ms once, saves 434 to 451 ms per TU G\u200bCC 16: 2254 ms once, saves 614 to 729 ms per TU

Change in compile time per translation unit at -O0 with a precompiled <nlohmann/json.hpp> (-std=c++17), and the one-off cost of building the precompiled header, taken from the table below.

Compiler Translation unit Default (-O0 / -O2) With PCH (-O0 / -O2) Change Apple clang model 1045 ms / 1295 ms 594 ms / 842 ms \u221243% / \u221235% GCC 16 model 1789 ms / 2101 ms 1060 ms / 1376 ms \u221241% / \u221235% Apple clang parsing 1148 ms / 2008 ms 714 ms / 1584 ms \u221238% / \u221221% GCC 16 parsing 2498 ms / 4075 ms 1884 ms / 3452 ms \u221225% / \u221215% Apple clang building the PCH \u2014 771 ms / 760 ms \u2014 GCC 16 building the PCH \u2014 2254 ms / 2218 ms \u2014

Compile time without and with a precompiled <nlohmann/json.hpp>, at -O0 and -O2. The last two rows are the one-off cost of building the precompiled header.

The saving is largest in translation units that instantiate little, and the PCH pays for itself from the second (Apple clang) or fourth (GCC) translation unit. A precompiled header only works with the flags it was built with: GCC silently ignores a mismatching .gch file (for example one built with another -O level) unless -Winvalid-pch is given.

How these numbers were measured

pch.hpp contains only #include <nlohmann/json.hpp>; the translation units are the ones listed at the top of this page.

# Apple clang\nclang++ -std=c++17 -O0 -I single_include -x c++-header pch.hpp -o pch.hpp.pch\nclang++ -std=c++17 -O0 -I single_include -include-pch pch.hpp.pch -include pch.hpp -c model.cpp\n\n# GCC 16 (Homebrew on macOS): pch.hpp.gch next to pch.hpp is picked up by -include pch.hpp\ng++-16 --sysroot=$(xcrun --show-sdk-path) -std=c++17 -O0 -I single_include -x c++-header pch.hpp -o pch.hpp.gch\ng++-16 --sysroot=$(xcrun --show-sdk-path) -std=c++17 -O0 -I single_include -include pch.hpp -Winvalid-pch -c model.cpp\n
"},{"location":"integration/compile_times/#options-without-effect-on-compile-times","title":"Options without effect on compile times","text":"

Some configuration macros change what the library declares, but do not measurably change compile times:

Macro Apple clang, model (-O0 / -O2) GCC 16, model (-O0 / -O2) default 1051 ms / 1300 ms 1801 ms / 2106 ms JSON_NO_IO 1034 ms / 1288 ms 1756 ms / 2087 ms JSON_USE_GLOBAL_UDLS=0 1055 ms / 1298 ms 1783 ms / 2109 ms

Compile time of the model translation unit with each macro defined; the first row is the default configuration for comparison.

JSON_NO_IO removes the library's stream functions and its #includes of <istream> and <ostream>, but with the default C++17 settings <filesystem> includes these headers anyway (and with libc++, <vector> already includes <streambuf> via <locale>), so only a few hundred lines of the library's own stream code go away. It also does not change what the translation unit instantiates. On the parsing translation unit, the change is 0% / 0% (Apple clang) and \u22122% / 0% (GCC). To get a saving, combine it with switching off filesystem support.

JSON_USE_GLOBAL_UDLS only controls where the literals are declared; to avoid their cost, use JSON_NO_AUTOMATIC_UDLS instead.

"},{"location":"integration/compile_times/#see-also","title":"See also","text":"
  • JSON_HAS_FILESYSTEM - control the conversions from and to std::filesystem::path
  • JSON_NO_AUTOMATIC_UDLS - do not include the user-defined string literals automatically
  • Modules - C++20 module support
  • Header only - including the library
  • Macros - reference of all macros
  • Supported Macros - overview of all configuration macros
  • Performance - run-time performance
  • JSON_NO_IO - remove all stream and file I/O
"},{"location":"integration/migration_guide/","title":"Migration Guide","text":"

This page collects some guidelines on how to future-proof your code for future versions of this library. For how to add the library to your project in the first place, see Integration, CMake, or Package Managers. The roadmap lists what will change in version 4.0, including the macros that let you try its behavior with a 3.x release; this page describes how to adjust your code.

"},{"location":"integration/migration_guide/#replace-deprecated-functions","title":"Replace deprecated functions","text":"

The following functions have been deprecated and will be removed in the next major version (i.e., 4.0.0), see the roadmap for an overview. All deprecations are annotated with HEDLEY_DEPRECATED_FOR to report which function to use instead.

Find all calls of deprecated functions

Define JSON_DELETE_DEPRECATED_FUNCTIONS to 1 (or set the CMake option JSON_DeleteDeprecatedFunctions) to delete all deprecated functions. Every remaining call then fails to compile, even if deprecation warnings are disabled, so your code is ready for version 4.0.0 unreleased once it compiles with the macro.

"},{"location":"integration/migration_guide/#parsing","title":"Parsing","text":"
  • Function friend std::istream& operator<<(basic_json&, std::istream&) is deprecated since 3.0.0. Please use friend std::istream& operator>>(std::istream&, basic_json&) instead.

    DeprecatedFuture-proof
    nlohmann::json j;\nstd::stringstream ss(\"[1,2,3]\");\nj << ss;\n
    nlohmann::json j;\nstd::stringstream ss(\"[1,2,3]\");\nss >> j;\n
  • Passing iterator pairs or pointer/length pairs to parsing functions (parse, accept, sax_parse, from_cbor, from_msgpack, from_ubjson, and from_bson) via initializer lists is deprecated since 3.8.0. Instead, pass two iterators; for instance, call from_cbor(ptr, ptr+len) instead of from_cbor({ptr, len}). Likewise, passing a pointer and a length as two separate arguments to from_cbor, from_msgpack, from_ubjson, and from_bson is deprecated since 3.8.0, and to from_bjdata and from_bon8 since 3.13.0; call from_cbor(ptr, ptr+len) instead of from_cbor(ptr, len). These overloads will not be removed in version 4.0.0, but deleted, so a call like from_cbor(ptr, len) cannot compile and convert len to the strict parameter.

    DeprecatedFuture-proof
    const char* s = \"[1,2,3]\";\nbool ok = nlohmann::json::accept({s, s + std::strlen(s)});\n
    const char* s = \"[1,2,3]\";\nbool ok = nlohmann::json::accept(s, s + std::strlen(s));\n
"},{"location":"integration/migration_guide/#json-pointers","title":"JSON Pointers","text":"
  • Comparing JSON Pointers with strings via operator== and operator!= is deprecated since 3.11.2. To compare a json_pointer p with a string s, convert s to a json_pointer first and use json_pointer::operator== or json_pointer::operator!=.

    DeprecatedFuture-proof
    nlohmann::json::json_pointer lhs(\"/foo/bar/1\");\nassert(lhs == \"/foo/bar/1\");\n
    nlohmann::json::json_pointer lhs(\"/foo/bar/1\");\nassert(lhs == nlohmann::json::json_pointer(\"/foo/bar/1\"));\n
  • The implicit conversion from JSON Pointers to string (json_pointer::operator string_t) is deprecated since 3.11.0. Use json_pointer::to_string instead.

    DeprecatedFuture-proof
    nlohmann::json::json_pointer ptr(\"/foo/bar/1\");\nstd::string s = ptr;\n
    nlohmann::json::json_pointer ptr(\"/foo/bar/1\");\nstd::string s = ptr.to_string();\n
  • Passing a basic_json specialization as template parameter RefStringType to json_pointer is deprecated since 3.11.0. The string type can now be directly provided. This also applies to passing such a JSON pointer to at, contains, operator[], and value.

    DeprecatedFuture-proof
    using my_json = nlohmann::json::with_string_t<my_string_type>;\nnlohmann::json_pointer<my_json> ptr(\"/foo/bar/1\");\n
    nlohmann::json_pointer<my_string_type> ptr(\"/foo/bar/1\");\n

    Thereby, my_json::json_pointer is an alias for nlohmann::json_pointer<my_string_type>; in general, basic_json::json_pointer is always an alias to the json_pointer with the appropriate string type for all specializations of basic_json.

"},{"location":"integration/migration_guide/#miscellaneous-functions","title":"Miscellaneous functions","text":"
  • The function iterator_wrapper is deprecated since 3.1.0. Please use the member function items instead.

    DeprecatedFuture-proof
    for (auto &x : nlohmann::json::iterator_wrapper(j))\n{\n    std::cout << x.key() << \":\" << x.value() << std::endl;\n}\n
    for (auto &x : j.items())\n{\n    std::cout << x.key() << \":\" << x.value() << std::endl;\n}\n
  • Function friend std::ostream& operator>>(const basic_json&, std::ostream&) is deprecated since 3.0.0. Please use friend operator<<(std::ostream&, const basic_json&) instead.

    DeprecatedFuture-proof
    j >> std::cout;\n
    std::cout << j;\n
  • The legacy comparison behavior for discarded values is deprecated since 3.11.0. It is already disabled by default and can still be enabled by defining JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON to 1.

    DeprecatedFuture-proof
    #define JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON 1\n#include <nlohmann/json.hpp>\n
    #include <nlohmann/json.hpp>\n
"},{"location":"integration/migration_guide/#replace-implicit-conversions","title":"Replace implicit conversions","text":"

Implicit conversions via operator ValueType will be switched off by default in the next major release of the library.

You can prepare existing code by already defining JSON_USE_IMPLICIT_CONVERSIONS to 0 and replace any implicit conversions with calls to get, get_to, get_ref, or get_ptr.

Automatic migration

The community-maintained clang-tidy check modernize-nlohmann-json-explicit-conversions rewrites most implicit conversions into calls to get. It is not part of clang-tidy itself; see discussion #4610 for how to build and use it.

DeprecatedFuture-proofFuture-proof (alternative)
nlohmann::json j = \"Hello, world!\";\nstd::string s = j;\n
nlohmann::json j = \"Hello, world!\";\nauto s = j.get<std::string>();\n
nlohmann::json j = \"Hello, world!\";\nstd::string s;\nj.get_to(s);\n
"},{"location":"integration/migration_guide/#import-namespace-literals-for-udls","title":"Import namespace literals for UDLs","text":"

The user-defined string literals operator\"\"_json and operator\"\"_json_pointer will be removed from the global namespace in the next major release of the library.

DeprecatedFuture-proof
nlohmann::json j = \"[1,2,3]\"_json;\n
using namespace nlohmann::literals;\nnlohmann::json j = \"[1,2,3]\"_json;\n

To prepare existing code, define JSON_USE_GLOBAL_UDLS to 0 and bring the string literals into scope where needed.

"},{"location":"integration/migration_guide/#do-not-hard-code-the-complete-library-namespace","title":"Do not hard-code the complete library namespace","text":"

The nlohmann namespace contains a sub-namespace to avoid problems when different versions or configurations of the library are used in the same project. Always use nlohmann as namespace or, when the exact version and configuration is relevant, use macro NLOHMANN_JSON_NAMESPACE to denote the namespace.

DangerousFuture-proofFuture-proof (alternative)
void to_json(nlohmann::json_abi_v3_11_2::json& j, const person& p)\n{\n    j[\"age\"] = p.age;\n}\n
void to_json(nlohmann::json& j, const person& p)\n{\n    j[\"age\"] = p.age;\n}\n
void to_json(NLOHMANN_JSON_NAMESPACE::json& j, const person& p)\n{\n    j[\"age\"] = p.age;\n}\n
"},{"location":"integration/migration_guide/#do-not-use-the-detail-namespace","title":"Do not use the detail namespace","text":"

The nlohmann::detail namespace is not part of the public API of the library and can change in any version without an announcement. Do not rely on any function or type in the detail namespace.

"},{"location":"integration/migration_guide/#see-also","title":"See also","text":"
  • JSON_DELETE_DEPRECATED_FUNCTIONS - remove deprecated functions to check the migration
  • JSON_USE_IMPLICIT_CONVERSIONS - control implicit conversions
  • NLOHMANN_JSON_NAMESPACE - refer to the library namespace without hard-coding it
  • nlohmann Namespace - how the library namespace is structured
  • Converting values - explicit conversions with get
  • basic_json - the main class and all its member functions
"},{"location":"integration/package_managers/","title":"Package Managers","text":"

Homebrew nlohmann-json Meson nlohmann_json Bazel nlohmann_json Conan nlohmann_json Spack nlohmann-json Hunter nlohmann_json vcpkg nlohmann-json cget nlohmann/json Swift Package Manager nlohmann/json NuGet nlohmann.json Conda nlohmann_json MacPorts nlohmann-json CPM.cmake gh:nlohmann/json xmake nlohmann_json

"},{"location":"integration/package_managers/#running-example","title":"Running example","text":"

Throughout this page, we will describe how to compile the example file example.cpp below.

#include <nlohmann/json.hpp>\n#include <iostream>\n#include <iomanip>\n\nusing nlohmann::json;\n\nint main()\n{\n    std::cout << std::setw(4) << json::meta() << std::endl;\n}\n

When executed, this program should create output similar to

{\n    \"compiler\": {\n        \"c++\": \"201103\",\n        \"family\": \"gcc\",\n        \"version\": \"12.4.0\"\n    },\n    \"copyright\": \"(C) 2013-2026 Niels Lohmann\",\n    \"name\": \"JSON for Modern C++\",\n    \"platform\": \"apple\",\n    \"url\": \"https://github.com/nlohmann/json\",\n    \"version\": {\n        \"major\": 3,\n        \"minor\": 12,\n        \"patch\": 0,\n        \"string\": \"3.12.0\"\n    }\n}\n

Many of the package managers below install a CMake package configuration that exposes the same nlohmann_json::nlohmann_json interface target described in CMake; their CMake examples below link against that target.

"},{"location":"integration/package_managers/#homebrew","title":"Homebrew","text":"

Summary

formula: nlohmann-json

  • Available versions: current version and development version (with --HEAD parameter)
  • The formula is updated with every release.
  • Maintainer: Niels Lohmann
  • File issues at the Homebrew issue tracker
  • Homebrew website

If you are using Homebrew, you can install the library with

brew install nlohmann-json\n

The header can be used directly in your code or via CMake.

Example: Raw compilation
  1. Create the following file:

    example.cpp
    #include <nlohmann/json.hpp>\n#include <iostream>\n#include <iomanip>\n\nusing nlohmann::json;\n\nint main()\n{\n    std::cout << std::setw(4) << json::meta() << std::endl;\n}\n
  2. Install the package:

    brew install nlohmann-json\n
  3. Compile the code and pass the Homebrew prefix to the include path such that the library can be found:

    c++ example.cpp -I$(brew --prefix nlohmann-json)/include -std=c++11 -o example\n
Example: CMake
  1. Create the following files:

    example.cpp
    #include <nlohmann/json.hpp>\n#include <iostream>\n#include <iomanip>\n\nusing nlohmann::json;\n\nint main()\n{\n    std::cout << std::setw(4) << json::meta() << std::endl;\n}\n
    CMakeLists.txt
    cmake_minimum_required(VERSION 3.15)\nproject(json_example)\n\nfind_package(nlohmann_json CONFIG REQUIRED)\n\nadd_executable(json_example example.cpp)\ntarget_link_libraries(json_example PRIVATE nlohmann_json::nlohmann_json)\n
  2. Install the package:

    brew install nlohmann-json\n
  3. Compile the code and pass the Homebrew prefix to CMake to find installed packages via find_package:

    CMAKE_PREFIX_PATH=$(brew --prefix) cmake -S . -B build\ncmake --build build\n
"},{"location":"integration/package_managers/#meson","title":"Meson","text":"

Summary

wrap: nlohmann_json

  • Available versions: current version and select older versions (see WrapDB)
  • The package is updated automatically from file meson.build.
  • File issues at the library issue tracker
  • Meson website

If you are using the Meson Build System, add this source tree as a meson subproject. You may also use the include.zip published in this project's Releases to reduce the size of the vendored source tree. Alternatively, you can get a wrap file by downloading it from Meson WrapDB, or use

meson wrap install nlohmann_json\n

Please see the Meson project for any issues regarding the packaging.

The provided meson.build can also be used as an alternative to CMake for installing nlohmann_json system-wide in which case a pkg-config file and the CMake package config files are installed. To use it, have your build system require the nlohmann_json pkg-config dependency, or use find_package(nlohmann_json) in CMake. In Meson, it is preferred to use the dependency() object with a subproject fallback, rather than using the subproject directly.

The options that change the library's configuration are available in Meson as well, named like the CMake options without the JSON_ prefix: MultipleHeaders, GlobalUDLs, ImplicitConversions, DisableEnumSerialization, DisableTupleReferenceConversion, Diagnostics, Diagnostic_Positions, LegacyDiscardedValueComparison, StrictNulHandling, StrictBinaryUTF8, and DeleteDeprecatedFunctions. They have the same defaults as in CMake, except that MultipleHeaders is false. Set them with -D when setting up the build, or with the subproject name as prefix when the library is used as a subproject:

meson setup build -Dnlohmann_json:Diagnostics=true\n

The resulting compile definitions are part of the Meson dependency, the pkg-config file, and the CMake target.

Example: Wrap
  1. Create the following files:

    meson.build
    project('json_example', 'cpp',\n  version: '1.0',\n  default_options: ['cpp_std=c++11']\n)\n\ndependency_json = dependency('nlohmann_json', required: true)\n\nexecutable('json_example',\n  sources: ['example.cpp'],\n  dependencies: [dependency_json],\n  install: true\n)\n
    example.cpp
    #include <nlohmann/json.hpp>\n#include <iostream>\n#include <iomanip>\n\nusing nlohmann::json;\n\nint main()\n{\n    std::cout << std::setw(4) << json::meta() << std::endl;\n}\n
  2. Use the Meson WrapDB to fetch the nlohmann/json wrap:

    mkdir subprojects\nmeson wrap install nlohmann_json\n
  3. Build:

    meson setup build\nmeson compile -C build\n
"},{"location":"integration/package_managers/#bazel","title":"Bazel","text":"

Summary

use bazel_dep, git_override, or local_path_override

  • Any version, that is available via Bazel Central Registry
  • File issues at the library issue tracker
  • Bazel website

This repository provides a Bazel MODULE.bazel and a corresponding BUILD.bazel file. Therefore, this repository can be referenced within a MODULE.bazel by rules such as archive_override, git_override, or local_path_override. To use the library, you need to depend on the target @nlohmann_json//:json (i.e., via deps attribute).

Example: Bazel module with bazel_dep
  1. Create the following files:

    BUILD
    cc_binary(\n    name = \"main\",\n    srcs = [\"example.cpp\"],\n    deps = [\"@nlohmann_json//:json\"],\n)\n
    MODULE.bazel
    bazel_dep(name = \"nlohmann_json\", version = \"3.12.0.bcr.2\")\n
    example.cpp
    #include <nlohmann/json.hpp>\n#include <iostream>\n#include <iomanip>\n\nusing nlohmann::json;\n\nint main()\n{\n    std::cout << std::setw(4) << json::meta() << std::endl;\n}\n
  2. Build and run:

    bazel build //:main\nbazel run //:main\n
"},{"location":"integration/package_managers/#conan","title":"Conan","text":"

Summary

recipe: nlohmann_json

  • Available versions: current version and older versions (see Conan Center)
  • The package is updated automatically via this recipe.
  • File issues at the Conan Center issue tracker
  • Conan website

If you are using Conan to manage your dependencies, merely add nlohmann_json/x.y.z to your conanfile's requires, where x.y.z is the release version you want to use.

Example: CMake with the Conan toolchain
  1. Create the following files:

    Conanfile.txt
    [requires]\nnlohmann_json/3.12.0\n\n[generators]\nCMakeToolchain\nCMakeDeps\n
    CMakeLists.txt
    cmake_minimum_required(VERSION 3.15)\nproject(json_example)\n\nfind_package(nlohmann_json REQUIRED)\n\nadd_executable(json_example example.cpp)\ntarget_link_libraries(json_example PRIVATE nlohmann_json::nlohmann_json)\n
    example.cpp
    #include <nlohmann/json.hpp>\n#include <iostream>\n#include <iomanip>\n\nusing nlohmann::json;\n\nint main()\n{\n    std::cout << std::setw(4) << json::meta() << std::endl;\n}\n
  2. Call Conan:

    conan install . --output-folder=build --build=missing\n
  3. Build:

    cmake -S . -B build -DCMAKE_TOOLCHAIN_FILE=\"conan_toolchain.cmake\" -DCMAKE_BUILD_TYPE=Release\ncmake --build build\n
"},{"location":"integration/package_managers/#spack","title":"Spack","text":"

Summary

package: nlohmann-json

  • Available versions: current version and older versions (see Spack package)
  • The package is updated with every release.
  • Maintainer: Axel Huebl
  • File issues at the Spack issue tracker
  • Spack website

If you are using Spack to manage your dependencies, you can use the nlohmann-json package via

spack install nlohmann-json\n

Please see the Spack project for any issues regarding the packaging.

Example: CMake with a Spack-installed package
  1. Create the following files:

    CMakeLists.txt
    cmake_minimum_required(VERSION 3.15)\nproject(json_example)\n\nfind_package(nlohmann_json REQUIRED)\n\nadd_executable(json_example example.cpp)\ntarget_link_libraries(json_example PRIVATE nlohmann_json::nlohmann_json)\n
    example.cpp
    #include <nlohmann/json.hpp>\n#include <iostream>\n#include <iomanip>\n\nusing nlohmann::json;\n\nint main()\n{\n    std::cout << std::setw(4) << json::meta() << std::endl;\n}\n
  2. Install the library:

    spack install nlohmann-json\n
  3. Load the environment for your Spack-installed packages:

    spack load nlohmann-json\n
  4. Build the project with CMake:

    cmake -S . -B build -DCMAKE_PREFIX_PATH=$(spack location -i nlohmann-json)\ncmake --build build\n
"},{"location":"integration/package_managers/#hunter","title":"Hunter","text":"

Summary

package: nlohmann_json

  • Available versions: current version and older versions (see Hunter package)
  • The package is updated with every release.
  • File issues at the Hunter issue tracker
  • Hunter website

If you are using Hunter on your project for external dependencies, then you can use the nlohmann_json package via

hunter_add_package(nlohmann_json)\n

Please see the Hunter project for any issues regarding the packaging.

Example: CMake with HunterGate
  1. Create the following files:

    CMakeLists.txt
    cmake_minimum_required(VERSION 3.15)\n\ninclude(\"cmake/HunterGate.cmake\")\nHunterGate(\n    URL \"https://github.com/cpp-pm/hunter/archive/v0.26.12.tar.gz\"\n    SHA1 \"6498c5d0dec25d7fffb2b0574ebaf265179b894d\"\n)\n\nproject(json_example)\n\nhunter_add_package(nlohmann_json)\nfind_package(nlohmann_json CONFIG REQUIRED)\n\nadd_executable(json_example example.cpp)\ntarget_link_libraries(json_example PRIVATE nlohmann_json::nlohmann_json)\n
    example.cpp
    #include <nlohmann/json.hpp>\n#include <iostream>\n#include <iomanip>\n\nusing nlohmann::json;\n\nint main()\n{\n    std::cout << std::setw(4) << json::meta() << std::endl;\n}\n
  2. Download required files

    mkdir cmake\nwget https://raw.githubusercontent.com/cpp-pm/gate/master/cmake/HunterGate.cmake -O cmake/HunterGate.cmake\n
  3. Build the project with CMake:

    cmake -S . -B build\ncmake --build build\n
"},{"location":"integration/package_managers/#vcpkg","title":"vcpkg","text":"

Summary

package: nlohmann-json

  • Available versions: current version
  • The package is updated with every release.
  • File issues at the vcpkg issue tracker
  • vcpkg website

If you are using vcpkg on your project for external dependencies, then you can install the nlohmann-json package with

vcpkg install nlohmann-json\n

and follow the then displayed descriptions. Please see the vcpkg project for any issues regarding the packaging.

Example: CMake with the vcpkg toolchain
  1. Create the following files:

    CMakeLists.txt
    cmake_minimum_required(VERSION 3.15)\nproject(json_example)\n\nfind_package(nlohmann_json CONFIG REQUIRED)\n\nadd_executable(json_example example.cpp)\ntarget_link_libraries(json_example PRIVATE nlohmann_json::nlohmann_json)\n
    example.cpp
    #include <nlohmann/json.hpp>\n#include <iostream>\n#include <iomanip>\n\nusing nlohmann::json;\n\nint main()\n{\n    std::cout << std::setw(4) << json::meta() << std::endl;\n}\n
  2. Install package:

    vcpkg install nlohmann-json\n
  3. Build:

    cmake -S . -B build -DCMAKE_TOOLCHAIN_FILE=$VCPKG_ROOT/scripts/buildsystems/vcpkg.cmake\ncmake --build build\n
"},{"location":"integration/package_managers/#cget","title":"cget","text":"

Summary

package: nlohmann/json

  • Available versions: current version and older versions
  • The package is updated with every release.
  • File issues at the cget issue tracker
  • cget website

If you are using cget, you can install the latest master version with

cget install nlohmann/json\n

A specific version can be installed with cget install nlohmann/json@v3.12.0. Also, the multiple header version can be installed by adding the -DJSON_MultipleHeaders=ON flag (i.e., cget install nlohmann/json -DJSON_MultipleHeaders=ON).

Example: CMake with the cget toolchain
  1. Create the following files:

    CMakeLists.txt
    cmake_minimum_required(VERSION 3.15)\nproject(json_example)\n\nfind_package(nlohmann_json REQUIRED)\n\nadd_executable(json_example example.cpp)\ntarget_link_libraries(json_example PRIVATE nlohmann_json::nlohmann_json)\n
    example.cpp
    #include <nlohmann/json.hpp>\n#include <iostream>\n#include <iomanip>\n\nusing nlohmann::json;\n\nint main()\n{\n    std::cout << std::setw(4) << json::meta() << std::endl;\n}\n
  2. Initialize cget

    cget init\n
  3. Install the library

    cget install nlohmann/json\n
  4. Build

    cmake -S . -B build -DCMAKE_TOOLCHAIN_FILE=cget/cget/cget.cmake\ncmake --build build\n
"},{"location":"integration/package_managers/#swift-package-manager","title":"Swift Package Manager","text":"

Summary

package: nlohmann/json

  • Available versions: current version and older versions
  • The package is updated with every release.
  • File issues at the library issue tracker
  • Xcode documentation

If you are using the Swift Package Manager, add this repository as a package dependency and depend on its json product:

dependencies: [\n    .package(url: \"https://github.com/nlohmann/json\", from: \"3.12.0\")\n],\ntargets: [\n    .target(name: \"MyTarget\", dependencies: [.product(name: \"json\", package: \"json\")])\n]\n

The library's own Package.swift publishes single_include/nlohmann (not single_include) as the public headers directory, so include the header without the nlohmann/ prefix:

#include <json.hpp>\n
Example: a minimal executable package
  1. Create the following files (the source file goes into Sources/json_example/, following Swift Package Manager's directory layout convention):

    Package.swift
    // swift-tools-version: 5.9\nimport PackageDescription\n\nlet package = Package(\n    name: \"json_example\",\n    dependencies: [\n        .package(url: \"https://github.com/nlohmann/json\", from: \"3.12.0\")\n    ],\n    targets: [\n        .executableTarget(\n            name: \"json_example\",\n            dependencies: [\n                .product(name: \"json\", package: \"json\")\n            ]\n        )\n    ]\n)\n
    Sources/json_example/example.cpp
    #include <json.hpp>\n#include <iostream>\n#include <iomanip>\n\nusing nlohmann::json;\n\nint main()\n{\n    std::cout << std::setw(4) << json::meta() << std::endl;\n}\n
  2. Build and run:

    swift run --build-system native\n

Warning

On some toolchains, swift run/swift build fail to link an executable target against the header-only json product with an error such as Build input file cannot be found: '.../json.o', because the product itself has no compiled sources; see #4650 and the upstream Swift Package Manager issue. Passing --build-system native (shown above) selects Swift Package Manager's legacy build system, which does not have this problem; depending on the library from a library target instead of an executable is not affected either.

You can also add the dependency from within Xcode via File \u2192 Add Package Dependencies\u2026 and the same repository URL; see Apple's documentation.

"},{"location":"integration/package_managers/#nuget","title":"NuGet","text":"

Summary

package: nlohmann.json

  • Available versions: current and previous versions
  • The package is updated with every release.
  • Maintainer: Hani Kaabi
  • File issues at the maintainer's issue tracker
  • NuGet website

If you are using NuGet, you can use the package nlohmann.json with

dotnet add package nlohmann.json\n

NuGet integrates with C++ projects through MSBuild, so it is mainly useful for Visual Studio/MSBuild projects; using it as a dependency from other build systems, such as CMake, is possible but more cumbersome than the other package managers on this page.

Example: Visual Studio project
  1. Right-click the project (any C++ project) in \"Solution Explorer\" and select \"Manage NuGet Packages\u2026\"

  2. Switch to the \"Browse\" tab.

  3. Search for nlohmann.json, select it, and click \"Install\".

  4. #include <nlohmann/json.hpp> in your code and build the project. The package's build/native/nlohmann.json.targets file adds $(MSBuildThisFileDirectory)include to the project's AdditionalIncludeDirectories, so no further include path configuration is needed.

For further details, see the original discussion this section is based on.

"},{"location":"integration/package_managers/#conda","title":"Conda","text":"

Summary

package: nlohmann_json

  • Available versions: current and previous versions
  • The package is updated with every release.
  • File issues at the feedstock's issue tracker
  • Conda documentation

If you are using conda, you can use the package nlohmann_json from conda-forge executing

conda install -c conda-forge nlohmann_json\n
Example: Raw compilation
  1. Create the following file:

    example.cpp
    #include <nlohmann/json.hpp>\n#include <iostream>\n#include <iomanip>\n\nusing nlohmann::json;\n\nint main()\n{\n    std::cout << std::setw(4) << json::meta() << std::endl;\n}\n
  2. Create and activate an environment json:

    conda create -n json\nconda activate json\n
  3. Install the package:

    conda install -c conda-forge nlohmann_json\n
  4. Build the code:

    g++ -std=c++11 -I$(conda info --base)/envs/json/include example.cpp -o example\n
"},{"location":"integration/package_managers/#msys2","title":"MSYS2","text":"

Summary

package: mingw-w64-nlohmann-json

  • The package is updated automatically.
  • File issues at the MINGW-packages issue tracker
  • MSYS2 website

If you are using MSYS2, you can use the mingw-w64-nlohmann-json package; type pacman -S mingw-w64-i686-nlohmann-json or pacman -S mingw-w64-x86_64-nlohmann-json for installation.

Example: Raw compilation
  1. Create the following file:

    example.cpp
    #include <nlohmann/json.hpp>\n#include <iostream>\n#include <iomanip>\n\nusing nlohmann::json;\n\nint main()\n{\n    std::cout << std::setw(4) << json::meta() << std::endl;\n}\n
  2. Install the package (from an MSYS2 MinGW 64-bit shell):

    pacman -S mingw-w64-x86_64-nlohmann-json\n
  3. Compile the code:

    g++ example.cpp -std=c++11 -o example\n
"},{"location":"integration/package_managers/#macports","title":"MacPorts","text":"

Summary

port: nlohmann-json

  • Available versions: current version
  • The port is updated with every release.
  • File issues at the MacPorts issue tracker
  • MacPorts website

If you are using MacPorts, execute

sudo port install nlohmann-json\n

to install the nlohmann-json package.

Example: Raw compilation
  1. Create the following file:

    example.cpp
    #include <nlohmann/json.hpp>\n#include <iostream>\n#include <iomanip>\n\nusing nlohmann::json;\n\nint main()\n{\n    std::cout << std::setw(4) << json::meta() << std::endl;\n}\n
  2. Install the package:

    sudo port install nlohmann-json\n
  3. Compile the code and pass the MacPorts prefix to the include path such that the library can be found:

    c++ example.cpp -I/opt/local/include -std=c++11 -o example\n
Example: CMake
  1. Create the following files:

    example.cpp
    #include <nlohmann/json.hpp>\n#include <iostream>\n#include <iomanip>\n\nusing nlohmann::json;\n\nint main()\n{\n    std::cout << std::setw(4) << json::meta() << std::endl;\n}\n
    CMakeLists.txt
    cmake_minimum_required(VERSION 3.15)\nproject(json_example)\n\nfind_package(nlohmann_json CONFIG REQUIRED)\n\nadd_executable(json_example example.cpp)\ntarget_link_libraries(json_example PRIVATE nlohmann_json::nlohmann_json)\n
  2. Install the package:

    sudo port install nlohmann-json\n
  3. Compile the code:

    cmake -S . -B build\ncmake --build build\n
"},{"location":"integration/package_managers/#build2","title":"build2","text":"

Summary

package: nlohmann-json library target: nlohmann-json%lib{json} available in package repositories: - cppget.org (recommended) - package's sources (for advanced users)

  • Available versions: current version and older versions since 3.7.3 (see cppget.org)
  • The package is maintained and published by the build2 community in this repository.
  • File issues at the package source repository
  • build2 website

Note: build2 should not be considered as a standalone package-manager. It is a build-system + package manager + project manager, a set of tools that work hand-in-hand. build2-based projects do not rely on existing CMake scripts and the build scripts defining the project's targets are specific to build2.

To use this package in an existing build2 project, the general steps are:

  1. Make the package available to download from a package repository that provides it.

    Your project's repositories.manifest specifies where the package manager will try to acquire packages by default. Make sure one of the repositories specified in this file provides nlohmann-json package. The recommended open-source repository is cppget.org.

    If the project has been created using bdep new, cppget.org is already specified in repositories.manifest but commented, just uncomment these lines:

    :\nrole: prerequisite\nlocation: https://pkg.cppget.org/1/stable\n

  2. Add this package as dependency of your project.

    In your project's manifest add the dependency to the package using depends: nlohmann-json. You could also add some version constraints. For example, to depend on the latest version available:

    depends: nlohmann-json\n

  3. Add this library as dependency of your target that uses it.

    In the buildfile defining the target that will use this library:

    - import the target `lib{json}` from the `nlohmann-json` package, for example:\n    ```\n    import nljson = nlohmann-json%lib{json}\n    ```\n\n- then add the library's target as requirement for your target using it, for example:\n    ```\n    exe{example} : ... $nljson\n    ```\n
  4. Use the library in your project's code and build it.

    At this point, assuming your project is initialized in a build-configuration, any b or bdep update command that will update/build the project will also acquire the missing dependency automatically, then build it and link it with your target.

    If you just want to synchronize dependencies for all your configurations to download the ones you just added:

    bdep sync -af\n

    Example: from scratch, using build2's bdep new command
    1. Create a new executable project \"example\" (see bdep new command details for the various options to create a new project):

      bdep new example\n
    2. Edit these files by replacing their content:

      • example/repositories.manifest: Enable acquiring packages from https://cppget.org by uncommenting the related lines:

        project's `repositories.manifest`
        : 1\nsummary: example project repository\n\n:\nrole: prerequisite\nlocation: https://pkg.cppget.org/1/stable\n#trust: ...\n\n#:\n#role: prerequisite\n#location: https://git.build2.org/hello/libhello.git\n
      • example/manifest: Add the latest version of the nlohmann-json package as dependency to the project:

        project's `manifest`
        name: example\nversion: 0.1.0-a.0.z\nlanguage: c++\nsummary: example C++ executable\nlicense: other: proprietary ; Not free/open source.\ndescription-file: README.md\nurl: https://example.org/example\nemail: your@emailprovider.com\n#build-error-email: your@emailprovider.com\ndepends: * build2 >= 0.16.0\ndepends: * bpkg >= 0.16.0\n#depends: libhello ^1.0.0\n\ndepends: nlohmann-json\n
      • example/example/buildfile: import the library's target to be used as requirement for building the executable target exe{example}:

        project's `buildfile`
        libs =\nimport libs = nlohmann-json%lib{json}\n\nexe{example}: {hxx ixx txx cxx}{**} $libs testscript\n\ncxx.poptions =+ \"-I$out_root\" \"-I$src_root\"\n
      • example/example/example.cxx: bdep new generates a \"hello world\" by default, replace it by this:

        example.cxx
        #include <nlohmann/json.hpp>\n#include <iostream>\n#include <iomanip>\n\nusing nlohmann::json;\n\nint main()\n{\n    std::cout << std::setw(4) << json::meta() << std::endl;\n}\n
      • example/example/testscript: (optional) if you want to be able to test that executable's output is correct using b test:

        `testscript` checking the output of the program
        : json basics\n:\n$* >>~/EOO/\n{\n    \"compiler\": {\n/        \"c\\+\\+\": \"\\d+\",/\n/        \"family\": \"[\\w\\d]+\",/\n/        \"version\": \\d+/\n    },\n/    \"copyright\": \"\\(C\\) 2013-\\d+ Niels Lohmann\",/\n    \"name\": \"JSON for Modern C++\",\n/    \"platform\": \"[\\w\\d]+\",/\n    \"url\": \"https://github.com/nlohmann/json\",\n    \"version\": {\n        \"major\": 3,\n/        \"minor\": \\d+,/\n/        \"patch\": \\d+,/\n/        \"string\": \"3\\.\\d+\\.\\d+\"/\n    }\n}\nEOO\n
    3. Initialize the project in a default C/C++ build configuration directory, then build and test:

      cd example/\n\n# create default C/C++ build configuration in ../example-myconfig/, initialize the project in it (downloads it's dependencies in it too)\nbdep init -C @myconfig cc\n\n# build only,\nb\n\n# or build and test the executable's output, will only work if the `testscript` is correct\nb test\n
    "},{"location":"integration/package_managers/#cpmcmake","title":"CPM.cmake","text":"

    Summary

    package: gh:nlohmann/json

    • Available versions: current and previous versions
    • The package is updated with every release.
    • File issues at the CPM.cmake issue tracker
    • CPM.cmake website

    If you are using CPM.cmake, add the CPM.cmake script and the following snippet to your CMake project:

    CPMAddPackage(\"gh:nlohmann/json@3.12.0\")\n
    Example: CMake with CPMAddPackage
    1. Create the following files:

      example.cpp
      #include <nlohmann/json.hpp>\n#include <iostream>\n#include <iomanip>\n\nusing nlohmann::json;\n\nint main()\n{\n    std::cout << std::setw(4) << json::meta() << std::endl;\n}\n
      CMakeLists.txt
      cmake_minimum_required(VERSION 3.15)\nproject(json_example)\n\ninclude(${CMAKE_SOURCE_DIR}/cmake/CPM.cmake)\n\nCPMAddPackage(\"gh:nlohmann/json@3.12.0\")\n\nadd_executable(json_example example.cpp)\ntarget_link_libraries(json_example PRIVATE nlohmann_json::nlohmann_json)\n
    2. Download CPM.cmake

      mkdir -p cmake\nwget -O cmake/CPM.cmake https://github.com/cpm-cmake/CPM.cmake/releases/latest/download/get_cpm.cmake\n
    3. Build

      cmake -S . -B build\ncmake --build build\n
    "},{"location":"integration/package_managers/#xmake","title":"xmake","text":"

    Summary

    package: nlohmann_json

    • Available versions: current and previous versions
    • The package is updated with every release.
    • File issues at the xmake issue tracker
    • xmake website
    Example: xmake project
    1. Create the following files:

      example.cpp
      #include <nlohmann/json.hpp>\n#include <iostream>\n#include <iomanip>\n\nusing nlohmann::json;\n\nint main()\n{\n    std::cout << std::setw(4) << json::meta() << std::endl;\n}\n
      xmake.lua
      add_requires(\"nlohmann_json\")\n\nadd_rules(\"mode.debug\", \"mode.release\")\ntarget(\"xm\")\n    set_kind(\"binary\")\n    add_files(\"example.cpp\")\n    add_packages(\"nlohmann_json\")\n    set_languages(\"cxx11\")\n
    2. Build

      xmake\n
    3. Run

      xmake run\n
    "},{"location":"integration/package_managers/#other-package-managers","title":"Other package managers","text":"

    The library is also contained in many other package repositories; Repology tracks the packaged versions across repositories.

    "},{"location":"integration/package_managers/#buckaroo","title":"Buckaroo","text":"

    If you are using Buckaroo, you can install this library's module with buckaroo add github.com/buckaroo-pm/nlohmann-json. There is a demo repo here.

    Warning

    The module is outdated as the respective repository has not been updated in years.

    "},{"location":"integration/package_managers/#cocoapods","title":"CocoaPods","text":"

    If you are using CocoaPods, you can use the library by adding pod \"nlohmann_json\", '~>3.1.2' to your podfile (see an example). Please file issues at the repository, as its issue tracker is no longer reachable.

    Warning

    The module is outdated as the respective pod has not been updated in years.

    "},{"location":"integration/package_managers/#npm","title":"npm","text":"

    This project does not publish an official npm package. The npm package nlohmann-json (or similarly named packages) is not maintained or endorsed by this project. Use one of the package managers listed above, or integrate the single header directly.

    "},{"location":"integration/package_managers/#esp-idf-and-platformio","title":"ESP-IDF and PlatformIO","text":"

    There is no official package published to the ESP-IDF Component Registry or the PlatformIO Registry. A community-maintained fork, Johboh/nlohmann-json, publishes this library to both registries on each new release and can be used as an unofficial component/package for ESP-IDF and PlatformIO projects. As the library is header-only, it can otherwise be used directly by adding its include/ directory to your component's/project's include paths, like any other integration method described on this page.

    "},{"location":"integration/package_managers/#see-also","title":"See also","text":"
    • CMake - use the library from CMake
    • Pkg-config - use the library with pkg-config
    • meta - query the library version at run time
    • NLOHMANN_JSON_VERSION_MAJOR - library version macros
    "},{"location":"integration/pkg-config/","title":"Pkg-config","text":"

    If you are using bare Makefiles, you can use pkg-config to generate the include flags that point to where the library is installed:

    pkg-config nlohmann_json --cflags\n

    A pkg-config file is installed by CMake (when the JSON_Install option is enabled, which is the default for a top-level build) as well as by several package managers.

    Users of the Meson build system will also be able to use a system-wide library, which will be found by pkg-config:

    json = dependency('nlohmann_json', required: true)\n
    "},{"location":"integration/pkg-config/#see-also","title":"See also","text":"
    • Integration - all ways to integrate the library
    • CMake - use the library from CMake
    • Package Managers - install the library via package managers
    "}]} \ No newline at end of file +{"config":{"lang":["en"],"separator":"[\\s\\-\\.]","pipeline":["stopWordFilter"],"fields":{"title":{"boost":1000.0},"text":{"boost":1.0},"tags":{"boost":1000000.0}}},"docs":[{"location":"","title":"JSON for Modern C++","text":"
    • Features

      Creating, parsing, accessing, and serializing JSON values, converting your own C++ types, JSON Pointer/Patch/Merge Patch, binary formats, zero-copy views, and more.

      Features

    • Integration

      Add the library to your project via a single header, CMake, a package manager, or pkg-config.

      Integration

    • API documentation

      The complete reference for basic_json and its member functions, types, and related classes, as well as for json_document and json_view.

      API documentation

    • FAQ

      Answers to common questions and known surprises when using the library.

      FAQ

    • Releases

      What changed in each release, with links to the relevant documentation.

      Releases

    • Community

      The ecosystem, contribution guidelines, governance, and quality assurance around the project.

      Community

    "},{"location":"api/is_json_view/","title":"nlohmann::is_json_view","text":"

    Defined in header <nlohmann/json_view.hpp>

    template<typename T>\nstruct is_json_view;\n

    A type trait: is_json_view<T>::value is true if T is a basic_json_view of any BasicJsonType and any view_mode -- json_view, json_editable_view, ordered_json_view, ... -- and false otherwise, for basic_json as well.

    It is meant for constraining templates that accept views, in particular a from_json() that should read views directly: get<T>() on a view calls a from_json() with the view only if that from_json() accepts views but not arbitrary types.

    "},{"location":"api/is_json_view/#template-parameters","title":"Template parameters","text":"T the type to check (without cv-qualifiers or references)"},{"location":"api/is_json_view/#notes","title":"Notes","text":"

    A view is recognized by its member type basic_json_type (a basic_json specialization) and its materialize() returning that type, so the trait needs no declaration of the view class.

    "},{"location":"api/is_json_view/#examples","title":"Examples","text":"Example

    The example below shows the trait, and a from_json() constrained to json values and views: get<T>() on a view reads the view directly.

    #include <iostream>\n#include <type_traits>\n#include <nlohmann/json_view.hpp>\n\nusing nlohmann::json;\n\nnamespace ns\n{\nstruct person\n{\n    std::string name;\n    int age = 0;\n};\n\n// reads json values and views (of any document type), but nothing else\ntemplate < typename J, typename std::enable_if < nlohmann::is_json_view<J>::value || std::is_same<J, json>::value, int >::type = 0 >\nvoid from_json(const J& j, person& p)\n{\n    p.name = j.at(\"name\").template get<std::string>();\n    p.age = j.at(\"age\").template get<int>();\n}\n} // namespace ns\n\nint main()\n{\n    std::cout << std::boolalpha\n              << nlohmann::is_json_view<nlohmann::json_view>::value << ' '\n              << nlohmann::is_json_view<nlohmann::ordered_json_editable_view>::value << ' '\n              << nlohmann::is_json_view<json>::value << '\\n';\n\n    const nlohmann::json_document doc = nlohmann::json_document::parse(R\"({\"name\": \"Ada\", \"age\": 36})\");\n    const auto p = doc.root().get<ns::person>(); // reads the view, no json value is built\n    std::cout << p.name << ' ' << p.age << '\\n';\n}\n

    Output:

    true true false\nAda 36\n
    "},{"location":"api/is_json_view/#see-also","title":"See also","text":"
    • basic_json_view - a handle to one value of a document
    • get - which conversions read the view directly
    • view_mode - read-only or editable
    • Writing generic code - functions and from_json() for views
    "},{"location":"api/is_json_view/#version-history","title":"Version history","text":"

    Added in version 3.13.0 unreleased.

    "},{"location":"api/json/","title":"nlohmann::json","text":"
    using json = basic_json<>;\n

    This type is the default specialization of the basic_json class which uses the standard template types.

    "},{"location":"api/json/#examples","title":"Examples","text":"Example

    The example below demonstrates how to use the type nlohmann::json.

    #include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create a JSON object\n    json j =\n    {\n        {\"pi\", 3.141},\n        {\"happy\", true},\n        {\"name\", \"Niels\"},\n        {\"nothing\", nullptr},\n        {\n            \"answer\", {\n                {\"everything\", 42}\n            }\n        },\n        {\"list\", {1, 0, 2}},\n        {\n            \"object\", {\n                {\"currency\", \"USD\"},\n                {\"value\", 42.99}\n            }\n        }\n    };\n\n    // add new values\n    j[\"new\"][\"key\"][\"value\"] = {\"another\", \"list\"};\n\n    // count elements\n    auto s = j.size();\n    j[\"size\"] = s;\n\n    // pretty print with indent of 4 spaces\n    std::cout << std::setw(4) << j << '\\n';\n}\n

    Output:

    {\n    \"answer\": {\n        \"everything\": 42\n    },\n    \"happy\": true,\n    \"list\": [\n        1,\n        0,\n        2\n    ],\n    \"name\": \"Niels\",\n    \"new\": {\n        \"key\": {\n            \"value\": [\n                \"another\",\n                \"list\"\n            ]\n        }\n    },\n    \"nothing\": null,\n    \"object\": {\n        \"currency\": \"USD\",\n        \"value\": 42.99\n    },\n    \"pi\": 3.141,\n    \"size\": 8\n}\n
    "},{"location":"api/json/#see-also","title":"See also","text":"
    • basic_json - the underlying class template
    • ordered_json - specialization that preserves the insertion order of object keys
    • Types - the JSON value types and how they are stored
    • Converting values - get values out of a JSON value and put values in
    • Creating JSON values - all the ways to build a JSON value
    "},{"location":"api/json/#version-history","title":"Version history","text":"

    Added in version 1.0.0.

    "},{"location":"api/json_document/","title":"nlohmann::json_document","text":"

    Defined in header <nlohmann/json_view.hpp>

    using json_document = basic_json_document<json, view_mode::read_only>;\n

    This type is a basic_json_document of the default json specialization.

    "},{"location":"api/json_document/#examples","title":"Examples","text":"Example

    The example below demonstrates how to use the type nlohmann::json_document.

    #include <iostream>\n#include <nlohmann/json_view.hpp>\n\nusing nlohmann::json_document;\n\nint main()\n{\n    std::cout << std::boolalpha;\n\n    // json_document is basic_json_document<nlohmann::json>: same value types\n    // and containers as the ordinary json specialization\n    json_document doc = json_document::parse(R\"({\"pi\": 3.14, \"numbers\": [1, 2, 3]})\");\n\n    std::cout << doc.root().is_object() << '\\n';\n    std::cout << doc.root().materialize().dump() << '\\n';\n}\n

    Output:

    true\n{\"numbers\":[1,2,3],\"pi\":3.14}\n
    "},{"location":"api/json_document/#see-also","title":"See also","text":"
    • json_view - a view of a value of a json_document
    • ordered_json_document - the corresponding document for ordered_json
    • Zero-copy JSON views - how to parse, inspect and edit a document without building a tree
    "},{"location":"api/json_document/#version-history","title":"Version history","text":"

    Added in version 3.13.0 unreleased.

    "},{"location":"api/json_editable_document/","title":"nlohmann::json_editable_document","text":"

    Defined in header <nlohmann/json_view.hpp>

    using json_editable_document = basic_json_document<json, view_mode::editable>;\n

    This type is an editable basic_json_document of the default json specialization: in addition to everything json_document offers, set and push_back change values after parsing, without ever rewriting the source text \u2014 see Edits and Editing a document.

    "},{"location":"api/json_editable_document/#examples","title":"Examples","text":"Example

    The example below patches two fields of a small configuration document \u2014 changing one and adding another \u2014 and dumps it back out with the member order and the spelling of the untouched number preserved, something a plain json value cannot do.

    #include <iostream>\n#include <nlohmann/json_view.hpp>\n\nusing nlohmann::json;\nusing nlohmann::json_editable_document;\nusing nlohmann::json_editable_view;\n\nint main()\n{\n    // a configuration file, as it might be read from disk\n    const std::string text = R\"({\"name\": \"cache\", \"host\": \"db1\", \"port\": 6379, \"price\": 19.90})\";\n    std::cout << text << \"\\n\\n\";\n\n    // patch two fields -- \"price\" is never touched\n    json_editable_document doc = json_editable_document::parse(text);\n    doc.set(doc.root(), \"host\", \"db2\");\n    doc.set(doc.root(), \"retries\", 3);\n\n    // member order (the new member at the end) and the untouched number's\n    // exact spelling survive\n    std::cout << doc.root().dump(-1, ' ', false, json_editable_view::number_format::source) << '\\n';\n\n    // the same patch on a plain json value: keys are sorted (object_t is a\n    // std::map), and \"price\" is rewritten even though the patch never\n    // touched it\n    json plain = json::parse(text);\n    plain[\"host\"] = \"db2\";\n    plain[\"retries\"] = 3;\n    std::cout << plain.dump() << '\\n';\n}\n

    Output:

    {\"name\": \"cache\", \"host\": \"db1\", \"port\": 6379, \"price\": 19.90}\n\n{\"name\":\"cache\",\"host\":\"db2\",\"port\":6379,\"price\":19.90,\"retries\":3}\n{\"host\":\"db2\",\"name\":\"cache\",\"port\":6379,\"price\":19.9,\"retries\":3}\n
    "},{"location":"api/json_editable_document/#see-also","title":"See also","text":"
    • json_editable_view - a view of a value of a json_editable_document
    • json_document - the read-only document this type adds edits to
    • ordered_json_editable_document - the corresponding editable document for ordered_json
    • Edits - what an edit guarantees
    "},{"location":"api/json_editable_document/#version-history","title":"Version history","text":"

    Added in version 3.13.0 unreleased.

    "},{"location":"api/json_editable_view/","title":"nlohmann::json_editable_view","text":"

    Defined in header <nlohmann/json_view.hpp>

    using json_editable_view = basic_json_view<json, view_mode::editable>;\n

    This type is a basic_json_view of a value of a json_editable_document. It offers the same read-only interface as json_view; what is different is what it can be a view of \u2014 a value that set and push_back can change, with every view still referring to it seeing the change, see Edits.

    "},{"location":"api/json_editable_view/#examples","title":"Examples","text":"Example

    The example below is the same as json_editable_document's: every view read back out of the document \u2014 doc.root() and the views nested under it \u2014 sees the edits made through set.

    #include <iostream>\n#include <nlohmann/json_view.hpp>\n\nusing nlohmann::json;\nusing nlohmann::json_editable_document;\nusing nlohmann::json_editable_view;\n\nint main()\n{\n    // a configuration file, as it might be read from disk\n    const std::string text = R\"({\"name\": \"cache\", \"host\": \"db1\", \"port\": 6379, \"price\": 19.90})\";\n    std::cout << text << \"\\n\\n\";\n\n    // patch two fields -- \"price\" is never touched\n    json_editable_document doc = json_editable_document::parse(text);\n    doc.set(doc.root(), \"host\", \"db2\");\n    doc.set(doc.root(), \"retries\", 3);\n\n    // member order (the new member at the end) and the untouched number's\n    // exact spelling survive\n    std::cout << doc.root().dump(-1, ' ', false, json_editable_view::number_format::source) << '\\n';\n\n    // the same patch on a plain json value: keys are sorted (object_t is a\n    // std::map), and \"price\" is rewritten even though the patch never\n    // touched it\n    json plain = json::parse(text);\n    plain[\"host\"] = \"db2\";\n    plain[\"retries\"] = 3;\n    std::cout << plain.dump() << '\\n';\n}\n

    Output:

    {\"name\": \"cache\", \"host\": \"db1\", \"port\": 6379, \"price\": 19.90}\n\n{\"name\":\"cache\",\"host\":\"db2\",\"port\":6379,\"price\":19.90,\"retries\":3}\n{\"host\":\"db2\",\"name\":\"cache\",\"port\":6379,\"price\":19.9,\"retries\":3}\n
    "},{"location":"api/json_editable_view/#see-also","title":"See also","text":"
    • json_editable_document - the document type this view refers into
    • json_view - the corresponding read-only view
    • ordered_json_editable_view - the corresponding view for ordered_json_editable_document
    • Zero-copy JSON views - editing a document in place and writing it back
    "},{"location":"api/json_editable_view/#version-history","title":"Version history","text":"

    Added in version 3.13.0 unreleased.

    "},{"location":"api/json_view/","title":"nlohmann::json_view","text":"

    Defined in header <nlohmann/json_view.hpp>

    using json_view = basic_json_view<json, view_mode::read_only>;\n

    This type is a basic_json_view of a value of a json_document.

    "},{"location":"api/json_view/#examples","title":"Examples","text":"Example

    The example below demonstrates how to use the type nlohmann::json_view.

    #include <iostream>\n#include <nlohmann/json_view.hpp>\n\nint main()\n{\n    std::cout << std::boolalpha;\n\n    // json_view is basic_json_view<nlohmann::json>: a read-only handle\n    // returned by json_document::root()\n    nlohmann::json_document doc = nlohmann::json_document::parse(\"[1, 2, 3]\");\n    nlohmann::json_view v = doc.root();\n\n    std::cout << v.is_array() << ' ' << v.size() << '\\n';\n}\n

    Output:

    true 3\n
    "},{"location":"api/json_view/#see-also","title":"See also","text":"
    • json_document - the document type this view refers into
    • ordered_json_view - the corresponding view for ordered_json_document
    • Zero-copy JSON views - how to parse, inspect and edit a document without building a tree
    "},{"location":"api/json_view/#version-history","title":"Version history","text":"

    Added in version 3.13.0 unreleased.

    "},{"location":"api/operator_gtgt/","title":"nlohmann::operator>>(basic_json)","text":"
    std::istream& operator>>(std::istream& i, basic_json& j);\n

    Deserializes an input stream to a JSON value.

    "},{"location":"api/operator_gtgt/#parameters","title":"Parameters","text":"i (in, out) input stream to read a serialized JSON value from j (in, out) JSON value to write the deserialized input to"},{"location":"api/operator_gtgt/#return-value","title":"Return value","text":"

    the stream i

    "},{"location":"api/operator_gtgt/#exception-safety","title":"Exception safety","text":"

    Strong guarantee: if an exception is thrown, there are no changes in j.

    "},{"location":"api/operator_gtgt/#exceptions","title":"Exceptions","text":"
    • Throws parse_error.101 in case of an unexpected token, or if i has no stream buffer (i.rdbuf() == nullptr, for instance std::istream(nullptr)).
    • If reading from i reaches the end of the input and eofbit is part of i's exceptions() mask, the std::ios_base::failure thrown by i itself propagates instead of a parse_error, the same as it would for the standard library's own extraction operators.
    "},{"location":"api/operator_gtgt/#complexity","title":"Complexity","text":"

    Linear in the length of the input. The parser is a predictive LL(1) parser.

    "},{"location":"api/operator_gtgt/#notes","title":"Notes","text":"

    A UTF-8 byte order mark is silently ignored.

    Invalid Unicode escapes and unpaired surrogates in the input are reported as parse_error.101 with a detailed message.

    operator>> parses exactly one JSON value, so it can be called repeatedly to read a sequence of concatenated JSON values from the same stream:

    json j1, j2;\ninput >> j1;  // parses the first value\ninput >> j2;  // parses the next value\n

    A number must be followed by whitespace

    A number is only terminated by the character that follows it. That character is read from the stream to detect the end of the number, and it is not put back. When a value that is a number is immediately followed by the next value, the first character of that next value is lost:

    std::istringstream input(\"1true\");\njson j1, j2;\ninput >> j1;  // j1 == 1\ninput >> j2;  // throws parse_error.101: the stream now starts at \"rue\"\n

    Separating the values with whitespace avoids this, because the character that is eaten is then the separator:

    std::istringstream input(\"1 true\");\njson j1, j2;\ninput >> j1;  // j1 == 1\ninput >> j2;  // j2 == true\n

    Only numbers are affected. Values ending in a self-delimiting character do not read past themselves, so truefalse, [1][2], {\"a\":1}{\"b\":2}, and \"a\"\"b\" can be read back to back without a separator.

    Define JSON_PRECISE_STREAM_POSITION to 1 to leave the terminating character in the stream instead, so that the stream is positioned right after the value for every value type and no separator is needed. This is tracked in #5340.

    Note that reading concatenated values does not work for JSON Lines (newline-delimited JSON) input \u2014 see that page for why and for the recommended alternative.

    By default, a '\\0' (NUL) byte encountered while reading a value is treated as end of input, rather than as an ordinary (and, outside of a string, invalid) byte; see the FAQ entry for details and the JSON_STRICT_NUL_HANDLING macro to opt into rejecting it instead. Because operator>> only parses a single value and does not require the rest of the stream to be consumed, a NUL byte after a complete value has no effect on operator>> either way; it only matters while a value is still being read.

    Deprecation

    This function replaces function std::istream& operator<<(basic_json& j, std::istream& i) which has been deprecated in version 3.0.0. It will be removed in version 4.0.0. Please replace calls like j << i; with i >> j;.

    See the migration guide for how to update existing code.

    "},{"location":"api/operator_gtgt/#examples","title":"Examples","text":"Example

    The example below shows how a JSON value is constructed by reading a serialization from a stream.

    #include <iostream>\n#include <iomanip>\n#include <sstream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create stream with serialized JSON\n    std::stringstream ss;\n    ss << R\"({\n        \"number\": 23,\n        \"string\": \"Hello, world!\",\n        \"array\": [1, 2, 3, 4, 5],\n        \"boolean\": false,\n        \"null\": null\n    })\";\n\n    // create JSON value and read the serialization from the stream\n    json j;\n    ss >> j;\n\n    // serialize JSON\n    std::cout << std::setw(2) << j << '\\n';\n}\n

    Output:

    {\n  \"array\": [\n    1,\n    2,\n    3,\n    4,\n    5\n  ],\n  \"boolean\": false,\n  \"null\": null,\n  \"number\": 23,\n  \"string\": \"Hello, world!\"\n}\n
    "},{"location":"api/operator_gtgt/#see-also","title":"See also","text":"
    • accept - check if the input is valid JSON
    • parse - deserialize from a compatible input
    • JSON_STRICT_NUL_HANDLING - opt in to rejecting a NUL byte in the input instead of treating it as end of input
    • JSON_PRECISE_STREAM_POSITION - opt in to leaving the stream positioned right after a number
    • JSON_DISABLE_STREAM_BULK_SCAN - read the stream one character at a time
    • Parsing - overview of the parsing functions
    • JSON Lines - newline-delimited JSON
    • Large, Streamed, and Partial Input - chunked, concatenated, and very large input
    "},{"location":"api/operator_gtgt/#version-history","title":"Version history","text":"
    • Added in version 1.0.0.
    • JSON_STRICT_NUL_HANDLING added in version 3.13.0 unreleased 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.
    • JSON_PRECISE_STREAM_POSITION added in version 3.13.0 unreleased to optionally leave the character that terminates a number in the stream; planned to become the default in version 4.0.0.
    • Fixed a null pointer dereference for an std::istream without a stream buffer (now throws parse_error.101), and a crash (std::terminate) when i has eofbit in its exception mask, in version 3.13.0 unreleased.
    • Changed to the strong exception safety guarantee in version 3.13.0 unreleased: j is no longer left with a partially parsed value if parsing throws.
    • Scans the characters in the stream buffer of i in bulk in version 3.13.0 unreleased; the position of i after the call is unchanged (JSON_DISABLE_STREAM_BULK_SCAN restores reading one character at a time).
    "},{"location":"api/operator_literal_json/","title":"nlohmann::operator\"\"_json","text":"
    json operator \"\"_json(const char* s, std::size_t n);\njson operator \"\"_json(const char8_t* s, std::size_t n);  // since C++20\n

    This operator implements a user-defined string literal for JSON objects. It can be used by adding _json to a string literal and returns a json object if no parse error occurred.

    It is recommended to bring the operator into scope using any of the following lines:

    using nlohmann::literals::operator \"\"_json;\nusing namespace nlohmann::literals;\nusing namespace nlohmann::json_literals;\nusing namespace nlohmann::literals::json_literals;\nusing namespace nlohmann;\n

    This is suggested to ease migration to the next major version release of the library. See JSON_USE_GLOBAL_UDLS and the migration guide for details. The operator is declared in header <nlohmann/json_literals.hpp>, which <nlohmann/json.hpp> includes unless JSON_NO_AUTOMATIC_UDLS is defined.

    "},{"location":"api/operator_literal_json/#parameters","title":"Parameters","text":"s (in) a string representation of a JSON object n (in) length of string s"},{"location":"api/operator_literal_json/#return-value","title":"Return value","text":"

    json value parsed from s

    "},{"location":"api/operator_literal_json/#exceptions","title":"Exceptions","text":"

    The function can throw anything that parse(s, s+n) would throw.

    "},{"location":"api/operator_literal_json/#complexity","title":"Complexity","text":"

    Linear.

    "},{"location":"api/operator_literal_json/#examples","title":"Examples","text":"Example

    The following code shows how to create JSON values from string literals.

    #include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\nusing namespace nlohmann::literals;\n\nint main()\n{\n    json j = R\"( {\"hello\": \"world\", \"answer\": 42} )\"_json;\n\n    std::cout << std::setw(2) << j << '\\n';\n}\n

    Output:

    {\n  \"answer\": 42,\n  \"hello\": \"world\"\n}\n
    "},{"location":"api/operator_literal_json/#see-also","title":"See also","text":"
    • Creating JSON values - the article on creating JSON values
    • JSON_NO_AUTOMATIC_UDLS - do not include the user-defined string literals automatically
    "},{"location":"api/operator_literal_json/#version-history","title":"Version history","text":"
    • Added in version 1.0.0.
    • Moved to namespace nlohmann::literals::json_literals in 3.11.0.
    • Added char8_t* overload in version 3.13.0 unreleased.
    "},{"location":"api/operator_literal_json_pointer/","title":"nlohmann::operator\"\"_json_pointer","text":"
    json_pointer operator \"\"_json_pointer(const char* s, std::size_t n);\njson_pointer operator \"\"_json_pointer(const char8_t* s, std::size_t n);  // since C++20\n

    This operator implements a user-defined string literal for JSON Pointers. It can be used by adding _json_pointer to a string literal and returns a json_pointer object if no parse error occurred.

    It is recommended to bring the operator into scope using any of the following lines:

    using nlohmann::literals::operator \"\"_json_pointer;\nusing namespace nlohmann::literals;\nusing namespace nlohmann::json_literals;\nusing namespace nlohmann::literals::json_literals;\nusing namespace nlohmann;\n
    This is suggested to ease migration to the next major version release of the library. See JSON_USE_GLOBAL_UDLS and the migration guide for details. The operator is declared in header <nlohmann/json_literals.hpp>, which <nlohmann/json.hpp> includes unless JSON_NO_AUTOMATIC_UDLS is defined.

    "},{"location":"api/operator_literal_json_pointer/#parameters","title":"Parameters","text":"s (in) a string representation of a JSON Pointer n (in) length of string s"},{"location":"api/operator_literal_json_pointer/#return-value","title":"Return value","text":"

    json_pointer value parsed from s

    "},{"location":"api/operator_literal_json_pointer/#exceptions","title":"Exceptions","text":"

    The function can throw anything that json_pointer::json_pointer would throw.

    "},{"location":"api/operator_literal_json_pointer/#complexity","title":"Complexity","text":"

    Linear.

    "},{"location":"api/operator_literal_json_pointer/#examples","title":"Examples","text":"Example

    The following code shows how to create JSON Pointers from string literals.

    #include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\nusing namespace nlohmann::literals;\n\nint main()\n{\n    json j = R\"( {\"hello\": \"world\", \"answer\": 42} )\"_json;\n    auto val = j[\"/hello\"_json_pointer];\n\n    std::cout << std::setw(2) << val << '\\n';\n}\n

    Output:

    \"world\"\n
    "},{"location":"api/operator_literal_json_pointer/#see-also","title":"See also","text":"
    • json_pointer - type to represent JSON Pointers
    • JSON_NO_AUTOMATIC_UDLS - do not include the user-defined string literals automatically
    • JSON Pointer - the article on JSON Pointer support
    "},{"location":"api/operator_literal_json_pointer/#version-history","title":"Version history","text":"
    • Added in version 2.0.0.
    • Moved to namespace nlohmann::literals::json_literals in 3.11.0.
    • Added char8_t* overload in version 3.13.0 unreleased.
    "},{"location":"api/operator_ltlt/","title":"nlohmann::operator<<(basic_json), nlohmann::operator<<(json_pointer)","text":"
    std::ostream& operator<<(std::ostream& o, const basic_json& j);      // (1)\n\nstd::ostream& operator<<(std::ostream& o, const json_pointer& ptr);  // (2)\n
    1. Serialize the given JSON value j to the output stream o. The JSON value will be serialized using the dump member function.
      • The indentation of the output can be controlled with the member variable width of the output stream o. For instance, using the manipulator std::setw(4) on o sets the indentation level to 4 and the serialization result is the same as calling dump(4).
      • The indentation character can be controlled with the member variable fill of the output stream o. For instance, the manipulator std::setfill('\\\\t') sets indentation to use a tab character rather than the default space character.
    2. Write a string representation of the given JSON pointer ptr to the output stream o. The string representation is obtained using the to_string member function.
    "},{"location":"api/operator_ltlt/#parameters","title":"Parameters","text":"o (in, out) stream to write to j (in) JSON value to serialize ptr (in) JSON pointer to write"},{"location":"api/operator_ltlt/#return-value","title":"Return value","text":"

    the stream o

    "},{"location":"api/operator_ltlt/#exceptions","title":"Exceptions","text":"
    1. Throws type_error.316 if a string stored inside the JSON value is not UTF-8 encoded. Note that unlike the dump member functions, no error_handler can be set.
    2. Throws no library exceptions. As the string representation is built with to_string, std::bad_alloc is possible.
    "},{"location":"api/operator_ltlt/#complexity","title":"Complexity","text":"

    Linear.

    "},{"location":"api/operator_ltlt/#notes","title":"Notes","text":"

    Deprecation

    Function std::ostream& operator<<(std::ostream& o, const basic_json& j) replaces function std::ostream& operator>>(const basic_json& j, std::ostream& o) which has been deprecated in version 3.0.0. It will be removed in version 4.0.0. Please replace calls like j >> o; with o << j;.

    See the migration guide for how to update existing code.

    "},{"location":"api/operator_ltlt/#examples","title":"Examples","text":"Example: (1) serialize JSON value to stream

    The example below shows the serialization with different parameters to width to adjust the indentation level.

    #include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create JSON values\n    json j_object = {{\"one\", 1}, {\"two\", 2}};\n    json j_array = {1, 2, 4, 8, 16};\n\n    // serialize without indentation\n    std::cout << j_object << \"\\n\\n\";\n    std::cout << j_array << \"\\n\\n\";\n\n    // serialize with indentation\n    std::cout << std::setw(4) << j_object << \"\\n\\n\";\n    std::cout << std::setw(2) << j_array << \"\\n\\n\";\n    std::cout << std::setw(1) << std::setfill('\\t') << j_object << \"\\n\\n\";\n}\n

    Output:

    {\"one\":1,\"two\":2}\n\n[1,2,4,8,16]\n\n{\n    \"one\": 1,\n    \"two\": 2\n}\n\n[\n  1,\n  2,\n  4,\n  8,\n  16\n]\n\n{\n    \"one\": 1,\n    \"two\": 2\n}\n
    Example: (2) write JSON pointer to stream

    The example below shows how to write a JSON pointer to a stream.

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create JSON pointer\n    json::json_pointer ptr(\"/foo/bar/baz\");\n\n    // write string representation to stream\n    std::cout << ptr << '\\n';\n}\n

    Output:

    /foo/bar/baz\n
    "},{"location":"api/operator_ltlt/#see-also","title":"See also","text":"
    • dump - serialize to a JSON-formatted string
    • basic_json_view::operator<< - the corresponding operator for basic_json_view
    • Serialization - the serialization article
    • JSON_NO_IO - remove stream and file I/O
    "},{"location":"api/operator_ltlt/#version-history","title":"Version history","text":"
    1. Added in version 1.0.0. Added support for indentation character and deprecated std::ostream& operator>>(const basic_json& j, std::ostream& o) in version 3.0.0.
    2. Added in version 3.11.0.
    "},{"location":"api/ordered_json/","title":"nlohmann::ordered_json","text":"
    using ordered_json = basic_json<ordered_map>;\n

    This type preserves the insertion order of object keys.

    "},{"location":"api/ordered_json/#iterator-invalidation","title":"Iterator invalidation","text":"

    The type is based on ordered_map which in turn uses a std::vector to store object elements. Therefore, adding object elements can yield a reallocation in which case all iterators (including the end() iterator) and all references to the elements are invalidated. Also, any iterator or reference after the insertion point will point to the same index, which is now a different value.

    "},{"location":"api/ordered_json/#complexity","title":"Complexity","text":"

    ordered_map has no lookup index: every key-based object operation is a linear scan, so building or parsing an object of n keys costs O(n\u00b2) rather than O(n log n). See ordered_map complexity for the per-operation table and for measured numbers.

    "},{"location":"api/ordered_json/#examples","title":"Examples","text":"Example

    The example below demonstrates how ordered_json preserves the insertion order of object keys.

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::ordered_json;\n\nint main()\n{\n    ordered_json j;\n    j[\"one\"] = 1;\n    j[\"two\"] = 2;\n    j[\"three\"] = 3;\n\n    std::cout << j.dump(2) << '\\n';\n}\n

    Output:

    {\n  \"one\": 1,\n  \"two\": 2,\n  \"three\": 3\n}\n
    "},{"location":"api/ordered_json/#see-also","title":"See also","text":"
    • ordered_map - ordered map type used by ordered_json
    • Object Order - preserving the insertion order of object keys
    "},{"location":"api/ordered_json/#version-history","title":"Version history","text":"

    Added in version 3.9.0.

    "},{"location":"api/ordered_json_document/","title":"nlohmann::ordered_json_document","text":"

    Defined in header <nlohmann/json_view.hpp>

    using ordered_json_document = basic_json_document<ordered_json, view_mode::read_only>;\n

    This type is a basic_json_document of the ordered_json specialization: materialize() on one of its views preserves the insertion order of object keys, instead of sorting them like json_document does.

    "},{"location":"api/ordered_json_document/#examples","title":"Examples","text":"Example

    The example below demonstrates how ordered_json_document preserves the insertion order of object keys when materializing.

    #include <iostream>\n#include <nlohmann/json_view.hpp>\n\nusing nlohmann::ordered_json_document;\n\nint main()\n{\n    // ordered_json_document is basic_json_document<nlohmann::ordered_json>:\n    // materialize() preserves the insertion (source) order of object keys,\n    // instead of sorting them like json_document does\n    ordered_json_document doc = ordered_json_document::parse(R\"({\"z\": 1, \"a\": 2, \"m\": 3})\");\n    std::cout << doc.root().materialize().dump() << '\\n';\n}\n

    Output:

    {\"z\":1,\"a\":2,\"m\":3}\n
    "},{"location":"api/ordered_json_document/#see-also","title":"See also","text":"
    • ordered_json_view - a view of a value of an ordered_json_document
    • json_document - the corresponding document for the default json specialization
    • Object Order - preserving the insertion order of object keys
    • Zero-copy JSON views - how to parse, inspect and edit a document without building a tree
    "},{"location":"api/ordered_json_document/#version-history","title":"Version history","text":"

    Added in version 3.13.0 unreleased.

    "},{"location":"api/ordered_json_editable_document/","title":"nlohmann::ordered_json_editable_document","text":"

    Defined in header <nlohmann/json_view.hpp>

    using ordered_json_editable_document = basic_json_document<ordered_json, view_mode::editable>;\n

    This type is an editable basic_json_document of the ordered_json specialization: set and push_back change values after parsing, as for json_editable_document, and materialize() preserves the document order of object members \u2014 including members set added \u2014 instead of sorting them like json_editable_document does.

    "},{"location":"api/ordered_json_editable_document/#examples","title":"Examples","text":"Example

    The example below edits a document with set, then shows that materialize() keeps the member order of the source text (with the new member at the end) for ordered_json_editable_document, where it would sort the members alphabetically for json_editable_document.

    #include <iostream>\n#include <nlohmann/json_view.hpp>\n\nusing nlohmann::ordered_json_editable_document;\n\nint main()\n{\n    // ordered_json_editable_document is basic_json_document<nlohmann::ordered_json, nlohmann::view_mode::editable>\n    ordered_json_editable_document doc = ordered_json_editable_document::parse(R\"({\"z\": 1, \"a\": 2, \"m\": 3})\");\n    doc.set(doc.root(), \"b\", 4); // set() always appends a new member at the end\n\n    // materialize() preserves the document order (with \"b\" at the end),\n    // instead of sorting the keys the way json_editable_document does\n    std::cout << doc.root().materialize().dump() << '\\n';\n}\n

    Output:

    {\"z\":1,\"a\":2,\"m\":3,\"b\":4}\n
    "},{"location":"api/ordered_json_editable_document/#see-also","title":"See also","text":"
    • ordered_json_editable_view - a view of a value of an ordered_json_editable_document
    • ordered_json_document - the read-only document this type adds edits to
    • json_editable_document - the corresponding editable document for the default json specialization
    • Object Order - preserving the insertion order of object keys
    • Edits - what an edit guarantees
    • Zero-copy JSON views - editing a document in place and writing it back
    "},{"location":"api/ordered_json_editable_document/#version-history","title":"Version history","text":"

    Added in version 3.13.0 unreleased.

    "},{"location":"api/ordered_json_editable_view/","title":"nlohmann::ordered_json_editable_view","text":"

    Defined in header <nlohmann/json_view.hpp>

    using ordered_json_editable_view = basic_json_view<ordered_json, view_mode::editable>;\n

    This type is a basic_json_view of a value of an ordered_json_editable_document, the corresponding view for ordered_json_view the way json_editable_view is for json_view.

    "},{"location":"api/ordered_json_editable_view/#examples","title":"Examples","text":"Example

    The example below is the same as ordered_json_editable_document's: the views set returns see the document's member order preserved on materialize(), unlike for a json_editable_document.

    #include <iostream>\n#include <nlohmann/json_view.hpp>\n\nusing nlohmann::ordered_json_editable_document;\n\nint main()\n{\n    // ordered_json_editable_document is basic_json_document<nlohmann::ordered_json, nlohmann::view_mode::editable>\n    ordered_json_editable_document doc = ordered_json_editable_document::parse(R\"({\"z\": 1, \"a\": 2, \"m\": 3})\");\n    doc.set(doc.root(), \"b\", 4); // set() always appends a new member at the end\n\n    // materialize() preserves the document order (with \"b\" at the end),\n    // instead of sorting the keys the way json_editable_document does\n    std::cout << doc.root().materialize().dump() << '\\n';\n}\n

    Output:

    {\"z\":1,\"a\":2,\"m\":3,\"b\":4}\n
    "},{"location":"api/ordered_json_editable_view/#see-also","title":"See also","text":"
    • ordered_json_editable_document - the document type this view refers into
    • ordered_json_view - the corresponding read-only view
    • json_editable_view - the corresponding view for json_editable_document
    • Zero-copy JSON views - editing a document in place and writing it back
    "},{"location":"api/ordered_json_editable_view/#version-history","title":"Version history","text":"

    Added in version 3.13.0 unreleased.

    "},{"location":"api/ordered_json_view/","title":"nlohmann::ordered_json_view","text":"

    Defined in header <nlohmann/json_view.hpp>

    using ordered_json_view = basic_json_view<ordered_json, view_mode::read_only>;\n

    This type is a basic_json_view of a value of an ordered_json_document.

    "},{"location":"api/ordered_json_view/#examples","title":"Examples","text":"Example

    The example below demonstrates how to use the type nlohmann::ordered_json_view.

    #include <iostream>\n#include <nlohmann/json_view.hpp>\n\nint main()\n{\n    nlohmann::ordered_json_document doc = nlohmann::ordered_json_document::parse(R\"({\"z\": 1, \"a\": 2})\");\n    nlohmann::ordered_json_view v = doc.root();\n\n    std::cout << std::boolalpha << v.is_object() << ' ' << v.size() << '\\n';\n}\n

    Output:

    true 2\n
    "},{"location":"api/ordered_json_view/#see-also","title":"See also","text":"
    • ordered_json_document - the document type this view refers into
    • json_view - the corresponding view for json_document
    • Zero-copy JSON views - how to parse, inspect and edit a document without building a tree
    "},{"location":"api/ordered_json_view/#version-history","title":"Version history","text":"

    Added in version 3.13.0 unreleased.

    "},{"location":"api/ordered_map/","title":"nlohmann::ordered_map","text":"
    template<class Key, class T, class IgnoredLess = std::less<Key>,\n         class Allocator = std::allocator<std::pair<const Key, T>>>\nstruct ordered_map : std::vector<std::pair<const Key, T>, Allocator>;\n

    A minimal map-like container that preserves insertion order for use within nlohmann::ordered_json (nlohmann::basic_json<ordered_map>).

    "},{"location":"api/ordered_map/#template-parameters","title":"Template parameters","text":"Key key type T mapped type IgnoredLess comparison function (ignored and only added to ensure compatibility with std::map) Allocator allocator type"},{"location":"api/ordered_map/#iterator-invalidation","title":"Iterator invalidation","text":"

    The type uses a std::vector to store object elements. Therefore, adding elements can yield a reallocation in which case all iterators (including the end() iterator) and all references to the elements are invalidated.

    When the storage grows, the keys are copied and the mapped values are moved to the new storage. A plain std::vector would copy the whole elements instead, because their const keys make them not nothrow move constructible; for ordered_json, this would be a deep copy of every nested value. The values are only copied if T is not default constructible or not nothrow move assignable.

    "},{"location":"api/ordered_map/#member-types","title":"Member types","text":"
    • key_type - key type (Key)
    • mapped_type - mapped type (T)
    • Container - base container type (std::vector<std::pair<const Key, T>, Allocator>)
    • iterator
    • const_iterator
    • size_type
    • value_type
    • key_compare - key comparison function
      std::equal_to<Key>  // until C++14\n\nstd::equal_to<>     // since C++14\n
    "},{"location":"api/ordered_map/#member-functions","title":"Member functions","text":"
    • (constructor)
    • (destructor)
    • emplace
    • operator[]
    • at
    • erase
    • count
    • find
    • insert
    "},{"location":"api/ordered_map/#exception-safety","title":"Exception safety","text":"

    emplace, operator[], and insert(value) have the strong exception guarantee: if an exception is thrown (for instance, because copying a key or allocating memory fails), the contents of the container are unchanged.

    "},{"location":"api/ordered_map/#complexity","title":"Complexity","text":"

    Because the elements are stored in a std::vector in insertion order, there is no index to look a key up by. Every key-based operation performs a linear scan over the stored elements. With n denoting the number of elements in the container:

    Operation Complexity Note emplace O(n) scans for an existing key, then appends (amortized O(1)) operator[] O(n) delegates to emplace (non-const) or at (const) at O(n) throws std::out_of_range if the key is not found find O(n) count O(n) the result is always 0 or 1 erase(key) O(n) scan, then move the remaining elements one position down erase(pos), erase(first, last) O(n) moves all elements after the erased range insert(value) O(n) equivalent to emplace insert(first, last) O((n + m) * m) for m inserted elements

    This differs from std::map, where the same operations are O(log n).

    Quadratic cost of building large objects

    Because every insertion scans all elements inserted so far, building an object of n distinct keys costs O(n\u00b2) in total. This applies to filling an ordered_json object key by key as well as to parsing one, since the parser inserts each key as it is read.

    The cost is negligible for the object sizes typically found in configuration files or API payloads, but it grows steeply for machine-generated objects with many thousands of keys. Measured with -O2 -DNDEBUG for parsing a flat object of n keys, relative to nlohmann::json (which uses std::map):

    n json ordered_json factor 2000 0.7 ms 3.6 ms 5\u00d7 4000 0.8 ms 14.0 ms 19\u00d7 8000 1.6 ms 67.8 ms 43\u00d7 16 000 3.3 ms 181.6 ms 54\u00d7

    If key order matters for objects of that size, consider a container with a lookup index, such as nlohmann::fifo_map (integration), as the object type \u2014 see object order.

    "},{"location":"api/ordered_map/#examples","title":"Examples","text":"Example

    The example shows the different behavior of std::map and nlohmann::ordered_map.

    #include <iostream>\n#include <nlohmann/json.hpp>\n\n// simple output function\ntemplate<typename Map>\nvoid output(const char* prefix, const Map& m)\n{\n    std::cout << prefix << \" = { \";\n    for (auto& element : m)\n    {\n        std::cout << element.first << \":\" << element.second << ' ';\n    }\n    std::cout << \"}\" << '\\n';\n}\n\nint main()\n{\n    // create and fill two maps\n    nlohmann::ordered_map<std::string, std::string> m_ordered;\n    m_ordered[\"one\"] = \"eins\";\n    m_ordered[\"two\"] = \"zwei\";\n    m_ordered[\"three\"] = \"drei\";\n\n    std::map<std::string, std::string> m_std;\n    m_std[\"one\"] = \"eins\";\n    m_std[\"two\"] = \"zwei\";\n    m_std[\"three\"] = \"drei\";\n\n    // output: m_ordered is ordered by insertion order, m_std is ordered by key\n    output(\"m_ordered\", m_ordered);\n    output(\"m_std\", m_std);\n\n    // erase and re-add \"one\" key\n    m_ordered.erase(\"one\");\n    m_ordered[\"one\"] = \"eins\";\n\n    m_std.erase(\"one\");\n    m_std[\"one\"] = \"eins\";\n\n    // output: m_ordered shows newly added key at the end; m_std is again ordered by key\n    output(\"m_ordered\", m_ordered);\n    output(\"m_std\", m_std);\n}\n

    Output:

    m_ordered = { one:eins two:zwei three:drei }\nm_std = { one:eins three:drei two:zwei }\nm_ordered = { two:zwei three:drei one:eins }\nm_std = { one:eins three:drei two:zwei }\n
    "},{"location":"api/ordered_map/#see-also","title":"See also","text":"
    • ordered_json - JSON specialization preserving insertion order
    • Object Order - the article on object key order
    "},{"location":"api/ordered_map/#version-history","title":"Version history","text":"
    • Added in version 3.9.0 to implement nlohmann::ordered_json.
    • Added key_compare member in version 3.11.0.
    • Changed in version 3.13.0 unreleased: growing the storage moves the mapped values instead of copying them.
    "},{"location":"api/view_mode/","title":"nlohmann::view_mode","text":"

    Defined in header <nlohmann/json_view.hpp>

    enum class view_mode : std::uint8_t\n{\n    read_only,\n    editable\n};\n

    The second template parameter of basic_json_document and basic_json_view: whether a document can be changed after parsing, and whether a view is of such a document.

    read_only the default: the document is parsed once and then only read. It carries none of the bookkeeping edits need, and calling set, push_back, insert, or erase on it fails to compile. editable the document also offers set, push_back, insert, and erase; its views see every edit, see Edits.

    The shortcuts name both modes: json_document and json_view are read-only, json_editable_document and json_editable_view are editable (and likewise for ordered_json).

    "},{"location":"api/view_mode/#notes","title":"Notes","text":"

    The mode is a compile-time property of the document's and the view's type, not a setting of a call. A read-only view reads a container in place, while a view of an editable document follows the links that edits leave behind. A view of a read-only document converts implicitly to a view of an editable document of the same BasicJsonType: a read-only document has no edits, so the converted view reads it like an editable document before its first edit (at the cost of one check per access). There is no conversion the other way, because a read-only view of an editable document would read wrong values after the next edit.

    A function that takes a json_editable_view therefore accepts the views of both modes. A function template deduces the mode from its argument instead, without conversions, so it names the modes it accepts in its signature:

    // views of editable documents only\ntemplate<typename BasicJsonType>\nvoid f(basic_json_view<BasicJsonType, view_mode::editable> v);\n\n// views of read-only documents only\ntemplate<typename BasicJsonType>\nvoid f(basic_json_view<BasicJsonType, view_mode::read_only> v);\n\n// views of either document type\ntemplate<typename BasicJsonType, view_mode Mode>\nvoid f(basic_json_view<BasicJsonType, Mode> v);\n

    A function that takes a json_view accepts neither an ordered_json_view nor a json_editable_view. Views of the two modes compare with operator==.

    "},{"location":"api/view_mode/#examples","title":"Examples","text":"Example

    The example below shows a function template that accepts the views of both modes, one that accepts only views of editable documents, and a function taking a json_editable_view that also accepts a view of a read-only document.

    #include <iostream>\n#include <nlohmann/json_view.hpp>\n\nusing nlohmann::basic_json_view;\nusing nlohmann::view_mode;\n\n// accepts the views of read-only and of editable documents, of json and of ordered_json\ntemplate<typename BasicJsonType, view_mode Mode>\nstd::size_t count_members(basic_json_view<BasicJsonType, Mode> v)\n{\n    return v.is_object() ? v.size() : 0;\n}\n\n// accepts only the views of editable documents\ntemplate<typename BasicJsonType>\nbool is_edited(basic_json_view<BasicJsonType, view_mode::editable> v)\n{\n    return v.is_string() && v.get_string() == \"edited\";\n}\n\n// a function (no template) taking a json_editable_view also accepts the view of a read-only document\nstd::size_t size_of(nlohmann::json_editable_view v)\n{\n    return v.size();\n}\n\nint main()\n{\n    const nlohmann::json_document doc = nlohmann::json_document::parse(R\"({\"a\": 1, \"b\": 2})\");\n    nlohmann::json_editable_document edoc = nlohmann::json_editable_document::parse(R\"({\"a\": 1})\");\n    edoc.set(edoc.root()[\"a\"], \"edited\");\n\n    std::cout << count_members(doc.root()) << ' ' << count_members(edoc.root()) << '\\n';\n    std::cout << std::boolalpha << is_edited(edoc.root()[\"a\"]) << '\\n';\n    std::cout << size_of(doc.root()) << ' ' << size_of(edoc.root()) << '\\n';\n}\n

    Output:

    2 1\ntrue\n2 1\n
    "},{"location":"api/view_mode/#see-also","title":"See also","text":"
    • basic_json_document - a parsed JSON text
    • basic_json_view - a handle to one value of a document
    • json_editable_document - an editable document of json
    • (constructor) - the conversion from a read-only to an editable view
    • Writing generic code - functions that accept views
    "},{"location":"api/view_mode/#version-history","title":"Version history","text":"

    Added in version 3.13.0 unreleased.

    "},{"location":"api/adl_serializer/","title":"nlohmann::adl_serializer","text":"
    template<typename, typename>\nstruct adl_serializer;\n

    Serializer that uses ADL (Argument-Dependent Lookup) to choose to_json/from_json functions from the types' namespaces.

    It is implemented similarly to

    template<typename ValueType>\nstruct adl_serializer {\n    template<typename BasicJsonType>\n    static void to_json(BasicJsonType& j, const T& value) {\n        // calls the \"to_json\" method in T's namespace\n    }\n\n    template<typename BasicJsonType>\n    static void from_json(const BasicJsonType& j, T& value) {\n        // same thing, but with the \"from_json\" method\n    }\n};\n
    "},{"location":"api/adl_serializer/#member-functions","title":"Member functions","text":"
    • from_json - convert a JSON value to any value type
    • to_json - convert any value type to a JSON value
    "},{"location":"api/adl_serializer/#see-also","title":"See also","text":"
    • Arbitrary type conversions - how to make your types convertible
    • get - / get_to - convert a JSON value to a C++ type
    • basic_json - construct a JSON value from a C++ value
    • NLOHMANN_DEFINE_TYPE_INTRUSIVE - generate the conversion functions for a type
    • Specializing enum conversion - serializing enums as JSON strings
    "},{"location":"api/adl_serializer/#version-history","title":"Version history","text":"
    • Added in version 2.1.0.
    "},{"location":"api/adl_serializer/from_json/","title":"nlohmann::adl_serializer::from_json","text":"
    // (1)\ntemplate<typename BasicJsonType, typename TargetType = ValueType>\nstatic auto from_json(BasicJsonType && j, TargetType& val) noexcept(\n    noexcept(::nlohmann::from_json(std::forward<BasicJsonType>(j), val)))\n-> decltype(::nlohmann::from_json(std::forward<BasicJsonType>(j), val), void())\n\n// (2)\ntemplate<typename BasicJsonType, typename TargetType = ValueType>\nstatic auto from_json(BasicJsonType && j) noexcept(\nnoexcept(::nlohmann::from_json(std::forward<BasicJsonType>(j), detail::identity_tag<TargetType> {})))\n-> decltype(::nlohmann::from_json(std::forward<BasicJsonType>(j), detail::identity_tag<TargetType> {}))\n

    This function is usually called by the get() function of the basic_json class (either explicitly or via the conversion operators).

    1. This function is chosen for default-constructible value types.
    2. This function is chosen for value types which are not default-constructible.
    "},{"location":"api/adl_serializer/from_json/#parameters","title":"Parameters","text":"j (in) JSON value to read from val (out) value to write to"},{"location":"api/adl_serializer/from_json/#return-value","title":"Return value","text":"
    1. (none) \u2014 the converted value is written to the output parameter val.
    2. the JSON value j converted to TargetType
    "},{"location":"api/adl_serializer/from_json/#examples","title":"Examples","text":"Example: (1) Default-constructible type

    The example below shows how a from_json function can be implemented for a user-defined type. This function is called by the adl_serializer when get<ns::person>() is called.

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nnamespace ns\n{\n// a simple struct to model a person\nstruct person\n{\n    std::string name;\n    std::string address;\n    int age;\n};\n} // namespace ns\n\nnamespace ns\n{\nvoid from_json(const json& j, person& p)\n{\n    j.at(\"name\").get_to(p.name);\n    j.at(\"address\").get_to(p.address);\n    j.at(\"age\").get_to(p.age);\n}\n} // namespace ns\n\nint main()\n{\n    json j;\n    j[\"name\"] = \"Ned Flanders\";\n    j[\"address\"] = \"744 Evergreen Terrace\";\n    j[\"age\"] = 60;\n\n    auto p = j.get<ns::person>();\n\n    std::cout << p.name << \" (\" << p.age << \") lives in \" << p.address << '\\n';\n}\n

    Output:

    Ned Flanders (60) lives in 744 Evergreen Terrace\n
    Example: (2) Non-default-constructible type

    The example below shows how a from_json is implemented as part of a specialization of the adl_serializer to realize the conversion of a non-default-constructible type.

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nnamespace ns\n{\n// a simple struct to model a person (not default constructible)\nstruct person\n{\n    person(std::string n, std::string a, int aa)\n        : name(std::move(n)), address(std::move(a)), age(aa)\n    {}\n\n    std::string name;\n    std::string address;\n    int age;\n};\n} // namespace ns\n\nnamespace nlohmann\n{\ntemplate <>\nstruct adl_serializer<ns::person>\n{\n    static ns::person from_json(const json& j)\n    {\n        return {j.at(\"name\"), j.at(\"address\"), j.at(\"age\")};\n    }\n\n    // Here's the catch! You must provide a to_json method! Otherwise, you\n    // will not be able to convert person to json, since you fully\n    // specialized adl_serializer on that type\n    static void to_json(json& j, ns::person p)\n    {\n        j[\"name\"] = p.name;\n        j[\"address\"] = p.address;\n        j[\"age\"] = p.age;\n    }\n};\n} // namespace nlohmann\n\nint main()\n{\n    json j;\n    j[\"name\"] = \"Ned Flanders\";\n    j[\"address\"] = \"744 Evergreen Terrace\";\n    j[\"age\"] = 60;\n\n    auto p = j.get<ns::person>();\n\n    std::cout << p.name << \" (\" << p.age << \") lives in \" << p.address << '\\n';\n}\n

    Output:

    Ned Flanders (60) lives in 744 Evergreen Terrace\n
    "},{"location":"api/adl_serializer/from_json/#see-also","title":"See also","text":"
    • to_json - convert a C++ value to JSON
    • Arbitrary Type Conversions - write your own from_json and to_json functions
    • Converting values - overview of get, get_to and implicit conversions
    "},{"location":"api/adl_serializer/from_json/#version-history","title":"Version history","text":"
    • Added in version 2.1.0.
    "},{"location":"api/adl_serializer/to_json/","title":"nlohmann::adl_serializer::to_json","text":"
    template<typename BasicJsonType, typename TargetType = ValueType>\nstatic auto to_json(BasicJsonType& j, TargetType && val) noexcept(\n    noexcept(::nlohmann::to_json(j, std::forward<TargetType>(val))))\n-> decltype(::nlohmann::to_json(j, std::forward<TargetType>(val)), void())\n

    This function is usually called by the constructors of the basic_json class.

    "},{"location":"api/adl_serializer/to_json/#parameters","title":"Parameters","text":"j (out) JSON value to write to val (in) value to read from"},{"location":"api/adl_serializer/to_json/#examples","title":"Examples","text":"Example

    The example below shows how a to_json function can be implemented for a user-defined type. This function is called by the adl_serializer when the constructor basic_json(ns::person) is called.

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nnamespace ns\n{\n// a simple struct to model a person\nstruct person\n{\n    std::string name;\n    std::string address;\n    int age;\n};\n} // namespace ns\n\nnamespace ns\n{\nvoid to_json(json& j, const person& p)\n{\n    j = json{ {\"name\", p.name}, {\"address\", p.address}, {\"age\", p.age} };\n}\n} // namespace ns\n\nint main()\n{\n    ns::person p = {\"Ned Flanders\", \"744 Evergreen Terrace\", 60};\n\n    json j = p;\n\n    std::cout << j << '\\n';\n}\n

    Output:

    {\"address\":\"744 Evergreen Terrace\",\"age\":60,\"name\":\"Ned Flanders\"}\n
    "},{"location":"api/adl_serializer/to_json/#see-also","title":"See also","text":"
    • from_json - convert JSON to a C++ value
    • Arbitrary Type Conversions - write your own from_json and to_json functions
    • Converting values - overview of get, get_to and implicit conversions
    "},{"location":"api/adl_serializer/to_json/#version-history","title":"Version history","text":"
    • Added in version 2.1.0.
    "},{"location":"api/basic_json/","title":"nlohmann::basic_json","text":"

    Defined in header <nlohmann/json.hpp>

    template<\n    template<typename U, typename V, typename... Args> class ObjectType = std::map,\n    template<typename U, typename... Args> class ArrayType = std::vector,\n    class StringType = std::string,\n    class BooleanType = bool,\n    class NumberIntegerType = std::int64_t,\n    class NumberUnsignedType = std::uint64_t,\n    class NumberFloatType = double,\n    template<typename U> class AllocatorType = std::allocator,\n    template<typename T, typename SFINAE = void> class JSONSerializer = adl_serializer,\n    class BinaryType = std::vector<std::uint8_t>,\n    class CustomBaseClass = void\n>\nclass basic_json;\n
    "},{"location":"api/basic_json/#template-parameters","title":"Template parameters","text":"Template parameter Description Derived type ObjectType type for JSON objects object_t ArrayType type for JSON arrays array_t StringType type for JSON strings and object keys string_t BooleanType type for JSON booleans boolean_t NumberIntegerType type for JSON integer numbers number_integer_t NumberUnsignedType type for JSON unsigned integer numbers number_unsigned_t NumberFloatType type for JSON floating-point numbers number_float_t AllocatorType type of the allocator to use JSONSerializer the serializer to resolve internal calls to to_json() and from_json() json_serializer BinaryType type for binary arrays binary_t CustomBaseClass extension point for user code json_base_class_t

    The library imposes a number of requirements on these types that are not expressed as C++ concepts, such as the container operations object_t and array_t must provide, or the fact that StringType must be char-based. They are collected in Template Parameter Requirements.

    "},{"location":"api/basic_json/#specializations","title":"Specializations","text":"
    • json - default specialization
    • ordered_json - a specialization that maintains the insertion order of object keys
    "},{"location":"api/basic_json/#documents-and-views","title":"Documents and views","text":"

    Besides basic_json, the library offers a second way to hold a parsed JSON text: a basic_json_document, which owns or borrows the text and holds a flat index of the values in it, and a basic_json_view, a read-only handle to one value of such a document. Both are defined in the header <nlohmann/json_view.hpp>; see Zero-copy JSON views for the concept and the trade-offs.

    • json_document / ordered_json_document - read-only documents of the basic_json specialization they belong to
    • json_editable_document / ordered_json_editable_document - documents that can be modified in place
    • json_view / ordered_json_view - views of a document
    • json_editable_view / ordered_json_editable_view - views of an editable document
    "},{"location":"api/basic_json/#iterator-invalidation","title":"Iterator invalidation","text":"

    All operations that add values to an array (push_back , operator+=, emplace_back, insert, and operator[] for a non-existing index) can yield a reallocation, in which case all iterators (including the end() iterator) and all references to the elements are invalidated.

    For ordered_json, also all operations that add a value to an object (push_back, operator+=, emplace, insert, update, and operator[] for a non-existing key) can yield a reallocation, in which case all iterators (including the end() iterator) and all references to the elements are invalidated.

    "},{"location":"api/basic_json/#requirements","title":"Requirements","text":"

    The class satisfies the following concept requirements:

    "},{"location":"api/basic_json/#basic","title":"Basic","text":"
    • DefaultConstructible: JSON values can be default-constructed. The result will be a JSON null value.
    • MoveConstructible: A JSON value can be constructed from an rvalue argument.
    • CopyConstructible: A JSON value can be copy-constructed from an lvalue expression.
    • MoveAssignable: A JSON value can be assigned from an rvalue argument.
    • CopyAssignable: A JSON value can be copy-assigned from an lvalue expression.
    • Destructible: JSON values can be destructed.
    "},{"location":"api/basic_json/#layout","title":"Layout","text":"
    • StandardLayoutType: JSON values have standard layout: All non-static data members are private and standard layout types, the class has no virtual functions or (virtual) base classes.
    "},{"location":"api/basic_json/#library-wide","title":"Library-wide","text":"
    • EqualityComparable: JSON values can be compared with ==, see operator==.
    • LessThanComparable: JSON values can be compared with <, see operator<.
    • Swappable: Any JSON lvalue or rvalue of can be swapped with any lvalue or rvalue of other compatible types, using unqualified function swap.
    • NullablePointer: JSON values can be compared against std::nullptr_t objects which are used to model the null value.
    "},{"location":"api/basic_json/#container","title":"Container","text":"
    • Container: JSON values can be used like STL containers and provide iterator access.
    • ReversibleContainer: JSON values can be used like STL containers and provide reverse iterator access.
    "},{"location":"api/basic_json/#member-types","title":"Member types","text":"
    • adl_serializer - the default serializer
    • value_t - the JSON type enumeration
    • json_pointer - JSON Pointer implementation
    • json_serializer - type of the serializer to for conversions from/to JSON
    • error_handler_t - type to choose behavior on decoding errors
    • bjdata_version_t - type to choose the BJData version to write
    • cbor_tag_handler_t - type to choose how to handle CBOR tags
    • initializer_list_t - type for initializer lists of basic_json values
    • input_format_t - type to choose the format to parse
    • json_sax_t - type for SAX events
    • with_object_t, with_array_t, with_string_t, with_boolean_t, with_integers_t, with_float_t, with_allocator_t, with_json_serializer_t, with_binary_t, with_base_class_t - types to create a basic_json type with one (or two) replaced template parameters
    "},{"location":"api/basic_json/#exceptions","title":"Exceptions","text":"
    • exception - general exception of the basic_json class
      • parse_error - exception indicating a parse error
      • invalid_iterator - exception indicating errors with iterators
      • type_error - exception indicating executing a member function with a wrong type
      • out_of_range - exception indicating access out of the defined range
      • other_error - exception indicating other library errors
    "},{"location":"api/basic_json/#container-types","title":"Container types","text":"Type Definition value_type basic_json reference value_type& const_reference const value_type& difference_type std::ptrdiff_t size_type std::size_t allocator_type AllocatorType<basic_json> pointer std::allocator_traits<allocator_type>::pointer const_pointer std::allocator_traits<allocator_type>::const_pointer iterator LegacyBidirectionalIterator const_iterator constant LegacyBidirectionalIterator reverse_iterator reverse iterator, derived from iterator const_reverse_iterator reverse iterator, derived from const_iterator iteration_proxy helper type for items function"},{"location":"api/basic_json/#json-value-data-types","title":"JSON value data types","text":"
    • array_t - type for arrays
    • binary_t - type for binary arrays
    • boolean_t - type for booleans
    • default_object_comparator_t - default comparator for objects
    • number_float_t - type for numbers (floating-point)
    • number_integer_t - type for numbers (integer)
    • number_unsigned_t - type for numbers (unsigned)
    • object_comparator_t - comparator for objects
    • object_t - type for objects
    • string_t - type for strings
    "},{"location":"api/basic_json/#parser-callback","title":"Parser callback","text":"
    • parse_event_t - parser event types
    • parser_callback_t - per-element parser callback type
    "},{"location":"api/basic_json/#member-functions","title":"Member functions","text":"
    • (constructor)
    • (destructor)
    • operator= - copy assignment
    • array (static) - explicitly create an array
    • binary (static) - explicitly create a binary array
    • object (static) - explicitly create an object
    "},{"location":"api/basic_json/#object-inspection","title":"Object inspection","text":"

    Functions to inspect the type of a JSON value.

    • type - return the type of the JSON value
    • operator value_t - return the type of the JSON value
    • type_name - return the type as string
    • is_primitive - return whether the type is primitive
    • is_structured - return whether the type is structured
    • is_null - return whether the value is null
    • is_boolean - return whether the value is a boolean
    • is_number - return whether the value is a number
    • is_number_integer - return whether the value is an integer number
    • is_number_unsigned - return whether the value is an unsigned integer number
    • is_number_float - return whether the value is a floating-point number
    • is_object - return whether the value is an object
    • is_array - return whether the value is an array
    • is_string - return whether the value is a string
    • is_binary - return whether the value is a binary array
    • is_discarded - return whether the value is discarded

    Optional functions to access the diagnostic positions.

    • start_pos - return the start position of the value
    • end_pos - return the one past the end position of the value
    "},{"location":"api/basic_json/#value-access","title":"Value access","text":"

    Direct access to the stored value of a JSON value.

    • get - get a value
    • get_to - get a value and write it to a destination
    • get_ptr - get a pointer value
    • get_ref - get a reference value
    • operator ValueType - get a value
    • get_binary - get a binary value
    • as_base_class - access the custom base class
    "},{"location":"api/basic_json/#element-access","title":"Element access","text":"

    Access to the JSON value

    • at - access specified element with bounds checking
    • operator[] - access specified element
    • value - access specified object element with default value
    • front - access the first element
    • back - access the last element
    "},{"location":"api/basic_json/#lookup","title":"Lookup","text":"
    • find - find an element in a JSON object
    • count - returns the number of occurrences of a key in a JSON object
    • contains - check the existence of an element in a JSON object
    "},{"location":"api/basic_json/#iterators","title":"Iterators","text":"
    • begin - returns an iterator to the first element
    • cbegin - returns a const iterator to the first element
    • end - returns an iterator to one past the last element
    • cend - returns a const iterator to one past the last element
    • rbegin - returns an iterator to the reverse-beginning
    • rend - returns an iterator to the reverse-end
    • crbegin - returns a const iterator to the reverse-beginning
    • crend - returns a const iterator to the reverse-end
    • items - wrapper to access iterator member functions in range-based for
    "},{"location":"api/basic_json/#capacity","title":"Capacity","text":"
    • empty - checks whether the container is empty
    • size - returns the number of elements
    • max_size - returns the maximum possible number of elements
    "},{"location":"api/basic_json/#modifiers","title":"Modifiers","text":"
    • clear - clears the contents
    • push_back - add a value to an array/object
    • operator+= - add a value to an array/object
    • emplace_back - add a value to an array
    • emplace - add a value to an object if a key does not exist
    • erase - remove elements
    • insert - inserts elements
    • update - updates a JSON object from another object, overwriting existing keys
    • swap - exchanges the values
    "},{"location":"api/basic_json/#lexicographical-comparison-operators","title":"Lexicographical comparison operators","text":"
    • operator== - comparison: equal
    • operator!= - comparison: not equal
    • operator< - comparison: less than
    • operator> - comparison: greater than
    • operator<= - comparison: less than or equal
    • operator>= - comparison: greater than or equal
    • operator<=> - comparison: 3-way
    "},{"location":"api/basic_json/#serialization-dumping","title":"Serialization / Dumping","text":"
    • dump - serialization
    "},{"location":"api/basic_json/#deserialization-parsing","title":"Deserialization / Parsing","text":"
    • parse (static) - deserialize from a compatible input
    • accept (static) - check if the input is valid JSON
    • sax_parse (static) - generate SAX events
    "},{"location":"api/basic_json/#json-pointer-functions","title":"JSON Pointer functions","text":"
    • flatten - return flattened JSON value
    • unflatten - unflatten a previously flattened JSON value
    "},{"location":"api/basic_json/#json-patch-functions","title":"JSON Patch functions","text":"
    • patch - applies a JSON patch
    • patch_inplace - applies a JSON patch in place
    • diff (static) - creates a diff as a JSON patch
    "},{"location":"api/basic_json/#json-merge-patch-functions","title":"JSON Merge Patch functions","text":"
    • merge_patch - applies a JSON Merge Patch
    • merge_diff (static) - creates a diff as a JSON Merge Patch
    "},{"location":"api/basic_json/#static-functions","title":"Static functions","text":"
    • meta - returns version information on the library
    • get_allocator - returns the allocator associated with the container
    "},{"location":"api/basic_json/#binary-formats","title":"Binary formats","text":"
    • from_bjdata (static) - create a JSON value from an input in BJData format
    • from_bon8 (static) - create a JSON value from an input in BON8 format
    • from_bson (static) - create a JSON value from an input in BSON format
    • from_cbor (static) - create a JSON value from an input in CBOR format
    • from_msgpack (static) - create a JSON value from an input in MessagePack format
    • from_ubjson (static) - create a JSON value from an input in UBJSON format
    • to_bjdata (static) - create a BJData serialization of a given JSON value
    • to_bon8 (static) - create a BON8 serialization of a given JSON value
    • to_bson (static) - create a BSON serialization of a given JSON value
    • to_cbor (static) - create a CBOR serialization of a given JSON value
    • to_msgpack (static) - create a MessagePack serialization of a given JSON value
    • to_ubjson (static) - create a UBJSON serialization of a given JSON value
    "},{"location":"api/basic_json/#non-member-functions","title":"Non-member functions","text":"
    • operator<<(std::ostream&) - serialize to stream
    • operator>>(std::istream&) - deserialize from stream
    • to_string - user-defined to_string function for JSON values
    • format_as - user-defined format_as function for JSON values (fmt support)
    "},{"location":"api/basic_json/#literals","title":"Literals","text":"
    • operator\"\"_json - user-defined string literal for JSON values
    "},{"location":"api/basic_json/#helper-classes","title":"Helper classes","text":"
    • std::formatter<basic_json> - make JSON values formattable with std::format
    • std::hash<basic_json> - return a hash value for a JSON object
    • std::swap<basic_json> - exchanges the values of two JSON objects
    "},{"location":"api/basic_json/#examples","title":"Examples","text":"Example

    The example shows how the library is used.

    #include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create a JSON object\n    json j =\n    {\n        {\"pi\", 3.141},\n        {\"happy\", true},\n        {\"name\", \"Niels\"},\n        {\"nothing\", nullptr},\n        {\n            \"answer\", {\n                {\"everything\", 42}\n            }\n        },\n        {\"list\", {1, 0, 2}},\n        {\n            \"object\", {\n                {\"currency\", \"USD\"},\n                {\"value\", 42.99}\n            }\n        }\n    };\n\n    // add new values\n    j[\"new\"][\"key\"][\"value\"] = {\"another\", \"list\"};\n\n    // count elements\n    auto s = j.size();\n    j[\"size\"] = s;\n\n    // pretty print with indent of 4 spaces\n    std::cout << std::setw(4) << j << '\\n';\n}\n

    Output:

    {\n    \"answer\": {\n        \"everything\": 42\n    },\n    \"happy\": true,\n    \"list\": [\n        1,\n        0,\n        2\n    ],\n    \"name\": \"Niels\",\n    \"new\": {\n        \"key\": {\n            \"value\": [\n                \"another\",\n                \"list\"\n            ]\n        }\n    },\n    \"nothing\": null,\n    \"object\": {\n        \"currency\": \"USD\",\n        \"value\": 42.99\n    },\n    \"pi\": 3.141,\n    \"size\": 8\n}\n
    "},{"location":"api/basic_json/#see-also","title":"See also","text":"
    • RFC 8259: The JavaScript Object Notation (JSON) Data Interchange Format - specification of the JSON data interchange format
    • basic_json_document - / basic_json_view - parse a JSON text into a flat index and read it through a view
    • Zero-copy JSON views - when to use a document and a view instead of a basic_json
    • Types - how JSON values are stored and which types exist
    • Converting values - get values out of a JSON value and put values in
    • Creating JSON values - all the ways to build a JSON value
    • Arbitrary Type Conversions - convert your own types to and from JSON
    "},{"location":"api/basic_json/#version-history","title":"Version history","text":"
    • Added in version 1.0.0.
    "},{"location":"api/basic_json/accept/","title":"nlohmann::basic_json::accept","text":"
    // (1)\ntemplate<typename InputType>\nstatic bool accept(InputType&& i,\n                   const bool ignore_comments = false,\n                   const bool ignore_trailing_commas = false);\n\n// (2)\ntemplate<typename IteratorType, typename SentinelType = IteratorType>\nstatic bool accept(IteratorType first, SentinelType last,\n                   const bool ignore_comments = false,\n                   const bool ignore_trailing_commas = false);\n

    Checks whether the input is valid JSON.

    1. Reads from a compatible input.
    2. Reads from a pair of character iterators, or an iterator and a sentinel of a different type (C++20 ranges support)

      The value_type of the iterator must be an integral type with a size of 1, 2, or 4 bytes, which will be interpreted respectively as UTF-8, UTF-16, and UTF-32. If SentinelType differs from IteratorType, it must be comparable to the iterator type with operator!=.

      Ill-formed UTF-16 and UTF-32 sequences are rejected: a lone surrogate, a high surrogate that is not followed by its low surrogate, and a code point above U+10FFFF all make this function return false.

    Unlike the parse() function, this function neither throws an exception in case of invalid JSON input (i.e., a parse error) nor creates diagnostic information.

    "},{"location":"api/basic_json/accept/#template-parameters","title":"Template parameters","text":"InputType

    A compatible input, for instance:

    • an std::istream object
    • a FILE pointer (throws if null)
    • a C-style array of characters
    • a pointer to a null-terminated string of single byte characters (throws if null)
    • a std::string or a std::string_view (C++17)
    • a container obj for which begin(obj) and end(obj) produce a valid pair of iterators (as found via ADL or member functions, with semantics compatible to std::begin and std::end)
    • wide characters (wchar_t, char16_t, char32_t), which are converted to UTF-8: a wide string object (std::wstring, std::u16string, std::u32string) or an array (e.g. a wide string literal); a pointer to a null-terminated wide string (e.g. std::u16string::c_str()) is not supported
    IteratorType

    a compatible iterator type, for instance.

    • a pair of std::string::iterator or std::vector<std::uint8_t>::iterator
    • a pair of pointers such as ptr and ptr + len
    SentinelType

    defaults to IteratorType; may be a different type comparable to IteratorType via operator!=, for instance.

    • a custom sentinel type for C++20 ranges
    • std::default_sentinel_t, when IteratorType is std::counted_iterator
    "},{"location":"api/basic_json/accept/#parameters","title":"Parameters","text":"i (in) Input to parse from. ignore_comments (in) whether comments should be ignored and treated like whitespace (true) or yield a parse error (false); (optional, false by default) ignore_trailing_commas (in) whether trailing commas in arrays or objects should be ignored and treated like whitespace (true) or yield a parse error (false); (optional, false by default) first (in) iterator to the start of the character range last (in) iterator to the end of the character range, or a sentinel value that compares equal to the end iterator with operator!="},{"location":"api/basic_json/accept/#return-value","title":"Return value","text":"

    Whether the input is valid JSON.

    "},{"location":"api/basic_json/accept/#exception-safety","title":"Exception safety","text":"

    Strong guarantee: if an exception is thrown, there are no changes in the JSON value.

    "},{"location":"api/basic_json/accept/#exceptions","title":"Exceptions","text":"

    Throws parse_error.101 in case of an empty input like a null FILE* or char* pointer.

    "},{"location":"api/basic_json/accept/#complexity","title":"Complexity","text":"

    Linear in the length of the input. The parser is a predictive LL(1) parser.

    "},{"location":"api/basic_json/accept/#notes","title":"Notes","text":"

    A UTF-8 byte order mark is silently ignored.

    By default, a '\\0' (NUL) byte anywhere in the input is treated as end of input, rather than as an ordinary (and, outside of a string, invalid) byte; see the FAQ entry for details and the JSON_STRICT_NUL_HANDLING macro to opt into rejecting it instead.

    "},{"location":"api/basic_json/accept/#examples","title":"Examples","text":"Example: (1) reading from a string

    The example below demonstrates the accept() function reading from a string.

    #include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // a valid JSON text\n    const auto* valid_text = R\"(\n    {\n        \"numbers\": [1, 2, 3]\n    }\n    )\";\n\n    // an invalid JSON text\n    const auto* invalid_text = R\"(\n    {\n        \"strings\": [\"extra\", \"comma\", ]\n    }\n    )\";\n\n    std::cout << std::boolalpha\n              << json::accept(valid_text) << ' '\n              << json::accept(invalid_text) << '\\n';\n}\n

    Output:

    true false\n
    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.

    #include <iostream>\n#include <vector>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // a buffer containing a JSON text followed by more data\n    std::vector<std::uint8_t> input = {'[', '1', ',', '2', ',', '3', ']', 'o', 't', 'h', 'e', 'r'};\n\n    std::cout << std::boolalpha\n              << json::accept(input.begin(), input.begin() + 7) << ' '\n              << json::accept(input.begin(), input.end()) << '\\n';\n}\n

    Output:

    true false\n
    Example: (3) reading from UTF-16 strings

    The encoding is deduced from the character type of the input. String literals like u\"...\", U\"...\", and L\"...\" work as well.

    #include <iostream>\n#include <string>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // a valid JSON text, given as UTF-16\n    const std::u16string valid_text = u\"{\\\"name\\\":\\\"\\u00e9\\\"}\";\n\n    // an invalid JSON text, given as UTF-16\n    const std::u16string invalid_text = u\"{\\\"name\\\":\\\"\\u00e9\\\",}\";\n\n    std::cout << std::boolalpha\n              << json::accept(valid_text) << ' '\n              << json::accept(invalid_text) << '\\n';\n}\n

    Output:

    true false\n
    "},{"location":"api/basic_json/accept/#see-also","title":"See also","text":"
    • parse - deserialize from a compatible input
    • sax_parse - parse input using the SAX interface
    • operator>> - deserialize from stream
    • JSON_STRICT_NUL_HANDLING - opt in to rejecting a NUL byte in the input instead of treating it as end of input
    • JSON_DISABLE_STREAM_BULK_SCAN - read a std::istream one character at a time
    • JSON_DISABLE_UNLOCKED_FILE_IO - read a FILE* with the locking stdio functions
    • Parsing - overview of the parsing functions
    • Comments - ignore // and /* */ comments while parsing
    • Trailing Commas - accept trailing commas in arrays and objects
    • Parsing and Exceptions - handling parse errors and locating them in the input
    • Parsing Untrusted Input - limits and checks for input you do not control
    "},{"location":"api/basic_json/accept/#version-history","title":"Version history","text":"
    • Added in version 3.0.0.
    • Ignoring comments via ignore_comments added in version 3.9.0.
    • Changed runtime assertion in case of FILE* null pointers to exception in version 3.12.0.
    • Added ignore_trailing_commas in version 3.13.0 unreleased.
    • Extended container support (1) to include types with lvalue-only ADL begin/end (matching std::begin/std::end semantics) in version 3.13.0 unreleased.
    • Extended overload (2) to accept heterogeneous iterator+sentinel pairs (C++20 ranges support) in version 3.13.0 unreleased.
    • JSON_STRICT_NUL_HANDLING added in version 3.13.0 unreleased 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.
    • Parsing from an std::istream scans the characters in its stream buffer in bulk in version 3.13.0 unreleased (JSON_DISABLE_STREAM_BULK_SCAN).
    • Parsing from a FILE* locks the file once instead of once per character in version 3.13.0 unreleased (JSON_DISABLE_UNLOCKED_FILE_IO).
    • Ill-formed UTF-16 and UTF-32 input (a lone surrogate, a high surrogate that is not followed by its low surrogate, or a code point above U+10FFFF) is rejected in version 3.13.0 unreleased; before that, some such sequences were accepted or ended the input silently.

    Deprecation

    Overload (2) replaces calls to accept 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 accept({ptr, ptr+len}, ...); with accept(ptr, ptr+len, ...);.

    You should be warned by your compiler with a -Wdeprecated-declarations warning if you are using a deprecated function.

    See the migration guide for how to update existing code.

    "},{"location":"api/basic_json/array/","title":"nlohmann::basic_json::array","text":"
    static basic_json array(initializer_list_t init = {});\n

    Creates a JSON array value from a given initializer list. That is, given a list of values a, b, c, creates the JSON value [a, b, c]. If the initializer list is empty, the empty array [] is created.

    "},{"location":"api/basic_json/array/#parameters","title":"Parameters","text":"init (in) initializer list with JSON values to create an array from (optional)"},{"location":"api/basic_json/array/#return-value","title":"Return value","text":"

    JSON array value

    "},{"location":"api/basic_json/array/#exception-safety","title":"Exception safety","text":"

    Strong guarantee: if an exception is thrown, there are no changes in the JSON value.

    "},{"location":"api/basic_json/array/#complexity","title":"Complexity","text":"

    Linear in the size of init.

    "},{"location":"api/basic_json/array/#notes","title":"Notes","text":"

    This function is only needed to express two edge cases that cannot be realized with the initializer list constructor (basic_json(initializer_list_t, bool, value_t)). These cases are:

    1. creating an array whose elements are all pairs whose first element is a string \u2014 in this case, the initializer list constructor would create an object, taking the first elements as keys
    2. creating an empty array \u2014 passing the empty initializer list to the initializer list constructor yields an empty object
    "},{"location":"api/basic_json/array/#examples","title":"Examples","text":"Example

    The following code shows an example for the array function.

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create JSON arrays\n    json j_no_init_list = json::array();\n    json j_empty_init_list = json::array({});\n    json j_nonempty_init_list = json::array({1, 2, 3, 4});\n    json j_list_of_pairs = json::array({ {\"one\", 1}, {\"two\", 2} });\n\n    // serialize the JSON arrays\n    std::cout << j_no_init_list << '\\n';\n    std::cout << j_empty_init_list << '\\n';\n    std::cout << j_nonempty_init_list << '\\n';\n    std::cout << j_list_of_pairs << '\\n';\n}\n

    Output:

    []\n[]\n[1,2,3,4]\n[[\"one\",1],[\"two\",2]]\n
    "},{"location":"api/basic_json/array/#see-also","title":"See also","text":"
    • basic_json(initializer_list_t) - create a JSON value from an initializer list
    • object - create a JSON object value from an initializer list
    • Creating JSON values - the article on creating JSON values
    "},{"location":"api/basic_json/array/#version-history","title":"Version history","text":"
    • Added in version 1.0.0.
    "},{"location":"api/basic_json/array_t/","title":"nlohmann::basic_json::array_t","text":"
    using array_t = ArrayType<basic_json, AllocatorType<basic_json>>;\n

    The type used to store JSON arrays.

    RFC 8259 describes JSON arrays as follows:

    An array is an ordered sequence of zero or more values.

    To store objects in C++, a type is defined by the template parameters explained below.

    "},{"location":"api/basic_json/array_t/#template-parameters","title":"Template parameters","text":"ArrayType container type to store arrays. It must be a vector-like container: the library uses operator[], at(), and resize(), and requires random-access iterators. std::vector and std::deque qualify; std::list does not. See Template Parameter Requirements for the full list of requirements. AllocatorType the allocator to use for objects (e.g., std::allocator)"},{"location":"api/basic_json/array_t/#notes","title":"Notes","text":""},{"location":"api/basic_json/array_t/#default-type","title":"Default type","text":"

    With the default values for ArrayType (std::vector) and AllocatorType (std::allocator), the default type for array_t is:

    std::vector<\n  basic_json, // value_type\n  std::allocator<basic_json> // allocator_type\n>\n
    "},{"location":"api/basic_json/array_t/#limits","title":"Limits","text":"

    RFC 8259 specifies:

    An implementation may set limits on the maximum depth of nesting.

    In this class, the array's limit of nesting is not explicitly constrained. However, a maximum depth of nesting may be introduced by the compiler or runtime environment. A theoretical limit can be queried by calling the max_size function of a JSON array.

    "},{"location":"api/basic_json/array_t/#storage","title":"Storage","text":"

    Arrays are stored as pointers in a basic_json type. That is, for any access to array values, a pointer of type array_t* must be dereferenced.

    "},{"location":"api/basic_json/array_t/#examples","title":"Examples","text":"Example

    The following code shows that array_t is by default, a typedef to std::vector<nlohmann::json>.

    #include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    std::cout << std::boolalpha << std::is_same<std::vector<json>, json::array_t>::value << '\\n';\n}\n

    Output:

    true\n
    "},{"location":"api/basic_json/array_t/#see-also","title":"See also","text":"
    • object_t - the type used to store JSON objects
    • binary_t - the type used to store binary values
    • is_array - checks whether the JSON value is an array
    • max_size - returns the maximum possible number of elements
    • Types - how arrays are stored
    • Template Parameter Requirements - requirements on the ArrayType template parameter
    "},{"location":"api/basic_json/array_t/#version-history","title":"Version history","text":"
    • Added in version 1.0.0.
    • Made capacity() optional, so that array types such as std::deque can be used, in version 3.13.0 unreleased.
    "},{"location":"api/basic_json/as_base_class/","title":"nlohmann::basic_json::as_base_class","text":"
    json_base_class_t& as_base_class() noexcept;\nconst json_base_class_t& as_base_class() const noexcept;\n

    Returns a reference to this object as its custom base class json_base_class_t. No copy is made.

    Since basic_json derives from json_base_class_t, a member of basic_json hides any member of the custom base class with the same name. This function makes such hidden members accessible again.

    "},{"location":"api/basic_json/as_base_class/#return-value","title":"Return value","text":"

    reference to this object as json_base_class_t

    "},{"location":"api/basic_json/as_base_class/#exception-safety","title":"Exception safety","text":"

    No-throw guarantee: this function never throws exceptions.

    "},{"location":"api/basic_json/as_base_class/#complexity","title":"Complexity","text":"

    Constant.

    "},{"location":"api/basic_json/as_base_class/#notes","title":"Notes","text":"

    The function is equivalent to static_cast<json_base_class_t&>(j) (or static_cast<const json_base_class_t&>(j)).

    "},{"location":"api/basic_json/as_base_class/#examples","title":"Examples","text":"Example

    The example shows how to use as_base_class to access members of the custom base class that are hidden by members of basic_json.

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nclass base_class_with_hidden_members\n{\n  public:\n    const char* type_name() const noexcept\n    {\n        return \"my_type_name\";\n    }\n\n    std::size_t size() const noexcept\n    {\n        return 42;\n    }\n};\n\nusing json = nlohmann::json::with_base_class_t<base_class_with_hidden_members>;\n\nint main()\n{\n    json j = {1, 2, 3};\n\n    // the members of basic_json hide the members of the base class\n    std::cout << j.type_name() << ' ' << j.size() << '\\n';\n\n    // access the hidden members of the base class\n    std::cout << j.as_base_class().type_name() << ' ' << j.as_base_class().size() << '\\n';\n}\n

    Output:

    array 3\nmy_type_name 42\n
    "},{"location":"api/basic_json/as_base_class/#see-also","title":"See also","text":"
    • json_base_class_t - type of the custom base class
    • Template Parameter Requirements - requirements on the CustomBaseClass template parameter
    "},{"location":"api/basic_json/as_base_class/#version-history","title":"Version history","text":"
    • Added in version 3.13.0 unreleased.
    "},{"location":"api/basic_json/at/","title":"nlohmann::basic_json::at","text":"
    // (1)\nreference at(size_type idx);\nconst_reference at(size_type idx) const;\n\n// (2)\nreference at(const typename object_t::key_type& key);\nconst_reference at(const typename object_t::key_type& key) const;\n\n// (3)\ntemplate<typename KeyType>\nreference at(KeyType&& key);\ntemplate<typename KeyType>\nconst_reference at(KeyType&& key) const;\n\n// (4)\nreference at(const json_pointer& ptr);\nconst_reference at(const json_pointer& ptr) const;\n
    1. Returns a reference to the array element at specified location idx, with bounds checking.
    2. Returns a reference to the object element with specified key key, with bounds checking.
    3. See 2. This overload is only available if KeyType is comparable with typename object_t::key_type and typename object_comparator_t::is_transparent denotes a type.
    4. Returns a reference to the element at specified JSON pointer ptr, with bounds checking.
    "},{"location":"api/basic_json/at/#template-parameters","title":"Template parameters","text":"KeyType A type for an object key other than json_pointer that is comparable with string_t using object_comparator_t. This can also be a string view (C++17)."},{"location":"api/basic_json/at/#parameters","title":"Parameters","text":"idx (in) index of the element to access key (in) object key of the elements to access ptr (in) JSON pointer to the desired element"},{"location":"api/basic_json/at/#return-value","title":"Return value","text":"
    1. reference to the element at index idx
    2. reference to the element at key key
    3. reference to the element at key key
    4. reference to the element pointed to by ptr
    "},{"location":"api/basic_json/at/#exception-safety","title":"Exception safety","text":"

    Strong exception safety: if an exception occurs, the original value stays intact.

    "},{"location":"api/basic_json/at/#exceptions","title":"Exceptions","text":"
    1. The function can throw the following exceptions:
      • Throws type_error.304 if the JSON value is not an array; in this case, calling at with an index makes no sense. See the example below.
      • Throws out_of_range.401 if the index idx is out of range of the array; that is, idx >= size(). See the example below.
    2. The function can throw the following exceptions:
      • Throws type_error.304 if the JSON value is not an object; in this case, calling at with a key makes no sense. See the example below.
      • Throws out_of_range.403 if the key key is not stored in the object; that is, find(key) == end(). See the example below.
    3. See 2.
    4. The function can throw the following exceptions:
      • Throws parse_error.106 if an array index in the passed JSON pointer ptr begins with '0'. See the example below.
      • Throws parse_error.109 if an array index in the passed JSON pointer ptr is not a number. See the example below.
      • Throws out_of_range.401 if an array index in the passed JSON pointer ptr is out of range. See the example below.
      • Throws out_of_range.402 if the array index '-' is used in the passed JSON pointer ptr. As at provides checked access (and no elements are implicitly inserted), the index '-' is always invalid. See the example below.
      • Throws out_of_range.403 if the JSON pointer describes a key of an object which cannot be found. See the example below.
      • Throws out_of_range.404 if the JSON pointer ptr can not be resolved. See the example below.
      • Throws out_of_range.410 if an array index in the passed JSON pointer ptr exceeds the range of size_type (e.g., on 32-bit platforms).
    "},{"location":"api/basic_json/at/#complexity","title":"Complexity","text":"
    1. Constant.
    2. Logarithmic in the size of the container.
    3. Logarithmic in the size of the container.
    4. Linear in the number of reference tokens of ptr; for each of them, logarithmic in the size of the object, or constant for an array.
    "},{"location":"api/basic_json/at/#notes","title":"Notes","text":"

    Deprecation

    Overload (4) also accepts a json_pointer 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 for how to update existing code.

    "},{"location":"api/basic_json/at/#examples","title":"Examples","text":"Example: (1) access specified array element with bounds checking

    The example below shows how array elements can be read and written using at(). It also demonstrates the different exceptions that can be thrown.

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create JSON array\n    json array = {\"first\", \"2nd\", \"third\", \"fourth\"};\n\n    // output element at index 2 (third element)\n    std::cout << array.at(2) << '\\n';\n\n    // change element at index 1 (second element) to \"second\"\n    array.at(1) = \"second\";\n\n    // output changed array\n    std::cout << array << '\\n';\n\n    // exception type_error.304\n    try\n    {\n        // use at() on a non-array type\n        json str = \"I am a string\";\n        str.at(0) = \"Another string\";\n    }\n    catch (const json::type_error& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n\n    // exception out_of_range.401\n    try\n    {\n        // try to write beyond the array limit\n        array.at(5) = \"sixth\";\n    }\n    catch (const json::out_of_range& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n}\n

    Output:

    \"third\"\n[\"first\",\"second\",\"third\",\"fourth\"]\n[json.exception.type_error.304] cannot use at() with string\n[json.exception.out_of_range.401] array index 5 is out of range\n
    Example: (1) access specified array element with bounds checking

    The example below shows how array elements can be read using at(). It also demonstrates the different exceptions that can be thrown.

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create JSON array\n    const json array = {\"first\", \"2nd\", \"third\", \"fourth\"};\n\n    // output element at index 2 (third element)\n    std::cout << array.at(2) << '\\n';\n\n    // exception type_error.304\n    try\n    {\n        // use at() on a non-array type\n        const json str = \"I am a string\";\n        std::cout << str.at(0) << '\\n';\n    }\n    catch (const json::type_error& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n\n    // exception out_of_range.401\n    try\n    {\n        // try to read beyond the array limit\n        std::cout << array.at(5) << '\\n';\n    }\n    catch (const json::out_of_range& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n}\n

    Output:

    \"third\"\n[json.exception.type_error.304] cannot use at() with string\n[json.exception.out_of_range.401] array index 5 is out of range\n
    Example: (2) access specified object element with bounds checking

    The example below shows how object elements can be read and written using at(). It also demonstrates the different exceptions that can be thrown.

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create JSON object\n    json object =\n    {\n        {\"the good\", \"il buono\"},\n        {\"the bad\", \"il cattivo\"},\n        {\"the ugly\", \"il brutto\"}\n    };\n\n    // output element with key \"the ugly\"\n    std::cout << object.at(\"the ugly\") << '\\n';\n\n    // change element with key \"the bad\"\n    object.at(\"the bad\") = \"il cattivo\";\n\n    // output changed array\n    std::cout << object << '\\n';\n\n    // exception type_error.304\n    try\n    {\n        // use at() on a non-object type\n        json str = \"I am a string\";\n        str.at(\"the good\") = \"Another string\";\n    }\n    catch (const json::type_error& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n\n    // exception out_of_range.401\n    try\n    {\n        // try to write at a nonexisting key\n        object.at(\"the fast\") = \"il rapido\";\n    }\n    catch (const json::out_of_range& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n}\n

    Output:

    \"il brutto\"\n{\"the bad\":\"il cattivo\",\"the good\":\"il buono\",\"the ugly\":\"il brutto\"}\n[json.exception.type_error.304] cannot use at() with string\n[json.exception.out_of_range.403] key 'the fast' not found\n
    Example: (2) access specified object element with bounds checking

    The example below shows how object elements can be read using at(). It also demonstrates the different exceptions that can be thrown.

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create JSON object\n    const json object =\n    {\n        {\"the good\", \"il buono\"},\n        {\"the bad\", \"il cattivo\"},\n        {\"the ugly\", \"il brutto\"}\n    };\n\n    // output element with key \"the ugly\"\n    std::cout << object.at(\"the ugly\") << '\\n';\n\n    // exception type_error.304\n    try\n    {\n        // use at() on a non-object type\n        const json str = \"I am a string\";\n        std::cout << str.at(\"the good\") << '\\n';\n    }\n    catch (const json::type_error& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n\n    // exception out_of_range.401\n    try\n    {\n        // try to read from a nonexisting key\n        std::cout << object.at(\"the fast\") << '\\n';\n    }\n    catch (const json::out_of_range)\n    {\n        std::cout << \"out of range\" << '\\n';\n    }\n}\n

    Output:

    \"il brutto\"\n[json.exception.type_error.304] cannot use at() with string\nout of range\n
    Example: (3) access specified object element using string_view with bounds checking

    The example below shows how object elements can be read and written using at(). It also demonstrates the different exceptions that can be thrown.

    #include <iostream>\n#include <string_view>\n#include <nlohmann/json.hpp>\n\nusing namespace std::string_view_literals;\nusing nlohmann::json;\n\nint main()\n{\n    // create JSON object\n    json object =\n    {\n        {\"the good\", \"il buono\"},\n        {\"the bad\", \"il cattivo\"},\n        {\"the ugly\", \"il brutto\"}\n    };\n\n    // output element with key \"the ugly\" using string_view\n    std::cout << object.at(\"the ugly\"sv) << '\\n';\n\n    // change element with key \"the bad\" using string_view\n    object.at(\"the bad\"sv) = \"il cattivo\";\n\n    // output changed array\n    std::cout << object << '\\n';\n\n    // exception type_error.304\n    try\n    {\n        // use at() with string_view on a non-object type\n        json str = \"I am a string\";\n        str.at(\"the good\"sv) = \"Another string\";\n    }\n    catch (const json::type_error& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n\n    // exception out_of_range.401\n    try\n    {\n        // try to write at a nonexisting key using string_view\n        object.at(\"the fast\"sv) = \"il rapido\";\n    }\n    catch (const json::out_of_range& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n}\n

    Output:

    \"il brutto\"\n{\"the bad\":\"il cattivo\",\"the good\":\"il buono\",\"the ugly\":\"il brutto\"}\n[json.exception.type_error.304] cannot use at() with string\n[json.exception.out_of_range.403] key 'the fast' not found\n
    Example: (3) access specified object element using string_view with bounds checking

    The example below shows how object elements can be read using at(). It also demonstrates the different exceptions that can be thrown.

    #include <iostream>\n#include <string_view>\n#include <nlohmann/json.hpp>\n\nusing namespace std::string_view_literals;\nusing nlohmann::json;\n\nint main()\n{\n    // create JSON object\n    const json object =\n    {\n        {\"the good\", \"il buono\"},\n        {\"the bad\", \"il cattivo\"},\n        {\"the ugly\", \"il brutto\"}\n    };\n\n    // output element with key \"the ugly\" using string_view\n    std::cout << object.at(\"the ugly\"sv) << '\\n';\n\n    // exception type_error.304\n    try\n    {\n        // use at() with string_view on a non-object type\n        const json str = \"I am a string\";\n        std::cout << str.at(\"the good\"sv) << '\\n';\n    }\n    catch (const json::type_error& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n\n    // exception out_of_range.401\n    try\n    {\n        // try to read from a nonexisting key using string_view\n        std::cout << object.at(\"the fast\"sv) << '\\n';\n    }\n    catch (const json::out_of_range& e)\n    {\n        std::cout << \"out of range\" << '\\n';\n    }\n}\n

    Output:

    \"il brutto\"\n[json.exception.type_error.304] cannot use at() with string\nout of range\n
    Example: (4) access specified element via JSON Pointer

    The example below shows how object elements can be read and written using at(). It also demonstrates the different exceptions that can be thrown.

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\nusing namespace nlohmann::literals;\n\nint main()\n{\n    // create a JSON value\n    json j =\n    {\n        {\"number\", 1}, {\"string\", \"foo\"}, {\"array\", {1, 2}}\n    };\n\n    // read-only access\n\n    // output element with JSON pointer \"/number\"\n    std::cout << j.at(\"/number\"_json_pointer) << '\\n';\n    // output element with JSON pointer \"/string\"\n    std::cout << j.at(\"/string\"_json_pointer) << '\\n';\n    // output element with JSON pointer \"/array\"\n    std::cout << j.at(\"/array\"_json_pointer) << '\\n';\n    // output element with JSON pointer \"/array/1\"\n    std::cout << j.at(\"/array/1\"_json_pointer) << '\\n';\n\n    // writing access\n\n    // change the string\n    j.at(\"/string\"_json_pointer) = \"bar\";\n    // output the changed string\n    std::cout << j[\"string\"] << '\\n';\n\n    // change an array element\n    j.at(\"/array/1\"_json_pointer) = 21;\n    // output the changed array\n    std::cout << j[\"array\"] << '\\n';\n\n    // out_of_range.106\n    try\n    {\n        // try to use an array index with leading '0'\n        json::reference ref = j.at(\"/array/01\"_json_pointer);\n    }\n    catch (const json::parse_error& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n\n    // out_of_range.109\n    try\n    {\n        // try to use an array index that is not a number\n        json::reference ref = j.at(\"/array/one\"_json_pointer);\n    }\n    catch (const json::parse_error& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n\n    // out_of_range.401\n    try\n    {\n        // try to use an invalid array index\n        json::reference ref = j.at(\"/array/4\"_json_pointer);\n    }\n    catch (const json::out_of_range& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n\n    // out_of_range.402\n    try\n    {\n        // try to use the array index '-'\n        json::reference ref = j.at(\"/array/-\"_json_pointer);\n    }\n    catch (const json::out_of_range& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n\n    // out_of_range.403\n    try\n    {\n        // try to use a JSON pointer to a nonexistent object key\n        json::const_reference ref = j.at(\"/foo\"_json_pointer);\n    }\n    catch (const json::out_of_range& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n\n    // out_of_range.404\n    try\n    {\n        // try to use a JSON pointer that cannot be resolved\n        json::reference ref = j.at(\"/number/foo\"_json_pointer);\n    }\n    catch (const json::out_of_range& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n}\n

    Output:

    1\n\"foo\"\n[1,2]\n2\n\"bar\"\n[1,21]\n[json.exception.parse_error.106] parse error: array index '01' must not begin with '0'\n[json.exception.parse_error.109] parse error: array index 'one' is not a number\n[json.exception.out_of_range.401] array index 4 is out of range\n[json.exception.out_of_range.402] array index '-' (2) is out of range\n[json.exception.out_of_range.403] key 'foo' not found\n[json.exception.out_of_range.404] unresolved reference token 'foo'\n
    Example: (4) access specified element via JSON Pointer

    The example below shows how object elements can be read using at(). It also demonstrates the different exceptions that can be thrown.

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\nusing namespace nlohmann::literals;\n\nint main()\n{\n    // create a JSON value\n    const json j =\n    {\n        {\"number\", 1}, {\"string\", \"foo\"}, {\"array\", {1, 2}}\n    };\n\n    // read-only access\n\n    // output element with JSON pointer \"/number\"\n    std::cout << j.at(\"/number\"_json_pointer) << '\\n';\n    // output element with JSON pointer \"/string\"\n    std::cout << j.at(\"/string\"_json_pointer) << '\\n';\n    // output element with JSON pointer \"/array\"\n    std::cout << j.at(\"/array\"_json_pointer) << '\\n';\n    // output element with JSON pointer \"/array/1\"\n    std::cout << j.at(\"/array/1\"_json_pointer) << '\\n';\n\n    // out_of_range.109\n    try\n    {\n        // try to use an array index that is not a number\n        json::const_reference ref = j.at(\"/array/one\"_json_pointer);\n    }\n    catch (const json::parse_error& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n\n    // out_of_range.401\n    try\n    {\n        // try to use an invalid array index\n        json::const_reference ref = j.at(\"/array/4\"_json_pointer);\n    }\n    catch (const json::out_of_range& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n\n    // out_of_range.402\n    try\n    {\n        // try to use the array index '-'\n        json::const_reference ref = j.at(\"/array/-\"_json_pointer);\n    }\n    catch (const json::out_of_range& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n\n    // out_of_range.403\n    try\n    {\n        // try to use a JSON pointer to a nonexistent object key\n        json::const_reference ref = j.at(\"/foo\"_json_pointer);\n    }\n    catch (const json::out_of_range& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n\n    // out_of_range.404\n    try\n    {\n        // try to use a JSON pointer that cannot be resolved\n        json::const_reference ref = j.at(\"/number/foo\"_json_pointer);\n    }\n    catch (const json::out_of_range& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n}\n

    Output:

    1\n\"foo\"\n[1,2]\n2\n[json.exception.parse_error.109] parse error: array index 'one' is not a number\n[json.exception.out_of_range.401] array index 4 is out of range\n[json.exception.out_of_range.402] array index '-' (2) is out of range\n[json.exception.out_of_range.403] key 'foo' not found\n[json.exception.out_of_range.404] unresolved reference token 'foo'\n
    "},{"location":"api/basic_json/at/#see-also","title":"See also","text":"
    • Checked access - element access with range checking
    • operator[] - unchecked access by reference
    • value - access with default value
    • basic_json_view::at - the same access on a zero-copy view
    • Element Access - overview of all ways to access elements
    • JSON Pointer - access nested values with a pointer
    "},{"location":"api/basic_json/at/#version-history","title":"Version history","text":"
    1. Added in version 1.0.0.
    2. Added in version 1.0.0.
    3. Added in version 3.11.0. Support for keys convertible to std::string_view added in version 3.13.0 unreleased, consistently across the lookup functions.
    4. Added in version 2.0.0. Throws parse_error.109 instead of out_of_range.404 for a one-character array index that is not a digit (e.g., /x) in version 3.13.0 unreleased, as it already did for longer ones.
    "},{"location":"api/basic_json/back/","title":"nlohmann::basic_json::back","text":"
    reference back();\n\nconst_reference back() const;\n

    Returns a reference to the last element in the container. For a JSON container c, the expression c.back() is equivalent to

    auto tmp = c.end();\n--tmp;\nreturn *tmp;\n
    "},{"location":"api/basic_json/back/#return-value","title":"Return value","text":"

    In the case of a structured type (array or object), a reference to the last element is returned. In the case of number, string, boolean, or binary values, a reference to the value is returned.

    "},{"location":"api/basic_json/back/#exception-safety","title":"Exception safety","text":"

    Strong guarantee: if an exception is thrown, there are no changes in the JSON value.

    "},{"location":"api/basic_json/back/#exceptions","title":"Exceptions","text":"

    If the JSON value is null, exception invalid_iterator.214 is thrown.

    "},{"location":"api/basic_json/back/#complexity","title":"Complexity","text":"

    Constant.

    "},{"location":"api/basic_json/back/#notes","title":"Notes","text":"

    Precondition

    The array or object must not be empty. Calling back on an empty array or object yields undefined behavior.

    "},{"location":"api/basic_json/back/#examples","title":"Examples","text":"Example

    The following code shows an example for back().

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create JSON values\n    json j_boolean = true;\n    json j_number_integer = 17;\n    json j_number_float = 23.42;\n    json j_object = {{\"one\", 1}, {\"two\", 2}};\n    json j_object_empty(json::value_t::object);\n    json j_array = {1, 2, 4, 8, 16};\n    json j_array_empty(json::value_t::array);\n    json j_string = \"Hello, world\";\n\n    // call back()\n    std::cout << j_boolean.back() << '\\n';\n    std::cout << j_number_integer.back() << '\\n';\n    std::cout << j_number_float.back() << '\\n';\n    std::cout << j_object.back() << '\\n';\n    //std::cout << j_object_empty.back() << '\\n';  // undefined behavior\n    std::cout << j_array.back() << '\\n';\n    //std::cout << j_array_empty.back() << '\\n';   // undefined behavior\n    std::cout << j_string.back() << '\\n';\n\n    // back() called on a null value\n    try\n    {\n        json j_null;\n        j_null.back();\n    }\n    catch (const json::invalid_iterator& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n}\n

    Output:

    true\n17\n23.42\n2\n16\n\"Hello, world\"\n[json.exception.invalid_iterator.214] cannot get value\n
    "},{"location":"api/basic_json/back/#see-also","title":"See also","text":"
    • front - to access the first element
    • basic_json_view::back - the same access on a zero-copy view
    • Element Access - overview of all ways to access elements
    "},{"location":"api/basic_json/back/#version-history","title":"Version history","text":"
    • Added in version 1.0.0.
    • Binary values are supported since version 3.8.0.
    "},{"location":"api/basic_json/basic_json/","title":"nlohmann::basic_json::basic_json","text":"
    // (1)\nbasic_json(const value_t v);\n\n// (2)\nbasic_json(std::nullptr_t = nullptr) noexcept;\n\n// (3)\ntemplate<typename CompatibleType>\nbasic_json(CompatibleType&& val) noexcept(noexcept(\n           JSONSerializer<U>::to_json(std::declval<basic_json_t&>(),\n                                      std::forward<CompatibleType>(val))));\n\n// (4)\ntemplate<typename BasicJsonType>\nbasic_json(const BasicJsonType& val);\n\n// (5)\nbasic_json(initializer_list_t init,\n           bool type_deduction = true,\n           value_t manual_type = value_t::array);\n\n// (6)\nbasic_json(size_type cnt, const basic_json& val);\n\n// (7)\nbasic_json(iterator first, iterator last);\nbasic_json(const_iterator first, const_iterator last);\n\n// (8)\nbasic_json(const basic_json& other);\n\n// (9)\nbasic_json(basic_json&& other) noexcept;\n
    1. Create an empty JSON value with a given type. The value will be default initialized with an empty value which depends on the type:

      Value type initial value null null boolean false string \"\" number 0 object {} array [] binary empty array

      The postcondition of this constructor can be restored by calling clear().

    2. Create a null JSON value. It either takes a null pointer as parameter (explicitly creating null) or no parameter (implicitly creating null). The passed null pointer itself is not read \u2014 it is only used to choose the right constructor.

    3. This is a \"catch all\" constructor for all compatible JSON types; that is, types for which a to_json() method exists. The constructor forwards the parameter val to that method (to json_serializer<U>::to_json method with U = uncvref_t<CompatibleType>, to be exact).

      Template type CompatibleType includes, but is not limited to, the following types:

      • arrays: array_t and all kinds of compatible containers such as std::vector, std::deque, std::list, std::forward_list, std::array, std::valarray, std::set, std::unordered_set, std::multiset, and std::unordered_multiset with a value_type from which a basic_json value can be constructed.
      • objects: object_t and all kinds of compatible associative containers such as std::map, std::unordered_map, std::multimap, and std::unordered_multimap with a key_type compatible to string_t and a value_type from which a basic_json value can be constructed.
      • strings: string_t, string literals, and all compatible string containers can be used.

      Rvalue containers are moved from

      If val is an rvalue of a compatible array-like or object-like container other than array_t/object_t (e.g., json j = std::move(vec); or json j(std::vector<std::string>{...});), the elements are moved into the JSON value instead of copied. Afterwards, the elements of the source container are in a valid but unspecified state (moved-from). Keys of associative containers are const and therefore still copied. Lvalues and const rvalues are copied, and the source is left unchanged.

      • numbers: number_integer_t, number_unsigned_t, number_float_t, and all convertible number types such as int, size_t, int64_t, float or double can be used.
      • boolean: boolean_t / bool can be used.
      • binary: binary_t / std::vector<uint8_t> may be used; unfortunately because string literals cannot be distinguished from binary character arrays by the C++ type system, all types compatible with const char* will be directed to the string constructor instead. This is both for backwards compatibility and due to the fact that a binary type is not a standard JSON type.

      See the examples below.

    4. This is a constructor for existing basic_json types. It does not hijack copy/move constructors, since the parameter has different template arguments than the current ones.

      The constructor tries to convert the internal m_value of the parameter. Each member value (object, array, string, etc.) is serialized via the corresponding to_json() overload. For objects and strings, the conversion requires that the target basic_json type's object_t::key_type (or string_t) be directly constructible from the source type's corresponding member type via is_constructible. If this requirement is not met, the conversion does not fail to compile; instead, it silently falls back to the array-conversion path, which represents objects as arrays of [key, value] pairs and strings as arrays of character codes. This is a known limitation tracked in issue #3425.

    5. Creates a JSON value of type array or object from the passed initializer list init. In case type_deduction is true (default), the type of the JSON value to be created is deducted from the initializer list init according to the following rules:

      1. If the list is empty, an empty JSON object value {} is created.
      2. If the list consists of pairs whose first element is a string, a JSON object value is created where the first 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 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):

      flowchart TD\n    A([\"initializer_list init\"]) --> B{{\"empty, or every element is a 2-element<br/>array whose first element is a string?\"}}\n    B -->|\"yes\"| C{{\"type_deduction\"}}\n    B -->|\"no\"| D{{\"type_deduction\"}}\n    C -->|\"true\"| OBJ[\"create object\"]\n    C -->|\"false\"| E{{\"manual_type\"}}\n    E -->|\"object\"| OBJ\n    E -->|\"array\"| ARR[\"create array\"]\n    D -->|\"true\"| ARR\n    D -->|\"false\"| F{{\"manual_type\"}}\n    F -->|\"array\"| ARR\n    F -->|\"object\"| ERR[\"throw type_error.301\"]

      Decision flow for an initializer list: hexagons are checks, edge labels are their outcomes, and rectangles are the resulting value or exception.

      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 {} which is exactly an empty JSON object.
      2. C++ has no way of describing mapped types other than to list a list of pairs. As JSON requires that keys must be of type string, rule 2 is the weakest constraint one can pose on initializer lists to interpret them as an object.
      3. In all other cases, the initializer list could not be interpreted as a JSON object type, so interpreting it as a JSON array type is safe.

      With the rules described above, the following JSON values cannot be expressed by an initializer list:

      • the empty array ([]): use array(initializer_list_t) with an empty initializer list in this case
      • arrays whose elements satisfy rule 2: use array(initializer_list_t) with the same initializer list in this case

      Function array() and object() force array and object creation from initializer lists, respectively.

      Brace initialization yields arrays

      Because this constructor takes an initializer_list_t, brace-initializing a json/ordered_json from another json value wraps it in a single-element array rather than copying it:

      json j1 = \"hello\";\njson j2{j1};   // [!] j2 is [\"hello\"], NOT a copy of j1\njson j3(j1);   // j3 is \"hello\" -- parentheses copy as expected\n

      See the FAQ entry on brace initialization for the full explanation, an opt-in macro to change this behavior, and how to explicitly create a single-element array (json::array({value})) if that is what you want.

    6. Constructs a JSON array value by creating cnt copies of a passed value. In case cnt is 0, an empty array is created.

    7. Constructs the JSON value with the contents of the range [first, last). The semantics depend on the different types a JSON value can have:

      • In case of a null type, invalid_iterator.206 is thrown.
      • 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 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.
    8. Creates a copy of a given JSON value.

    9. Move constructor. Constructs a JSON value with the contents of the given value other using move semantics. It \"steals\" the resources from other and leaves it as JSON null value.

    "},{"location":"api/basic_json/basic_json/#template-parameters","title":"Template parameters","text":"CompatibleType

    a type such that:

    • CompatibleType is not derived from std::istream,
    • CompatibleType is not basic_json (to avoid hijacking copy/move constructors),
    • CompatibleType is not a different basic_json type (i.e. with different template arguments)
    • CompatibleType is not a basic_json nested type (e.g., json_pointer, iterator, etc.)
    • if JSON_DISABLE_TUPLE_REFERENCE_CONVERSION is defined to 1: CompatibleType is not a one-element std::tuple holding a reference to basic_json
    • json_serializer<U> (with U = uncvref_t<CompatibleType>) has a to_json(basic_json_t&, CompatibleType&&) method
    BasicJsonType:

    a type such that:

    • BasicJsonType is a basic_json type.
    • 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 this requirement is not met.

    U: uncvref_t<CompatibleType>"},{"location":"api/basic_json/basic_json/#parameters","title":"Parameters","text":"v (in) the type of the value to create val (in) the value to be forwarded to the respective constructor init (in) initializer list with JSON values type_deduction (in) internal parameter; when set to true, the type of the JSON value is deducted from the initializer list init; when set to false, the type provided via manual_type is forced. This mode is used by the functions array(initializer_list_t) and object(initializer_list_t). manual_type (in) internal parameter; when type_deduction is set to false, the created JSON value will use the provided type (only value_t::array and value_t::object are valid); when type_deduction is set to true, this parameter has no effect cnt (in) the number of JSON copies of val to create first (in) the beginning of the range to copy from (included) last (in) the end of the range to copy from (excluded) other (in) the JSON value to copy/move"},{"location":"api/basic_json/basic_json/#exception-safety","title":"Exception safety","text":"
    1. Strong guarantee: if an exception is thrown, there are no changes to any JSON value.
    2. No-throw guarantee: this constructor never throws exceptions.
    3. Depends on the called constructor. For types directly supported by the library (i.e., all types for which no to_json() function was provided), a strong guarantee holds: if an exception is thrown, there are no changes to any JSON value. Exception: when val is an rvalue array-like or object-like container, its elements are moved one by one; if an exception is thrown in the middle of the conversion (e.g., an allocation failure), the JSON value is unchanged, but the source container may be left partially moved-from.
    4. Depends on the called constructor. For types directly supported by the library (i.e., all types for which no to_json() function was provided), a strong guarantee holds: if an exception is thrown, there are no changes to any JSON value.
    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.
    8. Strong guarantee: if an exception is thrown, there are no changes to any JSON value.
    9. No-throw guarantee: this constructor never throws exceptions.
    "},{"location":"api/basic_json/basic_json/#exceptions","title":"Exceptions","text":"
    1. (none)
    2. The function does not throw exceptions.
    3. (none)
    4. (none)
    5. The function can throw the following exceptions:
      • Throws type_error.301 if type_deduction is false, manual_type is value_t::object, but init contains an element which is not a pair whose first element is a string. In this case, the constructor could not create an object. If type_deduction would have been true, an array would have been created. See object(initializer_list_t) for an example.
    6. (none)
    7. The function can throw the following exceptions:
      • Throws invalid_iterator.201 if iterators first 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 if iterators first 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 if iterators first and last belong to a null value. In this case, the range [first, last) is undefined.
    8. (none)
    9. The function does not throw exceptions.
    "},{"location":"api/basic_json/basic_json/#complexity","title":"Complexity","text":"
    1. Constant.
    2. Constant.
    3. Usually linear in the size of the passed val, also depending on the implementation of the called to_json() method.
    4. Usually linear in the size of the passed val, also depending on the implementation of the called to_json() method.
    5. Linear in the size of the initializer list init.
    6. Linear in cnt.
    7. Linear in distance between first and last.
    8. Linear in the size of other.
    9. Constant.
    "},{"location":"api/basic_json/basic_json/#notes","title":"Notes","text":"
    • Overload 5:

      Empty initializer list

      When used without parentheses around an empty initializer list, basic_json() is called instead of this function, yielding the JSON null value.

    • Overload 4:

      Implicit conversion

      The conversion is implicit unless JSON_USE_IMPLICIT_CONVERSIONS is defined to 0 and BasicJsonType::string_t differs from string_t. In that case, the constructor is explicit, so a JSON value with a different string type is no longer silently converted, for example when it is passed to a function taking const json&. Write json(other) or other.get<json>() instead.

    • Overload 7:

      Preconditions

      • Iterators first and last must be initialized. **This precondition is enforced with a runtime assertion.
      • Range [first, last) is valid. Usually, this precondition cannot be checked efficiently. Only certain edge cases are detected; see the description of the exceptions above. A violation of this precondition yields undefined behavior.

      Runtime assertion

      A precondition is enforced with a runtime assertion.

    • Overload 8:

      Postcondition

      *this == other

    • Overload 9:

      Postconditions

      • *thishas the same value asother` before the call.
      • other is a JSON null value
    "},{"location":"api/basic_json/basic_json/#examples","title":"Examples","text":"Example: (1) create an empty value with a given type

    The following code shows the constructor for different value_t values.

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create the different JSON values with default values\n    json j_null(json::value_t::null);\n    json j_boolean(json::value_t::boolean);\n    json j_number_integer(json::value_t::number_integer);\n    json j_number_float(json::value_t::number_float);\n    json j_object(json::value_t::object);\n    json j_array(json::value_t::array);\n    json j_string(json::value_t::string);\n\n    // serialize the JSON values\n    std::cout << j_null << '\\n';\n    std::cout << j_boolean << '\\n';\n    std::cout << j_number_integer << '\\n';\n    std::cout << j_number_float << '\\n';\n    std::cout << j_object << '\\n';\n    std::cout << j_array << '\\n';\n    std::cout << j_string << '\\n';\n}\n

    Output:

    null\nfalse\n0\n0.0\n{}\n[]\n\"\"\n
    Example: (2) create a null object

    The following code shows the constructor with and without a null pointer parameter.

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // implicitly create a JSON null value\n    json j1;\n\n    // explicitly create a JSON null value\n    json j2(nullptr);\n\n    // serialize the JSON null value\n    std::cout << j1 << '\\n' << j2 << '\\n';\n}\n

    Output:

    null\nnull\n
    Example: (3) create a JSON value from compatible types

    The following code shows the constructor with several compatible types.

    #include <iostream>\n#include <deque>\n#include <list>\n#include <forward_list>\n#include <set>\n#include <unordered_map>\n#include <unordered_set>\n#include <valarray>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // ============\n    // object types\n    // ============\n\n    // create an object from an object_t value\n    json::object_t object_value = { {\"one\", 1}, {\"two\", 2} };\n    json j_object_t(object_value);\n\n    // create an object from std::map\n    std::map<std::string, int> c_map\n    {\n        {\"one\", 1}, {\"two\", 2}, {\"three\", 3}\n    };\n    json j_map(c_map);\n\n    // create an object from std::unordered_map\n    std::unordered_map<const char*, double> c_umap\n    {\n        {\"one\", 1.2}, {\"two\", 2.3}, {\"three\", 3.4}\n    };\n    json j_umap(c_umap);\n\n    // create an object from std::multimap\n    std::multimap<std::string, bool> c_mmap\n    {\n        {\"one\", true}, {\"two\", true}, {\"three\", false}, {\"three\", true}\n    };\n    json j_mmap(c_mmap); // only one entry for key \"three\" is used\n\n    // create an object from std::unordered_multimap\n    std::unordered_multimap<std::string, bool> c_ummap\n    {\n        {\"one\", true}, {\"two\", true}, {\"three\", false}, {\"three\", false}\n    };\n    json j_ummap(c_ummap); // only one entry for key \"three\" is used\n\n    // serialize the JSON objects\n    std::cout << j_object_t << '\\n';\n    std::cout << j_map << '\\n';\n    std::cout << j_umap << '\\n';\n    std::cout << j_mmap << '\\n';\n    std::cout << j_ummap << \"\\n\\n\";\n\n    // ===========\n    // array types\n    // ===========\n\n    // create an array from an array_t value\n    json::array_t array_value = {\"one\", \"two\", 3, 4.5, false};\n    json j_array_t(array_value);\n\n    // create an array from std::vector\n    std::vector<int> c_vector {1, 2, 3, 4};\n    json j_vec(c_vector);\n\n    // create an array from std::valarray\n    std::valarray<short> c_valarray {10, 9, 8, 7};\n    json j_valarray(c_valarray);\n\n    // create an array from std::deque\n    std::deque<double> c_deque {1.2, 2.3, 3.4, 5.6};\n    json j_deque(c_deque);\n\n    // create an array from std::list\n    std::list<bool> c_list {true, true, false, true};\n    json j_list(c_list);\n\n    // create an array from std::forward_list\n    std::forward_list<std::int64_t> c_flist {12345678909876, 23456789098765, 34567890987654, 45678909876543};\n    json j_flist(c_flist);\n\n    // create an array from std::array\n    std::array<unsigned long, 4> c_array {{1, 2, 3, 4}};\n    json j_array(c_array);\n\n    // create an array from std::set\n    std::set<std::string> c_set {\"one\", \"two\", \"three\", \"four\", \"one\"};\n    json j_set(c_set); // only one entry for \"one\" is used\n\n    // create an array from std::unordered_set\n    std::unordered_set<std::string> c_uset {\"one\", \"one\"};\n    json j_uset(c_uset); // only one entry for \"one\" is used\n\n    // create an array from std::multiset\n    std::multiset<std::string> c_mset {\"one\", \"two\", \"one\", \"four\"};\n    json j_mset(c_mset); // both entries for \"one\" are used\n\n    // create an array from std::unordered_multiset\n    std::unordered_multiset<std::string> c_umset {\"one\", \"one\"};\n    json j_umset(c_umset); // both entries for \"one\" are used\n\n    // serialize the JSON arrays\n    std::cout << j_array_t << '\\n';\n    std::cout << j_vec << '\\n';\n    std::cout << j_valarray << '\\n';\n    std::cout << j_deque << '\\n';\n    std::cout << j_list << '\\n';\n    std::cout << j_flist << '\\n';\n    std::cout << j_array << '\\n';\n    std::cout << j_set << '\\n';\n    std::cout << j_uset << '\\n';\n    std::cout << j_mset << '\\n';\n    std::cout << j_umset << \"\\n\\n\";\n\n    // ============\n    // string types\n    // ============\n\n    // create string from a string_t value\n    json::string_t string_value = \"The quick brown fox jumps over the lazy dog.\";\n    json j_string_t(string_value);\n\n    // create a JSON string directly from a string literal\n    json j_string_literal(\"The quick brown fox jumps over the lazy dog.\");\n\n    // create string from std::string\n    std::string s_stdstring = \"The quick brown fox jumps over the lazy dog.\";\n    json j_stdstring(s_stdstring);\n\n    // serialize the JSON strings\n    std::cout << j_string_t << '\\n';\n    std::cout << j_string_literal << '\\n';\n    std::cout << j_stdstring << \"\\n\\n\";\n\n    // ============\n    // number types\n    // ============\n\n    // create a JSON number from number_integer_t\n    json::number_integer_t value_integer_t = -42;\n    json j_integer_t(value_integer_t);\n\n    // create a JSON number from number_unsigned_t\n    json::number_integer_t value_unsigned_t = 17;\n    json j_unsigned_t(value_unsigned_t);\n\n    // create a JSON number from an anonymous enum\n    enum { enum_value = 17 };\n    json j_enum(enum_value);\n\n    // create values of different integer types\n    short n_short = 42;\n    int n_int = -23;\n    long n_long = 1024;\n    int_least32_t n_int_least32_t = -17;\n    uint8_t n_uint8_t = 8;\n\n    // create (integer) JSON numbers\n    json j_short(n_short);\n    json j_int(n_int);\n    json j_long(n_long);\n    json j_int_least32_t(n_int_least32_t);\n    json j_uint8_t(n_uint8_t);\n\n    // create values of different floating-point types\n    json::number_float_t v_ok = 3.141592653589793;\n    json::number_float_t v_nan = NAN;\n    json::number_float_t v_infinity = INFINITY;\n\n    // create values of different floating-point types\n    float n_float = 42.23;\n    float n_float_nan = 1.0f / 0.0f;\n    double n_double = 23.42;\n\n    // create (floating point) JSON numbers\n    json j_ok(v_ok);\n    json j_nan(v_nan);\n    json j_infinity(v_infinity);\n    json j_float(n_float);\n    json j_float_nan(n_float_nan);\n    json j_double(n_double);\n\n    // serialize the JSON numbers\n    std::cout << j_integer_t << '\\n';\n    std::cout << j_unsigned_t << '\\n';\n    std::cout << j_enum << '\\n';\n    std::cout << j_short << '\\n';\n    std::cout << j_int << '\\n';\n    std::cout << j_long << '\\n';\n    std::cout << j_int_least32_t << '\\n';\n    std::cout << j_uint8_t << '\\n';\n    std::cout << j_ok << '\\n';\n    std::cout << j_nan << '\\n';\n    std::cout << j_infinity << '\\n';\n    std::cout << j_float << '\\n';\n    std::cout << j_float_nan << '\\n';\n    std::cout << j_double << \"\\n\\n\";\n\n    // =============\n    // boolean types\n    // =============\n\n    // create boolean values\n    json j_truth = true;\n    json j_falsity = false;\n\n    // serialize the JSON booleans\n    std::cout << j_truth << '\\n';\n    std::cout << j_falsity << '\\n';\n}\n

    Output:

    {\"one\":1,\"two\":2}\n{\"one\":1,\"three\":3,\"two\":2}\n{\"one\":1.2,\"three\":3.4,\"two\":2.3}\n{\"one\":true,\"three\":false,\"two\":true}\n{\"one\":true,\"three\":false,\"two\":true}\n\n[\"one\",\"two\",3,4.5,false]\n[1,2,3,4]\n[10,9,8,7]\n[1.2,2.3,3.4,5.6]\n[true,true,false,true]\n[12345678909876,23456789098765,34567890987654,45678909876543]\n[1,2,3,4]\n[\"four\",\"one\",\"three\",\"two\"]\n[\"one\"]\n[\"four\",\"one\",\"one\",\"two\"]\n[\"one\",\"one\"]\n\n\"The quick brown fox jumps over the lazy dog.\"\n\"The quick brown fox jumps over the lazy dog.\"\n\"The quick brown fox jumps over the lazy dog.\"\n\n-42\n17\n17\n42\n-23\n1024\n-17\n8\n3.141592653589793\nnull\nnull\n42.22999954223633\nnull\n23.42\n\ntrue\nfalse\n

    Note the output is platform-dependent.

    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.

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\nusing nlohmann::ordered_json;\n\nint main()\n{\n    // create an ordered_json value; insertion order is preserved\n    ordered_json oj = {{\"c\", 3}, {\"a\", 1}, {\"b\", 2}};\n\n    // convert to json -- overload (4) is used; keys end up sorted\n    json j(oj);\n\n    // convert back to ordered_json -- the original insertion order is lost,\n    // because it was already given up when converting to json\n    ordered_json oj2(j);\n\n    std::cout << oj << '\\n';\n    std::cout << j << '\\n';\n    std::cout << oj2 << '\\n';\n}\n

    Output:

    {\"c\":3,\"a\":1,\"b\":2}\n{\"a\":1,\"b\":2,\"c\":3}\n{\"a\":1,\"b\":2,\"c\":3}\n
    Example: (5) create a container (array or object) from an initializer list

    The example below shows how JSON values are created from initializer lists.

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create JSON values\n    json j_empty_init_list = json({});\n    json j_object = { {\"one\", 1}, {\"two\", 2} };\n    json j_array = {1, 2, 3, 4};\n    json j_nested_object = { {\"one\", {1}}, {\"two\", {1, 2}} };\n    json j_nested_array = { {{1}, \"one\"}, {{1, 2}, \"two\"} };\n\n    // serialize the JSON value\n    std::cout << j_empty_init_list << '\\n';\n    std::cout << j_object << '\\n';\n    std::cout << j_array << '\\n';\n    std::cout << j_nested_object << '\\n';\n    std::cout << j_nested_array << '\\n';\n}\n

    Output:

    {}\n{\"one\":1,\"two\":2}\n[1,2,3,4]\n{\"one\":[1],\"two\":[1,2]}\n[[[1],\"one\"],[[1,2],\"two\"]]\n
    Example: (6) construct an array with count copies of a given value

    The following code shows examples for creating arrays with several copies of a given value.

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create an array by creating copies of a JSON value\n    json value = \"Hello\";\n    json array_0 = json(0, value);\n    json array_1 = json(1, value);\n    json array_5 = json(5, value);\n\n    // serialize the JSON arrays\n    std::cout << array_0 << '\\n';\n    std::cout << array_1 << '\\n';\n    std::cout << array_5 << '\\n';\n}\n

    Output:

    []\n[\"Hello\"]\n[\"Hello\",\"Hello\",\"Hello\",\"Hello\",\"Hello\"]\n
    Example: (7) construct a JSON container given an iterator range

    The example below shows several ways to create JSON values by specifying a subrange with iterators.

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create JSON values\n    json j_array = {\"alpha\", \"bravo\", \"charly\", \"delta\", \"easy\"};\n    json j_number = 42;\n    json j_object = {{\"one\", \"eins\"}, {\"two\", \"zwei\"}};\n\n    // create copies using iterators\n    json j_array_range(j_array.begin() + 1, j_array.end() - 2);\n    json j_number_range(j_number.begin(), j_number.end());\n    json j_object_range(j_object.begin(), j_object.find(\"two\"));\n\n    // serialize the values\n    std::cout << j_array_range << '\\n';\n    std::cout << j_number_range << '\\n';\n    std::cout << j_object_range << '\\n';\n\n    // example for an exception\n    try\n    {\n        json j_invalid(j_number.begin() + 1, j_number.end());\n    }\n    catch (const json::invalid_iterator& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n}\n

    Output:

    [\"bravo\",\"charly\"]\n42\n{\"one\":\"eins\"}\n[json.exception.invalid_iterator.204] iterators out of range\n
    Example: (8) copy constructor

    The following code shows an example for the copy constructor.

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create a JSON array\n    json j1 = {\"one\", \"two\", 3, 4.5, false};\n\n    // create a copy\n    json j2(j1);\n\n    // serialize the JSON array\n    std::cout << j1 << \" = \" << j2 << '\\n';\n    std::cout << std::boolalpha << (j1 == j2) << '\\n';\n}\n

    Output:

    [\"one\",\"two\",3,4.5,false] = [\"one\",\"two\",3,4.5,false]\ntrue\n
    Example: (9) move constructor

    The code below shows the move constructor explicitly called via std::move.

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create a JSON value\n    json a = 23;\n\n    // move contents of a to b\n    json b(std::move(a));\n\n    // serialize the JSON arrays\n    std::cout << a << '\\n';\n    std::cout << b << '\\n';\n}\n

    Output:

    null\n23\n
    "},{"location":"api/basic_json/basic_json/#see-also","title":"See also","text":"
    • array - create a JSON array value, forcing array creation from an initializer list even when it looks like an object
    • object - create a JSON object value, forcing object creation from an initializer list
    • binary - create a JSON binary array value
    • operator= - copy assignment operator
    • Creating JSON values - the article on creating JSON values
    • Converting values - which C++ types can be converted
    "},{"location":"api/basic_json/basic_json/#version-history","title":"Version history","text":"
    1. Added in version 1.0.0.
    2. Added in version 1.0.0.
    3. Added in version 2.1.0.
    4. Added in version 3.1.2. Explicit for different string types if JSON_USE_IMPLICIT_CONVERSIONS is 0 since version 3.13.0 unreleased.
    5. Added in version 1.0.0.
    6. Added in version 1.0.0.
    7. Added in version 1.0.0. Fixed in version 3.13.0 unreleased 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. Added in version 1.0.0.
    9. Added in version 1.0.0.
    "},{"location":"api/basic_json/begin/","title":"nlohmann::basic_json::begin","text":"
    iterator begin() noexcept;\nconst_iterator begin() const noexcept;\n

    Returns an iterator to the first element.

    A row of fifteen elements followed by a dashed past-the-last position. begin() points to the first element and end() points to the past-the-last position. begin end Past-the-last element

    begin() points to the first element and end() to the position after the last element; the dashed cell is the past-the-last position, which must not be dereferenced.

    "},{"location":"api/basic_json/begin/#return-value","title":"Return value","text":"

    iterator to the first element

    "},{"location":"api/basic_json/begin/#exception-safety","title":"Exception safety","text":"

    No-throw guarantee: this member function never throws exceptions.

    "},{"location":"api/basic_json/begin/#complexity","title":"Complexity","text":"

    Constant.

    "},{"location":"api/basic_json/begin/#examples","title":"Examples","text":"Example

    The following code shows an example for begin().

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create an array value\n    json array = {1, 2, 3, 4, 5};\n\n    // get an iterator to the first element\n    json::iterator it = array.begin();\n\n    // serialize the element that the iterator points to\n    std::cout << *it << '\\n';\n}\n

    Output:

    1\n
    "},{"location":"api/basic_json/begin/#see-also","title":"See also","text":"
    • end - returns an iterator to one past the last element
    • cbegin - returns a const iterator to the first element
    • rbegin - returns a reverse iterator to the last element
    • items - returns an iteration proxy to access keys and values during range-based for loops
    • Iterators - the article on iterators
    • basic_json_view::begin - the same iteration on a zero-copy view (in document order, not sorted by key)
    "},{"location":"api/basic_json/begin/#version-history","title":"Version history","text":"
    • Added in version 1.0.0.
    "},{"location":"api/basic_json/binary/","title":"nlohmann::basic_json::binary","text":"
    // (1)\nstatic basic_json binary(const typename binary_t::container_type& init);\nstatic basic_json binary(typename binary_t::container_type&& init);\n\n// (2)\nstatic basic_json binary(const typename binary_t::container_type& init,\n                         typename binary_t::subtype_type subtype);\nstatic basic_json binary(typename binary_t::container_type&& init,\n                         typename binary_t::subtype_type subtype);\n
    1. Creates a JSON binary array value from a given binary container.
    2. Creates a JSON binary array value from a given binary container with subtype.

    Binary values are part of various binary formats, such as CBOR, MessagePack, and BSON. This constructor is used to create a value for serialization to those formats.

    "},{"location":"api/basic_json/binary/#parameters","title":"Parameters","text":"init (in) container containing bytes to use as a binary type subtype (in) subtype to use in CBOR, MessagePack, and BSON"},{"location":"api/basic_json/binary/#return-value","title":"Return value","text":"

    JSON binary array value

    "},{"location":"api/basic_json/binary/#exception-safety","title":"Exception safety","text":"

    Strong guarantee: if an exception is thrown, there are no changes in the JSON value.

    "},{"location":"api/basic_json/binary/#complexity","title":"Complexity","text":"

    Linear in the size of init; constant for typename binary_t::container_type&& init versions.

    "},{"location":"api/basic_json/binary/#notes","title":"Notes","text":"

    Note, this function exists because of the difficulty in correctly specifying the correct template overload in the standard value ctor, as both JSON arrays and JSON binary arrays are backed with some form of a std::vector. Because JSON binary arrays are a non-standard extension, it was decided that it would be best to prevent automatic initialization of a binary array type, for backwards compatibility and so it does not happen on accident.

    "},{"location":"api/basic_json/binary/#examples","title":"Examples","text":"Example

    The following code shows how to create a binary value.

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create a binary vector\n    std::vector<std::uint8_t> vec = {0xCA, 0xFE, 0xBA, 0xBE};\n\n    // create a binary JSON value with subtype 42\n    json j = json::binary(vec, 42);\n\n    // output type and subtype\n    std::cout << \"type: \" << j.type_name() << \", subtype: \" << j.get_binary().subtype() << '\\n';\n}\n

    Output:

    type: binary, subtype: 42\n
    "},{"location":"api/basic_json/binary/#see-also","title":"See also","text":"
    • Binary formats - formats that can store binary values
    • binary_t - type for binary values
    • get_binary - get a reference to the stored binary value
    • is_binary - return whether the value is binary
    • byte_container_with_subtype - container for binary values with subtype
    • Binary Values - the article on binary values
    "},{"location":"api/basic_json/binary/#version-history","title":"Version history","text":"
    • 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.
    "},{"location":"api/basic_json/binary_t/","title":"nlohmann::basic_json::binary_t","text":"
    using binary_t = byte_container_with_subtype<BinaryType>;\n

    This type is a type designed to carry binary data that appears in various serialized formats, such as CBOR's Major Type 2, MessagePack's bin, and BSON's generic binary subtype. This type is NOT a part of standard JSON and exists solely for compatibility with these binary types. As such, it is simply defined as an ordered sequence of zero or more byte values.

    Additionally, as an implementation detail, the subtype of the binary data is carried around as a std::uint64_t, which is compatible with both of the binary data formats that use binary subtyping, (though the specific numbering is incompatible with each other, and it is up to the user to translate between them). The subtype is added to BinaryType via the helper type byte_container_with_subtype.

    CBOR's RFC 8949 describes this type as:

    Major type 2: A byte string. The number of bytes in the string is equal to the argument.

    MessagePack's documentation on the bin type family describes this type as:

    Bin format family stores a byte array in 2, 3, or 5 bytes of extra bytes in addition to the size of the byte array.

    BSON's specifications describe several binary types; however, this type is intended to represent the generic binary type which has the description:

    Generic binary subtype - This is the most commonly used binary subtype and should be the 'default' for drivers and tools.

    None of these impose any limitations on the internal representation other than the basic unit of storage be some type of array whose parts are decomposable into bytes.

    The default representation of this binary format is a std::vector<std::uint8_t>, which is a very common way to represent a byte array in modern C++.

    "},{"location":"api/basic_json/binary_t/#template-parameters","title":"Template parameters","text":"BinaryType

    container type to store arrays

    Although not formally expressed as a C++ concept, BinaryType must be default-constructible, copy/move-constructible, and support push_back(), .data(), and .size(), because byte_container_with_subtype derives directly from it. Its value_type must additionally be exactly one byte wide (e.g., std::uint8_t/char/std::byte): the binary serializers (CBOR, MessagePack, BSON, UBJSON) read and write the container's raw bytes via reinterpret_cast, which is only correct for byte-sized elements \u2014 a container like std::vector<std::intptr_t> will not work as BinaryType. The elements must be stored contiguously, and the binary readers additionally require resize() and operator[]. See Template Parameter Requirements for the full list.

    "},{"location":"api/basic_json/binary_t/#notes","title":"Notes","text":""},{"location":"api/basic_json/binary_t/#default-type","title":"Default type","text":"

    The default values for BinaryType is std::vector<std::uint8_t>.

    "},{"location":"api/basic_json/binary_t/#supported-byte-types","title":"Supported byte types","text":"

    std::vector<std::uint8_t>, std::vector<char>, and std::vector<std::byte> are supported. Regardless of which of them is configured, dump writes the bytes as the numbers 0..255.

    "},{"location":"api/basic_json/binary_t/#custom-binarytype-behavior","title":"Custom BinaryType behavior","text":"

    When a custom BinaryType is configured (other than the default 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 rather than arrays:

    using custom_json = nlohmann::ordered_json::with_binary_t<std::vector<std::byte>>;\n\nstd::vector<std::byte> data{std::byte{1}, std::byte{2}, std::byte{3}};\ncustom_json j = data;  // Creates a binary value, not an array\nassert(j.is_binary());\n\n// Round-tripping works seamlessly\nauto extracted = j.get<std::vector<std::byte>>();\nassert(extracted == data);\n

    This automatic type detection is a convenience feature that only applies to custom (non-default) BinaryType configurations. The default nlohmann::json continues to treat std::vector<std::uint8_t> as arrays for backward compatibility.

    "},{"location":"api/basic_json/binary_t/#storage","title":"Storage","text":"

    Binary Arrays are stored as pointers in a basic_json type. That is, for any access to array values, a pointer of the type binary_t* must be dereferenced.

    "},{"location":"api/basic_json/binary_t/#notes-on-subtypes","title":"Notes on subtypes","text":"
    • CBOR

      • Binary values are represented as byte strings. Subtypes are written as tags.
    • MessagePack

      • If a subtype is given and the binary array contains exactly 1, 2, 4, 8, or 16 elements, the fixext family (fixext1, fixext2, fixext4, fixext8, fixext16) is used. For other sizes, the ext family (ext8, ext16, ext32) is used. The subtype is then written as the signed 8-bit ext type: subtypes 128 to 255 map to the negative (reserved) ext types, and on reading the ext type is exposed as an unsigned subtype from 0 to 255.
      • If no subtype is given, the bin family (bin8, bin16, bin32) is used.
    • BSON

      • If a subtype is given, it is used and added as an unsigned 8-bit integer.
      • If no subtype is given, the generic binary subtype 0x00 is used.
    "},{"location":"api/basic_json/binary_t/#examples","title":"Examples","text":"Example

    The following code shows that binary_t is by default, a typedef to nlohmann::byte_container_with_subtype<std::vector<std::uint8_t>>.

    #include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    std::cout << std::boolalpha << std::is_same<nlohmann::byte_container_with_subtype<std::vector<std::uint8_t>>, json::binary_t>::value << '\\n';\n}\n

    Output:

    true\n
    "},{"location":"api/basic_json/binary_t/#see-also","title":"See also","text":"
    • Binary values - how binary values and subtypes are handled
    • Binary formats - formats that can store binary values
    • byte_container_with_subtype - container type used by binary values
    "},{"location":"api/basic_json/binary_t/#version-history","title":"Version history","text":"
    • Added in version 3.8.0. Changed the type of subtype to std::uint64_t in version 3.10.0.
    • Fixed dump, std::hash, and to_ubjson for byte types that are not integers (e.g., std::byte) in version 3.13.0 unreleased. dump now writes the bytes of a signed byte type (e.g., char) as 0..255 rather than as negative numbers.
    "},{"location":"api/basic_json/bjdata_version_t/","title":"nlohmann::basic_json::bjdata_version_t","text":"
    enum class bjdata_version_t\n{\n    draft2,\n    draft3\n};\n

    This enumeration is used in to_bjdata to choose the version of the BJData specification to write:

    draft2 BJData Draft 2 (the default). Binary values are written as arrays of U integers, and ND-arrays with \"_ArrayType_\": \"byte\" are written as regular objects, since the B marker is not part of Draft 2. draft3 BJData Draft 3. Binary values are written as B elements: as an optimized binary array ([$B#) if both use_size and use_type are set, and as an array of B-prefixed elements otherwise. ND-arrays with \"_ArrayType_\": \"byte\" are written as packed arrays ([$B#[...]).

    Only the writer is affected by the version. from_bjdata reads the markers of both drafts.

    "},{"location":"api/basic_json/bjdata_version_t/#examples","title":"Examples","text":"Example

    The example below shows how the different values of the bjdata_version_t influence the serialization of a binary value with to_bjdata.

    #include <iomanip>\n#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nvoid print_hex(const char* label, const std::vector<std::uint8_t>& v)\n{\n    std::cout << label << ':';\n    for (auto b : v)\n    {\n        std::cout << ' ' << std::hex << std::setw(2) << std::setfill('0') << static_cast<int>(b);\n    }\n    std::cout << std::dec << std::setfill(' ') << '\\n';\n}\n\nint main()\n{\n    // a binary value\n    json j = json::binary({0xCA, 0xFE, 0xBA, 0xBE});\n\n    // Draft 2 (the default) writes an array of integers\n    auto v2 = json::to_bjdata(j, true, true, json::bjdata_version_t::draft2);\n    print_hex(\"draft2\", v2);\n\n    // Draft 3 writes an optimized binary array\n    auto v3 = json::to_bjdata(j, true, true, json::bjdata_version_t::draft3);\n    print_hex(\"draft3\", v3);\n\n    // reading yields an array for Draft 2 and a binary value for Draft 3\n    std::cout << json::from_bjdata(v2) << '\\n';\n    std::cout << json::from_bjdata(v3) << '\\n';\n}\n

    Output:

    draft2: 5b 24 55 23 69 04 ca fe ba be\ndraft3: 5b 24 42 23 69 04 ca fe ba be\n[202,254,186,190]\n{\"bytes\":[202,254,186,190],\"subtype\":null}\n
    "},{"location":"api/basic_json/bjdata_version_t/#see-also","title":"See also","text":"
    • to_bjdata serializes a JSON value to BJData
    • BJData - the article on the BJData format
    "},{"location":"api/basic_json/bjdata_version_t/#version-history","title":"Version history","text":"
    • Added in version 3.12.0.
    "},{"location":"api/basic_json/boolean_t/","title":"nlohmann::basic_json::boolean_t","text":"
    using boolean_t = BooleanType;\n

    The type used to store JSON booleans.

    RFC 8259 implicitly describes a boolean as a type which differentiates the two literals true and false.

    To store boolean values in C++, a type is defined by the template parameter BooleanType which chooses the type to use.

    "},{"location":"api/basic_json/boolean_t/#template-parameters","title":"Template parameters","text":"BooleanType the type to store booleans. As it is stored directly inside a basic_json value (in a union), it must be a trivially default-constructible, trivially copyable, and trivially destructible type that is convertible to and from bool. See Template Parameter Requirements."},{"location":"api/basic_json/boolean_t/#notes","title":"Notes","text":""},{"location":"api/basic_json/boolean_t/#default-type","title":"Default type","text":"

    With the default values for BooleanType (bool), the default type for boolean_t is bool.

    "},{"location":"api/basic_json/boolean_t/#storage","title":"Storage","text":"

    Boolean values are stored directly inside a basic_json type.

    "},{"location":"api/basic_json/boolean_t/#examples","title":"Examples","text":"Example

    The following code shows that boolean_t is by default, a typedef to bool.

    #include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    std::cout << std::boolalpha << std::is_same<bool, json::boolean_t>::value << '\\n';\n}\n

    Output:

    true\n
    "},{"location":"api/basic_json/boolean_t/#see-also","title":"See also","text":"
    • is_boolean - checks whether the JSON value is a boolean
    • Types - how booleans are stored
    • Template Parameter Requirements - requirements on the BooleanType template parameter
    "},{"location":"api/basic_json/boolean_t/#version-history","title":"Version history","text":"
    • Added in version 1.0.0.
    "},{"location":"api/basic_json/cbegin/","title":"nlohmann::basic_json::cbegin","text":"
    const_iterator cbegin() const noexcept;\n

    Returns an iterator to the first element.

    A row of fifteen elements followed by a dashed past-the-last position. begin() points to the first element and end() points to the past-the-last position. begin end Past-the-last element

    cbegin() points to the first element, like begin(), and end() to the position after the last element; the dashed cell is the past-the-last position, which must not be dereferenced.

    "},{"location":"api/basic_json/cbegin/#return-value","title":"Return value","text":"

    iterator to the first element

    "},{"location":"api/basic_json/cbegin/#exception-safety","title":"Exception safety","text":"

    No-throw guarantee: this member function never throws exceptions.

    "},{"location":"api/basic_json/cbegin/#complexity","title":"Complexity","text":"

    Constant.

    "},{"location":"api/basic_json/cbegin/#examples","title":"Examples","text":"Example

    The following code shows an example for cbegin().

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create an array value\n    const json array = {1, 2, 3, 4, 5};\n\n    // get an iterator to the first element\n    json::const_iterator it = array.cbegin();\n\n    // serialize the element that the iterator points to\n    std::cout << *it << '\\n';\n}\n

    Output:

    1\n
    "},{"location":"api/basic_json/cbegin/#see-also","title":"See also","text":"
    • begin - returns an iterator to the first element
    • cend - returns a const iterator to one past the last element
    • crbegin - returns a const reverse iterator to the last element
    • Iterators - the article on iterators
    • basic_json_view::cbegin - the same iteration on a zero-copy view
    "},{"location":"api/basic_json/cbegin/#version-history","title":"Version history","text":"
    • Added in version 1.0.0.
    "},{"location":"api/basic_json/cbor_tag_handler_t/","title":"nlohmann::basic_json::cbor_tag_handler_t","text":"
    enum class cbor_tag_handler_t\n{\n    error,\n    ignore,\n    store\n};\n

    This enumeration is used in from_cbor and sax_parse to choose how to treat tags:

    error report a parse error in case of a tag (the from_cbor overloads throw a parse_error exception by default) ignore ignore tags (also in front of a text string map key) store store tagged byte strings (for bytes 0xd8..0xdb) as binary values with the tag as subtype; other tagged values are read as if the tag were ignored. If several tags precede a byte string, only the tag directly in front of it is stored, and only when it has the form 0xd8..0xdb (a tag 0..23 written as 0xc0..0xd7 is skipped). Tags in front of a text string map key are skipped."},{"location":"api/basic_json/cbor_tag_handler_t/#examples","title":"Examples","text":"Example

    The example below shows how the different values of the cbor_tag_handler_t influence the behavior of from_cbor when reading a tagged byte string.

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // tagged byte string\n    std::vector<std::uint8_t> vec = {{0xd8, 0x42, 0x44, 0xcA, 0xfe, 0xba, 0xbe}};\n\n    // cbor_tag_handler_t::error throws\n    try\n    {\n        auto b_throw_on_tag = json::from_cbor(vec, true, true, json::cbor_tag_handler_t::error);\n    }\n    catch (const json::parse_error& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n\n    // cbor_tag_handler_t::ignore ignores the tag\n    auto b_ignore_tag = json::from_cbor(vec, true, true, json::cbor_tag_handler_t::ignore);\n    std::cout << b_ignore_tag << '\\n';\n\n    // cbor_tag_handler_t::store stores the tag as binary subtype\n    auto b_store_tag = json::from_cbor(vec, true, true, json::cbor_tag_handler_t::store);\n    std::cout << b_store_tag << '\\n';\n}\n

    Output:

    [json.exception.parse_error.112] parse error at byte 1: syntax error while parsing CBOR value: invalid byte: 0xD8\n{\"bytes\":[202,254,186,190],\"subtype\":null}\n{\"bytes\":[202,254,186,190],\"subtype\":66}\n
    "},{"location":"api/basic_json/cbor_tag_handler_t/#see-also","title":"See also","text":"
    • Binary values - how binary values and subtypes are handled
    • from_cbor - deserializes a JSON value from CBOR
    • input_format_t - the enumeration of supported input formats
    • CBOR - the article on the CBOR format
    "},{"location":"api/basic_json/cbor_tag_handler_t/#version-history","title":"Version history","text":"
    • Added in version 3.9.0. Added value store in 3.10.0.
    "},{"location":"api/basic_json/cend/","title":"nlohmann::basic_json::cend","text":"
    const_iterator cend() const noexcept;\n

    Returns an iterator to one past the last element.

    A row of fifteen elements followed by a dashed past-the-last position. begin() points to the first element and end() points to the past-the-last position. begin end Past-the-last element

    cend() points to the position after the last element, like end(), and begin() to the first element; the dashed cell is the past-the-last position, which must not be dereferenced.

    "},{"location":"api/basic_json/cend/#return-value","title":"Return value","text":"

    iterator one past the last element

    "},{"location":"api/basic_json/cend/#exception-safety","title":"Exception safety","text":"

    No-throw guarantee: this member function never throws exceptions.

    "},{"location":"api/basic_json/cend/#complexity","title":"Complexity","text":"

    Constant.

    "},{"location":"api/basic_json/cend/#examples","title":"Examples","text":"Example

    The following code shows an example for cend().

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create an array value\n    json array = {1, 2, 3, 4, 5};\n\n    // get an iterator to one past the last element\n    json::const_iterator it = array.cend();\n\n    // decrement the iterator to point to the last element\n    --it;\n\n    // serialize the element that the iterator points to\n    std::cout << *it << '\\n';\n}\n

    Output:

    5\n
    "},{"location":"api/basic_json/cend/#see-also","title":"See also","text":"
    • end - returns an iterator to one past the last element
    • cbegin - returns a const iterator to the first element
    • crend - returns a const reverse iterator to one before the first element
    • Iterators - the article on iterators
    • basic_json_view::cend - the same iteration on a zero-copy view
    "},{"location":"api/basic_json/cend/#version-history","title":"Version history","text":"
    • Added in version 1.0.0.
    "},{"location":"api/basic_json/clear/","title":"nlohmann::basic_json::clear","text":"
    void clear() noexcept;\n

    Clears the content of a JSON value and resets it to the default value as if basic_json(value_t) would have been called with the current value type from type():

    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

    *this = basic_json(type());\n
    "},{"location":"api/basic_json/clear/#exception-safety","title":"Exception safety","text":"

    No-throw guarantee: this function never throws exceptions.

    "},{"location":"api/basic_json/clear/#complexity","title":"Complexity","text":"

    Linear in the size of the JSON value.

    "},{"location":"api/basic_json/clear/#notes","title":"Notes","text":"

    All iterators, pointers, and references related to this container are invalidated.

    "},{"location":"api/basic_json/clear/#examples","title":"Examples","text":"Example

    The example below shows the effect of clear() to different JSON types.

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create JSON values\n    json j_null;\n    json j_boolean = true;\n    json j_number_integer = 17;\n    json j_number_float = 23.42;\n    json j_object = {{\"one\", 1}, {\"two\", 2}};\n    json j_array = {1, 2, 4, 8, 16};\n    json j_string = \"Hello, world\";\n\n    // call clear()\n    j_null.clear();\n    j_boolean.clear();\n    j_number_integer.clear();\n    j_number_float.clear();\n    j_object.clear();\n    j_array.clear();\n    j_string.clear();\n\n    // serialize the cleared values()\n    std::cout << j_null << '\\n';\n    std::cout << j_boolean << '\\n';\n    std::cout << j_number_integer << '\\n';\n    std::cout << j_number_float << '\\n';\n    std::cout << j_object << '\\n';\n    std::cout << j_array << '\\n';\n    std::cout << j_string << '\\n';\n}\n

    Output:

    null\nfalse\n0\n0.0\n{}\n[]\n\"\"\n
    "},{"location":"api/basic_json/clear/#see-also","title":"See also","text":"
    • erase - removes elements from a JSON value
    • empty - checks whether the JSON value has no elements
    • Modifying values - the article on modifying values
    "},{"location":"api/basic_json/clear/#version-history","title":"Version history","text":"
    • Added in version 1.0.0.
    • Added support for binary types in version 3.8.0.
    • Fixed in version 3.13.0 unreleased to also clear the subtype of a binary value; before, the subtype was left unchanged.
    "},{"location":"api/basic_json/contains/","title":"nlohmann::basic_json::contains","text":"
    // (1)\nbool contains(const typename object_t::key_type& key) const;\n\n// (2)\ntemplate<typename KeyType>\nbool contains(KeyType&& key) const;\n\n// (3)\nbool contains(const json_pointer& ptr) const;\n\n// (4)\ntemplate<typename T>\nbool contains(T) const = delete;\n
    1. Check whether an element exists in a JSON object with a key equivalent to key. If the element is not found or the JSON value is not an object, false is returned.
    2. See 1. This overload is only available if KeyType is comparable with typename object_t::key_type and typename object_comparator_t::is_transparent denotes a type.
    3. Check whether the given JSON pointer ptr can be resolved in the current JSON value.
    4. Deleted: this overload is only available if T is an integral type and is declared as deleted, so that a call with an integer key (for example, j.contains(0)) fails to compile. Otherwise, the integer literal 0 would convert to a null const char* and, from there, to the key type, causing undefined behavior at runtime.
    "},{"location":"api/basic_json/contains/#template-parameters","title":"Template parameters","text":"KeyType A type for an object key other than json_pointer that is comparable with string_t using object_comparator_t. This can also be a string view (C++17)."},{"location":"api/basic_json/contains/#parameters","title":"Parameters","text":"key (in) key value to check its existence. ptr (in) JSON pointer to check its existence."},{"location":"api/basic_json/contains/#return-value","title":"Return value","text":"
    1. true if an element with specified key exists. If no such element with such a key is found or the JSON value is not an object, false is returned.
    2. See 1.
    3. true if the JSON pointer can be resolved to a stored value, false otherwise.
    4. Deleted; a call with an integral argument does not compile.
    "},{"location":"api/basic_json/contains/#exception-safety","title":"Exception safety","text":"

    Strong exception safety: if an exception occurs, the original value stays intact.

    "},{"location":"api/basic_json/contains/#exceptions","title":"Exceptions","text":"
    1. The function does not throw exceptions.
    2. The function does not throw exceptions.
    3. The function does not throw exceptions.
    4. Deleted; a call with an integral argument does not compile.
    "},{"location":"api/basic_json/contains/#complexity","title":"Complexity","text":"
    1. Logarithmic in the size of the JSON object.
    2. Logarithmic in the size of the JSON object.
    3. At most one lookup per reference token of ptr, each logarithmic in the size of the container at that level: O(n log m) for n reference tokens and containers of size at most m.
    4. Deleted; a call with an integral argument does not compile.
    "},{"location":"api/basic_json/contains/#notes","title":"Notes","text":"
    • Overloads (1) and (2) always return false when executed on a JSON type that is not an object. Overload (3) also works on arrays and on primitive values: the empty JSON pointer resolves in every JSON value (so json(1).contains(\"\"_json_pointer) returns true), and json({1, 2}).contains(\"/1\"_json_pointer) returns true.
    • This method can be executed on any JSON value type.
    • Calling this function with an integer argument (for example, contains(0)) does not compile: such an argument would otherwise implicitly convert to a null const char* and, from there, cause undefined behavior when constructing a std::string for the object key. To check for an array element instead, use at, operator[], or compare against size.

    Postconditions

    If j.contains(x) returns true for a key or JSON pointer x, then it is safe to call j[x].

    Deprecation

    Overload (3) also accepts a json_pointer 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 for how to update existing code.

    "},{"location":"api/basic_json/contains/#examples","title":"Examples","text":"Example: (1) check with key

    The example shows how contains() is used.

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\nusing namespace nlohmann::literals;\n\nint main()\n{\n    // create some JSON values\n    json j_object = R\"( {\"key\": \"value\"} )\"_json;\n    json j_array = R\"( [1, 2, 3] )\"_json;\n\n    // call contains\n    std::cout << std::boolalpha <<\n              \"j_object contains 'key': \" << j_object.contains(\"key\") << '\\n' <<\n              \"j_object contains 'another': \" << j_object.contains(\"another\") << '\\n' <<\n              \"j_array contains 'key': \" << j_array.contains(\"key\") << '\\n';\n}\n

    Output:

    j_object contains 'key': true\nj_object contains 'another': false\nj_array contains 'key': false\n
    Example: (2) check with key using string_view

    The example shows how contains() is used.

    #include <iostream>\n#include <string_view>\n#include <nlohmann/json.hpp>\n\nusing namespace std::string_view_literals;\nusing nlohmann::json;\nusing namespace nlohmann::literals;\n\nint main()\n{\n    // create some JSON values\n    json j_object = R\"( {\"key\": \"value\"} )\"_json;\n    json j_array = R\"( [1, 2, 3] )\"_json;\n\n    // call contains\n    std::cout << std::boolalpha <<\n              \"j_object contains 'key': \" << j_object.contains(\"key\"sv) << '\\n' <<\n              \"j_object contains 'another': \" << j_object.contains(\"another\"sv) << '\\n' <<\n              \"j_array contains 'key': \" << j_array.contains(\"key\"sv) << '\\n';\n}\n

    Output:

    j_object contains 'key': true\nj_object contains 'another': false\nj_array contains 'key': false\n
    Example: (3) check with JSON pointer

    The example shows how contains() is used.

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\nusing namespace nlohmann::literals;\n\nint main()\n{\n    // create a JSON value\n    json j =\n    {\n        {\"number\", 1}, {\"string\", \"foo\"}, {\"array\", {1, 2}}\n    };\n\n    std::cout << std::boolalpha\n              << j.contains(\"/number\"_json_pointer) << '\\n'\n              << j.contains(\"/string\"_json_pointer) << '\\n'\n              << j.contains(\"/array\"_json_pointer) << '\\n'\n              << j.contains(\"/array/1\"_json_pointer) << '\\n'\n              << j.contains(\"/array/-\"_json_pointer) << '\\n'\n              << j.contains(\"/array/4\"_json_pointer) << '\\n'\n              << j.contains(\"/baz\"_json_pointer) << '\\n'\n              // an array index with a leading '0' is not found\n              << j.contains(\"/array/01\"_json_pointer) << '\\n'\n              // an array index that is not a number is not found\n              << j.contains(\"/array/one\"_json_pointer) << '\\n';\n}\n

    Output:

    true\ntrue\ntrue\ntrue\nfalse\nfalse\nfalse\nfalse\nfalse\n
    "},{"location":"api/basic_json/contains/#see-also","title":"See also","text":"
    • find - find a value in an object
    • count - returns the number of occurrences of a key
    • basic_json_view::contains - the same check on a zero-copy view
    • Element Access - how to test whether a key exists
    "},{"location":"api/basic_json/contains/#version-history","title":"Version history","text":"
    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. Support for keys convertible to std::string_view added in version 3.13.0 unreleased, consistently across the lookup functions.
    3. Added in version 3.7.0.
    4. Deleted overloads for integral key types added in version 3.13.0 unreleased to reject such calls at compile time instead of causing undefined behavior at runtime.
    "},{"location":"api/basic_json/count/","title":"nlohmann::basic_json::count","text":"
    // (1)\nsize_type count(const typename object_t::key_type& key) const;\n\n// (2)\ntemplate<typename KeyType>\nsize_type count(KeyType&& key) const;\n\n// (3)\ntemplate<typename T>\nsize_type count(T) const = delete;\n
    1. Returns the number of elements with key key. If ObjectType is the default std::map type, the return value will always be 0 (key was not found) or 1 (key was found).
    2. See 1. This overload is only available if KeyType is comparable with typename object_t::key_type and typename object_comparator_t::is_transparent denotes a type.
    3. Deleted: this overload is only available if T is an integral type and is declared as deleted, so that a call with an integer key (for example, j.count(0)) fails to compile. Otherwise, the integer literal 0 would convert to a null const char* and, from there, to the key type, causing undefined behavior at runtime.
    "},{"location":"api/basic_json/count/#template-parameters","title":"Template parameters","text":"KeyType A type for an object key other than json_pointer that is comparable with string_t using object_comparator_t. This can also be a string view (C++17)."},{"location":"api/basic_json/count/#parameters","title":"Parameters","text":"key (in) key value of the element to count."},{"location":"api/basic_json/count/#return-value","title":"Return value","text":"

    Number of elements with key key. If the JSON value is not an object, the return value will be 0.

    "},{"location":"api/basic_json/count/#exception-safety","title":"Exception safety","text":"

    Strong exception safety: if an exception occurs, the original value stays intact.

    "},{"location":"api/basic_json/count/#complexity","title":"Complexity","text":"

    Logarithmic in the size of the JSON object.

    "},{"location":"api/basic_json/count/#notes","title":"Notes","text":"
    • 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, count(0)) does not compile: such an argument would otherwise implicitly convert to a null const char* and, from there, cause undefined behavior when constructing a std::string for the object key. To check for an array element instead, use at, operator[], or compare against size.
    "},{"location":"api/basic_json/count/#examples","title":"Examples","text":"Example: (1) count number of elements

    The example shows how count() is used.

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create a JSON object\n    json j_object = {{\"one\", 1}, {\"two\", 2}};\n\n    // call count()\n    auto count_two = j_object.count(\"two\");\n    auto count_three = j_object.count(\"three\");\n\n    // print values\n    std::cout << \"number of elements with key \\\"two\\\": \" << count_two << '\\n';\n    std::cout << \"number of elements with key \\\"three\\\": \" << count_three << '\\n';\n}\n

    Output:

    number of elements with key \"two\": 1\nnumber of elements with key \"three\": 0\n
    Example: (2) count number of elements using string_view

    The example shows how count() is used.

    #include <iostream>\n#include <string_view>\n#include <nlohmann/json.hpp>\n\nusing namespace std::string_view_literals;\nusing nlohmann::json;\n\nint main()\n{\n    // create a JSON object\n    json j_object = {{\"one\", 1}, {\"two\", 2}};\n\n    // call count()\n    auto count_two = j_object.count(\"two\"sv);\n    auto count_three = j_object.count(\"three\"sv);\n\n    // print values\n    std::cout << \"number of elements with key \\\"two\\\": \" << count_two << '\\n';\n    std::cout << \"number of elements with key \\\"three\\\": \" << count_three << '\\n';\n}\n

    Output:

    number of elements with key \"two\": 1\nnumber of elements with key \"three\": 0\n
    "},{"location":"api/basic_json/count/#see-also","title":"See also","text":"
    • find - find a value in an object
    • contains - checks whether a key exists
    • basic_json_view::count - the same check on a zero-copy view
    • Element Access - how to test whether a key exists
    "},{"location":"api/basic_json/count/#version-history","title":"Version history","text":"
    1. Added in version 3.11.0.
    2. Added in version 1.0.0. Changed to support comparable key types in version 3.11.0. Support for keys convertible to std::string_view added in version 3.13.0 unreleased, consistently across the lookup functions.
    3. Deleted overload for integral key types added in version 3.13.0 unreleased to reject such calls at compile time instead of causing undefined behavior at runtime.
    "},{"location":"api/basic_json/crbegin/","title":"nlohmann::basic_json::crbegin","text":"
    const_reverse_iterator crbegin() const noexcept;\n

    Returns an iterator to the reverse-beginning; that is, the last element.

    Two rows of sixteen cells. The upper row shows the reversed sequence: rend() points to a dashed position before the first element and rbegin() to the last element. The lower row shows the forward sequence: begin() points to the first element and end() to a dashed position after the last element. A reverse iterator stores an iterator to the next element, so rend() corresponds to begin() and rbegin() to end(). rend rbegin Reverse past-the-last element A reverse iterator stores an iterator to the next element begin end Past-the-last element

    crbegin() points to the last element, like rbegin(), and rend() to the position before the first element. The upper row is the reversed sequence and the lower row the forward sequence; dashed arrows link each reverse iterator to the forward iterator it stores, and dashed cells are past-the-last positions.

    "},{"location":"api/basic_json/crbegin/#return-value","title":"Return value","text":"

    reverse iterator to the last element

    "},{"location":"api/basic_json/crbegin/#exception-safety","title":"Exception safety","text":"

    No-throw guarantee: this member function never throws exceptions.

    "},{"location":"api/basic_json/crbegin/#complexity","title":"Complexity","text":"

    Constant.

    "},{"location":"api/basic_json/crbegin/#examples","title":"Examples","text":"Example

    The following code shows an example for crbegin().

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create an array value\n    json array = {1, 2, 3, 4, 5};\n\n    // get an iterator to the reverse-beginning\n    json::const_reverse_iterator it = array.crbegin();\n\n    // serialize the element that the iterator points to\n    std::cout << *it << '\\n';\n}\n

    Output:

    5\n
    "},{"location":"api/basic_json/crbegin/#see-also","title":"See also","text":"
    • crend - returns a const reverse iterator to one before the first element
    • rbegin - returns a reverse iterator to the last element
    • cbegin - returns a const iterator to the first element
    • Iterators - the article on iterators
    "},{"location":"api/basic_json/crbegin/#version-history","title":"Version history","text":"
    • Added in version 1.0.0.
    "},{"location":"api/basic_json/crend/","title":"nlohmann::basic_json::crend","text":"
    const_reverse_iterator crend() const noexcept;\n

    Returns an iterator to the reverse-end; that is, one before the first element. This element acts as a placeholder, attempting to access it results in undefined behavior.

    Two rows of sixteen cells. The upper row shows the reversed sequence: rend() points to a dashed position before the first element and rbegin() to the last element. The lower row shows the forward sequence: begin() points to the first element and end() to a dashed position after the last element. A reverse iterator stores an iterator to the next element, so rend() corresponds to begin() and rbegin() to end(). rend rbegin Reverse past-the-last element A reverse iterator stores an iterator to the next element begin end Past-the-last element

    crend() points to the position before the first element, like rend(), and rbegin() to the last element. The upper row is the reversed sequence and the lower row the forward sequence; dashed arrows link each reverse iterator to the forward iterator it stores, and dashed cells are past-the-last positions.

    "},{"location":"api/basic_json/crend/#return-value","title":"Return value","text":"

    reverse iterator to the element following the last element

    "},{"location":"api/basic_json/crend/#exception-safety","title":"Exception safety","text":"

    No-throw guarantee: this member function never throws exceptions.

    "},{"location":"api/basic_json/crend/#complexity","title":"Complexity","text":"

    Constant.

    "},{"location":"api/basic_json/crend/#examples","title":"Examples","text":"Example

    The following code shows an example for crend().

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create an array value\n    json array = {1, 2, 3, 4, 5};\n\n    // get an iterator to the reverse-end\n    json::const_reverse_iterator it = array.crend();\n\n    // increment the iterator to point to the first element\n    --it;\n\n    // serialize the element that the iterator points to\n    std::cout << *it << '\\n';\n}\n

    Output:

    1\n
    "},{"location":"api/basic_json/crend/#see-also","title":"See also","text":"
    • crbegin - returns a const reverse iterator to the last element
    • rend - returns a reverse iterator to one before the first element
    • cend - returns a const iterator to one past the last element
    • Iterators - the article on iterators
    "},{"location":"api/basic_json/crend/#version-history","title":"Version history","text":"
    • Added in version 1.0.0.
    "},{"location":"api/basic_json/default_object_comparator_t/","title":"nlohmann::basic_json::default_object_comparator_t","text":"
    using default_object_comparator_t = std::less<StringType>;  // until C++14\n\nusing default_object_comparator_t = std::less<>;            // since C++14\n

    The default comparator used by object_t.

    Since C++14 a transparent comparator is used which prevents unnecessary string construction when looking up a key in an object.

    The actual comparator used depends on object_t and can be obtained via object_comparator_t.

    "},{"location":"api/basic_json/default_object_comparator_t/#examples","title":"Examples","text":"Example

    The example below demonstrates the default comparator.

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    std::cout << std::boolalpha\n              << \"one < two : \" << json::default_object_comparator_t{}(\"one\", \"two\") << \"\\n\"\n              << \"three < four : \" << json::default_object_comparator_t{}(\"three\", \"four\") << '\\n';\n}\n

    Output:

    one < two : true\nthree < four : false\n
    "},{"location":"api/basic_json/default_object_comparator_t/#see-also","title":"See also","text":"
    • object_comparator_t - the comparator actually used by object_t
    • object_t - the type used to store JSON objects
    • Template Parameter Requirements - requirements on the ObjectType template parameter
    • Object order - preserve the insertion order of keys
    "},{"location":"api/basic_json/default_object_comparator_t/#version-history","title":"Version history","text":"
    • Added in version 3.11.0.
    "},{"location":"api/basic_json/diff/","title":"nlohmann::basic_json::diff","text":"
    static basic_json diff(const basic_json& source,\n                       const basic_json& target,\n                       const string_t& path = \"\");\n

    Creates a JSON Patch so that value source can be changed into the value target by calling patch function.

    For two JSON values source and target, the following code yields true:

    source.patch(diff(source, target)) == target;\n

    The equality holds up to operator==, so it has the following exceptions:

    • A value that is not equal to itself cannot round-trip. This applies to NaN (also nested in an array or object) and to discarded values: diff emits a replace operation for them. A NaN in the patch is serialized as null, so a patch that was dumped and parsed again would set null.
    • Numbers that compare equal produce no operation, even if their types differ or if one is zero and the other is negative zero: diff(1, 1.0) (integer and floating-point), diff(1u, 1) (unsigned and signed integer) and diff(0.0, -0.0) (positive and negative zero) all return []. The patched value is then the source and keeps its number type and sign.
    "},{"location":"api/basic_json/diff/#parameters","title":"Parameters","text":"source (in) JSON value to compare from target (in) JSON value to compare against path (in) a prefix that is put verbatim in front of the path member of every operation (default: \"\", which addresses the root of the value). The prefix is neither escaped nor validated: diff(1, 2, \"abc\") yields an operation with the path abc, which is not a valid JSON Pointer. Use it with a valid JSON Pointer such as /root and escape ~ and / in its reference tokens (see JSON Pointer)."},{"location":"api/basic_json/diff/#return-value","title":"Return value","text":"

    a JSON patch to convert the source to target

    "},{"location":"api/basic_json/diff/#exception-safety","title":"Exception safety","text":"

    Strong guarantee: source and target are never modified.

    "},{"location":"api/basic_json/diff/#complexity","title":"Complexity","text":"

    Linear in the total number of values (including nested ones) in source and target, times the cost of a key-based object operation (looking up a key in an object): logarithmic for json, and linear for ordered_json (see ordered_map complexity). For ordered_json, diffing two objects with n and m members therefore takes O((n+m)\u00b2) when their keys do not line up (e.g., a key was added or the keys are in a different order). The size of the patch is proportional to the number of operations times the length of their paths, so a small change deep inside a value yields a long path.

    "},{"location":"api/basic_json/diff/#notes","title":"Notes","text":"
    • Currently, only remove, add, and replace operations are generated.
    • The patch is correct, but not guaranteed to be minimal. For instance, diff([1,2,3], [0,1,2,3]) yields three replace operations and one add operation instead of a single insertion.
    • Differences between two arrays are reported index by index. Elements that were added at the end of the array are added with add operations on the path /- (appended in order), and elements that were removed are removed with remove operations from the highest index down to the lowest, so that the remaining indices stay valid.
    • For objects, the operations for the members of source come first (replace, remove, or the operations for nested values, in the iteration order of source), followed by add operations for the members that only target has.
    • For ordered_json, objects with the same keys in a different order are different. As a patch cannot reorder members, diff removes all keys of the source object and adds them again in the order of the target.
    • If source and target differ as a whole (e.g., different types), the patch consists of a single replace operation for the root of the value, i.e., with the path \"\" (or the given path prefix).
    • The value members of the patch hold copies of values of target. A binary value has no JSON representation: when a patch that contains one is serialized, it becomes an object such as {\"bytes\":[1,3],\"subtype\":null}, so a parsed patch no longer holds a binary value (and would set that object instead).
    "},{"location":"api/basic_json/diff/#examples","title":"Examples","text":"Example

    The following code shows how a JSON patch is created as a diff for two JSON values.

    #include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\nusing namespace nlohmann::literals;\n\nint main()\n{\n    // the source document\n    json source = R\"(\n        {\n            \"baz\": \"qux\",\n            \"foo\": \"bar\"\n        }\n    )\"_json;\n\n    // the target document\n    json target = R\"(\n        {\n            \"baz\": \"boo\",\n            \"hello\": [\n                \"world\"\n            ]\n        }\n    )\"_json;\n\n    // create the patch\n    json patch = json::diff(source, target);\n\n    // roundtrip\n    json patched_source = source.patch(patch);\n\n    // output patch and roundtrip result\n    std::cout << std::setw(4) << patch << \"\\n\\n\"\n              << std::setw(4) << patched_source << '\\n';\n}\n

    Output:

    [\n    {\n        \"op\": \"replace\",\n        \"path\": \"/baz\",\n        \"value\": \"boo\"\n    },\n    {\n        \"op\": \"remove\",\n        \"path\": \"/foo\"\n    },\n    {\n        \"op\": \"add\",\n        \"path\": \"/hello\",\n        \"value\": [\n            \"world\"\n        ]\n    }\n]\n\n{\n    \"baz\": \"boo\",\n    \"hello\": [\n        \"world\"\n    ]\n}\n
    "},{"location":"api/basic_json/diff/#see-also","title":"See also","text":"
    • RFC 6902 (JSON Patch) - specification of JSON Patch
    • patch - applies a JSON Patch
    • patch_inplace - applies a JSON Patch in place
    • merge_patch - applies a JSON Merge Patch
    • merge_diff - creates a diff as a JSON Merge Patch
    • JSON Patch and Diff - the article on JSON Patch
    "},{"location":"api/basic_json/diff/#version-history","title":"Version history","text":"
    • Added in version 2.0.0.
    "},{"location":"api/basic_json/dump/","title":"nlohmann::basic_json::dump","text":"
    string_t dump(const int indent = -1,\n              const char indent_char = ' ',\n              const bool ensure_ascii = false,\n              const error_handler_t error_handler = error_handler_t::strict) const;\n

    Serialization function for JSON values. The function tries to mimic Python's json.dumps() function, and currently supports its indent and ensure_ascii parameters.

    "},{"location":"api/basic_json/dump/#parameters","title":"Parameters","text":"indent (in) If indent is nonnegative, then array elements and object members will be pretty-printed with that indent level. An indent level of 0 will only insert newlines. -1 (the default) selects the most compact representation. indent_char (in) The character to use for indentation if indent is greater than 0. The default is (space). ensure_ascii (in) If ensure_ascii is true, all non-ASCII characters in the output are escaped with \\uXXXX sequences, and the result consists of ASCII characters only. error_handler (in) how to react on decoding errors; there are four possible values (see error_handler_t: strict (throws an exception in case a decoding error occurs; default), replace (replace invalid UTF-8 sequences with U+FFFD), ignore (ignore invalid UTF-8 sequences during serialization; all valid bytes are copied to the output unchanged, and invalid bytes are dropped), and keep (write the ill-formed bytes to the output as is, without escaping them, even if ensure_ascii is true; the result is then not valid UTF-8, but equals the input bytes exactly, and well-formed characters around the ill-formed bytes are still escaped as usual))."},{"location":"api/basic_json/dump/#return-value","title":"Return value","text":"

    string containing the serialization of the JSON value

    "},{"location":"api/basic_json/dump/#exception-safety","title":"Exception safety","text":"

    Strong guarantee: if an exception is thrown, there are no changes to any JSON value.

    "},{"location":"api/basic_json/dump/#exceptions","title":"Exceptions","text":"

    Throws type_error.316 if a string stored inside the JSON value is not UTF-8 encoded and error_handler is set to strict

    Serializing untrusted input

    When serializing values that may contain invalid or untrusted UTF-8 (e.g., bytes taken directly from network input), dump() throws type_error.316 in the default strict mode. To serialize such data without throwing, pass error_handler_t::replace (substitutes U+FFFD) or error_handler_t::ignore. Callers that serialize untrusted input on a crash-sensitive path should either choose a non-strict error handler or wrap dump() in a try/catch.

    See the FAQ for details.

    "},{"location":"api/basic_json/dump/#complexity","title":"Complexity","text":"

    Linear.

    "},{"location":"api/basic_json/dump/#notes","title":"Notes","text":"

    Floating-point numbers are written with the fewest digits that read back as the same value (for double; see number handling).

    Binary values are serialized as an object containing two keys:

    • \"bytes\": an array of bytes as integers
    • \"subtype\": the subtype as integer or null if the binary has no subtype
    "},{"location":"api/basic_json/dump/#examples","title":"Examples","text":"Example

    The following example shows the effect of different indent, indent_char, and ensure_ascii parameters to the result of the serialization.

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create JSON values\n    json j_object = {{\"one\", 1}, {\"two\", 2}};\n    json j_array = {1, 2, 4, 8, 16};\n    json j_string = \"Hell\u00f6 \ud83d\ude00!\";\n\n    // call dump()\n    std::cout << \"objects:\" << '\\n'\n              << j_object.dump() << \"\\n\\n\"\n              << j_object.dump(-1) << \"\\n\\n\"\n              << j_object.dump(0) << \"\\n\\n\"\n              << j_object.dump(4) << \"\\n\\n\"\n              << j_object.dump(1, '\\t') << \"\\n\\n\";\n\n    std::cout << \"arrays:\" << '\\n'\n              << j_array.dump() << \"\\n\\n\"\n              << j_array.dump(-1) << \"\\n\\n\"\n              << j_array.dump(0) << \"\\n\\n\"\n              << j_array.dump(4) << \"\\n\\n\"\n              << j_array.dump(1, '\\t') << \"\\n\\n\";\n\n    std::cout << \"strings:\" << '\\n'\n              << j_string.dump() << '\\n'\n              << j_string.dump(-1, ' ', true) << '\\n';\n\n    // create JSON value with invalid UTF-8 byte sequence\n    json j_invalid = \"\u00e4\\xA9\u00fc\";\n    try\n    {\n        std::cout << j_invalid.dump() << '\\n';\n    }\n    catch (const json::type_error& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n\n    std::cout << \"string with replaced invalid characters: \"\n              << j_invalid.dump(-1, ' ', false, json::error_handler_t::replace)\n              << \"\\nstring with ignored invalid characters: \"\n              << j_invalid.dump(-1, ' ', false, json::error_handler_t::ignore)\n              << '\\n';\n}\n

    Output:

    objects:\n{\"one\":1,\"two\":2}\n\n{\"one\":1,\"two\":2}\n\n{\n\"one\": 1,\n\"two\": 2\n}\n\n{\n    \"one\": 1,\n    \"two\": 2\n}\n\n{\n    \"one\": 1,\n    \"two\": 2\n}\n\narrays:\n[1,2,4,8,16]\n\n[1,2,4,8,16]\n\n[\n1,\n2,\n4,\n8,\n16\n]\n\n[\n    1,\n    2,\n    4,\n    8,\n    16\n]\n\n[\n    1,\n    2,\n    4,\n    8,\n    16\n]\n\nstrings:\n\"Hell\u00f6 \ud83d\ude00!\"\n\"Hell\\u00f6 \\ud83d\\ude00!\"\n[json.exception.type_error.316] invalid UTF-8 byte at index 2: 0xA9\nstring with replaced invalid characters: \"\u00e4\ufffd\u00fc\"\nstring with ignored invalid characters: \"\u00e4\u00fc\"\n
    "},{"location":"api/basic_json/dump/#see-also","title":"See also","text":"
    • to_string - returns a string representation of a JSON value
    • operator<< - serialize to stream
    • basic_json_view::dump - the corresponding function of basic_json_view, serializing directly from a flat index without building a basic_json value
    • Serialization - the serialization article
    "},{"location":"api/basic_json/dump/#version-history","title":"Version history","text":"
    • Added in version 1.0.0.
    • Indentation character indent_char, option ensure_ascii and exceptions added in version 3.0.0.
    • Error handlers added in version 3.4.0.
    • Serialization of binary values added in version 3.8.0.
    • Error handler keep added in version 3.13.0 unreleased.
    • Doubles are written with the shortest digits (\u017bmij instead of Grisu2) since version 3.13.0 unreleased; about 0.1% of doubles are written differently, most of them with fewer digits.
    "},{"location":"api/basic_json/emplace/","title":"nlohmann::basic_json::emplace","text":"
    template<class... Args>\nstd::pair<iterator, bool> emplace(Args&& ... args);\n

    Inserts a new element into a JSON object constructed in-place with the given args if there is no element with the key in the container. If the function is called on a JSON null value, an empty object is created before appending the value created from args.

    "},{"location":"api/basic_json/emplace/#template-parameters","title":"Template parameters","text":"Args compatible types to create a basic_json object"},{"location":"api/basic_json/emplace/#iterator-invalidation","title":"Iterator invalidation","text":"

    For ordered_json, adding a value to an object can yield a reallocation, in which case all iterators (including the end() iterator) and all references to the elements are invalidated.

    "},{"location":"api/basic_json/emplace/#parameters","title":"Parameters","text":"args (in) arguments to forward to a constructor of basic_json"},{"location":"api/basic_json/emplace/#return-value","title":"Return value","text":"

    a pair consisting of an iterator to the inserted element, or the already-existing element if no insertion happened, and a bool denoting whether the insertion took place.

    "},{"location":"api/basic_json/emplace/#exception-safety","title":"Exception safety","text":"

    Strong guarantee: if an exception is thrown, there are no changes to any JSON value. As an exception, a null value is converted to an empty object before the element is added and keeps that type if adding the element throws.

    "},{"location":"api/basic_json/emplace/#exceptions","title":"Exceptions","text":"

    Throws type_error.311 when called on a type other than JSON object or null; example: \"cannot use emplace() with number\"

    "},{"location":"api/basic_json/emplace/#complexity","title":"Complexity","text":"

    Logarithmic in the size of the container, O(log(size())).

    "},{"location":"api/basic_json/emplace/#examples","title":"Examples","text":"Example

    The example shows how emplace() can be used to add elements to a JSON object. Note how the null value was silently converted to a JSON object. Further note how no value is added if there was already one value stored with the same key.

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create JSON values\n    json object = {{\"one\", 1}, {\"two\", 2}};\n    json null;\n\n    // print values\n    std::cout << object << '\\n';\n    std::cout << null << '\\n';\n\n    // add values\n    auto res1 = object.emplace(\"three\", 3);\n    null.emplace(\"A\", \"a\");\n    null.emplace(\"B\", \"b\");\n\n    // the following call will not add an object, because there is already\n    // a value stored at key \"B\"\n    auto res2 = null.emplace(\"B\", \"c\");\n\n    // print values\n    std::cout << object << '\\n';\n    std::cout << *res1.first << \" \" << std::boolalpha << res1.second << '\\n';\n\n    std::cout << null << '\\n';\n    std::cout << *res2.first << \" \" << std::boolalpha << res2.second << '\\n';\n}\n

    Output:

    {\"one\":1,\"two\":2}\nnull\n{\"one\":1,\"three\":3,\"two\":2}\n3 true\n{\"A\":\"a\",\"B\":\"b\"}\n\"b\" false\n
    "},{"location":"api/basic_json/emplace/#see-also","title":"See also","text":"
    • emplace_back - add a value to an array
    • insert - add values to an array/object
    • Modifying values - the article on modifying values
    "},{"location":"api/basic_json/emplace/#version-history","title":"Version history","text":"
    • Added in version 2.0.8.
    • Fixed in version 3.13.0 unreleased: for ordered_json, the value could previously only be passed as an rvalue; it can now also be passed as an lvalue or a const lvalue, matching the behavior of json.
    "},{"location":"api/basic_json/emplace_back/","title":"nlohmann::basic_json::emplace_back","text":"
    template<class... Args>\nreference emplace_back(Args&& ... args);\n

    Creates a JSON value from the passed parameters args to the end of the JSON value. If the function is called on a JSON null value, an empty array is created before appending the value created from args.

    "},{"location":"api/basic_json/emplace_back/#template-parameters","title":"Template parameters","text":"Args compatible types to create a basic_json object"},{"location":"api/basic_json/emplace_back/#iterator-invalidation","title":"Iterator invalidation","text":"

    By adding an element to the end of the array, a reallocation can happen, in which case all iterators (including the end() iterator) and all references to the elements are invalidated. Otherwise, only the end() iterator is invalidated.

    "},{"location":"api/basic_json/emplace_back/#parameters","title":"Parameters","text":"args (in) arguments to forward to a constructor of basic_json"},{"location":"api/basic_json/emplace_back/#return-value","title":"Return value","text":"

    reference to the inserted element

    "},{"location":"api/basic_json/emplace_back/#exception-safety","title":"Exception safety","text":"

    Strong guarantee: if an exception is thrown, there are no changes to any JSON value. As an exception, a null value is converted to an empty array before the element is added and keeps that type if adding the element throws.

    "},{"location":"api/basic_json/emplace_back/#exceptions","title":"Exceptions","text":"

    Throws type_error.311 when called on a type other than JSON array or null; example: \"cannot use emplace_back() with number\"

    "},{"location":"api/basic_json/emplace_back/#complexity","title":"Complexity","text":"

    Amortized constant.

    "},{"location":"api/basic_json/emplace_back/#examples","title":"Examples","text":"Example

    The example shows how emplace_back() can be used to add elements to a JSON array. Note how the null value was silently converted to a JSON array.

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create JSON values\n    json array = {1, 2, 3, 4, 5};\n    json null;\n\n    // print values\n    std::cout << array << '\\n';\n    std::cout << null << '\\n';\n\n    // add values\n    array.emplace_back(6);\n    null.emplace_back(\"first\");\n    null.emplace_back(3, \"second\");\n\n    // print values\n    std::cout << array << '\\n';\n    std::cout << null << '\\n';\n}\n

    Output:

    [1,2,3,4,5]\nnull\n[1,2,3,4,5,6]\n[\"first\",[\"second\",\"second\",\"second\"]]\n
    "},{"location":"api/basic_json/emplace_back/#see-also","title":"See also","text":"
    • operator+= - add a value to an array/object
    • push_back - add a value to an array/object
    • Modifying values - the article on modifying values
    "},{"location":"api/basic_json/emplace_back/#version-history","title":"Version history","text":"
    • Added in version 2.0.8.
    • Returns reference since 3.7.0.
    "},{"location":"api/basic_json/empty/","title":"nlohmann::basic_json::empty","text":"
    bool empty() const noexcept;\n

    Checks if a JSON value has no elements (i.e., whether its size() is 0).

    "},{"location":"api/basic_json/empty/#return-value","title":"Return value","text":"

    The return value depends on the different types and is defined as follows:

    Value type return value null true boolean false string false number false binary false object result of function object_t::empty() array result of function array_t::empty()"},{"location":"api/basic_json/empty/#exception-safety","title":"Exception safety","text":"

    No-throw guarantee: this function never throws exceptions.

    "},{"location":"api/basic_json/empty/#complexity","title":"Complexity","text":"

    Constant, as long as array_t and object_t satisfy the Container concept; that is, their empty() functions have constant complexity.

    "},{"location":"api/basic_json/empty/#possible-implementation","title":"Possible implementation","text":"
    bool empty() const noexcept\n{\n    return size() == 0;\n}\n
    "},{"location":"api/basic_json/empty/#notes","title":"Notes","text":"

    This function does not return whether a string stored as JSON value is empty \u2014 it returns whether the JSON container itself is empty which is false in the case of a string.

    "},{"location":"api/basic_json/empty/#examples","title":"Examples","text":"Example

    The following code uses empty() to check if a JSON object contains any elements.

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create JSON values\n    json j_null;\n    json j_boolean = true;\n    json j_number_integer = 17;\n    json j_number_float = 23.42;\n    json j_object = {{\"one\", 1}, {\"two\", 2}};\n    json j_object_empty(json::value_t::object);\n    json j_array = {1, 2, 4, 8, 16};\n    json j_array_empty(json::value_t::array);\n    json j_string = \"Hello, world\";\n\n    // call empty()\n    std::cout << std::boolalpha;\n    std::cout << j_null.empty() << '\\n';\n    std::cout << j_boolean.empty() << '\\n';\n    std::cout << j_number_integer.empty() << '\\n';\n    std::cout << j_number_float.empty() << '\\n';\n    std::cout << j_object.empty() << '\\n';\n    std::cout << j_object_empty.empty() << '\\n';\n    std::cout << j_array.empty() << '\\n';\n    std::cout << j_array_empty.empty() << '\\n';\n    std::cout << j_string.empty() << '\\n';\n}\n

    Output:

    true\nfalse\nfalse\nfalse\nfalse\ntrue\nfalse\ntrue\nfalse\n
    "},{"location":"api/basic_json/empty/#see-also","title":"See also","text":"
    • size - returns the number of elements
    • clear - clears the content and resets the value to the default value
    • basic_json_view::empty - the same check on a zero-copy view
    "},{"location":"api/basic_json/empty/#version-history","title":"Version history","text":"
    • Added in version 1.0.0.
    • Extended to return false for binary types in version 3.8.0.
    "},{"location":"api/basic_json/end/","title":"nlohmann::basic_json::end","text":"
    iterator end() noexcept;\nconst_iterator end() const noexcept;\n

    Returns an iterator to one past the last element.

    A row of fifteen elements followed by a dashed past-the-last position. begin() points to the first element and end() points to the past-the-last position. begin end Past-the-last element

    end() points to the position after the last element and begin() to the first element; the dashed cell is the past-the-last position, which must not be dereferenced.

    "},{"location":"api/basic_json/end/#return-value","title":"Return value","text":"

    iterator one past the last element

    "},{"location":"api/basic_json/end/#exception-safety","title":"Exception safety","text":"

    No-throw guarantee: this member function never throws exceptions.

    "},{"location":"api/basic_json/end/#complexity","title":"Complexity","text":"

    Constant.

    "},{"location":"api/basic_json/end/#examples","title":"Examples","text":"Example

    The following code shows an example for end().

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create an array value\n    json array = {1, 2, 3, 4, 5};\n\n    // get an iterator to one past the last element\n    json::iterator it = array.end();\n\n    // decrement the iterator to point to the last element\n    --it;\n\n    // serialize the element that the iterator points to\n    std::cout << *it << '\\n';\n}\n

    Output:

    5\n
    "},{"location":"api/basic_json/end/#see-also","title":"See also","text":"
    • begin - returns an iterator to the first element
    • cend - returns a const iterator to one past the last element
    • rend - returns a reverse iterator to one before the first element
    • Iterators - the article on iterators
    • basic_json_view::end - the same iteration on a zero-copy view
    "},{"location":"api/basic_json/end/#version-history","title":"Version history","text":"
    • Added in version 1.0.0.
    "},{"location":"api/basic_json/end_pos/","title":"nlohmann::basic_json::end_pos","text":"
    #if JSON_DIAGNOSTIC_POSITIONS\nconstexpr std::size_t end_pos() const noexcept;\n#endif\n

    Returns the position immediately following the last character of the JSON string from which the value was parsed from.

    JSON type return value object position after the closing } array position after the closing ] string position after the closing \" number position after the last character boolean position after e null position after l"},{"location":"api/basic_json/end_pos/#return-value","title":"Return value","text":"

    the position of the character following the last character of the given value in the parsed JSON string, if the value was created by the parse function, or std::string::npos if the value was constructed otherwise

    "},{"location":"api/basic_json/end_pos/#exception-safety","title":"Exception safety","text":"

    No-throw guarantee: this member function never throws exceptions.

    "},{"location":"api/basic_json/end_pos/#complexity","title":"Complexity","text":"

    Constant.

    "},{"location":"api/basic_json/end_pos/#notes","title":"Notes","text":"

    Note

    The function is only available if macro JSON_DIAGNOSTIC_POSITIONS has been defined to 1 before including the library header.

    Invalidation

    The returned positions are only valid as long as the JSON value is not changed. The positions are not updated when the JSON value is changed.

    "},{"location":"api/basic_json/end_pos/#examples","title":"Examples","text":"Example
    #include <iostream>\n\n#define JSON_DIAGNOSTIC_POSITIONS 1\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    std::string json_string = R\"(\n    {\n        \"address\": {\n            \"street\": \"Fake Street\",\n            \"housenumber\": 1\n        }\n    }\n    )\";\n    json j = json::parse(json_string);\n\n    std::cout << \"Root diagnostic positions: \\n\";\n    std::cout << \"\\tstart_pos: \" << j.start_pos() << '\\n';\n    std::cout << \"\\tend_pos:\" << j.end_pos() << \"\\n\";\n    std::cout << \"Original string: \\n\";\n    std::cout << \"{\\n        \\\"address\\\": {\\n            \\\"street\\\": \\\"Fake Street\\\",\\n            \\\"housenumber\\\": 1\\n        }\\n    }\" << \"\\n\";\n    std::cout << \"Parsed string: \\n\";\n    std::cout << json_string.substr(j.start_pos(), j.end_pos() - j.start_pos()) << \"\\n\\n\";\n\n    std::cout << \"address diagnostic positions: \\n\";\n    std::cout << \"\\tstart_pos:\" << j[\"address\"].start_pos() << '\\n';\n    std::cout << \"\\tend_pos:\" << j[\"address\"].end_pos() << \"\\n\\n\";\n    std::cout << \"Original string: \\n\";\n    std::cout << \"{            \\\"street\\\": \\\"Fake Street\\\",\\n            \\\"housenumber\\\": 1\\n        }\" << \"\\n\";\n    std::cout << \"Parsed string: \\n\";\n    std::cout << json_string.substr(j[\"address\"].start_pos(), j[\"address\"].end_pos() - j[\"address\"].start_pos()) << \"\\n\\n\";\n\n    std::cout << \"street diagnostic positions: \\n\";\n    std::cout << \"\\tstart_pos:\" << j[\"address\"][\"street\"].start_pos() << '\\n';\n    std::cout << \"\\tend_pos:\" << j[\"address\"][\"street\"].end_pos() << \"\\n\\n\";\n    std::cout << \"Original string: \\n\";\n    std::cout << \"\\\"Fake Street\\\"\" << \"\\n\";\n    std::cout << \"Parsed string: \\n\";\n    std::cout << json_string.substr(j[\"address\"][\"street\"].start_pos(), j[\"address\"][\"street\"].end_pos() - j[\"address\"][\"street\"].start_pos()) << \"\\n\\n\";\n\n    std::cout << \"housenumber diagnostic positions: \\n\";\n    std::cout << \"\\tstart_pos:\" << j[\"address\"][\"housenumber\"].start_pos() << '\\n';\n    std::cout << \"\\tend_pos:\" << j[\"address\"][\"housenumber\"].end_pos() << \"\\n\\n\";\n    std::cout << \"Original string: \\n\";\n    std::cout << \"1\" << \"\\n\";\n    std::cout << \"Parsed string: \\n\";\n    std::cout << json_string.substr(j[\"address\"][\"housenumber\"].start_pos(), j[\"address\"][\"housenumber\"].end_pos() - j[\"address\"][\"housenumber\"].start_pos()) << \"\\n\\n\";\n}\n

    Output:

    Root diagnostic positions: \n    start_pos: 5\n    end_pos:109\nOriginal string: \n{\n        \"address\": {\n            \"street\": \"Fake Street\",\n            \"housenumber\": 1\n        }\n    }\nParsed string: \n{\n        \"address\": {\n            \"street\": \"Fake Street\",\n            \"housenumber\": 1\n        }\n    }\n\naddress diagnostic positions: \n    start_pos:26\n    end_pos:103\n\nOriginal string: \n{            \"street\": \"Fake Street\",\n            \"housenumber\": 1\n        }\nParsed string: \n{\n            \"street\": \"Fake Street\",\n            \"housenumber\": 1\n        }\n\nstreet diagnostic positions: \n    start_pos:50\n    end_pos:63\n\nOriginal string: \n\"Fake Street\"\nParsed string: \n\"Fake Street\"\n\nhousenumber diagnostic positions: \n    start_pos:92\n    end_pos:93\n\nOriginal string: \n1\nParsed string: \n1\n

    The output shows the start/end positions of all the objects and fields in the JSON string.

    "},{"location":"api/basic_json/end_pos/#see-also","title":"See also","text":"
    • start_pos - to access the start position
    • JSON_DIAGNOSTIC_POSITIONS - overview of the supported conversions
    • Parsing and Exceptions - handling parse errors and locating them in the input
    "},{"location":"api/basic_json/end_pos/#version-history","title":"Version history","text":"
    • Added in version 3.12.0.
    "},{"location":"api/basic_json/erase/","title":"nlohmann::basic_json::erase","text":"
    // (1)\niterator erase(iterator pos);\nconst_iterator erase(const_iterator pos);\n\n// (2)\niterator erase(iterator first, iterator last);\nconst_iterator erase(const_iterator first, const_iterator last);\n\n// (3)\nsize_type erase(const typename object_t::key_type& key);\n\n// (4)\ntemplate<typename KeyType>\nsize_type erase(KeyType&& key);\n\n// (5)\nvoid erase(const size_type idx);\n
    1. Removes an element from a JSON value specified by iterator pos. The iterator pos must be valid and dereferenceable. Thus, the end() iterator (which is valid, but is not dereferenceable) cannot be used as a value for pos.

      If called on a primitive type other than null, the resulting JSON value will be null.

    2. Remove an element range specified by [first; last) from a JSON value. The iterator first does not need to be dereferenceable if first == last: erasing an empty range is a no-op.

      If called on a primitive type other than null, the resulting JSON value will be null.

    3. Removes an element from a JSON object by key.

    4. See 3. This overload is only available if KeyType is comparable with typename object_t::key_type and typename object_comparator_t::is_transparent denotes a type.

    5. Removes an element from a JSON array by index.

    "},{"location":"api/basic_json/erase/#template-parameters","title":"Template parameters","text":"KeyType A type for an object key other than json_pointer that is comparable with string_t using object_comparator_t. This can also be a string view (C++17)."},{"location":"api/basic_json/erase/#parameters","title":"Parameters","text":"pos (in) iterator to the element to remove first (in) iterator to the beginning of the range to remove last (in) iterator past the end of the range to remove key (in) object key of the elements to remove idx (in) array index of the element to remove"},{"location":"api/basic_json/erase/#return-value","title":"Return value","text":"
    1. Iterator following the last removed element. If the iterator pos refers to the last element, the end() iterator is returned.
    2. Iterator following the last removed element. If the iterator last refers to the last element, the end() iterator is returned.
    3. Number of elements removed. If ObjectType is the default std::map type, the return value will always be 0 (key was not found) or 1 (key was found).
    4. See 3.
    5. (none)
    "},{"location":"api/basic_json/erase/#exception-safety","title":"Exception safety","text":"

    Strong exception safety: if an exception occurs, the original value stays intact.

    "},{"location":"api/basic_json/erase/#exceptions","title":"Exceptions","text":"
    1. The function can throw the following exceptions:
      • Throws type_error.307 if called on a null value; example: \"cannot use erase() with null\"
      • Throws invalid_iterator.202 if called on an iterator which does not belong to the current JSON value; example: \"iterator does not fit current value\"
      • Throws invalid_iterator.205 if called on a primitive type with invalid iterator (i.e., any iterator which is not begin()); example: \"iterator out of range\"
    2. The function can throw the following exceptions:
      • Throws type_error.307 if called on a null value; example: \"cannot use erase() with null\"
      • Throws invalid_iterator.203 if called on iterators which does not belong to the current JSON value; example: \"iterators do not fit current value\"
      • Throws invalid_iterator.204 if called on a primitive type with invalid iterators (i.e., if first != begin() and last != end()); example: \"iterators out of range\"
    3. The function can throw the following exceptions:
      • Throws type_error.307 when called on a type other than JSON object; example: \"cannot use erase() with null\"
    4. See 3.
    5. The function can throw the following exceptions:
      • Throws type_error.307 when called on a type other than JSON array; example: \"cannot use erase() with null\"
      • Throws out_of_range.401 when idx >= size(); example: \"array index 17 is out of range\"
    "},{"location":"api/basic_json/erase/#complexity","title":"Complexity","text":"
    1. The complexity depends on the type:
      • objects: amortized constant
      • arrays: linear in distance between pos and the end of the container
      • strings and binary: linear in the length of the member
      • other types: constant
    2. The complexity depends on the type:
      • objects: log(size()) + std::distance(first, last)
      • arrays: linear in the distance between first and last, plus linear in the distance between last and end of the container
      • strings and binary: linear in the length of the member
      • other types: constant
    3. log(size()) + count(key)
    4. log(size()) + count(key)
    5. Linear in distance between idx and the end of the container.
    "},{"location":"api/basic_json/erase/#notes","title":"Notes","text":"
    1. Invalidates iterators and references at or after the point of the erase, including the end() iterator.
    2. (none)
    3. References and iterators to the erased elements are invalidated. Other references and iterators are not affected.
    4. See 3.
    5. (none)
    "},{"location":"api/basic_json/erase/#examples","title":"Examples","text":"Example: (1) remove element given an iterator

    The example shows the effect of erase() for different JSON types using an iterator.

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create JSON values\n    json j_boolean = true;\n    json j_number_integer = 17;\n    json j_number_float = 23.42;\n    json j_object = {{\"one\", 1}, {\"two\", 2}};\n    json j_array = {1, 2, 4, 8, 16};\n    json j_string = \"Hello, world\";\n\n    // call erase()\n    j_boolean.erase(j_boolean.begin());\n    j_number_integer.erase(j_number_integer.begin());\n    j_number_float.erase(j_number_float.begin());\n    j_object.erase(j_object.find(\"two\"));\n    j_array.erase(j_array.begin() + 2);\n    j_string.erase(j_string.begin());\n\n    // print values\n    std::cout << j_boolean << '\\n';\n    std::cout << j_number_integer << '\\n';\n    std::cout << j_number_float << '\\n';\n    std::cout << j_object << '\\n';\n    std::cout << j_array << '\\n';\n    std::cout << j_string << '\\n';\n}\n

    Output:

    null\nnull\nnull\n{\"one\":1}\n[1,2,8,16]\nnull\n
    Example: (2) remove elements given an iterator range

    The example shows the effect of erase() for different JSON types using an iterator range.

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create JSON values\n    json j_boolean = true;\n    json j_number_integer = 17;\n    json j_number_float = 23.42;\n    json j_object = {{\"one\", 1}, {\"two\", 2}};\n    json j_array = {1, 2, 4, 8, 16};\n    json j_string = \"Hello, world\";\n\n    // call erase()\n    j_boolean.erase(j_boolean.begin(), j_boolean.end());\n    j_number_integer.erase(j_number_integer.begin(), j_number_integer.end());\n    j_number_float.erase(j_number_float.begin(), j_number_float.end());\n    j_object.erase(j_object.find(\"two\"), j_object.end());\n    j_array.erase(j_array.begin() + 1, j_array.begin() + 3);\n    j_string.erase(j_string.begin(), j_string.end());\n\n    // print values\n    std::cout << j_boolean << '\\n';\n    std::cout << j_number_integer << '\\n';\n    std::cout << j_number_float << '\\n';\n    std::cout << j_object << '\\n';\n    std::cout << j_array << '\\n';\n    std::cout << j_string << '\\n';\n}\n

    Output:

    null\nnull\nnull\n{\"one\":1}\n[1,8,16]\nnull\n
    Example: (3) remove element from a JSON object given a key

    The example shows the effect of erase() for different JSON types using an object key.

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create a JSON object\n    json j_object = {{\"one\", 1}, {\"two\", 2}};\n\n    // call erase()\n    auto count_one = j_object.erase(\"one\");\n    auto count_three = j_object.erase(\"three\");\n\n    // print values\n    std::cout << j_object << '\\n';\n    std::cout << count_one << \" \" << count_three << '\\n';\n}\n

    Output:

    {\"two\":2}\n1 0\n
    Example: (4) remove element from a JSON object given a key using string_view

    The example shows the effect of erase() for different JSON types using an object key.

    #include <iostream>\n#include <string_view>\n#include <nlohmann/json.hpp>\n\nusing namespace std::string_view_literals;\nusing nlohmann::json;\n\nint main()\n{\n    // create a JSON object\n    json j_object = {{\"one\", 1}, {\"two\", 2}};\n\n    // call erase()\n    auto count_one = j_object.erase(\"one\"sv);\n    auto count_three = j_object.erase(\"three\"sv);\n\n    // print values\n    std::cout << j_object << '\\n';\n    std::cout << count_one << \" \" << count_three << '\\n';\n}\n

    Output:

    {\"two\":2}\n1 0\n
    Example: (5) remove element from a JSON array given an index

    The example shows the effect of erase() using an array index.

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create a JSON array\n    json j_array = {0, 1, 2, 3, 4, 5};\n\n    // call erase()\n    j_array.erase(2);\n\n    // print values\n    std::cout << j_array << '\\n';\n}\n

    Output:

    [0,1,3,4,5]\n
    "},{"location":"api/basic_json/erase/#see-also","title":"See also","text":"
    • clear - clears the contents
    • insert - add values to an array/object
    • Modifying values - the article on modifying values
    "},{"location":"api/basic_json/erase/#version-history","title":"Version history","text":"
    1. Added in version 1.0.0. Added support for binary types in version 3.8.0.
    2. Added in version 1.0.0. Added support for binary types in version 3.8.0.
    3. Added in version 1.0.0.
    4. Added in version 3.11.0. Support for keys convertible to std::string_view added in version 3.13.0 unreleased, consistently across the lookup functions.
    5. Added in version 1.0.0.
    "},{"location":"api/basic_json/error_handler_t/","title":"nlohmann::basic_json::error_handler_t","text":"
    enum class error_handler_t {\n    strict,\n    replace,\n    ignore,\n    keep\n};\n

    This enumeration is used to choose how to treat ill-formed UTF-8 in a string value or object key:

    • dump uses it while serializing a basic_json value to text.
    • to_cbor, to_msgpack, to_ubjson, to_bjdata, and to_bson use it while serializing a basic_json value to that binary format. Their default is keep, as no binary writer checked before this parameter was added. CBOR, UBJSON, BJData, and BSON require valid UTF-8, so for these four the default is strict if JSON_STRICT_BINARY_UTF8 is enabled; MessagePack's specification explicitly allows a string to contain ill-formed UTF-8, so to_msgpack stays at keep. to_bon8 does not take this parameter: BON8 always validates, since UTF-8 lead bytes are structural to that format.
    • from_cbor, from_msgpack, from_ubjson, from_bjdata, and from_bson use it while parsing that binary format, to decide whether to check a string value or object key for well-formed UTF-8 at all; by default (keep) they do not, as no binary reader did before this parameter was added. from_bon8 does not take this parameter, for the same reason to_bon8 does not.

    Four values are differentiated:

    strict throw a type_error/parse_error exception in case of invalid UTF-8 replace replace invalid UTF-8 sequences with U+FFFD (\ufffd REPLACEMENT CHARACTER) ignore ignore invalid UTF-8 sequences; all valid bytes are copied to the output unchanged, and invalid bytes are dropped keep keep invalid UTF-8 sequences unchanged; only meaningful for the binary formats mentioned above, since dump itself must produce text, and keep there writes the ill-formed bytes to the output as is, so the result is then not valid UTF-8 (but still equals the input bytes exactly, including around any well-formed characters, which are still escaped as usual)"},{"location":"api/basic_json/error_handler_t/#examples","title":"Examples","text":"Example

    The example below shows how the different values of the error_handler_t influence the behavior of dump when reading serializing an invalid UTF-8 sequence.

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create JSON value with invalid UTF-8 byte sequence\n    json j_invalid = \"\u00e4\\xA9\u00fc\";\n    try\n    {\n        std::cout << j_invalid.dump() << '\\n';\n    }\n    catch (const json::type_error& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n\n    std::cout << \"string with replaced invalid characters: \"\n              << j_invalid.dump(-1, ' ', false, json::error_handler_t::replace)\n              << \"\\nstring with ignored invalid characters: \"\n              << j_invalid.dump(-1, ' ', false, json::error_handler_t::ignore)\n              << \"\\nstring with the invalid byte kept as is (\" << j_invalid.dump(-1, ' ', false, json::error_handler_t::keep).size()\n              << \" bytes, not valid UTF-8 itself)\\n\";\n}\n

    Output:

    [json.exception.type_error.316] invalid UTF-8 byte at index 2: 0xA9\nstring with replaced invalid characters: \"\u00e4\ufffd\u00fc\"\nstring with ignored invalid characters: \"\u00e4\u00fc\"\nstring with the invalid byte kept as is (7 bytes, not valid UTF-8 itself)\n
    "},{"location":"api/basic_json/error_handler_t/#see-also","title":"See also","text":"
    • dump - serializes a JSON value, with an error_handler_t parameter to configure invalid UTF-8 handling
    • Handling invalid UTF-8 - the article on handling invalid UTF-8
    "},{"location":"api/basic_json/error_handler_t/#version-history","title":"Version history","text":"
    • Added in version 3.4.0.
    • Added keep, and made this enumeration apply to the binary readers and writers in addition to dump, in version 3.13.0.
    "},{"location":"api/basic_json/exception/","title":"nlohmann::basic_json::exception","text":"
    class exception : public std::exception;\n

    This class is an extension of std::exception objects with a member id for exception ids. It is used as the base class for all exceptions thrown by the basic_json class. This class can hence be used as \"wildcard\" to catch exceptions, see example below.

    classDiagram\n  direction LR\n\n    class std_exception [\"std::exception\"] {\n        <<interface>>\n    }\n\n    class json_exception [\"basic_json::exception\"] {\n        +const int id\n        +const char* what() const\n    }\n\n    class json_parse_error [\"basic_json::parse_error\"] {\n        +const std::size_t byte\n    }\n\n    class json_invalid_iterator [\"basic_json::invalid_iterator\"]\n    class json_type_error [\"basic_json::type_error\"]\n    class json_out_of_range [\"basic_json::out_of_range\"]\n    class json_other_error [\"basic_json::other_error\"]\n\n    std_exception <|-- json_exception\n    json_exception <|-- json_parse_error\n    json_exception <|-- json_invalid_iterator\n    json_exception <|-- json_type_error\n    json_exception <|-- json_out_of_range\n    json_exception <|-- json_other_error\n\n    style json_exception fill:#CCCCFF

    Class hierarchy of the library's exceptions; arrows point from a derived class to its base class, and the highlighted box is basic_json::exception.

    Subclasses:

    • parse_error for exceptions indicating a parse error
    • invalid_iterator for exceptions indicating errors with iterators
    • type_error for exceptions indicating executing a member function with a wrong type
    • out_of_range for exceptions indicating access out of the defined range
    • other_error for exceptions indicating other library errors
    "},{"location":"api/basic_json/exception/#member-functions","title":"Member functions","text":"
    • what - returns explanatory string
    "},{"location":"api/basic_json/exception/#member-variables","title":"Member variables","text":"
    • id - the id of the exception
    "},{"location":"api/basic_json/exception/#notes","title":"Notes","text":"

    To have nothrow-copy-constructible exceptions, we internally use std::runtime_error which can cope with arbitrary-length error messages. Intermediate strings are built with static functions and then passed to the actual constructor.

    "},{"location":"api/basic_json/exception/#examples","title":"Examples","text":"Example

    The following code shows how arbitrary library exceptions can be caught.

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    try\n    {\n        // calling at() for a non-existing key\n        json j = {{\"foo\", \"bar\"}};\n        json k = j.at(\"non-existing\");\n    }\n    catch (const json::exception& e)\n    {\n        // output exception information\n        std::cout << \"message: \" << e.what() << '\\n'\n                  << \"exception id: \" << e.id << '\\n';\n    }\n}\n

    Output:

    message: [json.exception.out_of_range.403] key 'non-existing' not found\nexception id: 403\n
    "},{"location":"api/basic_json/exception/#see-also","title":"See also","text":"
    • List of exceptions - overview of all exceptions thrown by the library
    • Working Without Exceptions - using the library without exceptions
    • JSON_DIAGNOSTICS - extended exception messages with the path of the failing value
    • Parsing and Exceptions - parsing alternatives that do not throw
    • Debugging - debugging aids
    "},{"location":"api/basic_json/exception/#version-history","title":"Version history","text":"
    • Added in version 3.0.0.
    "},{"location":"api/basic_json/find/","title":"nlohmann::basic_json::find","text":"
    // (1)\niterator find(const typename object_t::key_type& key);\nconst_iterator find(const typename object_t::key_type& key) const;\n\n// (2)\ntemplate<typename KeyType>\niterator find(KeyType&& key);\ntemplate<typename KeyType>\nconst_iterator find(KeyType&& key) const;\n\n// (3)\ntemplate<typename T>\niterator find(T) = delete;\ntemplate<typename T>\nconst_iterator find(T) const = delete;\n
    1. Finds an element in a JSON object with a key equivalent to key. If the element is not found or the JSON value is not an object, end() is returned.
    2. See 1. This overload is only available if KeyType is comparable with typename object_t::key_type and typename object_comparator_t::is_transparent denotes a type.
    3. Deleted: this overload is only available if T is an integral type and is declared as deleted, so that a call with an integer key (for example, j.find(0)) fails to compile. Otherwise, the integer literal 0 would convert to a null const char* and, from there, to the key type, causing undefined behavior at runtime.
    "},{"location":"api/basic_json/find/#template-parameters","title":"Template parameters","text":"KeyType A type for an object key other than json_pointer that is comparable with string_t using object_comparator_t. This can also be a string view (C++17)."},{"location":"api/basic_json/find/#parameters","title":"Parameters","text":"key (in) key value of the element to search for."},{"location":"api/basic_json/find/#return-value","title":"Return value","text":"

    Iterator to an element with a key equivalent to key. If no such element is found or the JSON value is not an object, a past-the-end iterator (see end()) is returned.

    "},{"location":"api/basic_json/find/#exception-safety","title":"Exception safety","text":"

    Strong exception safety: if an exception occurs, the original value stays intact.

    "},{"location":"api/basic_json/find/#complexity","title":"Complexity","text":"

    Logarithmic in the size of the JSON object.

    "},{"location":"api/basic_json/find/#notes","title":"Notes","text":"
    • 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, find(0)) does not compile: such an argument would otherwise implicitly convert to a null const char* and, from there, cause undefined behavior when constructing a std::string for the object key. To access an array element instead, use at, operator[], or compare against size.
    "},{"location":"api/basic_json/find/#examples","title":"Examples","text":"Example: (1) find object element by key

    The example shows how find() is used.

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create a JSON object\n    json j_object = {{\"one\", 1}, {\"two\", 2}};\n\n    // call find\n    auto it_two = j_object.find(\"two\");\n    auto it_three = j_object.find(\"three\");\n\n    // print values\n    std::cout << std::boolalpha;\n    std::cout << \"\\\"two\\\" was found: \" << (it_two != j_object.end()) << '\\n';\n    std::cout << \"value at key \\\"two\\\": \" << *it_two << '\\n';\n    std::cout << \"\\\"three\\\" was found: \" << (it_three != j_object.end()) << '\\n';\n}\n

    Output:

    \"two\" was found: true\nvalue at key \"two\": 2\n\"three\" was found: false\n
    Example: (2) find object element by key using string_view

    The example shows how find() is used.

    #include <iostream>\n#include <string_view>\n#include <nlohmann/json.hpp>\n\nusing namespace std::string_view_literals;\nusing nlohmann::json;\n\nint main()\n{\n    // create a JSON object\n    json j_object = {{\"one\", 1}, {\"two\", 2}};\n\n    // call find\n    auto it_two = j_object.find(\"two\"sv);\n    auto it_three = j_object.find(\"three\"sv);\n\n    // print values\n    std::cout << std::boolalpha;\n    std::cout << \"\\\"two\\\" was found: \" << (it_two != j_object.end()) << '\\n';\n    std::cout << \"value at key \\\"two\\\": \" << *it_two << '\\n';\n    std::cout << \"\\\"three\\\" was found: \" << (it_three != j_object.end()) << '\\n';\n}\n

    Output:

    \"two\" was found: true\nvalue at key \"two\": 2\n\"three\" was found: false\n
    "},{"location":"api/basic_json/find/#see-also","title":"See also","text":"
    • count - returns the number of occurrences of a key
    • contains - checks whether a key exists
    • basic_json_view::find - the same lookup on a zero-copy view (a duplicate key resolves to the first member, whereas parse() keeps the last)
    • Element Access - how to test whether a key exists
    "},{"location":"api/basic_json/find/#version-history","title":"Version history","text":"
    1. Added in version 3.11.0.
    2. Added in version 1.0.0. Changed to support comparable types in version 3.11.0. Support for keys convertible to std::string_view added in version 3.13.0 unreleased, consistently across the lookup functions.
    3. Deleted overloads for integral key types added in version 3.13.0 unreleased to reject such calls at compile time instead of causing undefined behavior at runtime.
    "},{"location":"api/basic_json/flatten/","title":"nlohmann::basic_json::flatten","text":"
    basic_json flatten() const;\n

    The function creates a JSON object whose keys are JSON pointers (see RFC 6901) and whose values are all primitive (see is_primitive() for more information). The original JSON value can be restored using the unflatten() function.

    "},{"location":"api/basic_json/flatten/#return-value","title":"Return value","text":"

    an object that maps JSON pointers to primitive values

    "},{"location":"api/basic_json/flatten/#exception-safety","title":"Exception safety","text":"

    Strong exception safety: if an exception occurs, the original value stays intact.

    "},{"location":"api/basic_json/flatten/#complexity","title":"Complexity","text":"

    Linear in the size of the JSON value.

    "},{"location":"api/basic_json/flatten/#notes","title":"Notes","text":"

    Empty objects and arrays are flattened to null and will not be reconstructed correctly by the unflatten() function.

    "},{"location":"api/basic_json/flatten/#examples","title":"Examples","text":"Example: flatten a JSON object

    The following code shows how a JSON object is flattened to an object whose keys consist of JSON pointers.

    #include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create JSON value\n    json j =\n    {\n        {\"pi\", 3.141},\n        {\"happy\", true},\n        {\"name\", \"Niels\"},\n        {\"nothing\", nullptr},\n        {\n            \"answer\", {\n                {\"everything\", 42}\n            }\n        },\n        {\"list\", {1, 0, 2}},\n        {\n            \"object\", {\n                {\"currency\", \"USD\"},\n                {\"value\", 42.99}\n            }\n        }\n    };\n\n    // call flatten()\n    std::cout << std::setw(4) << j.flatten() << '\\n';\n}\n

    Output:

    {\n    \"/answer/everything\": 42,\n    \"/happy\": true,\n    \"/list/0\": 1,\n    \"/list/1\": 0,\n    \"/list/2\": 2,\n    \"/name\": \"Niels\",\n    \"/nothing\": null,\n    \"/object/currency\": \"USD\",\n    \"/object/value\": 42.99,\n    \"/pi\": 3.141\n}\n
    Example: empty objects and arrays are flattened to null

    The following code shows that an empty object and an empty array are both flattened to null, and that unflatten() restores them as null rather than as empty containers.

    #include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create a JSON value with an empty object and an empty array\n    json j =\n    {\n        {\"empty_object\", json::object()},\n        {\"empty_array\", json::array()},\n        {\"name\", \"Niels\"}\n    };\n\n    // call flatten()\n    json flattened = j.flatten();\n    std::cout << std::setw(4) << flattened << \"\\n\\n\";\n\n    // the empty containers cannot be restored by unflatten()\n    std::cout << std::setw(4) << flattened.unflatten() << '\\n';\n}\n

    Output:

    {\n    \"/empty_array\": null,\n    \"/empty_object\": null,\n    \"/name\": \"Niels\"\n}\n\n{\n    \"empty_array\": null,\n    \"empty_object\": null,\n    \"name\": \"Niels\"\n}\n
    "},{"location":"api/basic_json/flatten/#see-also","title":"See also","text":"
    • unflatten - the reverse function
    • JSON Pointer - the article on JSON Pointer and flattening
    "},{"location":"api/basic_json/flatten/#version-history","title":"Version history","text":"
    • Added in version 2.0.0.
    "},{"location":"api/basic_json/format_as/","title":"format_as(basic_json)","text":"
    template <typename BasicJsonType>\nstd::string format_as(const BasicJsonType& j);\n

    This function implements the format_as customization point used by the {fmt} library (fmtlib). It has no dependency on any fmt header and no effect at all unless a caller's translation unit also includes fmt and calls fmt::format/fmt::print on a JSON value.

    "},{"location":"api/basic_json/format_as/#template-parameters","title":"Template parameters","text":"BasicJsonType a specialization of basic_json"},{"location":"api/basic_json/format_as/#return-value","title":"Return value","text":"

    string containing the serialization of the JSON value (same as dump())

    "},{"location":"api/basic_json/format_as/#exception-safety","title":"Exception safety","text":"

    Strong guarantee: if an exception is thrown, there are no changes to any JSON value.

    "},{"location":"api/basic_json/format_as/#exceptions","title":"Exceptions","text":"

    Throws type_error.316 if a string stored inside the JSON value is not UTF-8 encoded

    "},{"location":"api/basic_json/format_as/#complexity","title":"Complexity","text":"

    Linear.

    "},{"location":"api/basic_json/format_as/#possible-implementation","title":"Possible implementation","text":"
    template <typename BasicJsonType>\nstd::string format_as(const BasicJsonType& j)\n{\n    return j.dump();\n}\n
    "},{"location":"api/basic_json/format_as/#notes","title":"Notes","text":"

    Version-dependent effect on fmt

    fmt only picks up a format_as overload that returns a std::string in fmt 10.0.0 through 11.0.2. Starting with fmt 11.1.0, fmt restricts automatic format_as pickup to overloads that return an arithmetic type, so this function has no effect there (it is simply unused, not a compile error).

    If you use fmt >= 11.1.0, or want the same pretty-print spec support that std::formatter<basic_json> has (\"{:#}\", a width to set the indent such as \"{:2}\"/\"{:#2}\", and fill-and-align to pick the indent character such as \"{:.>#}\"), define your own fmt::formatter specialization mirroring the same logic:

    template <>\nstruct fmt::formatter<nlohmann::json>\n{\n    // -1 means compact output (dump()); any value >= 0 means pretty-printed\n    // output with that many spaces (or indent_char) per level.\n    int indent = -1;\n    char indent_char = ' ';\n\n    constexpr auto parse(format_parse_context& ctx) -> format_parse_context::iterator\n    {\n        auto it = ctx.begin();\n        const auto end = ctx.end();\n        constexpr auto is_align = [](char c)\n        {\n            return c == '<' || c == '>' || c == '^';\n        };\n\n        // [[fill] align] - repurposed here to pick a custom indent character\n        if (it != end && it + 1 != end && is_align(it[1]))\n        {\n            indent_char = *it;\n            it += 2;\n        }\n        else if (it != end && is_align(*it))\n        {\n            ++it;\n        }\n\n        // ['#'] - \"alternate form\", used here to request pretty-printing with a\n        // default indent of 4 (overridden by an explicit width below, if given)\n        if (it != end && *it == '#')\n        {\n            indent = 4;\n            ++it;\n        }\n\n        // [width] - repurposed here to pick the indent size; a width without '#'\n        // implies pretty-printing since an indent otherwise has no meaning\n        if (it != end && *it >= '1' && *it <= '9')\n        {\n            indent = 0;\n            while (it != end && *it >= '0' && *it <= '9')\n            {\n                indent = (indent * 10) + (*it - '0');\n                ++it;\n            }\n        }\n\n        if (it != end && *it != '}')\n        {\n            throw fmt::format_error(\"invalid format args for nlohmann::json\");\n        }\n\n        return it;\n    }\n\n    auto format(const nlohmann::json& j, format_context& ctx) const\n    {\n        const auto dumped = j.dump(indent, indent_char);\n        return fmt::format_to(ctx.out(), \"{}\", dumped);\n    }\n};\n

    This recipe isn't shipped by the library itself, since doing so would make fmt a build dependency (see the FAQ entry on using JSON values with std::format or fmt for more background) \u2014 but it is compiled and exercised against a real, current fmt release as part of the library's own test suite (tests/fmt_formatter, via CMake FetchContent), so it's kept in sync with std::formatter<basic_json> and verified to actually work, not just illustrative.

    "},{"location":"api/basic_json/format_as/#examples","title":"Examples","text":"Example

    The following code shows how the library's format_as() function integrates with fmt::format, allowing argument-dependent lookup.

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create a JSON value\n    json j = {{\"one\", 1}, {\"two\", 2}};\n\n    // format_as() is found via argument-dependent lookup, the same way\n    // fmt::format/fmt::print would find it\n    auto j_str = format_as(j);\n\n    std::cout << j_str << '\\n';\n}\n

    Output:

    {\"one\":1,\"two\":2}\n
    "},{"location":"api/basic_json/format_as/#see-also","title":"See also","text":"
    • dump - serialize a JSON value to a string
    • std::formatter<basic_json> - the std::format (C++20) equivalent
    • Serialization - the serialization article
    "},{"location":"api/basic_json/format_as/#version-history","title":"Version history","text":"
    • Added in version 3.13.0 unreleased.
    "},{"location":"api/basic_json/from_bjdata/","title":"nlohmann::basic_json::from_bjdata","text":"
    // (1)\ntemplate<typename InputType>\nstatic basic_json from_bjdata(InputType&& i,\n                              const bool strict = true,\n                              const bool allow_exceptions = true,\n                              const error_handler_t error_handler = error_handler_t::keep);\n// (2)\ntemplate<typename IteratorType, typename SentinelType = IteratorType>\nstatic basic_json from_bjdata(IteratorType first, SentinelType last,\n                              const bool strict = true,\n                              const bool allow_exceptions = true,\n                              const error_handler_t error_handler = error_handler_t::keep);\n

    Deserializes a given input to a JSON value using the BJData (Binary JData) serialization format.

    1. Reads from a compatible input.
    2. Reads from an iterator range, or an iterator and a sentinel of a different type (C++20 ranges support).

    The exact mapping and its limitations are described on a dedicated page.

    "},{"location":"api/basic_json/from_bjdata/#template-parameters","title":"Template parameters","text":"InputType

    A compatible input, for instance:

    • an std::istream object
    • a FILE pointer
    • a C-style array of characters
    • a pointer to a null-terminated string of single byte characters
    • a container obj for which begin(obj) and end(obj) produce a valid pair of iterators (as found via ADL or member functions, with semantics compatible to std::begin and std::end)
    IteratorType a compatible iterator type SentinelType

    defaults to IteratorType; may be a different type comparable to IteratorType via operator!=, for instance.

    • a custom sentinel type for C++20 ranges
    • std::default_sentinel_t, when IteratorType is std::counted_iterator
    "},{"location":"api/basic_json/from_bjdata/#parameters","title":"Parameters","text":"i (in) an input in BJData format convertible to an input adapter first (in) iterator to the start of the input last (in) iterator to the end of the input, or a sentinel value that compares equal to the end iterator with operator!= strict (in) whether to expect the input to be consumed until EOF (true by default) allow_exceptions (in) whether to throw exceptions in case of a parse error (optional, true by default) error_handler (in) how to treat a string value or object key that is not valid UTF-8; see error_handler_t. BJData does not require a decoder to reject ill-formed UTF-8, so checking is opt-in: the default, keep, does not check at all, as every binary reader did before this parameter was added; strict checks and throws; replace/ignore sanitize the string the same way dump would"},{"location":"api/basic_json/from_bjdata/#return-value","title":"Return value","text":"

    deserialized JSON value; in case of a parse error and allow_exceptions set to false, the return value will be value_t::discarded. The latter can be checked with is_discarded.

    "},{"location":"api/basic_json/from_bjdata/#exception-safety","title":"Exception safety","text":"

    Strong guarantee: if an exception is thrown, there are no changes in the JSON value.

    "},{"location":"api/basic_json/from_bjdata/#exceptions","title":"Exceptions","text":"
    • Throws parse_error.110 if the given input ends prematurely or the end of the file was not reached when strict was set to true
    • Throws parse_error.112 if a parse error occurs
    • Throws parse_error.113 if a string could not be parsed successfully, or if a string value or object key is not valid UTF-8 and error_handler is strict
    • Throws parse_error.115 if the text of a high-precision number (H) is not a valid number
    • Throws out_of_range.408 if the size of an optimized container cannot be represented by std::size_t or exceeds the container's max_size(), or if the product of the dimensions of an n-dimensional array overflows
    "},{"location":"api/basic_json/from_bjdata/#complexity","title":"Complexity","text":"

    Linear in the size of the input.

    "},{"location":"api/basic_json/from_bjdata/#examples","title":"Examples","text":"Example

    The example shows the deserialization of a byte vector in BJData format to a JSON value.

    #include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create byte vector\n    std::vector<std::uint8_t> v = {0x7B, 0x69, 0x07, 0x63, 0x6F, 0x6D, 0x70, 0x61,\n                                   0x63, 0x74, 0x54, 0x69, 0x06, 0x73, 0x63, 0x68,\n                                   0x65, 0x6D, 0x61, 0x69, 0x00, 0x7D\n                                  };\n\n    // deserialize it with BJData\n    json j = json::from_bjdata(v);\n\n    // print the deserialized JSON value\n    std::cout << std::setw(2) << j << '\\n';\n}\n

    Output:

    {\n  \"compact\": true,\n  \"schema\": 0\n}\n
    "},{"location":"api/basic_json/from_bjdata/#see-also","title":"See also","text":"
    • BJData - the format, its byte layout and how values are mapped
    • Binary formats - overview and comparison of the supported binary formats
    • Parsing untrusted input - limits and safe handling of hostile data
    • Binary values - how binary values and subtypes are handled
    • to_bjdata - create a BJData serialization of a JSON value
    • from_cbor - create a JSON value from an input in CBOR format
    • from_msgpack - create a JSON value from an input in MessagePack format
    • from_bson - create a JSON value from an input in BSON format
    • from_ubjson - create a JSON value from an input in UBJSON format
    • from_bon8 - create a JSON value from an input in BON8 format
    "},{"location":"api/basic_json/from_bjdata/#version-history","title":"Version history","text":"
    • Added in version 3.11.0.
    • Extended container support (1) to include types with lvalue-only ADL begin/end (matching std::begin/std::end semantics) in version 3.13.0 unreleased.
    • Extended overload (2) to accept heterogeneous iterator+sentinel pairs (C++20 ranges support) in version 3.13.0 unreleased.
    • Added error_handler parameter in version 3.13.0 unreleased.

    Deprecation

    • Overload (2) replaces calls to from_bjdata with a pointer and a length as first two parameters, which has been deprecated in version 3.13.0 unreleased. In version 4.0.0 unreleased, this overload will be deleted (= delete) rather than removed. Please replace all calls like from_bjdata(ptr, len, ...); with from_bjdata(ptr, ptr+len, ...);.

    You should be warned by your compiler with a -Wdeprecated-declarations warning if you are using a deprecated function.

    "},{"location":"api/basic_json/from_bon8/","title":"nlohmann::basic_json::from_bon8","text":"
    // (1)\ntemplate<typename InputType>\nstatic basic_json from_bon8(InputType&& i,\n                            const bool strict = true,\n                            const bool allow_exceptions = true);\n// (2)\ntemplate<typename IteratorType, typename SentinelType = IteratorType>\nstatic basic_json from_bon8(IteratorType first, SentinelType last,\n                            const bool strict = true,\n                            const bool allow_exceptions = true);\n

    Deserializes a given input to a JSON value using the BON8 (Binary Object Notation 8) serialization format.

    1. Reads from a compatible input.
    2. Reads from an iterator range, or an iterator and a sentinel of a different type (C++20 ranges support).

    The exact mapping and its limitations are described on a dedicated page.

    "},{"location":"api/basic_json/from_bon8/#template-parameters","title":"Template parameters","text":"InputType

    A compatible input, for instance:

    • an std::istream object
    • a FILE pointer
    • a C-style array of characters
    • a pointer to a null-terminated string of single byte characters
    • a container obj for which begin(obj) and end(obj) produce a valid pair of iterators (as found via ADL or member functions, with semantics compatible to std::begin and std::end)
    IteratorType a compatible iterator type SentinelType

    defaults to IteratorType; may be a different type comparable to IteratorType via operator!=, for instance.

    • a custom sentinel type for C++20 ranges
    • std::default_sentinel_t, when IteratorType is std::counted_iterator
    "},{"location":"api/basic_json/from_bon8/#parameters","title":"Parameters","text":"i (in) an input in BON8 format convertible to an input adapter first (in) iterator to the start of the input last (in) iterator to the end of the input, or a sentinel value that compares equal to the end iterator with operator!= strict (in) whether to expect the input to be consumed until EOF (true by default) allow_exceptions (in) whether to throw exceptions in case of a parse error (optional, true by default)"},{"location":"api/basic_json/from_bon8/#return-value","title":"Return value","text":"

    deserialized JSON value; in case of a parse error and allow_exceptions set to false, the return value will be value_t::discarded. The latter can be checked with is_discarded.

    "},{"location":"api/basic_json/from_bon8/#exception-safety","title":"Exception safety","text":"

    Strong guarantee: if an exception is thrown, there are no changes in the JSON value.

    "},{"location":"api/basic_json/from_bon8/#exceptions","title":"Exceptions","text":"
    • Throws parse_error.110 if the given input ends prematurely or the end of the file was not reached when strict was set to true
    • Throws parse_error.112 if a parse error occurs, for instance an invalid byte, a string that is not valid UTF-8, or an object key that is not a string

    The UTF-8 validity of strings is always checked, independent of JSON_STRICT_BINARY_UTF8, because the end of a BON8 string is determined from its encoding. Duplicate object keys are accepted; the last value wins (see BON8).

    "},{"location":"api/basic_json/from_bon8/#complexity","title":"Complexity","text":"

    Linear in the size of the input.

    "},{"location":"api/basic_json/from_bon8/#examples","title":"Examples","text":"Example

    The example shows the deserialization of a byte vector in BON8 format to a JSON value.

    #include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create byte vector\n    std::vector<std::uint8_t> v = {0x89, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x63, 0x74,\n                                   0xf9, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0xff,\n                                   0x42, 0x4f, 0x4e, 0x38, 0xff, 0x73, 0x63, 0x68,\n                                   0x65, 0x6d, 0x61, 0x90\n                                  };\n\n    // deserialize it with BON8\n    json j = json::from_bon8(v);\n\n    // print the deserialized JSON value\n    std::cout << std::setw(2) << j << '\\n';\n}\n

    Output:

    {\n  \"compact\": true,\n  \"format\": \"BON8\",\n  \"schema\": 0\n}\n
    "},{"location":"api/basic_json/from_bon8/#see-also","title":"See also","text":"
    • BON8 - the format, its byte layout and how values are mapped
    • Binary formats - overview and comparison of the supported binary formats
    • Parsing untrusted input - limits and safe handling of hostile data
    • to_bon8 - create a BON8 serialization of a JSON value
    • from_cbor - create a JSON value from an input in CBOR format
    • from_msgpack - create a JSON value from an input in MessagePack format
    • from_bson - create a JSON value from an input in BSON format
    • from_ubjson - create a JSON value from an input in UBJSON format
    • from_bjdata - create a JSON value from an input in BJData format
    "},{"location":"api/basic_json/from_bon8/#version-history","title":"Version history","text":"
    • Added in version 3.13.0 unreleased.

    Deprecation

    • Overload (2) replaces calls to from_bon8 with a pointer and a length as first two parameters, which has been deprecated in version 3.13.0 unreleased. In version 4.0.0 unreleased, this overload will be deleted (= delete) rather than removed. Please replace all calls like from_bon8(ptr, len, ...); with from_bon8(ptr, ptr+len, ...);.

    You should be warned by your compiler with a -Wdeprecated-declarations warning if you are using a deprecated function.

    "},{"location":"api/basic_json/from_bson/","title":"nlohmann::basic_json::from_bson","text":"
    // (1)\ntemplate<typename InputType>\nstatic basic_json from_bson(InputType&& i,\n                            const bool strict = true,\n                            const bool allow_exceptions = true,\n                            const error_handler_t error_handler = error_handler_t::keep);\n// (2)\ntemplate<typename IteratorType, typename SentinelType = IteratorType>\nstatic basic_json from_bson(IteratorType first, SentinelType last,\n                            const bool strict = true,\n                            const bool allow_exceptions = true,\n                            const error_handler_t error_handler = error_handler_t::keep);\n

    Deserializes a given input to a JSON value using the BSON (Binary JSON) serialization format.

    1. Reads from a compatible input.
    2. Reads from an iterator range, or an iterator and a sentinel of a different type (C++20 ranges support).

    The exact mapping and its limitations are described on a dedicated page.

    "},{"location":"api/basic_json/from_bson/#template-parameters","title":"Template parameters","text":"InputType

    A compatible input, for instance:

    • an std::istream object
    • a FILE pointer
    • a C-style array of characters
    • a pointer to a null-terminated string of single byte characters
    • a container obj for which begin(obj) and end(obj) produce a valid pair of iterators (as found via ADL or member functions, with semantics compatible to std::begin and std::end)
    IteratorType a compatible iterator type SentinelType

    defaults to IteratorType; may be a different type comparable to IteratorType via operator!=, for instance.

    • a custom sentinel type for C++20 ranges
    • std::default_sentinel_t, when IteratorType is std::counted_iterator
    "},{"location":"api/basic_json/from_bson/#parameters","title":"Parameters","text":"i (in) an input in BSON format convertible to an input adapter first (in) iterator to the start of the input last (in) iterator to the end of the input, or a sentinel value that compares equal to the end iterator with operator!= strict (in) whether to expect the input to be consumed until EOF (true by default) allow_exceptions (in) whether to throw exceptions in case of a parse error (optional, true by default) error_handler (in) how to treat a string value or object key that is not valid UTF-8; see error_handler_t. BSON does not require a decoder to reject ill-formed UTF-8, so checking is opt-in: the default, keep, does not check at all, as every binary reader did before this parameter was added; strict checks and throws; replace/ignore sanitize the string the same way dump would"},{"location":"api/basic_json/from_bson/#return-value","title":"Return value","text":"

    deserialized JSON value; in case of a parse error and allow_exceptions set to false, the return value will be value_t::discarded. The latter can be checked with is_discarded.

    "},{"location":"api/basic_json/from_bson/#exception-safety","title":"Exception safety","text":"

    Strong guarantee: if an exception is thrown, there are no changes in the JSON value.

    "},{"location":"api/basic_json/from_bson/#exceptions","title":"Exceptions","text":"
    • Throws parse_error.110 if the given input ends prematurely or the end of the input was not reached when strict was set to true
    • Throws parse_error.112 if a parse error occurs (e.g., an invalid string or byte array length, an invalid inner length of a binary value with subtype 0x02, or a document size that does not match the content; strict does not affect the document size checks)
    • Throws parse_error.114 if an unsupported BSON record type is encountered
    • Throws parse_error.113 if a string value or object key is not valid UTF-8 and error_handler is strict
    "},{"location":"api/basic_json/from_bson/#complexity","title":"Complexity","text":"

    Linear in the size of the input.

    "},{"location":"api/basic_json/from_bson/#examples","title":"Examples","text":"Example

    The example shows the deserialization of a byte vector in BSON format to a JSON value.

    #include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create byte vector\n    std::vector<std::uint8_t> v = {0x1b, 0x00, 0x00, 0x00, 0x08, 0x63, 0x6f, 0x6d,\n                                   0x70, 0x61, 0x63, 0x74, 0x00, 0x01, 0x10, 0x73,\n                                   0x63, 0x68, 0x65, 0x6d, 0x61, 0x00, 0x00, 0x00,\n                                   0x00, 0x00, 0x00\n                                  };\n\n    // deserialize it with BSON\n    json j = json::from_bson(v);\n\n    // print the deserialized JSON value\n    std::cout << std::setw(2) << j << '\\n';\n}\n

    Output:

    {\n  \"compact\": true,\n  \"schema\": 0\n}\n
    "},{"location":"api/basic_json/from_bson/#see-also","title":"See also","text":"
    • BSON - the format, its byte layout and how values are mapped
    • Binary formats - overview and comparison of the supported binary formats
    • Parsing untrusted input - limits and safe handling of hostile data
    • Binary values - how binary values and subtypes are handled
    • BSON specification - specification of the BSON format
    • to_bson - the analogous serialization
    • from_cbor - the related CBOR format
    • from_msgpack - the related MessagePack format
    • from_ubjson - the related UBJSON format
    • from_bjdata - the related BJData format
    • from_bon8 - the related BON8 format
    "},{"location":"api/basic_json/from_bson/#version-history","title":"Version history","text":"
    • Added in version 3.4.0.
    • Extended container support (1) to include types with lvalue-only ADL begin/end (matching std::begin/std::end semantics) in version 3.13.0 unreleased.
    • Extended overload (2) to accept heterogeneous iterator+sentinel pairs (C++20 ranges support) in version 3.13.0 unreleased.
    • Added error_handler parameter in version 3.13.0 unreleased.

    Deprecation

    • Overload (2) replaces calls to from_bson with a pointer and a length as first two parameters, which has been deprecated in version 3.8.0. In version 4.0.0 unreleased, this overload will be deleted (= delete) rather than removed. Please replace all calls like from_bson(ptr, len, ...); with from_bson(ptr, ptr+len, ...);.
    • Overload (2) replaces calls to from_bson with a pair of iterators as their first parameter, which has been deprecated in version 3.8.0. This overload will be removed in version 4.0.0. Please replace all calls like from_bson({ptr, ptr+len}, ...); with from_bson(ptr, ptr+len, ...);.

    You should be warned by your compiler with a -Wdeprecated-declarations warning if you are using a deprecated function.

    See the migration guide for how to update existing code.

    "},{"location":"api/basic_json/from_cbor/","title":"nlohmann::basic_json::from_cbor","text":"
    // (1)\ntemplate<typename InputType>\nstatic basic_json from_cbor(InputType&& i,\n                            const bool strict = true,\n                            const bool allow_exceptions = true,\n                            const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error,\n                            const error_handler_t error_handler = error_handler_t::keep);\n\n// (2)\ntemplate<typename IteratorType, typename SentinelType = IteratorType>\nstatic basic_json from_cbor(IteratorType first, SentinelType last,\n                            const bool strict = true,\n                            const bool allow_exceptions = true,\n                            const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error,\n                            const error_handler_t error_handler = error_handler_t::keep);\n

    Deserializes a given input to a JSON value using the CBOR (Concise Binary Object Representation) serialization format.

    1. Reads from a compatible input.
    2. Reads from an iterator range, or an iterator and a sentinel of a different type (C++20 ranges support).

    The exact mapping and its limitations are described on a dedicated page.

    "},{"location":"api/basic_json/from_cbor/#template-parameters","title":"Template parameters","text":"InputType

    A compatible input, for instance:

    • an std::istream object
    • a FILE pointer
    • a C-style array of characters (its terminating NUL is read as trailing data: parse_error.110 unless strict is false)
    • a pointer to a null-terminated string of single byte characters (read up to the first 0x00 byte, which is a valid CBOR byte)
    • a container obj for which begin(obj) and end(obj) produce a valid pair of iterators (as found via ADL or member functions, with semantics compatible to std::begin and std::end)
    IteratorType a compatible iterator type SentinelType

    defaults to IteratorType; may be a different type comparable to IteratorType via operator!=, for instance.

    • a custom sentinel type for C++20 ranges
    • std::default_sentinel_t, when IteratorType is std::counted_iterator
    "},{"location":"api/basic_json/from_cbor/#parameters","title":"Parameters","text":"i (in) an input in CBOR format convertible to an input adapter first (in) iterator to the start of the input last (in) iterator to the end of the input, or a sentinel value that compares equal to the end iterator with operator!= strict (in) whether to expect the input to be consumed until EOF (true by default) allow_exceptions (in) whether to throw exceptions in case of a parse error (optional, true by default) tag_handler (in) how to treat CBOR tags (optional, error by default); see cbor_tag_handler_t for more information error_handler (in) how to treat a string value or object key that is not valid UTF-8; see error_handler_t. CBOR does not require a decoder to reject ill-formed UTF-8, so checking is opt-in: the default, keep, does not check at all, as every binary reader did before this parameter was added; strict checks and throws; replace/ignore sanitize the string the same way dump would"},{"location":"api/basic_json/from_cbor/#return-value","title":"Return value","text":"

    deserialized JSON value; in case of a parse error and allow_exceptions set to false, the return value will be value_t::discarded. The latter can be checked with is_discarded.

    "},{"location":"api/basic_json/from_cbor/#exception-safety","title":"Exception safety","text":"

    Strong guarantee: if an exception is thrown, there are no changes in the JSON value.

    "},{"location":"api/basic_json/from_cbor/#exceptions","title":"Exceptions","text":"
    • Throws parse_error.110 if the given input ends prematurely or the end of the file was not reached when strict was set to true
    • Throws parse_error.112 if unsupported features from CBOR were used in the given input or if the input is not valid CBOR
    • Throws parse_error.113 if a map key is not a string (keys of other types are not supported, as JSON object keys are always strings), if the head of a string or byte string is malformed (including a chunk of the wrong type or an indefinite-length string nested inside an indefinite-length string), or if a string value or object key (or one chunk of an indefinite-length string) is not valid UTF-8 and error_handler is strict
    • Throws out_of_range.408 if an array or map announces a length that std::size_t cannot hold, or that equals std::size_t(-1) (for example 9B FF FF FF FF FF FF FF FF)
    • Throws out_of_range.406 if a floating-point number does not fit into number_float_t
    "},{"location":"api/basic_json/from_cbor/#complexity","title":"Complexity","text":"

    Linear in the size of the input.

    "},{"location":"api/basic_json/from_cbor/#examples","title":"Examples","text":"Example

    The example shows the deserialization of a byte vector in CBOR format to a JSON value.

    #include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create byte vector\n    std::vector<std::uint8_t> v = {0xa2, 0x67, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x63,\n                                   0x74, 0xf5, 0x66, 0x73, 0x63, 0x68, 0x65, 0x6d,\n                                   0x61, 0x00\n                                  };\n\n    // deserialize it with CBOR\n    json j = json::from_cbor(v);\n\n    // print the deserialized JSON value\n    std::cout << std::setw(2) << j << '\\n';\n}\n

    Output:

    {\n  \"compact\": true,\n  \"schema\": 0\n}\n
    "},{"location":"api/basic_json/from_cbor/#see-also","title":"See also","text":"
    • CBOR - the format, its byte layout and how values are mapped
    • Binary formats - overview and comparison of the supported binary formats
    • Parsing untrusted input - limits and safe handling of hostile data
    • Binary values - how binary values and subtypes are handled
    • to_cbor - create a CBOR serialization of a JSON value
    • from_msgpack - create a JSON value from an input in MessagePack format
    • from_bson - create a JSON value from an input in BSON format
    • from_ubjson - create a JSON value from an input in UBJSON format
    • from_bjdata - create a JSON value from an input in BJData format
    • from_bon8 - create a JSON value from an input in BON8 format
    "},{"location":"api/basic_json/from_cbor/#version-history","title":"Version history","text":"
    • Added in version 2.0.9.
    • Parameter start_index since version 2.1.1.
    • Changed to consume input adapters, removed start_index parameter, and added strict parameter in version 3.0.0.
    • Added allow_exceptions parameter in version 3.2.0.
    • Added tag_handler parameter in version 3.9.0.
    • Extended container support (1) to include types with lvalue-only ADL begin/end (matching std::begin/std::end semantics) in version 3.13.0 unreleased.
    • Extended overload (2) to accept heterogeneous iterator+sentinel pairs (C++20 ranges support) in version 3.13.0 unreleased.
    • Added error_handler parameter in version 3.13.0 unreleased.

    Deprecation

    • Overload (2) replaces calls to from_cbor with a pointer and a length as first two parameters, which has been deprecated in version 3.8.0. In version 4.0.0 unreleased, this overload will be deleted (= delete) rather than removed. Please replace all calls like from_cbor(ptr, len, ...); with from_cbor(ptr, ptr+len, ...);.
    • Overload (2) replaces calls to from_cbor with a pair of iterators as their first parameter, which has been deprecated in version 3.8.0. This overload will be removed in version 4.0.0. Please replace all calls like from_cbor({ptr, ptr+len}, ...); with from_cbor(ptr, ptr+len, ...);.

    You should be warned by your compiler with a -Wdeprecated-declarations warning if you are using a deprecated function.

    See the migration guide for how to update existing code.

    "},{"location":"api/basic_json/from_msgpack/","title":"nlohmann::basic_json::from_msgpack","text":"
    // (1)\ntemplate<typename InputType>\nstatic basic_json from_msgpack(InputType&& i,\n                               const bool strict = true,\n                               const bool allow_exceptions = true,\n                               const error_handler_t error_handler = error_handler_t::keep);\n// (2)\ntemplate<typename IteratorType, typename SentinelType = IteratorType>\nstatic basic_json from_msgpack(IteratorType first, SentinelType last,\n                               const bool strict = true,\n                               const bool allow_exceptions = true,\n                               const error_handler_t error_handler = error_handler_t::keep);\n

    Deserializes a given input to a JSON value using the MessagePack serialization format.

    1. Reads from a compatible input.
    2. Reads from an iterator range, or an iterator and a sentinel of a different type (C++20 ranges support).

    The exact mapping and its limitations are described on a dedicated page.

    "},{"location":"api/basic_json/from_msgpack/#template-parameters","title":"Template parameters","text":"InputType

    A compatible input, for instance:

    • an std::istream object
    • a FILE pointer
    • a C-style array of characters
    • a pointer to a null-terminated string of single byte characters
    • a container obj for which begin(obj) and end(obj) produce a valid pair of iterators (as found via ADL or member functions, with semantics compatible to std::begin and std::end)
    IteratorType a compatible iterator type SentinelType

    defaults to IteratorType; may be a different type comparable to IteratorType via operator!=, for instance.

    • a custom sentinel type for C++20 ranges
    • std::default_sentinel_t, when IteratorType is std::counted_iterator
    "},{"location":"api/basic_json/from_msgpack/#parameters","title":"Parameters","text":"i (in) an input in MessagePack format convertible to an input adapter first (in) iterator to the start of the input last (in) iterator to the end of the input, or a sentinel value that compares equal to the end iterator with operator!= strict (in) whether to expect the input to be consumed until EOF (true by default) allow_exceptions (in) whether to throw exceptions in case of a parse error (optional, true by default) error_handler (in) how to treat a string value or object key that is not valid UTF-8; see error_handler_t. MessagePack's specification explicitly allows ill-formed UTF-8, so checking is opt-in: the default, keep, does not check at all, as every binary reader did before this parameter was added; strict checks and throws; replace/ignore sanitize the string the same way dump would"},{"location":"api/basic_json/from_msgpack/#return-value","title":"Return value","text":"

    deserialized JSON value; in case of a parse error and allow_exceptions set to false, the return value will be value_t::discarded. The latter can be checked with is_discarded.

    "},{"location":"api/basic_json/from_msgpack/#exception-safety","title":"Exception safety","text":"

    Strong guarantee: if an exception is thrown, there are no changes in the JSON value.

    "},{"location":"api/basic_json/from_msgpack/#exceptions","title":"Exceptions","text":"
    • Throws parse_error.110 if the given input ends prematurely or the end of the file was not reached when strict was set to true
    • Throws parse_error.112 if unsupported features from MessagePack were used in the given input or if the input is not valid MessagePack
    • Throws parse_error.113 if a map key is not a string (keys of other types are not supported, as JSON object keys are always strings), or if a string value or object key is not valid UTF-8 and error_handler is strict
    "},{"location":"api/basic_json/from_msgpack/#complexity","title":"Complexity","text":"

    Linear in the size of the input.

    "},{"location":"api/basic_json/from_msgpack/#examples","title":"Examples","text":"Example

    The example shows the deserialization of a byte vector in MessagePack format to a JSON value.

    #include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create byte vector\n    std::vector<std::uint8_t> v = {0x82, 0xa7, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x63,\n                                   0x74, 0xc3, 0xa6, 0x73, 0x63, 0x68, 0x65, 0x6d,\n                                   0x61, 0x00\n                                  };\n\n    // deserialize it with MessagePack\n    json j = json::from_msgpack(v);\n\n    // print the deserialized JSON value\n    std::cout << std::setw(2) << j << '\\n';\n}\n

    Output:

    {\n  \"compact\": true,\n  \"schema\": 0\n}\n
    "},{"location":"api/basic_json/from_msgpack/#see-also","title":"See also","text":"
    • MessagePack - the format, its byte layout and how values are mapped
    • Binary formats - overview and comparison of the supported binary formats
    • Parsing untrusted input - limits and safe handling of hostile data
    • Binary values - how binary values and subtypes are handled
    • to_msgpack - create a MessagePack serialization of a JSON value
    • from_cbor - create a JSON value from an input in CBOR format
    • from_bson - create a JSON value from an input in BSON format
    • from_ubjson - create a JSON value from an input in UBJSON format
    • from_bjdata - create a JSON value from an input in BJData format
    • from_bon8 - create a JSON value from an input in BON8 format
    "},{"location":"api/basic_json/from_msgpack/#version-history","title":"Version history","text":"
    • Added in version 2.0.9.
    • Parameter start_index since version 2.1.1.
    • Changed to consume input adapters, removed start_index parameter, and added strict parameter in version 3.0.0.
    • Added allow_exceptions parameter in version 3.2.0.
    • Extended container support (1) to include types with lvalue-only ADL begin/end (matching std::begin/std::end semantics) in version 3.13.0 unreleased.
    • Extended overload (2) to accept heterogeneous iterator+sentinel pairs (C++20 ranges support) in version 3.13.0 unreleased.
    • Added error_handler parameter in version 3.13.0 unreleased.

    Deprecation

    • Overload (2) replaces calls to from_msgpack with a pointer and a length as first two parameters, which has been deprecated in version 3.8.0. In version 4.0.0 unreleased, this overload will be deleted (= delete) rather than removed. Please replace all calls like from_msgpack(ptr, len, ...); with from_msgpack(ptr, ptr+len, ...);.
    • Overload (2) replaces calls to from_msgpack with a pair of iterators as their first parameter, which has been deprecated in version 3.8.0. This overload will be removed in version 4.0.0. Please replace all calls like from_msgpack({ptr, ptr+len}, ...); with from_msgpack(ptr, ptr+len, ...);.

    You should be warned by your compiler with a -Wdeprecated-declarations warning if you are using a deprecated function.

    See the migration guide for how to update existing code.

    "},{"location":"api/basic_json/from_ubjson/","title":"nlohmann::basic_json::from_ubjson","text":"
    // (1)\ntemplate<typename InputType>\nstatic basic_json from_ubjson(InputType&& i,\n                              const bool strict = true,\n                              const bool allow_exceptions = true,\n                              const error_handler_t error_handler = error_handler_t::keep);\n// (2)\ntemplate<typename IteratorType, typename SentinelType = IteratorType>\nstatic basic_json from_ubjson(IteratorType first, SentinelType last,\n                              const bool strict = true,\n                              const bool allow_exceptions = true,\n                              const error_handler_t error_handler = error_handler_t::keep);\n

    Deserializes a given input to a JSON value using the UBJSON (Universal Binary JSON) serialization format.

    1. Reads from a compatible input.
    2. Reads from an iterator range, or an iterator and a sentinel of a different type (C++20 ranges support).

    The exact mapping and its limitations are described on a dedicated page.

    "},{"location":"api/basic_json/from_ubjson/#template-parameters","title":"Template parameters","text":"InputType

    A compatible input, for instance:

    • an std::istream object
    • a FILE pointer
    • a C-style array of characters
    • a pointer to a null-terminated string of single byte characters
    • a container obj for which begin(obj) and end(obj) produce a valid pair of iterators (as found via ADL or member functions, with semantics compatible to std::begin and std::end)
    IteratorType a compatible iterator type SentinelType

    defaults to IteratorType; may be a different type comparable to IteratorType via operator!=, for instance.

    • a custom sentinel type for C++20 ranges
    • std::default_sentinel_t, when IteratorType is std::counted_iterator
    "},{"location":"api/basic_json/from_ubjson/#parameters","title":"Parameters","text":"i (in) an input in UBJSON format convertible to an input adapter first (in) iterator to the start of the input last (in) iterator to the end of the input, or a sentinel value that compares equal to the end iterator with operator!= strict (in) whether to expect the input to be consumed until EOF (true by default) allow_exceptions (in) whether to throw exceptions in case of a parse error (optional, true by default) error_handler (in) how to treat a string value or object key that is not valid UTF-8; see error_handler_t. UBJSON does not require a decoder to reject ill-formed UTF-8, so checking is opt-in: the default, keep, does not check at all, as every binary reader did before this parameter was added; strict checks and throws; replace/ignore sanitize the string the same way dump would"},{"location":"api/basic_json/from_ubjson/#return-value","title":"Return value","text":"

    deserialized JSON value; in case of a parse error and allow_exceptions set to false, the return value will be value_t::discarded. The latter can be checked with is_discarded.

    "},{"location":"api/basic_json/from_ubjson/#exception-safety","title":"Exception safety","text":"

    Strong guarantee: if an exception is thrown, there are no changes in the JSON value.

    "},{"location":"api/basic_json/from_ubjson/#exceptions","title":"Exceptions","text":"
    • Throws parse_error.110 if the given input ends prematurely or the end of the file was not reached when strict was set to true
    • Throws parse_error.112 if an invalid type marker is read (including a type marker after $ of an optimized container, even if its count is 0), or if $ is not followed by #
    • Throws parse_error.113 if a string could not be parsed successfully (negative or non-integer length, C followed by a byte above 0x7F), if the count of an optimized container is negative, or if a string value or object key is not valid UTF-8 and error_handler is strict
    • Throws parse_error.115 if the text of a high-precision number (H) is not a valid JSON number
    • Throws out_of_range.406 if a high-precision number, or a float64 when number_float_t is float, does not fit into number_float_t
    • Throws out_of_range.408 if the count of an optimized container exceeds the capacity of the container (or of std::size_t), or if an optimized array of Z, T, or F has more than 1,048,576 elements
    "},{"location":"api/basic_json/from_ubjson/#complexity","title":"Complexity","text":"

    Linear in the size of the input.

    "},{"location":"api/basic_json/from_ubjson/#examples","title":"Examples","text":"Example

    The example shows the deserialization of a byte vector in UBJSON format to a JSON value.

    #include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create byte vector\n    std::vector<std::uint8_t> v = {0x7B, 0x69, 0x07, 0x63, 0x6F, 0x6D, 0x70, 0x61,\n                                   0x63, 0x74, 0x54, 0x69, 0x06, 0x73, 0x63, 0x68,\n                                   0x65, 0x6D, 0x61, 0x69, 0x00, 0x7D\n                                  };\n\n    // deserialize it with UBJSON\n    json j = json::from_ubjson(v);\n\n    // print the deserialized JSON value\n    std::cout << std::setw(2) << j << '\\n';\n}\n

    Output:

    {\n  \"compact\": true,\n  \"schema\": 0\n}\n
    "},{"location":"api/basic_json/from_ubjson/#see-also","title":"See also","text":"
    • UBJSON - the format, its byte layout and how values are mapped
    • Binary formats - overview and comparison of the supported binary formats
    • Parsing untrusted input - limits and safe handling of hostile data
    • Binary values - how binary values and subtypes are handled
    • to_ubjson - create a UBJSON serialization of a JSON value
    • from_cbor - create a JSON value from an input in CBOR format
    • from_msgpack - create a JSON value from an input in MessagePack format
    • from_bson - create a JSON value from an input in BSON format
    • from_bjdata - create a JSON value from an input in BJData format
    • from_bon8 - create a JSON value from an input in BON8 format
    "},{"location":"api/basic_json/from_ubjson/#version-history","title":"Version history","text":"
    • Added in version 3.1.0.
    • Added allow_exceptions parameter in version 3.2.0.
    • Extended container support (1) to include types with lvalue-only ADL begin/end (matching std::begin/std::end semantics) in version 3.13.0 unreleased.
    • Extended overload (2) to accept heterogeneous iterator+sentinel pairs (C++20 ranges support) in version 3.13.0 unreleased.
    • Added error_handler parameter in version 3.13.0 unreleased.

    Deprecation

    • Overload (2) replaces calls to from_ubjson with a pointer and a length as first two parameters, which has been deprecated in version 3.8.0. In version 4.0.0 unreleased, this overload will be deleted (= delete) rather than removed. Please replace all calls like from_ubjson(ptr, len, ...); with from_ubjson(ptr, ptr+len, ...);.
    • Overload (2) replaces calls to from_ubjson with a pair of iterators as their first parameter, which has been deprecated in version 3.8.0. This overload will be removed in version 4.0.0. Please replace all calls like from_ubjson({ptr, ptr+len}, ...); with from_ubjson(ptr, ptr+len, ...);.

    You should be warned by your compiler with a -Wdeprecated-declarations warning if you are using a deprecated function.

    See the migration guide for how to update existing code.

    "},{"location":"api/basic_json/front/","title":"nlohmann::basic_json::front","text":"
    reference front();\nconst_reference front() const;\n

    Returns a reference to the first element in the container. For a JSON container c, the expression c.front() is equivalent to *c.begin().

    "},{"location":"api/basic_json/front/#return-value","title":"Return value","text":"

    In the case of a structured type (array or object), a reference to the first element is returned. In the case of number, string, boolean, or binary values, a reference to the value is returned.

    "},{"location":"api/basic_json/front/#exception-safety","title":"Exception safety","text":"

    Strong guarantee: if an exception is thrown, there are no changes in the JSON value.

    "},{"location":"api/basic_json/front/#exceptions","title":"Exceptions","text":"

    If the JSON value is null, exception invalid_iterator.214 is thrown.

    "},{"location":"api/basic_json/front/#complexity","title":"Complexity","text":"

    Constant.

    "},{"location":"api/basic_json/front/#notes","title":"Notes","text":"

    Precondition

    The array or object must not be empty. Calling front on an empty array or object yields undefined behavior.

    "},{"location":"api/basic_json/front/#examples","title":"Examples","text":"Example

    The following code shows an example for front().

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create JSON values\n    json j_null;\n    json j_boolean = true;\n    json j_number_integer = 17;\n    json j_number_float = 23.42;\n    json j_object = {{\"one\", 1}, {\"two\", 2}};\n    json j_object_empty(json::value_t::object);\n    json j_array = {1, 2, 4, 8, 16};\n    json j_array_empty(json::value_t::array);\n    json j_string = \"Hello, world\";\n\n    // call front()\n    //std::cout << j_null.front() << '\\n';          // would throw\n    std::cout << j_boolean.front() << '\\n';\n    std::cout << j_number_integer.front() << '\\n';\n    std::cout << j_number_float.front() << '\\n';\n    std::cout << j_object.front() << '\\n';\n    //std::cout << j_object_empty.front() << '\\n';  // undefined behavior\n    std::cout << j_array.front() << '\\n';\n    //std::cout << j_array_empty.front() << '\\n';   // undefined behavior\n    std::cout << j_string.front() << '\\n';\n}\n

    Output:

    true\n17\n23.42\n1\n1\n\"Hello, world\"\n
    "},{"location":"api/basic_json/front/#see-also","title":"See also","text":"
    • back - to access the last element
    • basic_json_view::front - the same access on a zero-copy view (document order, not sorted; duplicate keys are visited)
    • Element Access - overview of all ways to access elements
    "},{"location":"api/basic_json/front/#version-history","title":"Version history","text":"
    • Added in version 1.0.0.
    • Binary values are supported since version 3.8.0.
    "},{"location":"api/basic_json/get/","title":"nlohmann::basic_json::get","text":"
    // (1)\ntemplate<typename ValueType>\nValueType get() const noexcept(\n    noexcept(JSONSerializer<ValueType>::from_json(\n        std::declval<const basic_json_t&>(), std::declval<ValueType&>())));\n\n// (2)\ntemplate<typename BasicJsonType>\nBasicJsonType get() const;\n\n// (3)\ntemplate<typename PointerType>\nPointerType get() noexcept;\n\ntemplate<typename PointerType>\nconst PointerType get() const noexcept;  // constexpr since C++14\n
    1. Explicit type conversion between the JSON value and a compatible value which is CopyConstructible and DefaultConstructible. The value is converted by calling the json_serializer<ValueType> from_json() method.

      The function is equivalent to executing

      ValueType ret;\nJSONSerializer<ValueType>::from_json(*this, ret);\nreturn ret;\n

      This overload is chosen if:

      • ValueType is not basic_json,
      • json_serializer<ValueType> has a from_json() method of the form void from_json(const basic_json&, ValueType&), and
      • json_serializer<ValueType> does not have a from_json() method of the form ValueType from_json(const basic_json&)

      If the type is not CopyConstructible and not DefaultConstructible, the value is converted by calling the json_serializer<ValueType> from_json() method.

      The function is then equivalent to executing

      return JSONSerializer<ValueTypeCV>::from_json(*this);\n

      This overload is chosen if:

      • ValueType is not basic_json and
      • json_serializer<ValueType> has a from_json() method of the form ValueType from_json(const basic_json&)

      If json_serializer<ValueType> has both overloads of from_json(), the latter one is chosen.

    2. Overload for basic_json specializations. The function is equivalent to executing

      return *this;\n

    3. Explicit pointer access to the internally stored JSON value. No copies are made.

    "},{"location":"api/basic_json/get/#template-parameters","title":"Template parameters","text":"ValueType the value type to return BasicJsonType a specialization of basic_json PointerType pointer type; must be a pointer to array_t, object_t, string_t, boolean_t, number_integer_t, or number_unsigned_t, number_float_t, or binary_t. Other types will not compile."},{"location":"api/basic_json/get/#return-value","title":"Return value","text":"
    1. copy of the JSON value, converted to ValueType
    2. a copy of *this, converted into BasicJsonType
    3. pointer to the internally stored JSON value if the requested pointer type fits to the JSON value; nullptr otherwise
    "},{"location":"api/basic_json/get/#exception-safety","title":"Exception safety","text":"

    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 const member function. No-throw guarantee for overload (3): this function never throws exceptions.

    "},{"location":"api/basic_json/get/#exceptions","title":"Exceptions","text":"

    Depends on what json_serializer<ValueType> from_json() method throws

    "},{"location":"api/basic_json/get/#complexity","title":"Complexity","text":"

    Depends on the json_serializer<ValueType>::from_json() implementation for overloads (1) and (2); constant for overload (3).

    "},{"location":"api/basic_json/get/#notes","title":"Notes","text":"

    Undefined behavior for pointers

    Writing data to the pointee (overload 3) of the result yields an undefined state.

    Undefined behavior for numeric conversions

    Conversions between numeric types are performed by the corresponding from_json() implementation using the target C++ type. When converting between numeric types, the library does not check whether the source value is representable by the target type.

    If the source value is outside the range of the target type, the behavior is the same as the corresponding C++ conversion. In particular, converting a floating-point value to an integer type that cannot represent the value results in undefined behavior.

    See Number conversion for more information.

    std::optional conversions

    Prior to version 3.13.0 unreleased, get<std::optional<T>>() (and other conversions to std::optional<T>) failed to compile in every configuration, due to an internal implementation bug that made the from_json overload for std::optional unreachable regardless of the JSON_USE_IMPLICIT_CONVERSIONS setting. This has been fixed.

    "},{"location":"api/basic_json/get/#examples","title":"Examples","text":"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::map<std::string, json>.

    #include <iostream>\n#include <map>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create a JSON value with different types\n    json json_types =\n    {\n        {\"boolean\", true},\n        {\n            \"number\", {\n                {\"integer\", 42},\n                {\"floating-point\", 17.23}\n            }\n        },\n        {\"string\", \"Hello, world!\"},\n        {\"array\", {1, 2, 3, 4, 5}},\n        {\"null\", nullptr}\n    };\n\n    // use explicit conversions\n    auto v1 = json_types[\"boolean\"].get<bool>();\n    auto v2 = json_types[\"number\"][\"integer\"].get<int>();\n    auto v3 = json_types[\"number\"][\"integer\"].get<short>();\n    auto v4 = json_types[\"number\"][\"floating-point\"].get<float>();\n    auto v5 = json_types[\"number\"][\"floating-point\"].get<int>();\n    auto v6 = json_types[\"string\"].get<std::string>();\n    auto v7 = json_types[\"array\"].get<std::vector<short>>();\n    auto v8 = json_types.get<std::map<std::string, json>>();\n\n    // print the conversion results\n    std::cout << v1 << '\\n';\n    std::cout << v2 << ' ' << v3 << '\\n';\n    std::cout << v4 << ' ' << v5 << '\\n';\n    std::cout << v6 << '\\n';\n\n    for (auto i : v7)\n    {\n        std::cout << i << ' ';\n    }\n    std::cout << \"\\n\\n\";\n\n    for (const auto& i : v8)\n    {\n        std::cout << i.first << \": \" << i.second << '\\n';\n    }\n}\n

    Output:

    1\n42 42\n17.23 17\nHello, world!\n1 2 3 4 5 \n\narray: [1,2,3,4,5]\nboolean: true\nnull: null\nnumber: {\"floating-point\":17.23,\"integer\":42}\nstring: \"Hello, world!\"\n
    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>().

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\nusing nlohmann::ordered_json;\n\nint main()\n{\n    // create a JSON value\n    json j = {{\"one\", 1}, {\"two\", 2}, {\"three\", 3}};\n\n    // convert to a different basic_json specialization\n    ordered_json oj = j.get<ordered_json>();\n\n    std::cout << j << '\\n';\n    std::cout << oj << '\\n';\n}\n

    Output:

    {\"one\":1,\"three\":3,\"two\":2}\n{\"one\":1,\"three\":3,\"two\":2}\n
    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.

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create a JSON number\n    json value = 17;\n\n    // explicitly getting pointers\n    const auto* p1 = value.get<const json::number_integer_t*>();\n    auto* p2 = value.get<json::number_integer_t*>();\n    auto* p3 = value.get<json::number_integer_t* const>();\n    const auto* p4 = value.get<const json::number_integer_t* const>();\n    auto* p5 = value.get<json::number_float_t*>();\n\n    // print the pointees\n    std::cout << *p1 << ' ' << *p2 << ' ' << *p3 << ' ' << *p4 << '\\n';\n    std::cout << std::boolalpha << (p5 == nullptr) << '\\n';\n}\n

    Output:

    17 17 17 17\ntrue\n
    "},{"location":"api/basic_json/get/#see-also","title":"See also","text":"
    • get_to - convert and write into a passed value
    • get_ptr - get a pointer to the stored value
    • get_ref - get a reference to the stored value
    • operator ValueType - get a value via implicit conversion
    • Converting values - the type conversions article
    • basic_json_view::get - the same conversion on a zero-copy view (many types are converted without ever building a basic_json value)
    • Arbitrary Type Conversions - make your own types usable with get
    "},{"location":"api/basic_json/get/#version-history","title":"Version history","text":"
    1. Added in version 2.1.0.
    2. Added in version 2.1.0. Extended to work with other specializations of basic_json in version 3.1.2.
    3. Added in version 1.0.0.
    "},{"location":"api/basic_json/get_allocator/","title":"nlohmann::basic_json::get_allocator","text":"
    static allocator_type get_allocator();\n

    Returns the allocator associated with the container.

    "},{"location":"api/basic_json/get_allocator/#return-value","title":"Return value","text":"

    associated allocator

    "},{"location":"api/basic_json/get_allocator/#exception-safety","title":"Exception safety","text":"

    Strong guarantee: if an exception is thrown, there are no changes to any JSON value.

    "},{"location":"api/basic_json/get_allocator/#complexity","title":"Complexity","text":"

    Constant.

    "},{"location":"api/basic_json/get_allocator/#examples","title":"Examples","text":"Example

    The example shows how get_allocator() is used to created json values.

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    auto alloc = json::get_allocator();\n    using traits_t = std::allocator_traits<decltype(alloc)>;\n\n    json* j = traits_t::allocate(alloc, 1);\n    traits_t::construct(alloc, j, \"Hello, world!\");\n\n    std::cout << *j << '\\n';\n\n    traits_t::destroy(alloc, j);\n    traits_t::deallocate(alloc, j, 1);\n}\n

    Output:

    \"Hello, world!\"\n
    "},{"location":"api/basic_json/get_allocator/#see-also","title":"See also","text":"
    • basic_json - the class template, with AllocatorType as one of its template parameters
    • Template Parameter Requirements - the requirements for AllocatorType
    "},{"location":"api/basic_json/get_allocator/#version-history","title":"Version history","text":"
    • Added in version 1.0.0.
    "},{"location":"api/basic_json/get_binary/","title":"nlohmann::basic_json::get_binary","text":"
    binary_t& get_binary();\n\nconst binary_t& get_binary() const;\n

    Returns a reference to the stored binary value.

    "},{"location":"api/basic_json/get_binary/#return-value","title":"Return value","text":"

    Reference to binary value.

    "},{"location":"api/basic_json/get_binary/#exception-safety","title":"Exception safety","text":"

    Strong exception safety: if an exception occurs, the original value stays intact.

    "},{"location":"api/basic_json/get_binary/#exceptions","title":"Exceptions","text":"

    Throws type_error.302 if the value is not binary

    "},{"location":"api/basic_json/get_binary/#complexity","title":"Complexity","text":"

    Constant.

    "},{"location":"api/basic_json/get_binary/#examples","title":"Examples","text":"Example

    The following code shows how to query a binary value.

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create a binary vector\n    std::vector<std::uint8_t> vec = {0xCA, 0xFE, 0xBA, 0xBE};\n\n    // create a binary JSON value with subtype 42\n    json j = json::binary(vec, 42);\n\n    // output type and subtype\n    std::cout << \"type: \" << j.type_name() << \", subtype: \" << j.get_binary().subtype() << '\\n';\n}\n

    Output:

    type: binary, subtype: 42\n
    "},{"location":"api/basic_json/get_binary/#see-also","title":"See also","text":"
    • Binary values - how binary values and subtypes are handled
    • binary - create a binary value
    • is_binary - check whether a value is binary
    • get - get a value (explicit conversion)
    • get_ref - get a reference to the stored value
    "},{"location":"api/basic_json/get_binary/#version-history","title":"Version history","text":"
    • Added in version 3.8.0.
    "},{"location":"api/basic_json/get_ptr/","title":"nlohmann::basic_json::get_ptr","text":"
    template<typename PointerType>\nPointerType get_ptr() noexcept;\n\ntemplate<typename PointerType>\nconstexpr const PointerType get_ptr() const noexcept;\n

    Implicit pointer access to the internally stored JSON value. No copies are made.

    "},{"location":"api/basic_json/get_ptr/#template-parameters","title":"Template parameters","text":"PointerType pointer type; must be a pointer to array_t, object_t, string_t, boolean_t, number_integer_t, or number_unsigned_t, number_float_t, or binary_t. Other types will not compile."},{"location":"api/basic_json/get_ptr/#return-value","title":"Return value","text":"

    pointer to the internally stored JSON value if the requested pointer type fits to the JSON value; nullptr otherwise

    "},{"location":"api/basic_json/get_ptr/#exception-safety","title":"Exception safety","text":"

    No-throw guarantee: this function never throws exceptions.

    "},{"location":"api/basic_json/get_ptr/#complexity","title":"Complexity","text":"

    Constant.

    "},{"location":"api/basic_json/get_ptr/#notes","title":"Notes","text":"

    Undefined behavior

    The pointer becomes invalid if the underlying JSON object changes.

    Consider the following example code where the pointer ptr changes after the array is resized. As a result, reading or writing to ptr after the array change would be undefined behavior. The address of the first array element changes, because the underlying std::vector is resized after adding a fifth element.

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    json j = {1, 2, 3, 4};\n    auto* ptr = j[0].get_ptr<std::int64_t*>();\n    std::cout << \"value at \" << ptr << \" is \" << *ptr << std::endl;\n\n    j.push_back(5);\n\n    ptr = j[0].get_ptr<std::int64_t*>();\n    std::cout << \"value at \" << ptr << \" is \" << *ptr << std::endl;\n}\n

    Output:

    value at 0x6000012fc1c8 is 1\nvalue at 0x6000029fc088 is 1\n
    "},{"location":"api/basic_json/get_ptr/#examples","title":"Examples","text":"Example

    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 nullptr is returned if the value and the requested pointer type does not match.

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create a JSON number\n    json value = 17;\n\n    // explicitly getting pointers\n    const auto* p1 = value.get_ptr<const json::number_integer_t*>();\n    auto* p2 = value.get_ptr<json::number_integer_t*>();\n    auto* p3 = value.get_ptr<json::number_integer_t* const>();\n    const auto* p4 = value.get_ptr<const json::number_integer_t* const>();\n    auto* p5 = value.get_ptr<json::number_float_t*>();\n\n    // print the pointees\n    std::cout << *p1 << ' ' << *p2 << ' ' << *p3 << ' ' << *p4 << '\\n';\n    std::cout << std::boolalpha << (p5 == nullptr) << '\\n';\n}\n

    Output:

    17 17 17 17\ntrue\n
    "},{"location":"api/basic_json/get_ptr/#see-also","title":"See also","text":"
    • get_ref() - get a reference value
    • Converting values - getting values out, with or without copying
    "},{"location":"api/basic_json/get_ptr/#version-history","title":"Version history","text":"
    • Added in version 1.0.0.
    • Extended to binary types in version 3.8.0.
    "},{"location":"api/basic_json/get_ref/","title":"nlohmann::basic_json::get_ref","text":"
    template<typename ReferenceType>\nReferenceType get_ref();\n\ntemplate<typename ReferenceType>\nconst ReferenceType get_ref() const;\n

    Implicit reference access to the internally stored JSON value. No copies are made.

    "},{"location":"api/basic_json/get_ref/#template-parameters","title":"Template parameters","text":"ReferenceType reference type; must be a reference to array_t, object_t, string_t, boolean_t, number_integer_t, or number_unsigned_t, number_float_t, or binary_t. Enforced by a static assertion."},{"location":"api/basic_json/get_ref/#return-value","title":"Return value","text":"

    reference to the internally stored JSON value if the requested reference type fits to the JSON value; throws type_error.303 otherwise

    "},{"location":"api/basic_json/get_ref/#exception-safety","title":"Exception safety","text":"

    Strong exception safety: if an exception occurs, the original value stays intact.

    "},{"location":"api/basic_json/get_ref/#exceptions","title":"Exceptions","text":"

    Throws type_error.303 if the requested reference type does not match the stored JSON value type; example: \"incompatible ReferenceType for get_ref, actual type is binary\".

    "},{"location":"api/basic_json/get_ref/#complexity","title":"Complexity","text":"

    Constant.

    "},{"location":"api/basic_json/get_ref/#notes","title":"Notes","text":"

    Undefined behavior

    The reference becomes invalid if the underlying JSON object changes.

    "},{"location":"api/basic_json/get_ref/#examples","title":"Examples","text":"Example

    The example shows several calls to get_ref().

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create a JSON number\n    json value = 17;\n\n    // explicitly getting references\n    auto r1 = value.get_ref<const json::number_integer_t&>();\n    auto r2 = value.get_ref<json::number_integer_t&>();\n\n    // print the values\n    std::cout << r1 << ' ' << r2 << '\\n';\n\n    // incompatible type throws exception\n    try\n    {\n        auto r3 = value.get_ref<json::number_float_t&>();\n    }\n    catch (const json::type_error& ex)\n    {\n        std::cout << ex.what() << '\\n';\n    }\n}\n

    Output:

    17 17\n[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is number\n
    "},{"location":"api/basic_json/get_ref/#see-also","title":"See also","text":"
    • get_ptr() - get a pointer value
    • basic_json_view::get_string - the closest counterpart on a zero-copy view: a string without a copy, but as a view rather than a reference to a value that must already exist
    • Converting values - getting values out, with or without copying
    "},{"location":"api/basic_json/get_ref/#version-history","title":"Version history","text":"
    • Added in version 1.1.0.
    • Extended to binary types in version 3.8.0.
    "},{"location":"api/basic_json/get_to/","title":"nlohmann::basic_json::get_to","text":"
    template<typename ValueType>\nValueType& get_to(ValueType& v) const noexcept(\n    noexcept(JSONSerializer<ValueType>::from_json(\n        std::declval<const basic_json_t&>(), v)));\n

    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.

    The function is equivalent to executing

    ValueType v;\nJSONSerializer<ValueType>::from_json(*this, v);\n

    This overload is chosen if:

    • ValueType is not basic_json,
    • json_serializer<ValueType> has a from_json() method of the form void from_json(const basic_json&, ValueType&)

    v must not be const. Passing a const object is a compile-time error. For types such as arithmetic types, enums, and C arrays, the error is a static_assert that names the problem. For other types, the overload is not viable, and the compiler reports that no matching get_to was found.

    "},{"location":"api/basic_json/get_to/#template-parameters","title":"Template parameters","text":"ValueType the value type to return"},{"location":"api/basic_json/get_to/#return-value","title":"Return value","text":"

    the input parameter, allowing chaining calls

    "},{"location":"api/basic_json/get_to/#exception-safety","title":"Exception safety","text":"

    Depends on what json_serializer<ValueType> from_json() method throws; the JSON value itself is never modified, since get_to() is a const member function.

    "},{"location":"api/basic_json/get_to/#exceptions","title":"Exceptions","text":"

    Depends on what json_serializer<ValueType> from_json() method throws

    "},{"location":"api/basic_json/get_to/#complexity","title":"Complexity","text":"

    Depends on the json_serializer<ValueType>::from_json() implementation.

    "},{"location":"api/basic_json/get_to/#examples","title":"Examples","text":"Example

    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::map<std::string, json>.

    #include <iostream>\n#include <map>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create a JSON value with different types\n    json json_types =\n    {\n        {\"boolean\", true},\n        {\n            \"number\", {\n                {\"integer\", 42},\n                {\"floating-point\", 17.23}\n            }\n        },\n        {\"string\", \"Hello, world!\"},\n        {\"array\", {1, 2, 3, 4, 5}},\n        {\"null\", nullptr}\n    };\n\n    bool v1;\n    int v2;\n    short v3;\n    float v4;\n    int v5;\n    std::string v6;\n    std::vector<short> v7;\n    std::map<std::string, json> v8;\n\n    // use explicit conversions\n    json_types[\"boolean\"].get_to(v1);\n    json_types[\"number\"][\"integer\"].get_to(v2);\n    json_types[\"number\"][\"integer\"].get_to(v3);\n    json_types[\"number\"][\"floating-point\"].get_to(v4);\n    json_types[\"number\"][\"floating-point\"].get_to(v5);\n    json_types[\"string\"].get_to(v6);\n    json_types[\"array\"].get_to(v7);\n    json_types.get_to(v8);\n\n    // print the conversion results\n    std::cout << v1 << '\\n';\n    std::cout << v2 << ' ' << v3 << '\\n';\n    std::cout << v4 << ' ' << v5 << '\\n';\n    std::cout << v6 << '\\n';\n\n    for (auto i : v7)\n    {\n        std::cout << i << ' ';\n    }\n    std::cout << \"\\n\\n\";\n\n    for (const auto& i : v8)\n    {\n        std::cout << i.first << \": \" << i.second << '\\n';\n    }\n}\n

    Output:

    1\n42 42\n17.23 17\nHello, world!\n1 2 3 4 5 \n\narray: [1,2,3,4,5]\nboolean: true\nnull: null\nnumber: {\"floating-point\":17.23,\"integer\":42}\nstring: \"Hello, world!\"\n
    "},{"location":"api/basic_json/get_to/#see-also","title":"See also","text":"
    • get - get a value (explicit conversion)
    • get_ref - get a reference to the stored value
    • get_ptr - get a pointer to the stored value
    • Converting values - the type conversions article
    • basic_json_view::get_to - the same conversion on a zero-copy view
    • Arbitrary Type Conversions - make your own types usable with get_to
    "},{"location":"api/basic_json/get_to/#version-history","title":"Version history","text":"
    • Added in version 3.3.0.
    • Added a static_assert with a clear message for const arguments in version 3.13.0 unreleased.
    "},{"location":"api/basic_json/input_format_t/","title":"nlohmann::basic_json::input_format_t","text":"
    enum class input_format_t {\n    json,\n    cbor,\n    msgpack,\n    ubjson,\n    bson,\n    bjdata,\n    bon8\n};\n

    This enumeration is used in the sax_parse function to choose the input format to parse:

    json JSON (JavaScript Object Notation) cbor CBOR (Concise Binary Object Representation) msgpack MessagePack ubjson UBJSON (Universal Binary JSON) bson BSON (Binary JSON) bjdata BJData (Binary JData) bon8 BON8 (Binary Object Notation 8)"},{"location":"api/basic_json/input_format_t/#examples","title":"Examples","text":"Example

    The example below shows how an input_format_t enum value is passed to sax_parse to set the input format to CBOR.

    #include <iostream>\n#include <iomanip>\n#include <sstream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\n// a simple event consumer that collects string representations of the passed\n// values; note inheriting from json::json_sax_t is not required, but can\n// help not to forget a required function\nclass sax_event_consumer : public json::json_sax_t\n{\n  public:\n    std::vector<std::string> events;\n\n    bool null() override\n    {\n        events.push_back(\"null()\");\n        return true;\n    }\n\n    bool boolean(bool val) override\n    {\n        events.push_back(\"boolean(val=\" + std::string(val ? \"true\" : \"false\") + \")\");\n        return true;\n    }\n\n    bool number_integer(number_integer_t val) override\n    {\n        events.push_back(\"number_integer(val=\" + std::to_string(val) + \")\");\n        return true;\n    }\n\n    bool number_unsigned(number_unsigned_t val) override\n    {\n        events.push_back(\"number_unsigned(val=\" + std::to_string(val) + \")\");\n        return true;\n    }\n\n    bool number_float(number_float_t val, const string_t& s) override\n    {\n        events.push_back(\"number_float(val=\" + std::to_string(val) + \", s=\" + s + \")\");\n        return true;\n    }\n\n    bool string(string_t& val) override\n    {\n        events.push_back(\"string(val=\" + val + \")\");\n        return true;\n    }\n\n    bool start_object(std::size_t elements) override\n    {\n        events.push_back(\"start_object(elements=\" + std::to_string(elements) + \")\");\n        return true;\n    }\n\n    bool end_object() override\n    {\n        events.push_back(\"end_object()\");\n        return true;\n    }\n\n    bool start_array(std::size_t elements) override\n    {\n        events.push_back(\"start_array(elements=\" + std::to_string(elements) + \")\");\n        return true;\n    }\n\n    bool end_array() override\n    {\n        events.push_back(\"end_array()\");\n        return true;\n    }\n\n    bool key(string_t& val) override\n    {\n        events.push_back(\"key(val=\" + val + \")\");\n        return true;\n    }\n\n    bool binary(json::binary_t& val) override\n    {\n        events.push_back(\"binary(val=[...])\");\n        return true;\n    }\n\n    bool parse_error(std::size_t position, const std::string& last_token, const json::exception& ex) override\n    {\n        events.push_back(\"parse_error(position=\" + std::to_string(position) + \", last_token=\" + last_token + \",\\n            ex=\" + std::string(ex.what()) + \")\");\n        return false;\n    }\n};\n\nint main()\n{\n    // CBOR byte string\n    std::vector<std::uint8_t> vec = {{0x44, 0xcA, 0xfe, 0xba, 0xbe}};\n\n    // create a SAX event consumer object\n    sax_event_consumer sec;\n\n    // parse CBOR\n    bool result = json::sax_parse(vec, &sec, json::input_format_t::cbor);\n\n    // output the recorded events\n    for (auto& event : sec.events)\n    {\n        std::cout << event << \"\\n\";\n    }\n\n    // output the result of sax_parse\n    std::cout << \"\\nresult: \" << std::boolalpha << result << '\\n';\n}\n

    Output:

    binary(val=[...])\n\nresult: true\n
    "},{"location":"api/basic_json/input_format_t/#see-also","title":"See also","text":"
    • sax_parse - generic SAX parse interface, taking an input_format_t to select the input format
    • cbor_tag_handler_t - configures how CBOR tags are treated while parsing
    • Binary Formats - CBOR, MessagePack, BSON, and other formats
    "},{"location":"api/basic_json/input_format_t/#version-history","title":"Version history","text":"
    • Added in version 3.2.0.
    "},{"location":"api/basic_json/insert/","title":"nlohmann::basic_json::insert","text":"
    // (1)\niterator insert(const_iterator pos, const basic_json& val);\niterator insert(const_iterator pos, basic_json&& val);\n\n// (2)\niterator insert(const_iterator pos, size_type cnt, const basic_json& val);\n\n// (3)\niterator insert(const_iterator pos, const_iterator first, const_iterator last);\n\n// (4)\niterator insert(const_iterator pos, initializer_list_t ilist);\n\n// (5)\nvoid insert(const_iterator first, const_iterator last);\n
    1. Inserts element val into an array before iterator pos.
    2. Inserts cnt copies of val into an array before iterator pos.
    3. Inserts elements from range [first, last) into an array before iterator pos.
    4. Inserts elements from initializer list ilist into an array before iterator pos.
    5. Inserts elements from range [first, last) into an object.
    "},{"location":"api/basic_json/insert/#iterator-invalidation","title":"Iterator invalidation","text":"

    For all cases where an element is added to an array, a reallocation can happen, in which case all iterators (including the end() iterator) and all references to the elements are invalidated. Otherwise, only the end() iterator is invalidated. Also, any iterator or reference after the insertion point will point to the same index, which is now a different value.

    For ordered_json, also adding an element to an object can yield a reallocation which again invalidates all iterators and all references. Also, any iterator or reference after the insertion point will point to the same index, which is now a different value.

    "},{"location":"api/basic_json/insert/#parameters","title":"Parameters","text":"pos (in) iterator before which the content will be inserted; may be the end() iterator val (in) value to insert cnt (in) number of copies of val to insert first (in) the start of the range of elements to insert last (in) the end of the range of elements to insert ilist (in) initializer list to insert the values from"},{"location":"api/basic_json/insert/#return-value","title":"Return value","text":"
    1. iterator pointing to the inserted val.
    2. iterator pointing to the first element inserted, or pos if cnt==0
    3. iterator pointing to the first element inserted, or pos if first==last
    4. iterator pointing to the first element inserted, or pos if ilist is empty
    5. (none)
    "},{"location":"api/basic_json/insert/#exception-safety","title":"Exception safety","text":"

    Strong exception safety: if an exception occurs, the original value stays intact.

    "},{"location":"api/basic_json/insert/#exceptions","title":"Exceptions","text":"
    1. The function can throw the following exceptions:
      • Throws type_error.309 if called on JSON values other than arrays; example: \"cannot use insert() with string\"
      • Throws invalid_iterator.202 if called on an iterator which does not belong to the current JSON value; example: \"iterator does not fit current value\"
    2. The function can throw the following exceptions:
      • Throws type_error.309 if called on JSON values other than arrays; example: \"cannot use insert() with string\"
      • Throws invalid_iterator.202 if called on an iterator which does not belong to the current JSON value; example: \"iterator does not fit current value\"
    3. The function can throw the following exceptions:
      • Throws type_error.309 if called on JSON values other than arrays; example: \"cannot use insert() with string\"
      • Throws invalid_iterator.202 if called on an iterator which does not belong to the current JSON value; example: \"iterator does not fit current value\"
      • Throws invalid_iterator.210 if first and last do not belong to the same JSON value; example: \"iterators do not fit\"
      • Throws invalid_iterator.211 if first or last are iterators into container for which insert is called; example: \"passed iterators may not belong to container\"
      • Throws invalid_iterator.202 if first or last do not point to an array; example: \"iterators first and last must point to arrays\"
    4. The function can throw the following exceptions:
      • Throws type_error.309 if called on JSON values other than arrays; example: \"cannot use insert() with string\"
      • Throws invalid_iterator.202 if called on an iterator which does not belong to the current JSON value; example: \"iterator does not fit current value\"
    5. The function can throw the following exceptions:
      • Throws type_error.309 if called on JSON values other than objects; example: \"cannot use insert() with string\"
      • Throws invalid_iterator.202 if first or last do not point to an object; example: \"iterators first and last must point to objects\"
      • Throws invalid_iterator.210 if first and last do not belong to the same JSON value; example: \"iterators do not fit\"
    "},{"location":"api/basic_json/insert/#complexity","title":"Complexity","text":"
    1. Constant plus linear in the distance between pos and end of the container.
    2. Linear in cnt plus linear in the distance between pos and end of the container.
    3. Linear in 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. O(N*log(size() + N)), where N is the number of elements to insert.
    "},{"location":"api/basic_json/insert/#examples","title":"Examples","text":"Example: (1) insert element into array

    The example shows how insert() is used.

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create a JSON array\n    json v = {1, 2, 3, 4};\n\n    // insert number 10 before number 3\n    auto new_pos = v.insert(v.begin() + 2, 10);\n\n    // output new array and result of insert call\n    std::cout << *new_pos << '\\n';\n    std::cout << v << '\\n';\n}\n

    Output:

    10\n[1,2,10,3,4]\n
    Example: (2) insert copies of element into array

    The example shows how insert() is used.

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create a JSON array\n    json v = {1, 2, 3, 4};\n\n    // insert number 7 copies of number 7 before number 3\n    auto new_pos = v.insert(v.begin() + 2, 7, 7);\n\n    // output new array and result of insert call\n    std::cout << *new_pos << '\\n';\n    std::cout << v << '\\n';\n}\n

    Output:

    7\n[1,2,7,7,7,7,7,7,7,3,4]\n
    Example: (3) insert a range of elements into an array

    The example shows how insert() is used.

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create a JSON array\n    json v = {1, 2, 3, 4};\n\n    // create a JSON array to copy values from\n    json v2 = {\"one\", \"two\", \"three\", \"four\"};\n\n    // insert range from v2 before the end of array v\n    auto new_pos = v.insert(v.end(), v2.begin(), v2.end());\n\n    // output new array and result of insert call\n    std::cout << *new_pos << '\\n';\n    std::cout << v << '\\n';\n}\n

    Output:

    \"one\"\n[1,2,3,4,\"one\",\"two\",\"three\",\"four\"]\n
    Example: (4) insert elements from an initializer list into an array

    The example shows how insert() is used.

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create a JSON array\n    json v = {1, 2, 3, 4};\n\n    // insert range from v2 before the end of array v\n    auto new_pos = v.insert(v.end(), {7, 8, 9});\n\n    // output new array and result of insert call\n    std::cout << *new_pos << '\\n';\n    std::cout << v << '\\n';\n}\n

    Output:

    7\n[1,2,3,4,7,8,9]\n
    Example: (5) insert a range of elements into an object

    The example shows how insert() is used.

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create two JSON objects\n    json j1 = {{\"one\", \"eins\"}, {\"two\", \"zwei\"}};\n    json j2 = {{\"eleven\", \"elf\"}, {\"seventeen\", \"siebzehn\"}};\n\n    // output objects\n    std::cout << j1 << '\\n';\n    std::cout << j2 << '\\n';\n\n    // insert range from j2 to j1\n    j1.insert(j2.begin(), j2.end());\n\n    // output result of insert call\n    std::cout << j1 << '\\n';\n}\n

    Output:

    {\"one\":\"eins\",\"two\":\"zwei\"}\n{\"eleven\":\"elf\",\"seventeen\":\"siebzehn\"}\n{\"eleven\":\"elf\",\"one\":\"eins\",\"seventeen\":\"siebzehn\",\"two\":\"zwei\"}\n
    "},{"location":"api/basic_json/insert/#see-also","title":"See also","text":"
    • emplace - add a value to an object
    • emplace_back - add a value to an array
    • push_back - add a value to an array/object
    • update - merges objects
    • Modifying values - the article on modifying values
    "},{"location":"api/basic_json/insert/#version-history","title":"Version history","text":"
    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. Fixed in version 3.13.0 unreleased 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.
    "},{"location":"api/basic_json/invalid_iterator/","title":"nlohmann::basic_json::invalid_iterator","text":"
    class invalid_iterator : public exception;\n

    This exception is thrown if iterators passed to a library function do not match the expected semantics.

    Exceptions have ids 2xx (see list of iterator errors).

    classDiagram\n  direction LR\n\n    class std_exception [\"std::exception\"] {\n        <<interface>>\n    }\n\n    class json_exception [\"basic_json::exception\"] {\n        +const int id\n        +const char* what() const\n    }\n\n    class json_parse_error [\"basic_json::parse_error\"] {\n        +const std::size_t byte\n    }\n\n    class json_invalid_iterator [\"basic_json::invalid_iterator\"]\n    class json_type_error [\"basic_json::type_error\"]\n    class json_out_of_range [\"basic_json::out_of_range\"]\n    class json_other_error [\"basic_json::other_error\"]\n\n    std_exception <|-- json_exception\n    json_exception <|-- json_parse_error\n    json_exception <|-- json_invalid_iterator\n    json_exception <|-- json_type_error\n    json_exception <|-- json_out_of_range\n    json_exception <|-- json_other_error\n\n    style json_invalid_iterator fill:#CCCCFF

    Class hierarchy of the library's exceptions; arrows point from a derived class to its base class, and the highlighted box is basic_json::invalid_iterator.

    "},{"location":"api/basic_json/invalid_iterator/#member-functions","title":"Member functions","text":"
    • what - returns explanatory string
    "},{"location":"api/basic_json/invalid_iterator/#member-variables","title":"Member variables","text":"
    • id - the id of the exception
    "},{"location":"api/basic_json/invalid_iterator/#examples","title":"Examples","text":"Example

    The following code shows how a invalid_iterator exception can be caught.

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    try\n    {\n        // calling iterator::key() on non-object iterator\n        json j = \"string\";\n        json::iterator it = j.begin();\n        auto k = it.key();\n    }\n    catch (const json::invalid_iterator& e)\n    {\n        // output exception information\n        std::cout << \"message: \" << e.what() << '\\n'\n                  << \"exception id: \" << e.id << '\\n';\n    }\n}\n

    Output:

    message: [json.exception.invalid_iterator.207] cannot use key() for non-object iterators\nexception id: 207\n
    "},{"location":"api/basic_json/invalid_iterator/#see-also","title":"See also","text":"
    • exception - the base class of all exceptions thrown by the library
    • List of iterator errors - overview of iterator errors (invalid_iterator)
    • parse_error - exceptions indicating a parse error
    • type_error - exceptions indicating executing a member function with a wrong type
    • out_of_range - exceptions indicating access out of the defined range
    • other_error - exceptions indicating other library errors
    • Exceptions - all exceptions and their error codes
    • JSON_DIAGNOSTICS - extended exception messages with the path of the failing value
    "},{"location":"api/basic_json/invalid_iterator/#version-history","title":"Version history","text":"
    • Added in version 3.0.0.
    "},{"location":"api/basic_json/is_array/","title":"nlohmann::basic_json::is_array","text":"
    constexpr bool is_array() const noexcept;\n

    This function returns true if and only if the JSON value is an array.

    "},{"location":"api/basic_json/is_array/#return-value","title":"Return value","text":"

    true if type is an array, false otherwise.

    "},{"location":"api/basic_json/is_array/#exception-safety","title":"Exception safety","text":"

    No-throw guarantee: this member function never throws exceptions.

    "},{"location":"api/basic_json/is_array/#complexity","title":"Complexity","text":"

    Constant.

    "},{"location":"api/basic_json/is_array/#examples","title":"Examples","text":"Example

    The following code exemplifies is_array() for all JSON types.

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create JSON values\n    json j_null;\n    json j_boolean = true;\n    json j_number_integer = 17;\n    json j_number_unsigned_integer = 12345678987654321u;\n    json j_number_float = 23.42;\n    json j_object = {{\"one\", 1}, {\"two\", 2}};\n    json j_array = {1, 2, 4, 8, 16};\n    json j_string = \"Hello, world\";\n    json j_binary = json::binary({1, 2, 3});\n\n    // call is_array()\n    std::cout << std::boolalpha;\n    std::cout << j_null.is_array() << '\\n';\n    std::cout << j_boolean.is_array() << '\\n';\n    std::cout << j_number_integer.is_array() << '\\n';\n    std::cout << j_number_unsigned_integer.is_array() << '\\n';\n    std::cout << j_number_float.is_array() << '\\n';\n    std::cout << j_object.is_array() << '\\n';\n    std::cout << j_array.is_array() << '\\n';\n    std::cout << j_string.is_array() << '\\n';\n    std::cout << j_binary.is_array() << '\\n';\n}\n

    Output:

    false\nfalse\nfalse\nfalse\nfalse\nfalse\ntrue\nfalse\nfalse\n
    "},{"location":"api/basic_json/is_array/#see-also","title":"See also","text":"
    • is_object - checks whether the JSON value is an object
    • is_structured - checks whether the JSON value is structured (array or object)
    • type - returns the type of the JSON value
    • array_t - the type used to store JSON arrays
    • basic_json_view::is_array - the same check on a zero-copy view
    • Types - the JSON value types and how they are stored
    "},{"location":"api/basic_json/is_array/#version-history","title":"Version history","text":"
    • Added in version 1.0.0.
    "},{"location":"api/basic_json/is_binary/","title":"nlohmann::basic_json::is_binary","text":"
    constexpr bool is_binary() const noexcept;\n

    This function returns true if and only if the JSON value is a binary array.

    "},{"location":"api/basic_json/is_binary/#return-value","title":"Return value","text":"

    true if type is binary, false otherwise.

    "},{"location":"api/basic_json/is_binary/#exception-safety","title":"Exception safety","text":"

    No-throw guarantee: this member function never throws exceptions.

    "},{"location":"api/basic_json/is_binary/#complexity","title":"Complexity","text":"

    Constant.

    "},{"location":"api/basic_json/is_binary/#examples","title":"Examples","text":"Example

    The following code exemplifies is_binary() for all JSON types.

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create JSON values\n    json j_null;\n    json j_boolean = true;\n    json j_number_integer = 17;\n    json j_number_unsigned_integer = 12345678987654321u;\n    json j_number_float = 23.42;\n    json j_object = {{\"one\", 1}, {\"two\", 2}};\n    json j_array = {1, 2, 4, 8, 16};\n    json j_string = \"Hello, world\";\n    json j_binary = json::binary({1, 2, 3});\n\n    // call is_binary()\n    std::cout << std::boolalpha;\n    std::cout << j_null.is_binary() << '\\n';\n    std::cout << j_boolean.is_binary() << '\\n';\n    std::cout << j_number_integer.is_binary() << '\\n';\n    std::cout << j_number_unsigned_integer.is_binary() << '\\n';\n    std::cout << j_number_float.is_binary() << '\\n';\n    std::cout << j_object.is_binary() << '\\n';\n    std::cout << j_array.is_binary() << '\\n';\n    std::cout << j_string.is_binary() << '\\n';\n    std::cout << j_binary.is_binary() << '\\n';\n}\n

    Output:

    false\nfalse\nfalse\nfalse\nfalse\nfalse\nfalse\nfalse\ntrue\n
    "},{"location":"api/basic_json/is_binary/#see-also","title":"See also","text":"
    • Binary values - how binary values and subtypes are handled
    • is_primitive - checks whether the JSON value is primitive
    • binary_t - the type used to store binary values
    • get_binary - returns a reference to the stored binary value
    • basic_json_view::is_binary - the same check on a zero-copy view
    "},{"location":"api/basic_json/is_binary/#version-history","title":"Version history","text":"
    • Added in version 3.8.0.
    "},{"location":"api/basic_json/is_boolean/","title":"nlohmann::basic_json::is_boolean","text":"
    constexpr bool is_boolean() const noexcept;\n

    This function returns true if and only if the JSON value is true or false.

    "},{"location":"api/basic_json/is_boolean/#return-value","title":"Return value","text":"

    true if type is boolean, false otherwise.

    "},{"location":"api/basic_json/is_boolean/#exception-safety","title":"Exception safety","text":"

    No-throw guarantee: this member function never throws exceptions.

    "},{"location":"api/basic_json/is_boolean/#complexity","title":"Complexity","text":"

    Constant.

    "},{"location":"api/basic_json/is_boolean/#examples","title":"Examples","text":"Example

    The following code exemplifies is_boolean() for all JSON types.

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create JSON values\n    json j_null;\n    json j_boolean = true;\n    json j_number_integer = 17;\n    json j_number_unsigned_integer = 12345678987654321u;\n    json j_number_float = 23.42;\n    json j_object = {{\"one\", 1}, {\"two\", 2}};\n    json j_array = {1, 2, 4, 8, 16};\n    json j_string = \"Hello, world\";\n    json j_binary = json::binary({1, 2, 3});\n\n    // call is_boolean()\n    std::cout << std::boolalpha;\n    std::cout << j_null.is_boolean() << '\\n';\n    std::cout << j_boolean.is_boolean() << '\\n';\n    std::cout << j_number_integer.is_boolean() << '\\n';\n    std::cout << j_number_unsigned_integer.is_boolean() << '\\n';\n    std::cout << j_number_float.is_boolean() << '\\n';\n    std::cout << j_object.is_boolean() << '\\n';\n    std::cout << j_array.is_boolean() << '\\n';\n    std::cout << j_string.is_boolean() << '\\n';\n    std::cout << j_binary.is_boolean() << '\\n';\n}\n

    Output:

    false\ntrue\nfalse\nfalse\nfalse\nfalse\nfalse\nfalse\nfalse\n
    "},{"location":"api/basic_json/is_boolean/#see-also","title":"See also","text":"
    • boolean_t - the type used to store JSON booleans
    • is_primitive - checks whether the JSON value is primitive
    • basic_json_view::is_boolean - the same check on a zero-copy view
    • Types - the JSON value types and how they are stored
    "},{"location":"api/basic_json/is_boolean/#version-history","title":"Version history","text":"
    • Added in version 1.0.0.
    "},{"location":"api/basic_json/is_discarded/","title":"nlohmann::basic_json::is_discarded","text":"
    constexpr bool is_discarded() const noexcept;\n

    This function returns true for a JSON value if either:

    • the value was discarded during parsing with a callback function (see parser_callback_t), or
    • the value is the result of parsing invalid JSON with parameter allow_exceptions set to false; see parse for more information.
    "},{"location":"api/basic_json/is_discarded/#return-value","title":"Return value","text":"

    true if type is discarded, false otherwise.

    "},{"location":"api/basic_json/is_discarded/#exception-safety","title":"Exception safety","text":"

    No-throw guarantee: this member function never throws exceptions.

    "},{"location":"api/basic_json/is_discarded/#complexity","title":"Complexity","text":"

    Constant.

    "},{"location":"api/basic_json/is_discarded/#notes","title":"Notes","text":"

    Comparisons

    Discarded values are never compared equal with operator==. That is, checking whether a JSON value j is discarded will only work via:

    j.is_discarded()\n

    because

    j == json::value_t::discarded\n

    will always be false.

    Removal during parsing with callback functions

    When a value is discarded by a callback function (see parser_callback_t) during parsing, then it is removed when it is part of a structured value. For instance, if the second value of an array is discarded, instead of [null, discarded, false], the array [null, false] is returned. If the top-level value itself is discarded by the callback, the parse call returns a null value.

    After a successful parse, this function always returns false: discarded values can only occur during parsing and are either removed when inside a structured value or replaced by null at the top level. The exception is parsing with allow_exceptions set to false: a parse error then yields a discarded value for which this function returns true (see parse).

    "},{"location":"api/basic_json/is_discarded/#examples","title":"Examples","text":"Example: is_discarded() for ordinary JSON values

    The following code exemplifies is_discarded() for all JSON types.

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create JSON values\n    json j_null;\n    json j_boolean = true;\n    json j_number_integer = 17;\n    json j_number_unsigned_integer = 12345678987654321u;\n    json j_number_float = 23.42;\n    json j_object = {{\"one\", 1}, {\"two\", 2}};\n    json j_array = {1, 2, 4, 8, 16};\n    json j_string = \"Hello, world\";\n    json j_binary = json::binary({1, 2, 3});\n\n    // call is_discarded()\n    std::cout << std::boolalpha;\n    std::cout << j_null.is_discarded() << '\\n';\n    std::cout << j_boolean.is_discarded() << '\\n';\n    std::cout << j_number_integer.is_discarded() << '\\n';\n    std::cout << j_number_unsigned_integer.is_discarded() << '\\n';\n    std::cout << j_number_float.is_discarded() << '\\n';\n    std::cout << j_object.is_discarded() << '\\n';\n    std::cout << j_array.is_discarded() << '\\n';\n    std::cout << j_string.is_discarded() << '\\n';\n    std::cout << j_binary.is_discarded() << '\\n';\n}\n

    Output:

    false\nfalse\nfalse\nfalse\nfalse\nfalse\nfalse\nfalse\nfalse\n
    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 false, and a parser callback that discards the top-level value (which is replaced by null and therefore does not remain discarded).

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // parsing invalid JSON without exceptions yields a discarded value\n    json j_invalid = json::parse(\"[1,2,3\", nullptr, false);\n\n    // a callback that discards the top-level value does not leave it\n    // \"discarded\" -- it is replaced by null instead\n    json j_discarded_by_callback = json::parse(\"[1,2,3]\", [](int /*depth*/, json::parse_event_t event, json& /*parsed*/)\n    {\n        return event != json::parse_event_t::array_start;\n    });\n\n    std::cout << std::boolalpha;\n    std::cout << \"j_invalid.is_discarded()               = \" << j_invalid.is_discarded() << '\\n';\n    std::cout << \"j_discarded_by_callback                = \" << j_discarded_by_callback << '\\n';\n    std::cout << \"j_discarded_by_callback.is_discarded() = \" << j_discarded_by_callback.is_discarded() << '\\n';\n}\n

    Output:

    j_invalid.is_discarded()               = true\nj_discarded_by_callback                = null\nj_discarded_by_callback.is_discarded() = false\n
    "},{"location":"api/basic_json/is_discarded/#see-also","title":"See also","text":"
    • basic_json_view::is_discarded - the corresponding check on a zero-copy view, which is true if the view refers to no value
    • Types - the JSON value types and how they are stored
    "},{"location":"api/basic_json/is_discarded/#version-history","title":"Version history","text":"
    • Added in version 1.0.0.
    "},{"location":"api/basic_json/is_null/","title":"nlohmann::basic_json::is_null","text":"
    constexpr bool is_null() const noexcept;\n

    This function returns true if and only if the JSON value is null.

    "},{"location":"api/basic_json/is_null/#return-value","title":"Return value","text":"

    true if type is null, false otherwise.

    "},{"location":"api/basic_json/is_null/#exception-safety","title":"Exception safety","text":"

    No-throw guarantee: this member function never throws exceptions.

    "},{"location":"api/basic_json/is_null/#complexity","title":"Complexity","text":"

    Constant.

    "},{"location":"api/basic_json/is_null/#examples","title":"Examples","text":"Example

    The following code exemplifies is_null() for all JSON types.

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create JSON values\n    json j_null;\n    json j_boolean = true;\n    json j_number_integer = 17;\n    json j_number_unsigned_integer = 12345678987654321u;\n    json j_number_float = 23.42;\n    json j_object = {{\"one\", 1}, {\"two\", 2}};\n    json j_array = {1, 2, 4, 8, 16};\n    json j_string = \"Hello, world\";\n    json j_binary = json::binary({1, 2, 3});\n\n    // call is_null()\n    std::cout << std::boolalpha;\n    std::cout << j_null.is_null() << '\\n';\n    std::cout << j_boolean.is_null() << '\\n';\n    std::cout << j_number_integer.is_null() << '\\n';\n    std::cout << j_number_unsigned_integer.is_null() << '\\n';\n    std::cout << j_number_float.is_null() << '\\n';\n    std::cout << j_object.is_null() << '\\n';\n    std::cout << j_array.is_null() << '\\n';\n    std::cout << j_string.is_null() << '\\n';\n    std::cout << j_binary.is_null() << '\\n';\n}\n

    Output:

    true\nfalse\nfalse\nfalse\nfalse\nfalse\nfalse\nfalse\nfalse\n
    "},{"location":"api/basic_json/is_null/#see-also","title":"See also","text":"
    • is_array - checks whether the JSON value is an array
    • is_object - checks whether the JSON value is an object
    • type - returns the type of the JSON value
    • value_t - the enumeration of JSON types
    • basic_json_view::is_null - the same check on a zero-copy view
    • Types - the JSON value types and how they are stored
    "},{"location":"api/basic_json/is_null/#version-history","title":"Version history","text":"
    • Added in version 1.0.0.
    "},{"location":"api/basic_json/is_number/","title":"nlohmann::basic_json::is_number","text":"
    constexpr bool is_number() const noexcept;\n

    This function returns true if and only if the JSON value is a number. This includes both integer (signed and unsigned) and floating-point values.

    "},{"location":"api/basic_json/is_number/#return-value","title":"Return value","text":"

    true if type is number (regardless whether integer, unsigned integer, or floating-point), false otherwise.

    "},{"location":"api/basic_json/is_number/#exception-safety","title":"Exception safety","text":"

    No-throw guarantee: this member function never throws exceptions.

    "},{"location":"api/basic_json/is_number/#complexity","title":"Complexity","text":"

    Constant.

    "},{"location":"api/basic_json/is_number/#possible-implementation","title":"Possible implementation","text":"
    constexpr bool is_number() const noexcept\n{\n    return is_number_integer() || is_number_float();\n}\n
    "},{"location":"api/basic_json/is_number/#examples","title":"Examples","text":"Example

    The following code exemplifies is_number() for all JSON types.

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create JSON values\n    json j_null;\n    json j_boolean = true;\n    json j_number_integer = 17;\n    json j_number_unsigned_integer = 12345678987654321u;\n    json j_number_float = 23.42;\n    json j_object = {{\"one\", 1}, {\"two\", 2}};\n    json j_array = {1, 2, 4, 8, 16};\n    json j_string = \"Hello, world\";\n    json j_binary = json::binary({1, 2, 3});\n\n    // call is_number()\n    std::cout << std::boolalpha;\n    std::cout << j_null.is_number() << '\\n';\n    std::cout << j_boolean.is_number() << '\\n';\n    std::cout << j_number_integer.is_number() << '\\n';\n    std::cout << j_number_unsigned_integer.is_number() << '\\n';\n    std::cout << j_number_float.is_number() << '\\n';\n    std::cout << j_object.is_number() << '\\n';\n    std::cout << j_array.is_number() << '\\n';\n    std::cout << j_string.is_number() << '\\n';\n    std::cout << j_binary.is_number() << '\\n';\n}\n

    Output:

    false\nfalse\ntrue\ntrue\ntrue\nfalse\nfalse\nfalse\nfalse\n
    "},{"location":"api/basic_json/is_number/#see-also","title":"See also","text":"
    • is_number_integer() - check if the value is an integer or unsigned integer number
    • is_number_unsigned() - check if the value is an unsigned integer number
    • is_number_float() - check if the value is a floating-point number
    • basic_json_view::is_number - the same check on a zero-copy view
    • Types - the JSON value types and how they are stored
    • Number Handling - how numbers are stored and converted
    "},{"location":"api/basic_json/is_number/#version-history","title":"Version history","text":"
    • Added in version 1.0.0.
    • Extended to also return true for unsigned integers in 2.0.0.
    "},{"location":"api/basic_json/is_number_float/","title":"nlohmann::basic_json::is_number_float","text":"
    constexpr bool is_number_float() const noexcept;\n

    This function returns true if and only if the JSON value is a floating-point number. This excludes signed and unsigned integer values.

    "},{"location":"api/basic_json/is_number_float/#return-value","title":"Return value","text":"

    true if type is a floating-point number, false otherwise.

    "},{"location":"api/basic_json/is_number_float/#exception-safety","title":"Exception safety","text":"

    No-throw guarantee: this member function never throws exceptions.

    "},{"location":"api/basic_json/is_number_float/#complexity","title":"Complexity","text":"

    Constant.

    "},{"location":"api/basic_json/is_number_float/#examples","title":"Examples","text":"Example

    The following code exemplifies is_number_float() for all JSON types.

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create JSON values\n    json j_null;\n    json j_boolean = true;\n    json j_number_integer = 17;\n    json j_number_unsigned_integer = 12345678987654321u;\n    json j_number_float = 23.42;\n    json j_object = {{\"one\", 1}, {\"two\", 2}};\n    json j_array = {1, 2, 4, 8, 16};\n    json j_string = \"Hello, world\";\n    json j_binary = json::binary({1, 2, 3});\n\n    // call is_number_float()\n    std::cout << std::boolalpha;\n    std::cout << j_null.is_number_float() << '\\n';\n    std::cout << j_boolean.is_number_float() << '\\n';\n    std::cout << j_number_integer.is_number_float() << '\\n';\n    std::cout << j_number_unsigned_integer.is_number_float() << '\\n';\n    std::cout << j_number_float.is_number_float() << '\\n';\n    std::cout << j_object.is_number_float() << '\\n';\n    std::cout << j_array.is_number_float() << '\\n';\n    std::cout << j_string.is_number_float() << '\\n';\n    std::cout << j_binary.is_number_float() << '\\n';\n}\n

    Output:

    false\nfalse\nfalse\nfalse\ntrue\nfalse\nfalse\nfalse\nfalse\n
    "},{"location":"api/basic_json/is_number_float/#see-also","title":"See also","text":"
    • is_number() - check if the value is a number
    • is_number_integer() - check if the value is an integer or unsigned integer number
    • is_number_unsigned() - check if the value is an unsigned integer number
    • basic_json_view::is_number_float - the same check on a zero-copy view
    • Types - the JSON value types and how they are stored
    • Number Handling - how numbers are stored and converted
    "},{"location":"api/basic_json/is_number_float/#version-history","title":"Version history","text":"
    • Added in version 1.0.0.
    "},{"location":"api/basic_json/is_number_integer/","title":"nlohmann::basic_json::is_number_integer","text":"
    constexpr bool is_number_integer() const noexcept;\n

    This function returns true if and only if the JSON value is a signed or unsigned integer number. This excludes floating-point values.

    "},{"location":"api/basic_json/is_number_integer/#return-value","title":"Return value","text":"

    true if type is an integer or unsigned integer number, false otherwise.

    "},{"location":"api/basic_json/is_number_integer/#exception-safety","title":"Exception safety","text":"

    No-throw guarantee: this member function never throws exceptions.

    "},{"location":"api/basic_json/is_number_integer/#complexity","title":"Complexity","text":"

    Constant.

    "},{"location":"api/basic_json/is_number_integer/#examples","title":"Examples","text":"Example

    The following code exemplifies is_number_integer() for all JSON types.

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create JSON values\n    json j_null;\n    json j_boolean = true;\n    json j_number_integer = 17;\n    json j_number_unsigned_integer = 12345678987654321u;\n    json j_number_float = 23.42;\n    json j_object = {{\"one\", 1}, {\"two\", 2}};\n    json j_array = {1, 2, 4, 8, 16};\n    json j_string = \"Hello, world\";\n    json j_binary = json::binary({1, 2, 3});\n\n    // call is_number_integer()\n    std::cout << std::boolalpha;\n    std::cout << j_null.is_number_integer() << '\\n';\n    std::cout << j_boolean.is_number_integer() << '\\n';\n    std::cout << j_number_integer.is_number_integer() << '\\n';\n    std::cout << j_number_unsigned_integer.is_number_integer() << '\\n';\n    std::cout << j_number_float.is_number_integer() << '\\n';\n    std::cout << j_object.is_number_integer() << '\\n';\n    std::cout << j_array.is_number_integer() << '\\n';\n    std::cout << j_string.is_number_integer() << '\\n';\n    std::cout << j_binary.is_number_integer() << '\\n';\n}\n

    Output:

    false\nfalse\ntrue\ntrue\nfalse\nfalse\nfalse\nfalse\nfalse\n
    "},{"location":"api/basic_json/is_number_integer/#see-also","title":"See also","text":"
    • is_number() - check if the value is a number
    • is_number_unsigned() - check if the value is an unsigned integer number
    • is_number_float() - check if the value is a floating-point number
    • basic_json_view::is_number_integer - the same check on a zero-copy view
    • Types - the JSON value types and how they are stored
    • Number Handling - how numbers are stored and converted
    "},{"location":"api/basic_json/is_number_integer/#version-history","title":"Version history","text":"
    • Added in version 1.0.0.
    • Extended to also return true for unsigned integers in 2.0.0.
    "},{"location":"api/basic_json/is_number_unsigned/","title":"nlohmann::basic_json::is_number_unsigned","text":"
    constexpr bool is_number_unsigned() const noexcept;\n

    This function returns true if and only if the JSON value is an unsigned integer number. This excludes floating-point and signed integer values.

    If number_unsigned_t is the same type as number_integer_t, every integer is stored as number_integer_t, and this function always returns false.

    "},{"location":"api/basic_json/is_number_unsigned/#return-value","title":"Return value","text":"

    true if type is an unsigned integer number, false otherwise.

    "},{"location":"api/basic_json/is_number_unsigned/#exception-safety","title":"Exception safety","text":"

    No-throw guarantee: this member function never throws exceptions.

    "},{"location":"api/basic_json/is_number_unsigned/#complexity","title":"Complexity","text":"

    Constant.

    "},{"location":"api/basic_json/is_number_unsigned/#examples","title":"Examples","text":"Example

    The following code exemplifies is_number_unsigned() for all JSON types.

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create JSON values\n    json j_null;\n    json j_boolean = true;\n    json j_number_integer = 17;\n    json j_number_unsigned_integer = 12345678987654321u;\n    json j_number_float = 23.42;\n    json j_object = {{\"one\", 1}, {\"two\", 2}};\n    json j_array = {1, 2, 4, 8, 16};\n    json j_string = \"Hello, world\";\n    json j_binary = json::binary({1, 2, 3});\n\n    // call is_number_unsigned()\n    std::cout << std::boolalpha;\n    std::cout << j_null.is_number_unsigned() << '\\n';\n    std::cout << j_boolean.is_number_unsigned() << '\\n';\n    std::cout << j_number_integer.is_number_unsigned() << '\\n';\n    std::cout << j_number_unsigned_integer.is_number_unsigned() << '\\n';\n    std::cout << j_number_float.is_number_unsigned() << '\\n';\n    std::cout << j_object.is_number_unsigned() << '\\n';\n    std::cout << j_array.is_number_unsigned() << '\\n';\n    std::cout << j_string.is_number_unsigned() << '\\n';\n    std::cout << j_binary.is_number_unsigned() << '\\n';\n}\n

    Output:

    false\nfalse\nfalse\ntrue\nfalse\nfalse\nfalse\nfalse\nfalse\n
    "},{"location":"api/basic_json/is_number_unsigned/#see-also","title":"See also","text":"
    • is_number() - check if the value is a number
    • is_number_integer() - check if the value is an integer or unsigned integer number
    • is_number_float() - check if the value is a floating-point number
    • basic_json_view::is_number_unsigned - the same check on a zero-copy view
    • Types - the JSON value types and how they are stored
    • Number Handling - how numbers are stored and converted
    "},{"location":"api/basic_json/is_number_unsigned/#version-history","title":"Version history","text":"
    • Added in version 2.0.0.
    "},{"location":"api/basic_json/is_object/","title":"nlohmann::basic_json::is_object","text":"
    constexpr bool is_object() const noexcept;\n

    This function returns true if and only if the JSON value is an object.

    "},{"location":"api/basic_json/is_object/#return-value","title":"Return value","text":"

    true if type is an object, false otherwise.

    "},{"location":"api/basic_json/is_object/#exception-safety","title":"Exception safety","text":"

    No-throw guarantee: this member function never throws exceptions.

    "},{"location":"api/basic_json/is_object/#complexity","title":"Complexity","text":"

    Constant.

    "},{"location":"api/basic_json/is_object/#examples","title":"Examples","text":"Example

    The following code exemplifies is_object() for all JSON types.

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create JSON values\n    json j_null;\n    json j_boolean = true;\n    json j_number_integer = 17;\n    json j_number_float = 23.42;\n    json j_number_unsigned_integer = 12345678987654321u;\n    json j_object = {{\"one\", 1}, {\"two\", 2}};\n    json j_array = {1, 2, 4, 8, 16};\n    json j_string = \"Hello, world\";\n    json j_binary = json::binary({1, 2, 3});\n\n    // call is_object()\n    std::cout << std::boolalpha;\n    std::cout << j_null.is_object() << '\\n';\n    std::cout << j_boolean.is_object() << '\\n';\n    std::cout << j_number_integer.is_object() << '\\n';\n    std::cout << j_number_unsigned_integer.is_object() << '\\n';\n    std::cout << j_number_float.is_object() << '\\n';\n    std::cout << j_object.is_object() << '\\n';\n    std::cout << j_array.is_object() << '\\n';\n    std::cout << j_string.is_object() << '\\n';\n    std::cout << j_binary.is_object() << '\\n';\n}\n

    Output:

    false\nfalse\nfalse\nfalse\nfalse\ntrue\nfalse\nfalse\nfalse\n
    "},{"location":"api/basic_json/is_object/#see-also","title":"See also","text":"
    • is_array - checks whether the JSON value is an array
    • is_structured - checks whether the JSON value is structured (array or object)
    • type - returns the type of the JSON value
    • object_t - the type used to store JSON objects
    • basic_json_view::is_object - the same check on a zero-copy view
    • Types - the JSON value types and how they are stored
    "},{"location":"api/basic_json/is_object/#version-history","title":"Version history","text":"
    • Added in version 1.0.0.
    "},{"location":"api/basic_json/is_primitive/","title":"nlohmann::basic_json::is_primitive","text":"
    constexpr bool is_primitive() const noexcept;\n

    This function returns true if and only if the JSON type is primitive (string, number, boolean, null, binary).

    "},{"location":"api/basic_json/is_primitive/#return-value","title":"Return value","text":"

    true if type is primitive (string, number, boolean, null, or binary), false otherwise.

    "},{"location":"api/basic_json/is_primitive/#exception-safety","title":"Exception safety","text":"

    No-throw guarantee: this member function never throws exceptions.

    "},{"location":"api/basic_json/is_primitive/#complexity","title":"Complexity","text":"

    Constant.

    "},{"location":"api/basic_json/is_primitive/#possible-implementation","title":"Possible implementation","text":"
    constexpr bool is_primitive() const noexcept\n{\n    return is_null() || is_string() || is_boolean() || is_number() || is_binary();\n}\n
    "},{"location":"api/basic_json/is_primitive/#notes","title":"Notes","text":"

    The term primitive stems from RFC 8259:

    JSON can represent four primitive types (strings, numbers, booleans, and null) and two structured types (objects and arrays).

    This library extends primitive types to binary types, because binary types are roughly comparable to strings. Hence, is_primitive() returns true for binary values.

    "},{"location":"api/basic_json/is_primitive/#examples","title":"Examples","text":"Example

    The following code exemplifies is_primitive() for all JSON types.

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create JSON values\n    json j_null;\n    json j_boolean = true;\n    json j_number_integer = 17;\n    json j_number_float = 23.42;\n    json j_number_unsigned_integer = 12345678987654321u;\n    json j_object = {{\"one\", 1}, {\"two\", 2}};\n    json j_array = {1, 2, 4, 8, 16};\n    json j_string = \"Hello, world\";\n    json j_binary = json::binary({1, 2, 3});\n\n    // call is_primitive()\n    std::cout << std::boolalpha;\n    std::cout << j_null.is_primitive() << '\\n';\n    std::cout << j_boolean.is_primitive() << '\\n';\n    std::cout << j_number_integer.is_primitive() << '\\n';\n    std::cout << j_number_unsigned_integer.is_primitive() << '\\n';\n    std::cout << j_number_float.is_primitive() << '\\n';\n    std::cout << j_object.is_primitive() << '\\n';\n    std::cout << j_array.is_primitive() << '\\n';\n    std::cout << j_string.is_primitive() << '\\n';\n    std::cout << j_binary.is_primitive() << '\\n';\n}\n

    Output:

    true\ntrue\ntrue\ntrue\ntrue\nfalse\nfalse\ntrue\ntrue\n
    "},{"location":"api/basic_json/is_primitive/#see-also","title":"See also","text":"
    • is_structured() - returns whether the JSON value is structured
    • is_null() - returns whether the JSON value is null
    • is_string() - returns whether the JSON value is a string
    • is_boolean() - returns whether the JSON value is a boolean
    • is_number() - returns whether the JSON value is a number
    • is_binary() - returns whether the JSON value is a binary array
    • basic_json_view::is_primitive - the same check on a zero-copy view
    • Types - the JSON value types and how they are stored
    "},{"location":"api/basic_json/is_primitive/#version-history","title":"Version history","text":"
    • Added in version 1.0.0.
    • Extended to return true for binary types in version 3.8.0.
    "},{"location":"api/basic_json/is_string/","title":"nlohmann::basic_json::is_string","text":"
    constexpr bool is_string() const noexcept;\n

    This function returns true if and only if the JSON value is a string.

    "},{"location":"api/basic_json/is_string/#return-value","title":"Return value","text":"

    true if type is a string, false otherwise.

    "},{"location":"api/basic_json/is_string/#exception-safety","title":"Exception safety","text":"

    No-throw guarantee: this member function never throws exceptions.

    "},{"location":"api/basic_json/is_string/#complexity","title":"Complexity","text":"

    Constant.

    "},{"location":"api/basic_json/is_string/#examples","title":"Examples","text":"Example

    The following code exemplifies is_string() for all JSON types.

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create JSON values\n    json j_null;\n    json j_boolean = true;\n    json j_number_integer = 17;\n    json j_number_float = 23.42;\n    json j_number_unsigned_integer = 12345678987654321u;\n    json j_object = {{\"one\", 1}, {\"two\", 2}};\n    json j_array = {1, 2, 4, 8, 16};\n    json j_string = \"Hello, world\";\n    json j_binary = json::binary({1, 2, 3});\n\n    // call is_string()\n    std::cout << std::boolalpha;\n    std::cout << j_null.is_string() << '\\n';\n    std::cout << j_boolean.is_string() << '\\n';\n    std::cout << j_number_integer.is_string() << '\\n';\n    std::cout << j_number_unsigned_integer.is_string() << '\\n';\n    std::cout << j_number_float.is_string() << '\\n';\n    std::cout << j_object.is_string() << '\\n';\n    std::cout << j_array.is_string() << '\\n';\n    std::cout << j_string.is_string() << '\\n';\n    std::cout << j_binary.is_string() << '\\n';\n}\n

    Output:

    false\nfalse\nfalse\nfalse\nfalse\nfalse\nfalse\ntrue\nfalse\n
    "},{"location":"api/basic_json/is_string/#see-also","title":"See also","text":"
    • is_primitive - checks whether the JSON value is primitive
    • type - returns the type of the JSON value
    • string_t - the type used to store JSON strings
    • basic_json_view::is_string - the same check on a zero-copy view
    • Types - the JSON value types and how they are stored
    "},{"location":"api/basic_json/is_string/#version-history","title":"Version history","text":"
    • Added in version 1.0.0.
    "},{"location":"api/basic_json/is_structured/","title":"nlohmann::basic_json::is_structured","text":"
    constexpr bool is_structured() const noexcept;\n

    This function returns true if and only if the JSON type is structured (array or object).

    "},{"location":"api/basic_json/is_structured/#return-value","title":"Return value","text":"

    true if type is structured (array or object), false otherwise.

    "},{"location":"api/basic_json/is_structured/#exception-safety","title":"Exception safety","text":"

    No-throw guarantee: this member function never throws exceptions.

    "},{"location":"api/basic_json/is_structured/#complexity","title":"Complexity","text":"

    Constant.

    "},{"location":"api/basic_json/is_structured/#possible-implementation","title":"Possible implementation","text":"
    constexpr bool is_structured() const noexcept\n{\n    return is_array() || is_object();\n}\n
    "},{"location":"api/basic_json/is_structured/#notes","title":"Notes","text":"

    The term structured stems from RFC 8259:

    JSON can represent four primitive types (strings, numbers, booleans, and null) and two structured types (objects and arrays).

    Note that though strings are containers in C++, they are treated as primitive values in JSON.

    "},{"location":"api/basic_json/is_structured/#examples","title":"Examples","text":"Example

    The following code exemplifies is_structured() for all JSON types.

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create JSON values\n    json j_null;\n    json j_boolean = true;\n    json j_number_integer = 17;\n    json j_number_float = 23.42;\n    json j_number_unsigned_integer = 12345678987654321u;\n    json j_object = {{\"one\", 1}, {\"two\", 2}};\n    json j_array = {1, 2, 4, 8, 16};\n    json j_string = \"Hello, world\";\n    json j_binary = json::binary({1, 2, 3});\n\n    // call is_structured()\n    std::cout << std::boolalpha;\n    std::cout << j_null.is_structured() << '\\n';\n    std::cout << j_boolean.is_structured() << '\\n';\n    std::cout << j_number_integer.is_structured() << '\\n';\n    std::cout << j_number_unsigned_integer.is_structured() << '\\n';\n    std::cout << j_number_float.is_structured() << '\\n';\n    std::cout << j_object.is_structured() << '\\n';\n    std::cout << j_array.is_structured() << '\\n';\n    std::cout << j_string.is_structured() << '\\n';\n    std::cout << j_binary.is_structured() << '\\n';\n}\n

    Output:

    false\nfalse\nfalse\nfalse\nfalse\ntrue\ntrue\nfalse\nfalse\n
    "},{"location":"api/basic_json/is_structured/#see-also","title":"See also","text":"
    • is_primitive() - returns whether JSON value is primitive
    • is_array() - returns whether the value is an array
    • is_object() - returns whether the value is an object
    • basic_json_view::is_structured - the same check on a zero-copy view
    • Types - the JSON value types and how they are stored
    "},{"location":"api/basic_json/is_structured/#version-history","title":"Version history","text":"
    • Added in version 1.0.0.
    "},{"location":"api/basic_json/items/","title":"nlohmann::basic_json::items","text":"
    iteration_proxy<iterator> items() noexcept;\niteration_proxy<const_iterator> items() const noexcept;\n

    This function allows accessing iterator::key() and iterator::value() during range-based for loops. In these loops, a reference to the JSON values is returned, so there is no access to the underlying iterator.

    For loop without items() function:

    for (auto it = j_object.begin(); it != j_object.end(); ++it)\n{\n    std::cout << \"key: \" << it.key() << \", value:\" << it.value() << '\\n';\n}\n

    Range-based for loop without items() function:

    for (auto it : j_object)\n{\n    // \"it\" is of type json::reference and has no key() member\n    std::cout << \"value: \" << it << '\\n';\n}\n

    Range-based for loop with items() function:

    for (auto& el : j_object.items())\n{\n    std::cout << \"key: \" << el.key() << \", value:\" << el.value() << '\\n';\n}\n

    The items() function also allows using structured bindings (C++17):

    for (auto& [key, val] : j_object.items())\n{\n    std::cout << \"key: \" << key << \", value:\" << val << '\\n';\n}\n

    If you need to name the type of the dereferenced element explicitly (e.g., to write a standalone function that takes it as a parameter, or to use items() with std::for_each), use decltype:

    using element_type = decltype(*j_object.items().begin());\n

    The per-element type (iteration_proxy_value) lives in the library's internal detail namespace and is intentionally unspecified as a stable, named type \u2014 decltype is the supported way to obtain it, but its exact name/definition may change between versions.

    "},{"location":"api/basic_json/items/#return-value","title":"Return value","text":"

    iteration proxy object wrapping the current value with an interface to use in range-based for loops

    "},{"location":"api/basic_json/items/#exception-safety","title":"Exception safety","text":"

    Strong guarantee: if an exception is thrown, there are no changes in the JSON value.

    "},{"location":"api/basic_json/items/#complexity","title":"Complexity","text":"

    Constant.

    "},{"location":"api/basic_json/items/#notes","title":"Notes","text":"

    When iterating over an array, key() will return the index of the element as string (see example). For primitive types (e.g., numbers), key() returns an empty string.

    Lifetime issues

    Using items() on temporary objects is dangerous. Make sure the object's lifetime exceeds the iteration. See #2040 for more information.

    "},{"location":"api/basic_json/items/#examples","title":"Examples","text":"Example

    The following code shows an example for items().

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create JSON values\n    json j_object = {{\"one\", 1}, {\"two\", 2}};\n    json j_array = {1, 2, 4, 8, 16};\n\n    // example for an object\n    for (const auto& x : j_object.items())\n    {\n        std::cout << \"key: \" << x.key() << \", value: \" << x.value() << '\\n';\n    }\n\n    // example for an array\n    for (const auto& x : j_array.items())\n    {\n        std::cout << \"key: \" << x.key() << \", value: \" << x.value() << '\\n';\n    }\n}\n

    Output:

    key: one, value: 1\nkey: two, value: 2\nkey: 0, value: 1\nkey: 1, value: 2\nkey: 2, value: 4\nkey: 3, value: 8\nkey: 4, value: 16\n
    "},{"location":"api/basic_json/items/#see-also","title":"See also","text":"
    • begin - returns an iterator to the first element
    • end - returns an iterator to one past the last element
    • basic_json_view::items - the same range on a zero-copy view (const auto, not const auto&: items are produced on the fly; document order, not sorted; duplicate keys are visited)
    • Iterators - the article on iterating over keys and values
    "},{"location":"api/basic_json/items/#version-history","title":"Version history","text":"
    • Added in version 3.1.0 as the replacement of the static function iterator_wrapper, which was available since version 1.0.0 and is deprecated since version 3.1.0.
    • Added structured binding support in version 3.5.0.

    Deprecation

    This function replaces the static function iterator_wrapper which was introduced in version 1.0.0, but has been deprecated in version 3.1.0. Function iterator_wrapper will be removed in version 4.0.0. Please replace all occurrences of iterator_wrapper(j) with j.items().

    You should be warned by your compiler with a -Wdeprecated-declarations warning if you are using a deprecated function.

    See the migration guide for how to update existing code.

    "},{"location":"api/basic_json/json_base_class_t/","title":"nlohmann::basic_json::json_base_class_t","text":"
    using json_base_class_t = detail::json_base_class<CustomBaseClass>;\n

    The base class used to inject custom functionality into each instance of basic_json. Examples of such functionality might be metadata, additional member functions (e.g., visitors), or other application-specific code.

    "},{"location":"api/basic_json/json_base_class_t/#template-parameters","title":"Template parameters","text":"CustomBaseClass the base class to be added to basic_json"},{"location":"api/basic_json/json_base_class_t/#notes","title":"Notes","text":""},{"location":"api/basic_json/json_base_class_t/#default-type","title":"Default type","text":"

    The default value for CustomBaseClass is void. In this case, an empty base class is used and no additional functionality is injected.

    "},{"location":"api/basic_json/json_base_class_t/#limitations","title":"Limitations","text":"

    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. A CustomBaseClass with non-static data members forfeits basic_json's standard layout guarantee. See Template Parameter Requirements.

    "},{"location":"api/basic_json/json_base_class_t/#name-conflicts","title":"Name conflicts","text":"

    Since basic_json derives from CustomBaseClass, members of basic_json hide members of CustomBaseClass with the same name. Hidden members remain accessible via as_base_class or by casting the value to json_base_class_t.

    Avoid generic member names

    Future versions of the library may add members to basic_json that hide members of CustomBaseClass that are accessible today. To reduce the risk of such conflicts, avoid generic names for the members of CustomBaseClass, for instance by using a distinctive prefix.

    "},{"location":"api/basic_json/json_base_class_t/#examples","title":"Examples","text":"Example

    The following code shows how to inject custom data and methods for each node.

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nclass visitor_adaptor_with_metadata\n{\n  public:\n    template <class Fnc>\n    void visit(const Fnc& fnc) const;\n\n    int metadata = 42;\n  private:\n    template <class Ptr, class Fnc>\n    void do_visit(const Ptr& ptr, const Fnc& fnc) const;\n};\n\nusing json = nlohmann::json::with_base_class_t<visitor_adaptor_with_metadata>;\n\ntemplate <class Fnc>\nvoid visitor_adaptor_with_metadata::visit(const Fnc& fnc) const\n{\n    do_visit(json::json_pointer{}, fnc);\n}\n\ntemplate <class Ptr, class Fnc>\nvoid visitor_adaptor_with_metadata::do_visit(const Ptr& ptr, const Fnc& fnc) const\n{\n    using nlohmann::detail::value_t;\n    const json& j = *static_cast<const json*>(this);\n    switch (j.type())\n    {\n        case value_t::object:\n            fnc(ptr, j);\n            for (const auto& entry : j.items())\n            {\n                entry.value().do_visit(ptr / entry.key(), fnc);\n            }\n            break;\n        case value_t::array:\n            fnc(ptr, j);\n            for (std::size_t i = 0; i < j.size(); ++i)\n            {\n                j.at(i).do_visit(ptr / std::to_string(i), fnc);\n            }\n            break;\n        case value_t::null:\n        case value_t::string:\n        case value_t::boolean:\n        case value_t::number_integer:\n        case value_t::number_unsigned:\n        case value_t::number_float:\n        case value_t::binary:\n            fnc(ptr, j);\n            break;\n        case value_t::discarded:\n        default:\n            break;\n    }\n}\n\nint main()\n{\n    // create a json object\n    json j;\n    j[\"null\"];\n    j[\"object\"][\"uint\"] = 1U;\n    j[\"object\"].metadata = 21;\n\n    // visit and output\n    j.visit(\n         [&](const json::json_pointer & p,\n             const json & j)\n    {\n        std::cout << (p.empty() ? std::string{\"/\"} : p.to_string())\n                  << \" - metadata = \" << j.metadata << \" -> \" << j.dump() << '\\n';\n    });\n}\n

    Output:

    / - metadata = 42 -> {\"null\":null,\"object\":{\"uint\":1}}\n/null - metadata = 42 -> null\n/object - metadata = 21 -> {\"uint\":1}\n/object/uint - metadata = 42 -> 1\n
    "},{"location":"api/basic_json/json_base_class_t/#see-also","title":"See also","text":"
    • as_base_class - access the custom base class
    • Template Parameter Requirements - the requirements for CustomBaseClass
    "},{"location":"api/basic_json/json_base_class_t/#version-history","title":"Version history","text":"
    • Added in version 3.11.3.
    • Made a public member type in version 3.13.0 unreleased; it was private before, so it could not be named outside the class.
    "},{"location":"api/basic_json/json_serializer/","title":"nlohmann::basic_json::json_serializer","text":"
    template<typename T, typename SFINAE>\nusing json_serializer = JSONSerializer<T, SFINAE>;\n
    "},{"location":"api/basic_json/json_serializer/#template-parameters","title":"Template parameters","text":"T type to convert; will be used in the to_json/from_json functions SFINAE type to add compile type checks via SFINAE; usually void"},{"location":"api/basic_json/json_serializer/#notes","title":"Notes","text":""},{"location":"api/basic_json/json_serializer/#default-type","title":"Default type","text":"

    The default values for json_serializer is adl_serializer.

    "},{"location":"api/basic_json/json_serializer/#requirements","title":"Requirements","text":"

    A custom serializer must provide static void to_json(basic_json&, T) for every type it serializes, and either static void from_json(const basic_json&, T&) or static T from_json(const basic_json&) for every type it deserializes. See Template Parameter Requirements.

    "},{"location":"api/basic_json/json_serializer/#examples","title":"Examples","text":"Example

    The example below shows how a conversion of a non-default-constructible type is implemented via a specialization of the adl_serializer.

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nnamespace ns\n{\n// a simple struct to model a person (not default constructible)\nstruct person\n{\n    person(std::string n, std::string a, int aa)\n        : name(std::move(n)), address(std::move(a)), age(aa)\n    {}\n\n    std::string name;\n    std::string address;\n    int age;\n};\n} // namespace ns\n\nnamespace nlohmann\n{\ntemplate <>\nstruct adl_serializer<ns::person>\n{\n    static ns::person from_json(const json& j)\n    {\n        return {j.at(\"name\"), j.at(\"address\"), j.at(\"age\")};\n    }\n\n    // Here's the catch! You must provide a to_json method! Otherwise, you\n    // will not be able to convert person to json, since you fully\n    // specialized adl_serializer on that type\n    static void to_json(json& j, ns::person p)\n    {\n        j[\"name\"] = p.name;\n        j[\"address\"] = p.address;\n        j[\"age\"] = p.age;\n    }\n};\n} // namespace nlohmann\n\nint main()\n{\n    json j;\n    j[\"name\"] = \"Ned Flanders\";\n    j[\"address\"] = \"744 Evergreen Terrace\";\n    j[\"age\"] = 60;\n\n    auto p = j.get<ns::person>();\n\n    std::cout << p.name << \" (\" << p.age << \") lives in \" << p.address << '\\n';\n}\n

    Output:

    Ned Flanders (60) lives in 744 Evergreen Terrace\n
    "},{"location":"api/basic_json/json_serializer/#see-also","title":"See also","text":"
    • adl_serializer - the default json_serializer
    • get - explicit type conversion using the json_serializer's from_json() method
    • get_to - explicit type conversion into a variable using the json_serializer's from_json() method
    • Arbitrary Type Conversions - the article on converting between JSON values and arbitrary types
    • Template Parameter Requirements - requirements on the JSONSerializer template parameter
    "},{"location":"api/basic_json/json_serializer/#version-history","title":"Version history","text":"
    • Added in version 2.1.0.
    "},{"location":"api/basic_json/max_size/","title":"nlohmann::basic_json::max_size","text":"
    size_type max_size() const noexcept;\n

    Returns the maximum number of elements a JSON value is able to hold due to system or library implementation limitations, i.e. std::distance(begin(), end()) for the JSON value.

    "},{"location":"api/basic_json/max_size/#return-value","title":"Return value","text":"

    The return value depends on the different types and is defined as follows:

    Value type return value null 0 (same as size()) boolean 1 (same as size()) string 1 (same as size()) number 1 (same as size()) binary 1 (same as size()) object result of function object_t::max_size() array result of function array_t::max_size()"},{"location":"api/basic_json/max_size/#exception-safety","title":"Exception safety","text":"

    No-throw guarantee: this function never throws exceptions.

    "},{"location":"api/basic_json/max_size/#complexity","title":"Complexity","text":"

    Constant, as long as array_t and object_t satisfy the Container concept; that is, their max_size() functions have constant complexity.

    "},{"location":"api/basic_json/max_size/#notes","title":"Notes","text":"

    This function does not return the maximal length of a string stored as JSON value \u2014 it returns the maximal number of string elements the JSON value can store which is 1.

    "},{"location":"api/basic_json/max_size/#examples","title":"Examples","text":"Example

    The following code calls max_size() on the different value types.

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create JSON values\n    json j_null;\n    json j_boolean = true;\n    json j_number_integer = 17;\n    json j_number_float = 23.42;\n    json j_object = {{\"one\", 1}, {\"two\", 2}};\n    json j_array = {1, 2, 4, 8, 16};\n    json j_string = \"Hello, world\";\n\n    // call max_size()\n    std::cout << j_null.max_size() << '\\n';\n    std::cout << j_boolean.max_size() << '\\n';\n    std::cout << j_number_integer.max_size() << '\\n';\n    std::cout << j_number_float.max_size() << '\\n';\n    std::cout << j_object.max_size() << '\\n';\n    std::cout << j_array.max_size() << '\\n';\n    std::cout << j_string.max_size() << '\\n';\n}\n

    Output:

    0\n1\n1\n1\n115292150460684697\n576460752303423487\n1\n

    Note the output is platform-dependent.

    "},{"location":"api/basic_json/max_size/#see-also","title":"See also","text":"
    • size - returns the number of elements
    • array_t - the type used to store JSON arrays
    • object_t - the type used to store JSON objects
    "},{"location":"api/basic_json/max_size/#version-history","title":"Version history","text":"
    • Added in version 1.0.0.
    • Extended to return 1 for binary types in version 3.8.0.
    "},{"location":"api/basic_json/merge_diff/","title":"nlohmann::basic_json::merge_diff","text":"
    static basic_json merge_diff(const basic_json& source,\n                             const basic_json& target);\n

    Creates a JSON Merge Patch so that value source can be changed into the value target by calling the merge_patch function. The patch contains only what differs: changed and added members with their new values, and removed members with the value null. Nested objects are compared member by member; any other value that differs, including an array, is replaced as a whole.

    For two JSON values source and target, where target contains no object member whose value is null, the following code always yields true (for ordered_json, see the notes below):

    basic_json patched = source;\npatched.merge_patch(merge_diff(source, target));\npatched == target;\n

    "},{"location":"api/basic_json/merge_diff/#parameters","title":"Parameters","text":"source (in) JSON value to compare from target (in) JSON value to compare against"},{"location":"api/basic_json/merge_diff/#return-value","title":"Return value","text":"

    a JSON Merge Patch to convert the source to target

    "},{"location":"api/basic_json/merge_diff/#exception-safety","title":"Exception safety","text":"

    Strong guarantee: source and target are never modified.

    "},{"location":"api/basic_json/merge_diff/#complexity","title":"Complexity","text":"

    Linear in the total number of values (including nested ones) in source and target, times the cost of a key-based object operation (looking up a key, or adding one to the patch): logarithmic for json, and linear for ordered_json (see ordered_map complexity). For ordered_json, diffing two objects with n and m members therefore takes O((n+m)\u00b2).

    "},{"location":"api/basic_json/merge_diff/#notes","title":"Notes","text":"
    • A merge patch uses null to remove a member, so it cannot set a member to null. As in RFC 7396, a null member of target is treated as absent: the patch removes the member from source instead of setting it to null. A member that is null in both source and target is unchanged and left out of the patch, so source keeps it.
    • A merge patch cannot reorder object members, and merge_patch appends added members at the end. For ordered_json, the patched value therefore has the same members as target, but not necessarily in the same order, and may compare unequal to it. The patch lists changed and removed members in the order of source, followed by added members in the order of target.
    "},{"location":"api/basic_json/merge_diff/#examples","title":"Examples","text":"Example

    The following code shows how a JSON Merge Patch is created as a diff for two JSON values.

    #include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\nusing namespace nlohmann::literals;\n\nint main()\n{\n    // the source document\n    json source = R\"(\n        {\n            \"title\": \"Goodbye!\",\n            \"author\": {\n                \"givenName\": \"John\",\n                \"familyName\": \"Doe\"\n            },\n            \"tags\": [\n                \"example\",\n                \"sample\"\n            ],\n            \"content\": \"This will be unchanged\"\n        }\n    )\"_json;\n\n    // the target document\n    json target = R\"(\n        {\n            \"title\": \"Hello!\",\n            \"author\": {\n                \"givenName\": \"John\"\n            },\n            \"tags\": [\n                \"example\"\n            ],\n            \"content\": \"This will be unchanged\",\n            \"phoneNumber\": \"+01-123-456-7890\"\n        }\n    )\"_json;\n\n    // create the patch\n    json patch = json::merge_diff(source, target);\n\n    // roundtrip\n    json patched_source = source;\n    patched_source.merge_patch(patch);\n\n    // output patch and roundtrip result\n    std::cout << std::setw(4) << patch << \"\\n\\n\"\n              << std::setw(4) << patched_source << '\\n';\n}\n

    Output:

    {\n    \"author\": {\n        \"familyName\": null\n    },\n    \"phoneNumber\": \"+01-123-456-7890\",\n    \"tags\": [\n        \"example\"\n    ],\n    \"title\": \"Hello!\"\n}\n\n{\n    \"author\": {\n        \"givenName\": \"John\"\n    },\n    \"content\": \"This will be unchanged\",\n    \"phoneNumber\": \"+01-123-456-7890\",\n    \"tags\": [\n        \"example\"\n    ],\n    \"title\": \"Hello!\"\n}\n
    "},{"location":"api/basic_json/merge_diff/#see-also","title":"See also","text":"
    • RFC 7396 (JSON Merge Patch) - specification of JSON Merge Patch
    • merge_patch - applies a JSON Merge Patch
    • diff - creates a diff as a JSON Patch
    • JSON Merge Patch - the article on JSON Merge Patch
    "},{"location":"api/basic_json/merge_diff/#version-history","title":"Version history","text":"
    • Added in version 3.13.0 unreleased.
    "},{"location":"api/basic_json/merge_patch/","title":"nlohmann::basic_json::merge_patch","text":"
    void merge_patch(const basic_json& apply_patch);\n

    The merge patch format is primarily intended for use with the HTTP PATCH method as a means of describing a set of modifications to a target resource's content. This function applies a merge patch to the current JSON value.

    The function implements the following algorithm from Section 2 of RFC 7396 (JSON Merge Patch):

    define MergePatch(Target, Patch):\n  if Patch is an Object:\n    if Target is not an Object:\n      Target = {} // Ignore the contents and set it to an empty Object\n    for each Name/Value pair in Patch:\n      if Value is null:\n        if Name exists in Target:\n          remove the Name/Value pair from Target\n      else:\n        Target[Name] = MergePatch(Target[Name], Value)\n    return Target\n  else:\n    return Patch\n

    Thereby, Target is the current object; that is, the patch is applied to the current value.

    "},{"location":"api/basic_json/merge_patch/#parameters","title":"Parameters","text":"apply_patch (in) the patch to apply"},{"location":"api/basic_json/merge_patch/#exception-safety","title":"Exception safety","text":"

    Basic guarantee: if an exception is thrown during the operation, the JSON value may be partially modified.

    "},{"location":"api/basic_json/merge_patch/#complexity","title":"Complexity","text":"

    Linear in the total number of values (including nested ones) in apply_patch, times the cost of a key-based object operation (looking up, adding, or erasing a member): logarithmic for json, and linear for ordered_json (see ordered_map complexity). For ordered_json, patching an object that has n members with a patch that has m members therefore takes O(n\u00b7m). The cost also includes one copy of apply_patch (see the notes below).

    "},{"location":"api/basic_json/merge_patch/#notes","title":"Notes","text":"
    • apply_patch may be *this itself or refer to a value contained in *this (for example, a subobject returned by (*this)[key]); it is read as it was when merge_patch() was called, before any modification of *this. To make this possible, the function copies apply_patch before it modifies *this, so the cost includes one copy of the patch.
    • A merge patch uses null to remove a member, so it cannot set a member to null: applying {\"a\":null} to {\"a\":1} gives {}.
    • Arrays are not merged: an array in the patch replaces the target value as a whole, and a null inside an array is kept as an element. null members of the target that the patch does not mention are preserved.
    • A null in the patch only removes a member; it does not prevent the creation of the enclosing objects. Applying {\"a\":{\"b\":null}} to {} gives {\"a\":{}} (see example 15 in Appendix A of the RFC).
    • If apply_patch is not an object, it replaces the target as a whole. In particular, a null patch turns the target into null. If apply_patch is an object and the target is not, the target is first replaced by an empty object, so applying {} to 1 gives {}.
    • A merge patch cannot express every change; for example, it cannot reorder array elements or remove a specific array element. Use JSON Patch (RFC 6902) for that. merge_diff has a matching limitation, see its notes.
    • A discarded value is treated like any other non-object value: a discarded apply_patch turns the target into a discarded value, and an object patch replaces a discarded target by an object as described above.
    "},{"location":"api/basic_json/merge_patch/#examples","title":"Examples","text":"Example

    The following code shows how a JSON Merge Patch is applied to a JSON document.

    #include <iostream>\n#include <nlohmann/json.hpp>\n#include <iomanip> // for std::setw\n\nusing nlohmann::json;\nusing namespace nlohmann::literals;\n\nint main()\n{\n    // the original document\n    json document = R\"({\n                \"title\": \"Goodbye!\",\n                \"author\": {\n                    \"givenName\": \"John\",\n                    \"familyName\": \"Doe\"\n                },\n                \"tags\": [\n                    \"example\",\n                    \"sample\"\n                ],\n                \"content\": \"This will be unchanged\"\n            })\"_json;\n\n    // the patch\n    json patch = R\"({\n                \"title\": \"Hello!\",\n                \"phoneNumber\": \"+01-123-456-7890\",\n                \"author\": {\n                    \"familyName\": null\n                },\n                \"tags\": [\n                    \"example\"\n                ]\n            })\"_json;\n\n    // apply the patch\n    document.merge_patch(patch);\n\n    // output original and patched document\n    std::cout << std::setw(4) << document << '\\n';\n}\n

    Output:

    {\n    \"author\": {\n        \"givenName\": \"John\"\n    },\n    \"content\": \"This will be unchanged\",\n    \"phoneNumber\": \"+01-123-456-7890\",\n    \"tags\": [\n        \"example\"\n    ],\n    \"title\": \"Hello!\"\n}\n
    "},{"location":"api/basic_json/merge_patch/#see-also","title":"See also","text":"
    • RFC 7396 (JSON Merge Patch) - specification of JSON Merge Patch
    • patch - apply a JSON patch
    • merge_diff - creates a diff as a JSON Merge Patch
    • JSON Merge Patch - the article on JSON Merge Patch
    "},{"location":"api/basic_json/merge_patch/#version-history","title":"Version history","text":"
    • Added in version 3.1.0.
    • Fixed use of freed or relocated memory when apply_patch is *this or refers to a value contained in *this, in version 3.13.0 unreleased.
    "},{"location":"api/basic_json/meta/","title":"nlohmann::basic_json::meta","text":"
    static basic_json meta();\n

    This function returns a JSON object with information about the library, including the version number and information on the platform and compiler.

    "},{"location":"api/basic_json/meta/#return-value","title":"Return value","text":"

    JSON object holding version information

    key description compiler Information on the used compiler. It is an object with the following keys: c++ (the used C++ standard), family (the compiler family; possible values are clang, icc, gcc, hp, ilecpp, msvc, pgcpp, sunpro, and unknown), and version (the compiler version). copyright The copyright line for the library as string. name The name of the library as string. platform The used platform as string. Possible values are win32, linux, apple, unix, and unknown. url The URL of the project as string. version The version of the library. It is an object with the following keys: major, minor, and patch as defined by Semantic Versioning, and string (the version string)."},{"location":"api/basic_json/meta/#exception-safety","title":"Exception safety","text":"

    Strong guarantee: if an exception is thrown, there are no changes to any JSON value.

    "},{"location":"api/basic_json/meta/#complexity","title":"Complexity","text":"

    Constant.

    "},{"location":"api/basic_json/meta/#examples","title":"Examples","text":"Example

    The following code shows an example output of the meta() function.

    #include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // call meta()\n    std::cout << std::setw(4) << json::meta() << '\\n';\n}\n

    Output:

    {\n    \"compiler\": {\n        \"c++\": \"201103\",\n        \"family\": \"gcc\",\n        \"version\": \"12.4.0\"\n    },\n    \"copyright\": \"(C) 2013-2026 Niels Lohmann\",\n    \"name\": \"JSON for Modern C++\",\n    \"platform\": \"apple\",\n    \"url\": \"https://github.com/nlohmann/json\",\n    \"version\": {\n        \"major\": 3,\n        \"minor\": 12,\n        \"patch\": 0,\n        \"string\": \"3.12.0\"\n    }\n}\n

    Note the output is platform-dependent.

    "},{"location":"api/basic_json/meta/#see-also","title":"See also","text":"
    • NLOHMANN_JSON_VERSION_MAJOR / NLOHMANN_JSON_VERSION_MINOR / NLOHMANN_JSON_VERSION_PATCH - library version information
    • Integration - integrate the library
    • Supported Macros - guide to all supported macros
    "},{"location":"api/basic_json/meta/#version-history","title":"Version history","text":"
    • Added in version 2.1.0.
    "},{"location":"api/basic_json/number_float_t/","title":"nlohmann::basic_json::number_float_t","text":"
    using number_float_t = NumberFloatType;\n

    The type used to store JSON numbers (floating-point).

    RFC 8259 describes numbers as follows:

    The representation of numbers is similar to that used in most programming languages. A number is represented in base 10 using decimal digits. It contains an integer component that may be prefixed with an optional minus sign, which may be followed by a fraction part and/or an exponent part. Leading zeros are not allowed. (...) Numeric values that cannot be represented in the grammar below (such as Infinity and NaN) are not permitted.

    This description includes both integer and floating-point numbers. However, C++ allows more precise storage if it is known whether the number is a signed integer, an unsigned integer, or a floating-point number. Therefore, three different types, number_integer_t, number_unsigned_t and number_float_t are used.

    To store floating-point numbers in C++, a type is defined by the template parameter NumberFloatType which chooses the type to use.

    "},{"location":"api/basic_json/number_float_t/#template-parameters","title":"Template parameters","text":"NumberFloatType the type to store floating-point numbers. The type must be float, double, or long double. The parser converts float, double, and a long double that is IEEE 754 binary64 itself. It converts other long double formats with std::from_chars where available, or with std::strtold otherwise. Serialization falls back to std::snprintf. The binary formats additionally require float or double, because they have no encoding for long double. See Template Parameter Requirements."},{"location":"api/basic_json/number_float_t/#notes","title":"Notes","text":""},{"location":"api/basic_json/number_float_t/#default-type","title":"Default type","text":"

    With the default values for NumberFloatType (double), the default type for number_float_t is double.

    "},{"location":"api/basic_json/number_float_t/#default-behavior","title":"Default behavior","text":"
    • 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.
    "},{"location":"api/basic_json/number_float_t/#limits","title":"Limits","text":"

    RFC 8259 states:

    This specification allows implementations to set limits on the range and precision of numbers accepted. Since software that implements IEEE 754-2008 binary64 (double precision) numbers is generally available and widely used, good interoperability can be achieved by implementations that expect no more precision or range than these provide, in the sense that implementations will approximate JSON numbers within the expected precision.

    This implementation does exactly follow this approach, as it uses double precision floating-point numbers by default. Note that with the default double, numbers smaller than -1.79769313486232e+308 or greater than 1.79769313486232e+308 are rejected during parsing with out_of_range.406. Non-finite values (NaN and infinity) can only be stored by assigning them directly and are serialized to null.

    During deserialization (from JSON text or any of the binary formats), a finite number that does not fit into number_float_t is rejected with out_of_range.406, for example a double-precision number in a binary format when number_float_t is float.

    "},{"location":"api/basic_json/number_float_t/#storage","title":"Storage","text":"

    Floating-point number values are stored directly inside a basic_json type.

    "},{"location":"api/basic_json/number_float_t/#examples","title":"Examples","text":"Example

    The following code shows that number_float_t is by default, a typedef to double.

    #include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    std::cout << std::boolalpha << std::is_same<double, json::number_float_t>::value << '\\n';\n}\n

    Output:

    true\n
    "},{"location":"api/basic_json/number_float_t/#see-also","title":"See also","text":"
    • number_integer_t - the type used to store JSON integer numbers
    • number_unsigned_t - the type used to store JSON unsigned integer numbers
    • is_number_float - checks whether the JSON value is a floating-point number
    • Number Handling - the article on number handling
    • Template Parameter Requirements - requirements on the number template parameters
    "},{"location":"api/basic_json/number_float_t/#version-history","title":"Version history","text":"
    • Added in version 1.0.0.
    "},{"location":"api/basic_json/number_integer_t/","title":"nlohmann::basic_json::number_integer_t","text":"
    using number_integer_t = NumberIntegerType;\n

    The type used to store JSON numbers (integers).

    RFC 8259 describes numbers as follows:

    The representation of numbers is similar to that used in most programming languages. A number is represented in base 10 using decimal digits. It contains an integer component that may be prefixed with an optional minus sign, which may be followed by a fraction part and/or an exponent part. Leading zeros are not allowed. (...) Numeric values that cannot be represented in the grammar below (such as Infinity and NaN) are not permitted.

    This description includes both integer and floating-point numbers. However, C++ allows more precise storage if it is known whether the number is a signed integer, an unsigned integer, or a floating-point number. Therefore, three different types, number_integer_t, number_unsigned_t and number_float_t are used.

    To store integer numbers in C++, a type is defined by the template parameter NumberIntegerType which chooses the type to use.

    "},{"location":"api/basic_json/number_integer_t/#template-parameters","title":"Template parameters","text":"NumberIntegerType the type to store signed integers. It must be a signed integral type (std::is_integral) with a std::numeric_limits specialization, and it is stored directly inside a basic_json value. See Template Parameter Requirements."},{"location":"api/basic_json/number_integer_t/#notes","title":"Notes","text":""},{"location":"api/basic_json/number_integer_t/#default-type","title":"Default type","text":"

    With the default values for NumberIntegerType (std::int64_t), the default type for number_integer_t is std::int64_t.

    "},{"location":"api/basic_json/number_integer_t/#default-behavior","title":"Default behavior","text":"
    • 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.
    "},{"location":"api/basic_json/number_integer_t/#limits","title":"Limits","text":"

    RFC 8259 specifies:

    An implementation may set limits on the range and precision of numbers.

    When the default type is used, the maximal integer number that can be stored is 9223372036854775807 (INT64_MAX) and the minimal integer number that can be stored is -9223372036854775808 (INT64_MIN). Integer numbers that are out of range will yield over/underflow when used in a constructor. During deserialization (from JSON text or any of the binary formats), too large or small integer numbers will automatically be stored as number_unsigned_t or number_float_t.

    RFC 8259 further states:

    Note that when such software is used, numbers that are integers and are in the range [-253+1, 253-1] are interoperable in the sense that implementations will agree exactly on their numeric values.

    As this range is a subrange of the exactly supported range [INT64_MIN, INT64_MAX], this class's integer type is interoperable.

    "},{"location":"api/basic_json/number_integer_t/#storage","title":"Storage","text":"

    Integer number values are stored directly inside a basic_json type.

    "},{"location":"api/basic_json/number_integer_t/#examples","title":"Examples","text":"Example

    The following code shows that number_integer_t is by default, a typedef to std::int64_t.

    #include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    std::cout << std::boolalpha << std::is_same<std::int64_t, json::number_integer_t>::value << '\\n';\n}\n

    Output:

    true\n
    "},{"location":"api/basic_json/number_integer_t/#see-also","title":"See also","text":"
    • number_unsigned_t - the type used to store JSON unsigned integer numbers
    • number_float_t - the type used to store JSON floating-point numbers
    • is_number_integer - checks whether the JSON value is a signed integer number
    • Number Handling - the article on number handling
    • Template Parameter Requirements - requirements on the number template parameters
    "},{"location":"api/basic_json/number_integer_t/#version-history","title":"Version history","text":"
    • Added in version 1.0.0.
    "},{"location":"api/basic_json/number_unsigned_t/","title":"nlohmann::basic_json::number_unsigned_t","text":"
    using number_unsigned_t = NumberUnsignedType;\n

    The type used to store JSON numbers (unsigned).

    RFC 8259 describes numbers as follows:

    The representation of numbers is similar to that used in most programming languages. A number is represented in base 10 using decimal digits. It contains an integer component that may be prefixed with an optional minus sign, which may be followed by a fraction part and/or an exponent part. Leading zeros are not allowed. (...) Numeric values that cannot be represented in the grammar below (such as Infinity and NaN) are not permitted.

    This description includes both integer and floating-point numbers. However, C++ allows more precise storage if it is known whether the number is a signed integer, an unsigned integer, or a floating-point number. Therefore, three different types, number_integer_t, number_unsigned_t and number_float_t are used.

    To store unsigned integer numbers in C++, a type is defined by the template parameter NumberUnsignedType which chooses the type to use.

    "},{"location":"api/basic_json/number_unsigned_t/#template-parameters","title":"Template parameters","text":"NumberUnsignedType the type to store unsigned integers. It must be an unsigned integral type (std::is_integral) with a std::numeric_limits specialization, and it must be able to represent the absolute value of every number_integer_t value. Alternatively, it can be the same type as number_integer_t; then every integer is stored as number_integer_t. See Template Parameter Requirements."},{"location":"api/basic_json/number_unsigned_t/#notes","title":"Notes","text":""},{"location":"api/basic_json/number_unsigned_t/#default-type","title":"Default type","text":"

    With the default values for NumberUnsignedType (std::uint64_t), the default type for number_unsigned_t is std::uint64_t.

    "},{"location":"api/basic_json/number_unsigned_t/#default-behavior","title":"Default behavior","text":"
    • 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.
    "},{"location":"api/basic_json/number_unsigned_t/#limits","title":"Limits","text":"

    RFC 8259 specifies:

    An implementation may set limits on the range and precision of numbers.

    When the default type is used, the maximal integer number that can be stored is 18446744073709551615 (UINT64_MAX) and the minimal integer number that can be stored is 0. Integer numbers that are out of range will yield over/underflow when used in a constructor. During deserialization (from JSON text or any of the binary formats), too large or small integer numbers will automatically be stored as number_integer_t or number_float_t.

    RFC 8259 further states:

    Note that when such software is used, numbers that are integers and are in the range [-253+1, 253-1] are interoperable in the sense that implementations will agree exactly on their numeric values.

    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.

    "},{"location":"api/basic_json/number_unsigned_t/#storage","title":"Storage","text":"

    Integer number values are stored directly inside a basic_json type.

    "},{"location":"api/basic_json/number_unsigned_t/#examples","title":"Examples","text":"Example

    The following code shows that number_unsigned_t is by default, a typedef to std::uint64_t.

    #include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    std::cout << std::boolalpha << std::is_same<std::uint64_t, json::number_unsigned_t>::value << '\\n';\n}\n

    Output:

    true\n
    "},{"location":"api/basic_json/number_unsigned_t/#see-also","title":"See also","text":"
    • number_integer_t - the type used to store JSON integer numbers
    • number_float_t - the type used to store JSON floating-point numbers
    • is_number_unsigned - checks whether the JSON value is an unsigned integer number
    • Number Handling - the article on number handling
    • Template Parameter Requirements - requirements on the number template parameters
    "},{"location":"api/basic_json/number_unsigned_t/#version-history","title":"Version history","text":"
    • Added in version 2.0.0.
    • Can be the same type as number_integer_t since version 3.13.0 unreleased.
    "},{"location":"api/basic_json/object/","title":"nlohmann::basic_json::object","text":"
    static basic_json object(initializer_list_t init = {});\n

    Creates a JSON object value from a given initializer list. The initializer lists elements must be pairs, and their first elements must be strings. If the initializer list is empty, the empty object {} is created.

    "},{"location":"api/basic_json/object/#parameters","title":"Parameters","text":"init (in) initializer list with JSON values to create an object from (optional)"},{"location":"api/basic_json/object/#return-value","title":"Return value","text":"

    JSON object value

    "},{"location":"api/basic_json/object/#exception-safety","title":"Exception safety","text":"

    Strong guarantee: if an exception is thrown, there are no changes in the JSON value.

    "},{"location":"api/basic_json/object/#exceptions","title":"Exceptions","text":"

    Throws type_error.301 if init is not a list of pairs whose first elements are strings. In this case, no object can be created. When such a value is passed to basic_json(initializer_list_t, bool, value_t), an array would have been created from the passed initializer list init. See the example below.

    "},{"location":"api/basic_json/object/#complexity","title":"Complexity","text":"

    Linear in the size of init.

    "},{"location":"api/basic_json/object/#notes","title":"Notes","text":"

    This function is only added for symmetry reasons. In contrast to the related function array(initializer_list_t), there are no cases that can only be expressed by this function. That is, any initializer list init can also be passed to the initializer list constructor basic_json(initializer_list_t, bool, value_t).

    "},{"location":"api/basic_json/object/#examples","title":"Examples","text":"Example

    The following code shows an example for the object function.

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create JSON objects\n    json j_no_init_list = json::object();\n    json j_empty_init_list = json::object({});\n    json j_list_of_pairs = json::object({ {\"one\", 1}, {\"two\", 2} });\n\n    // serialize the JSON objects\n    std::cout << j_no_init_list << '\\n';\n    std::cout << j_empty_init_list << '\\n';\n    std::cout << j_list_of_pairs << '\\n';\n\n    // example for an exception\n    try\n    {\n        // can only create an object from a list of pairs\n        json j_invalid_object = json::object({{ \"one\", 1, 2 }});\n    }\n    catch (const json::type_error& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n}\n

    Output:

    {}\n{}\n{\"one\":1,\"two\":2}\n[json.exception.type_error.301] cannot create object from initializer list\n
    "},{"location":"api/basic_json/object/#see-also","title":"See also","text":"
    • basic_json(initializer_list_t) - create a JSON value from an initializer list
    • array - create a JSON array value from an initializer list
    • Creating JSON values - the article on creating JSON values
    "},{"location":"api/basic_json/object/#version-history","title":"Version history","text":"
    • Added in version 1.0.0.
    "},{"location":"api/basic_json/object_comparator_t/","title":"nlohmann::basic_json::object_comparator_t","text":"
    using object_comparator_t = typename object_t::key_compare;\n// or\nusing object_comparator_t = default_object_comparator_t;\n

    The comparator used by object_t. Defined as typename object_t::key_compare if available, and default_object_comparator_t otherwise.

    "},{"location":"api/basic_json/object_comparator_t/#examples","title":"Examples","text":"Example

    The example below demonstrates the used object comparator.

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    std::cout << std::boolalpha\n              << \"json::object_comparator_t(\\\"one\\\", \\\"two\\\") = \" << json::object_comparator_t{}(\"one\", \"two\") << \"\\n\"\n              << \"json::object_comparator_t(\\\"three\\\", \\\"four\\\") = \" << json::object_comparator_t{}(\"three\", \"four\") << '\\n';\n}\n

    Output:

    json::object_comparator_t(\"one\", \"two\") = true\njson::object_comparator_t(\"three\", \"four\") = false\n
    "},{"location":"api/basic_json/object_comparator_t/#see-also","title":"See also","text":"
    • object_t - the type used to store JSON objects
    • default_object_comparator_t - the fallback comparator used when object_t has no key_compare member type
    • Template Parameter Requirements - requirements on the ObjectType template parameter
    • Object order - preserve the insertion order of keys
    "},{"location":"api/basic_json/object_comparator_t/#version-history","title":"Version history","text":"
    • Added in version 3.0.0.
    • Changed to be conditionally defined as typename object_t::key_compare or default_object_comparator_t in version 3.11.0.
    • Fixed the fallback to default_object_comparator_t, which previously failed to compile for object types without a key_compare member type, in version 3.13.0 unreleased.
    "},{"location":"api/basic_json/object_t/","title":"nlohmann::basic_json::object_t","text":"
    using object_t = ObjectType<StringType,\n                            basic_json,\n                            default_object_comparator_t,\n                            AllocatorType<std::pair<const StringType, basic_json>>>;\n

    The type used to store JSON objects.

    RFC 8259 describes JSON objects as follows:

    An object is an unordered collection of zero or more name/value pairs, where a name is a string and a value is a string, number, boolean, null, object, or array.

    To store objects in C++, a type is defined by the template parameters described below.

    "},{"location":"api/basic_json/object_t/#template-parameters","title":"Template parameters","text":"ObjectType the container to store objects. Its template parameters must have the same order and meaning as those of std::map; in particular, the third parameter is a comparator. std::unordered_map, whose third parameter is a hash function, therefore needs an adapter \u2014 see Template Parameter Requirements for the full list of requirements, an adapter example, and the containers that are known to work. StringType the type of the keys or names (e.g., std::string). The comparison function std::less<StringType> is used to order elements inside the container. AllocatorType the allocator to use for objects (e.g., std::allocator)"},{"location":"api/basic_json/object_t/#notes","title":"Notes","text":""},{"location":"api/basic_json/object_t/#default-type","title":"Default type","text":"

    With the default values for ObjectType (std::map), StringType (std::string), and AllocatorType (std::allocator), the default type for object_t is:

    // until C++14\nstd::map<\n  std::string, // key_type\n  basic_json, // value_type\n  std::less<std::string>, // key_compare\n  std::allocator<std::pair<const std::string, basic_json>> // allocator_type\n>\n\n// since C++14\nstd::map<\n  std::string, // key_type\n  basic_json, // value_type\n  std::less<>, // key_compare\n  std::allocator<std::pair<const std::string, basic_json>> // allocator_type\n>\n

    See default_object_comparator_t for more information.

    "},{"location":"api/basic_json/object_t/#behavior","title":"Behavior","text":"

    The choice of object_t influences the behavior of the JSON class. With the default type, objects have the following behavior:

    • When all names are unique, objects will be interoperable in the sense that all software implementations receiving that object will agree on the name-value mappings.
    • When the names within an object are not unique, it is unspecified which one of the values for a given key will be chosen. For instance, {\"key\": 2, \"key\": 1} could be equal to either {\"key\": 1} or {\"key\": 2}. To reject duplicate keys instead of silently resolving them one way or another, see this parsing recipe.
    • Internally, name/value pairs are stored in lexicographical order of the names. Objects will also be serialized (see dump) in this order. For instance, {\"b\": 1, \"a\": 2} and {\"a\": 2, \"b\": 1} will be stored and serialized as {\"a\": 2, \"b\": 1}.
    • When comparing objects, the order of the name/value pairs is irrelevant. This makes objects interoperable in the sense that they will not be affected by these differences. For instance, {\"b\": 1, \"a\": 2} and {\"a\": 2, \"b\": 1} will be treated as equal.
    "},{"location":"api/basic_json/object_t/#limits","title":"Limits","text":"

    RFC 8259 specifies:

    An implementation may set limits on the maximum depth of nesting.

    In this class, the object's limit of nesting is not explicitly constrained. However, a maximum depth of nesting may be introduced by the compiler or runtime environment. A theoretical limit can be queried by calling the max_size function of a JSON object.

    "},{"location":"api/basic_json/object_t/#storage","title":"Storage","text":"

    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.

    "},{"location":"api/basic_json/object_t/#object-key-order","title":"Object key order","text":"

    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 alphabetical order as std::map with std::less is used by default. Please note this behavior conforms to RFC 8259, because any order implements the specified \"unordered\" nature of JSON objects.

    "},{"location":"api/basic_json/object_t/#cross-basic_json-conversion-requirements","title":"Cross-basic_json conversion requirements","text":"

    When converting an object from one basic_json specialization to another via the converting constructor (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 issue #3425 for details and an example.

    "},{"location":"api/basic_json/object_t/#examples","title":"Examples","text":"Example

    The following code shows that object_t is by default, a typedef to std::map<json::string_t, json>.

    #include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    std::cout << std::boolalpha << std::is_same<std::map<json::string_t, json>, json::object_t>::value << '\\n';\n}\n

    Output:

    true\n
    "},{"location":"api/basic_json/object_t/#see-also","title":"See also","text":"
    • array_t - the type used to store JSON arrays
    • string_t - the type used to store JSON strings
    • object_comparator_t - the comparator used to order object keys
    • Object Order - the article on object key ordering
    • Types - how objects are stored
    • Template Parameter Requirements - requirements on the ObjectType template parameter
    "},{"location":"api/basic_json/object_t/#version-history","title":"Version history","text":"
    • Added in version 1.0.0.
    • Allowed object types whose erase(iterator) returns void in version 3.13.0 unreleased.
    "},{"location":"api/basic_json/operator%2B%3D/","title":"nlohmann::basic_json::operator+=","text":"
    // (1)\nreference operator+=(basic_json&& val);\nreference operator+=(const basic_json& val);\n\n// (2)\nreference operator+=(const typename object_t::value_type& val);\n\n// (3)\nreference operator+=(initializer_list_t init);\n
    1. Appends the given element val to the end of the JSON array. If the function is called on a JSON null value, an empty array is created before appending val.

    2. Inserts the given element val to the JSON object. If the function is called on a JSON null value, an empty object is created before inserting val.

    3. This function allows using operator+= with an initializer list. In case

      1. the current value is an object,
      2. the initializer list init contains only two elements, and
      3. the first element of init is a string,

      init is converted into an object element and added using operator+=(const typename object_t::value_type&). Otherwise, init is converted to a JSON value and added using operator+=(basic_json&&).

    "},{"location":"api/basic_json/operator%2B%3D/#iterator-invalidation","title":"Iterator invalidation","text":"

    For all cases where an element is added to an array, a reallocation can happen, in which case all iterators (including the end() iterator) and all references to the elements are invalidated. Otherwise, only the end() iterator is invalidated.

    For ordered_json, also adding an element to an object can yield a reallocation which again invalidates all iterators and all references.

    "},{"location":"api/basic_json/operator%2B%3D/#parameters","title":"Parameters","text":"val (in) the value to add to the JSON array/object init (in) an initializer list"},{"location":"api/basic_json/operator%2B%3D/#return-value","title":"Return value","text":"

    *this

    "},{"location":"api/basic_json/operator%2B%3D/#exception-safety","title":"Exception safety","text":"

    Strong guarantee: if an exception is thrown, there are no changes to any JSON value. As an exception, a null value is converted to an empty array or object before the element is added and keeps that type if adding the element throws.

    "},{"location":"api/basic_json/operator%2B%3D/#exceptions","title":"Exceptions","text":"
    1. Throws type_error.308 when called on a type other than JSON array or null; example: \"cannot use push_back() with number\"
    2. Throws type_error.308 when called on a type other than JSON object or null; example: \"cannot use push_back() with number\"
    3. Throws type_error.308 when called on a type other than JSON array or null; example: \"cannot use push_back() with number\"
    "},{"location":"api/basic_json/operator%2B%3D/#complexity","title":"Complexity","text":"
    1. Amortized constant.
    2. Logarithmic in the size of the container, O(log(size())).
    3. Linear in the size of the initializer list init.
    "},{"location":"api/basic_json/operator%2B%3D/#notes","title":"Notes","text":"

    (3) This function is required to resolve an ambiguous overload error, because pairs like {\"key\", \"value\"} can be both interpreted as object_t::value_type or std::initializer_list<basic_json>, see #235 for more information.

    "},{"location":"api/basic_json/operator%2B%3D/#examples","title":"Examples","text":"Example: (1) add element to array

    The example shows how push_back() and += can be used to add elements to a JSON array. Note how the null value was silently converted to a JSON array.

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create JSON values\n    json array = {1, 2, 3, 4, 5};\n    json null;\n\n    // print values\n    std::cout << array << '\\n';\n    std::cout << null << '\\n';\n\n    // add values\n    array.push_back(6);\n    array += 7;\n    null += \"first\";\n    null += \"second\";\n\n    // print values\n    std::cout << array << '\\n';\n    std::cout << null << '\\n';\n}\n

    Output:

    [1,2,3,4,5]\nnull\n[1,2,3,4,5,6,7]\n[\"first\",\"second\"]\n
    Example: (2) add element to object

    The example shows how push_back() and += can be used to add elements to a JSON object. Note how the null value was silently converted to a JSON object.

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create JSON values\n    json object = {{\"one\", 1}, {\"two\", 2}};\n    json null;\n\n    // print values\n    std::cout << object << '\\n';\n    std::cout << null << '\\n';\n\n    // add values\n    object.push_back(json::object_t::value_type(\"three\", 3));\n    object += json::object_t::value_type(\"four\", 4);\n    null += json::object_t::value_type(\"A\", \"a\");\n    null += json::object_t::value_type(\"B\", \"b\");\n\n    // print values\n    std::cout << object << '\\n';\n    std::cout << null << '\\n';\n}\n

    Output:

    {\"one\":1,\"two\":2}\nnull\n{\"four\":4,\"one\":1,\"three\":3,\"two\":2}\n{\"A\":\"a\",\"B\":\"b\"}\n
    Example: (3) add to object from initializer list

    The example shows how initializer lists are treated as objects when possible.

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create JSON values\n    json object = {{\"one\", 1}, {\"two\", 2}};\n    json null;\n\n    // print values\n    std::cout << object << '\\n';\n    std::cout << null << '\\n';\n\n    // add values:\n    object.push_back({\"three\", 3});  // object is extended\n    object += {\"four\", 4};           // object is extended\n    null.push_back({\"five\", 5});     // null is converted to array\n\n    // print values\n    std::cout << object << '\\n';\n    std::cout << null << '\\n';\n\n    // would throw:\n    //object.push_back({1, 2, 3});\n}\n

    Output:

    {\"one\":1,\"two\":2}\nnull\n{\"four\":4,\"one\":1,\"three\":3,\"two\":2}\n[[\"five\",5]]\n
    "},{"location":"api/basic_json/operator%2B%3D/#see-also","title":"See also","text":"
    • emplace_back - add a value to an array
    • push_back - add a value to an array/object
    • Modifying values - the article on modifying values
    "},{"location":"api/basic_json/operator%2B%3D/#version-history","title":"Version history","text":"
    1. Added in version 1.0.0.
    2. Added in version 1.0.0.
    3. Added in version 2.0.0.
    "},{"location":"api/basic_json/operator%3D/","title":"nlohmann::basic_json::operator=","text":"
    basic_json& operator=(basic_json other) noexcept (\n    std::is_nothrow_move_constructible<value_t>::value &&\n    std::is_nothrow_move_assignable<value_t>::value &&\n    std::is_nothrow_move_constructible<json_value>::value &&\n    std::is_nothrow_move_assignable<json_value>::value &&\n    std::is_nothrow_move_assignable<json_base_class_t>::value\n);\n

    Copy assignment operator. Copies a JSON value via the \"copy and swap\" strategy: It is expressed in terms of the copy constructor, destructor, and the swap() member function.

    "},{"location":"api/basic_json/operator%3D/#parameters","title":"Parameters","text":"other (in) value to copy from"},{"location":"api/basic_json/operator%3D/#exception-safety","title":"Exception safety","text":"

    Strong guarantee: if an exception is thrown while copying other, there are no changes to *this.

    "},{"location":"api/basic_json/operator%3D/#complexity","title":"Complexity","text":"

    Linear.

    "},{"location":"api/basic_json/operator%3D/#examples","title":"Examples","text":"Example

    The code below shows and example for the copy assignment. It creates a copy of value a which is then swapped with b. Finally, the copy of a (which is the null value after the swap) is destroyed.

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create JSON values\n    json a = 23;\n    json b = 42;\n\n    // copy-assign a to b\n    b = a;\n\n    // serialize the JSON arrays\n    std::cout << a << '\\n';\n    std::cout << b << '\\n';\n}\n

    Output:

    23\n23\n
    "},{"location":"api/basic_json/operator%3D/#see-also","title":"See also","text":"
    • basic_json - create a JSON value
    • swap - exchanges the contents of two JSON values
    • Creating JSON values - ways to create and assign JSON values
    "},{"location":"api/basic_json/operator%3D/#version-history","title":"Version history","text":"
    • Added in version 1.0.0.
    "},{"location":"api/basic_json/operator%5B%5D/","title":"nlohmann::basic_json::operator[]","text":"
    // (1)\nreference operator[](size_type idx);\nconst_reference operator[](size_type idx) const;\n\n// (2)\nreference operator[](typename object_t::key_type key);\nconst_reference operator[](const typename object_t::key_type& key) const;\n\n// (3)\ntemplate<typename KeyType>\nreference operator[](KeyType&& key);\ntemplate<typename KeyType>\nconst_reference operator[](KeyType&& key) const;\n\n// (4)\nreference operator[](const json_pointer& ptr);\nconst_reference operator[](const json_pointer& ptr) const;\n
    1. Returns a reference to the array element at specified location idx.
    2. Returns a reference to the object element with specified key key. The non-const qualified overload takes the key by value.
    3. See 2. This overload is only available if KeyType is comparable with typename object_t::key_type and typename object_comparator_t::is_transparent denotes a type.
    4. Returns a reference to the element with specified JSON pointer ptr.
    "},{"location":"api/basic_json/operator%5B%5D/#template-parameters","title":"Template parameters","text":"KeyType A type for an object key other than json_pointer that is comparable with string_t using object_comparator_t. This can also be a string view (C++17)."},{"location":"api/basic_json/operator%5B%5D/#iterator-invalidation","title":"Iterator invalidation","text":"

    For the non-const versions 1. and 4., when passing an array index that does not exist, it is created and filled with a null value before a reference to it is returned. For this, a reallocation can happen, in which case all iterators (including the end() iterator) and all references to the elements are invalidated.

    For ordered_json, also passing an object key to the non-const versions 2., 3., and 4., a reallocation can happen which again invalidates all iterators and all references.

    "},{"location":"api/basic_json/operator%5B%5D/#parameters","title":"Parameters","text":"idx (in) index of the element to access key (in) object key of the element to access ptr (in) JSON pointer to the desired element"},{"location":"api/basic_json/operator%5B%5D/#return-value","title":"Return value","text":"
    1. (const) reference to the element at index idx
    2. (const) reference to the element at key key
    3. (const) reference to the element at key key
    4. (const) reference to the element pointed to by ptr
    "},{"location":"api/basic_json/operator%5B%5D/#exception-safety","title":"Exception safety","text":"

    Strong exception safety: if an exception occurs, the original value stays intact.

    "},{"location":"api/basic_json/operator%5B%5D/#exceptions","title":"Exceptions","text":"
    1. The function can throw the following exceptions:
      • Throws type_error.305 if the JSON value is not an array or null; in that case, using the [] operator with an index makes no sense.
      • Throws 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 throws.)
    2. The function can throw the following exceptions:
      • Throws type_error.305 if the JSON value is not an object or null; in that case, using the [] operator with a key makes no sense.
    3. See 2.
    4. The function can throw the following exceptions:

      • Throws parse_error.106 if an array index in the passed JSON pointer ptr begins with '0'.
      • Throws parse_error.109 if an array index in the passed JSON pointer ptr is not a number.
      • Throws out_of_range.402 if the array index '-' is used in the passed JSON pointer ptr for the const version.
      • Throws out_of_range.404 if the JSON pointer ptr can not be resolved.
      • Throws out_of_range.410 if an array index in the passed JSON pointer ptr exceeds the range of size_type (e.g., on 32-bit platforms).

      For the const version, an object key or array index in ptr that does not exist is not reported by an exception, but is undefined behavior (see the notes below). Use at for checked access.

      If the non-const version throws, the value is left unchanged: values it created for earlier reference tokens of ptr are removed again. This also holds for exceptions such as std::bad_alloc or std::length_error thrown while padding an array up to a very large index. With custom template parameters, this requires that erase() of the object and array types and the move operations of the custom base class do not throw.

    "},{"location":"api/basic_json/operator%5B%5D/#complexity","title":"Complexity","text":"
    1. Constant if idx is in the range of the array. Otherwise, linear in idx - size().
    2. Logarithmic in the size of the container.
    3. Logarithmic in the size of the container.
    4. Linear in the number of reference tokens of ptr; for each of them, logarithmic in the size of the object, or constant for an array. When the non-const version pads an array with null values, it is additionally linear in idx - size() for that array.
    "},{"location":"api/basic_json/operator%5B%5D/#notes","title":"Notes","text":"

    Undefined behavior and runtime assertions

    The following cases apply to the const overloads; the non-const overloads instead insert the missing element (see the notes below).

    1. If the element at index idx does not exist, the behavior is undefined and is guarded by a runtime assertion!
    2. If the element with key key does not exist, the behavior is undefined and is guarded by a runtime assertion!
    3. If the JSON pointer ptr refers to an object key or an array index that does not exist, the behavior is undefined and is guarded by a runtime assertion!
    1. The non-const version may add values: If idx is beyond the range of the array (i.e., idx >= size()), then the array is silently filled up with null values to make idx a valid reference to the last stored element. In case the value was null before, it is converted to an array.

    2. If key is not found in the object, then it is silently added to the object and filled with a null value to make key a valid reference. In case the value was null before, it is converted to an object.

    3. See 2.

    4. null values are created in arrays and objects if necessary.

      In particular:

      • If the JSON pointer points to an object key that does not exist, it is created and filled with a null value before a reference to it is returned.
      • If the JSON pointer points to an array index that does not exist, it is created and filled with a null value before a reference to it is returned. All indices between the current maximum and the given index are also filled with null.
      • The special value - is treated as a synonym for the index past the end.

      Creating intermediate levels that don't exist yet

      When the JSON pointer traverses intermediate levels that don't exist at all yet (not just a missing leaf), each missing level is created as an array or an object depending on whether the corresponding pointer token is a valid array index: the token 0, a sequence of digits that does not begin with 0, or the token - creates an array, and every other token creates an object. For example, on an initially null value, /foo/0/0/0 creates nested arrays, while /foo/one/one/one creates nested objects. Tokens such as 01 or the empty token cannot be array indices (cf. RFC 6901, Sect. 4) and therefore create objects, just as they would if the level already existed as an object. This is not specified by the JSON Pointer RFC; it is this library's own, intentional disambiguation rule. See also JSON Pointer.

      Large array indices

      As the array is filled up with null values to the given index, the memory used grows with the index and not with the size of the pointer: on a 64-bit platform, the index 10000000 allocates about 160 MB. The library does not limit the index, so check the array indices of a JSON pointer from untrusted input before using it with the non-const version. See Parsing untrusted input.

    Deprecation

    Overload (4) also accepts a json_pointer 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 for how to update existing code.

    "},{"location":"api/basic_json/operator%5B%5D/#examples","title":"Examples","text":"Example: (1) access specified array element

    The example below shows how array elements can be read and written using [] operator. Note the addition of null values.

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create a JSON array\n    json array = {1, 2, 3, 4, 5};\n\n    // output element at index 3 (fourth element)\n    std::cout << array[3] << '\\n';\n\n    // change last element to 6\n    array[array.size() - 1] = 6;\n\n    // output changed array\n    std::cout << array << '\\n';\n\n    // write beyond array limit\n    array[10] = 11;\n\n    // output changed array\n    std::cout << array << '\\n';\n}\n

    Output:

    4\n[1,2,3,4,6]\n[1,2,3,4,6,null,null,null,null,null,11]\n
    Example: (1) access specified array element (const)

    The example below shows how array elements can be read using the [] operator.

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create JSON array\n    const json array = {\"first\", \"2nd\", \"third\", \"fourth\"};\n\n    // output element at index 2 (third element)\n    std::cout << array.at(2) << '\\n';\n}\n

    Output:

    \"third\"\n
    Example: (2) access specified object element

    The example below shows how object elements can be read and written using the [] operator.

    #include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create a JSON object\n    json object =\n    {\n        {\"one\", 1}, {\"two\", 2}, {\"three\", 2.9}\n    };\n\n    // output element with key \"two\"\n    std::cout << object[\"two\"] << \"\\n\\n\";\n\n    // change element with key \"three\"\n    object[\"three\"] = 3;\n\n    // output changed array\n    std::cout << std::setw(4) << object << \"\\n\\n\";\n\n    // mention nonexisting key\n    object[\"four\"];\n\n    // write to nonexisting key\n    object[\"five\"][\"really\"][\"nested\"] = true;\n\n    // output changed object\n    std::cout << std::setw(4) << object << '\\n';\n}\n

    Output:

    2\n\n{\n    \"one\": 1,\n    \"three\": 3,\n    \"two\": 2\n}\n\n{\n    \"five\": {\n        \"really\": {\n            \"nested\": true\n        }\n    },\n    \"four\": null,\n    \"one\": 1,\n    \"three\": 3,\n    \"two\": 2\n}\n
    Example: (2) access specified object element (const)

    The example below shows how object elements can be read using the [] operator.

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create a JSON object\n    const json object =\n    {\n        {\"one\", 1}, {\"two\", 2}, {\"three\", 2.9}\n    };\n\n    // output element with key \"two\"\n    std::cout << object[\"two\"] << '\\n';\n}\n

    Output:

    2\n
    Example: (3) access specified object element using string_view

    The example below shows how object elements can be read using the [] operator.

    #include <iostream>\n#include <iomanip>\n#include <string_view>\n#include <nlohmann/json.hpp>\n\nusing namespace std::string_view_literals;\nusing nlohmann::json;\n\nint main()\n{\n    // create a JSON object\n    json object =\n    {\n        {\"one\", 1}, {\"two\", 2}, {\"three\", 2.9}\n    };\n\n    // output element with key \"two\"\n    std::cout << object[\"two\"sv] << \"\\n\\n\";\n\n    // change element with key \"three\"\n    object[\"three\"sv] = 3;\n\n    // output changed array\n    std::cout << std::setw(4) << object << \"\\n\\n\";\n\n    // mention nonexisting key\n    object[\"four\"sv];\n\n    // write to nonexisting key\n    object[\"five\"sv][\"really\"sv][\"nested\"sv] = true;\n\n    // output changed object\n    std::cout << std::setw(4) << object << '\\n';\n}\n

    Output:

    2\n\n{\n    \"one\": 1,\n    \"three\": 3,\n    \"two\": 2\n}\n\n{\n    \"five\": {\n        \"really\": {\n            \"nested\": true\n        }\n    },\n    \"four\": null,\n    \"one\": 1,\n    \"three\": 3,\n    \"two\": 2\n}\n
    Example: (3) access specified object element using string_view (const)

    The example below shows how object elements can be read using the [] operator.

    #include <iostream>\n#include <string_view>\n#include <nlohmann/json.hpp>\n\nusing namespace std::string_view_literals;\nusing nlohmann::json;\n\nint main()\n{\n    // create a JSON object\n    const json object =\n    {\n        {\"one\", 1}, {\"two\", 2}, {\"three\", 2.9}\n    };\n\n    // output element with key \"two\"\n    std::cout << object[\"two\"sv] << '\\n';\n}\n

    Output:

    2\n
    Example: (4) access specified element via JSON Pointer

    The example below shows how values can be read and written using JSON Pointers.

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\nusing namespace nlohmann::literals;\n\nint main()\n{\n    // create a JSON value\n    json j =\n    {\n        {\"number\", 1}, {\"string\", \"foo\"}, {\"array\", {1, 2}}\n    };\n\n    // read-only access\n\n    // output element with JSON pointer \"/number\"\n    std::cout << j[\"/number\"_json_pointer] << '\\n';\n    // output element with JSON pointer \"/string\"\n    std::cout << j[\"/string\"_json_pointer] << '\\n';\n    // output element with JSON pointer \"/array\"\n    std::cout << j[\"/array\"_json_pointer] << '\\n';\n    // output element with JSON pointer \"/array/1\"\n    std::cout << j[\"/array/1\"_json_pointer] << '\\n';\n\n    // writing access\n\n    // change the string\n    j[\"/string\"_json_pointer] = \"bar\";\n    // output the changed string\n    std::cout << j[\"string\"] << '\\n';\n\n    // \"change\" a nonexisting object entry\n    j[\"/boolean\"_json_pointer] = true;\n    // output the changed object\n    std::cout << j << '\\n';\n\n    // change an array element\n    j[\"/array/1\"_json_pointer] = 21;\n    // \"change\" an array element with nonexisting index\n    j[\"/array/4\"_json_pointer] = 44;\n    // output the changed array\n    std::cout << j[\"array\"] << '\\n';\n\n    // \"change\" the array element past the end\n    j[\"/array/-\"_json_pointer] = 55;\n    // output the changed array\n    std::cout << j[\"array\"] << '\\n';\n}\n

    Output:

    1\n\"foo\"\n[1,2]\n2\n\"bar\"\n{\"array\":[1,2],\"boolean\":true,\"number\":1,\"string\":\"bar\"}\n[1,21,null,null,44]\n[1,21,null,null,44,55]\n
    Example: (4) access specified element via JSON Pointer (const)

    The example below shows how values can be read using JSON Pointers.

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\nusing namespace nlohmann::literals;\n\nint main()\n{\n    // create a JSON value\n    const json j =\n    {\n        {\"number\", 1}, {\"string\", \"foo\"}, {\"array\", {1, 2}}\n    };\n\n    // read-only access\n\n    // output element with JSON pointer \"/number\"\n    std::cout << j[\"/number\"_json_pointer] << '\\n';\n    // output element with JSON pointer \"/string\"\n    std::cout << j[\"/string\"_json_pointer] << '\\n';\n    // output element with JSON pointer \"/array\"\n    std::cout << j[\"/array\"_json_pointer] << '\\n';\n    // output element with JSON pointer \"/array/1\"\n    std::cout << j[\"/array/1\"_json_pointer] << '\\n';\n}\n

    Output:

    1\n\"foo\"\n[1,2]\n2\n
    "},{"location":"api/basic_json/operator%5B%5D/#see-also","title":"See also","text":"
    • Unchecked access - element access without range checking
    • Runtime assertions - assertions guarding against undefined behavior
    • at - access by reference with range checking
    • value - access with default value
    • basic_json_view::operator[] - the same access on a zero-copy view (a duplicate key resolves to the first member, whereas parse() keeps the last; a missing key gives a discarded view instead of undefined behavior)
    • Element Access - overview of all ways to access elements
    • JSON Pointer - access nested values with a pointer
    "},{"location":"api/basic_json/operator%5B%5D/#version-history","title":"Version history","text":"
    1. Added in version 1.0.0. Fixed in version 3.13.0 unreleased to throw std::length_error instead of emptying the array and accessing it out of bounds when idx equals the maximum value of size_type. A missing index in the const version is guarded by a runtime assertion since version 3.13.0 unreleased.
    2. Added in version 1.0.0. Added overloads for T* key in version 1.1.0. The T* key overloads forward to overload 3 since version 3.11.0.
    3. Added in version 3.11.0. Support for keys convertible to std::string_view added in version 3.13.0 unreleased, consistently across the lookup functions.
    4. Added in version 2.0.0. A missing array index in the const version is guarded by a runtime assertion since version 3.13.0 unreleased. Throws parse_error.109 instead of out_of_range.404 for a one-character array index that is not a digit (e.g., /x) in version 3.13.0 unreleased, as it already did for longer ones. Fixed in version 3.13.0 unreleased to leave the value unchanged if the non-const version throws (strong exception safety, as documented); before, values created for earlier reference tokens of ptr were kept.
    "},{"location":"api/basic_json/operator_ValueType/","title":"nlohmann::basic_json::operator ValueType","text":"
    template<typename ValueType>\nJSON_EXPLICIT operator ValueType() const;\n

    Implicit type conversion between the JSON value and a compatible value. The call is realized by calling get(). See Notes for the meaning of JSON_EXPLICIT.

    "},{"location":"api/basic_json/operator_ValueType/#template-parameters","title":"Template parameters","text":"ValueType the value type to return"},{"location":"api/basic_json/operator_ValueType/#return-value","title":"Return value","text":"

    copy of the JSON value, converted to ValueType

    "},{"location":"api/basic_json/operator_ValueType/#exception-safety","title":"Exception safety","text":"

    Depends on what json_serializer<ValueType> from_json() method throws; the JSON value itself is never modified, since operator ValueType() is a const member function that only calls get().

    "},{"location":"api/basic_json/operator_ValueType/#exceptions","title":"Exceptions","text":"

    Depends on what json_serializer<ValueType> from_json() method throws

    "},{"location":"api/basic_json/operator_ValueType/#complexity","title":"Complexity","text":"

    Linear in the size of the JSON value.

    "},{"location":"api/basic_json/operator_ValueType/#notes","title":"Notes","text":"

    Definition of JSON_EXPLICIT

    By default JSON_EXPLICIT is defined to the empty string, so the signature is:

    template<typename ValueType>\noperator ValueType() const;\n

    If JSON_USE_IMPLICIT_CONVERSIONS is set to 0, JSON_EXPLICIT is defined to explicit:

    template<typename ValueType>\nexplicit operator ValueType() const;\n

    That is, implicit conversions can be switched off by defining JSON_USE_IMPLICIT_CONVERSIONS to 0.

    Future behavior change

    Implicit conversions will be switched off by default in the next major release of the library. That is, JSON_EXPLICIT will be set to explicit by default.

    You can prepare existing code by already defining JSON_USE_IMPLICIT_CONVERSIONS to 0 and replace any implicit conversions with calls to get.

    See the migration guide for how to update existing code.

    "},{"location":"api/basic_json/operator_ValueType/#examples","title":"Examples","text":"Example

    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::map<std::string, json>.

    #include <iostream>\n#include <map>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create a JSON value with different types\n    json json_types =\n    {\n        {\"boolean\", true},\n        {\n            \"number\", {\n                {\"integer\", 42},\n                {\"floating-point\", 17.23}\n            }\n        },\n        {\"string\", \"Hello, world!\"},\n        {\"array\", {1, 2, 3, 4, 5}},\n        {\"null\", nullptr}\n    };\n\n    // use implicit conversions\n    bool v1 = json_types[\"boolean\"];\n    int v2 = json_types[\"number\"][\"integer\"];\n    short v3 = json_types[\"number\"][\"integer\"];\n    float v4 = json_types[\"number\"][\"floating-point\"];\n    int v5 = json_types[\"number\"][\"floating-point\"];\n    std::string v6 = json_types[\"string\"];\n    std::vector<short> v7 = json_types[\"array\"];\n    std::map<std::string, json> v8 = json_types;\n\n    // print the conversion results\n    std::cout << v1 << '\\n';\n    std::cout << v2 << ' ' << v3 << '\\n';\n    std::cout << v4 << ' ' << v5 << '\\n';\n    std::cout << v6 << '\\n';\n\n    for (auto i : v7)\n    {\n        std::cout << i << ' ';\n    }\n    std::cout << \"\\n\\n\";\n\n    for (const auto& i : v8)\n    {\n        std::cout << i.first << \": \" << i.second << '\\n';\n    }\n\n    // example for an exception\n    try\n    {\n        bool v1 = json_types[\"string\"];\n    }\n    catch (const json::type_error& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n}\n

    Output:

    1\n42 42\n17.23 17\nHello, world!\n1 2 3 4 5 \n\narray: [1,2,3,4,5]\nboolean: true\nnull: null\nnumber: {\"floating-point\":17.23,\"integer\":42}\nstring: \"Hello, world!\"\n[json.exception.type_error.302] type must be boolean, but is string\n
    "},{"location":"api/basic_json/operator_ValueType/#see-also","title":"See also","text":"
    • get - get a value (explicit conversion)
    • Converting values - the type conversions article
    "},{"location":"api/basic_json/operator_ValueType/#version-history","title":"Version history","text":"
    • Added in version 1.0.0.
    • Macros JSON_EXPLICIT/JSON_USE_IMPLICIT_CONVERSIONS added in version 3.9.0.
    "},{"location":"api/basic_json/operator_eq/","title":"nlohmann::basic_json::operator==","text":"
    // until C++20\nbool operator==(const_reference lhs, const_reference rhs) noexcept;   // (1)\n\ntemplate<typename ScalarType>\nbool operator==(const_reference lhs, const ScalarType rhs) noexcept(/* see below */); // (2)\n\ntemplate<typename ScalarType>\nbool operator==(ScalarType lhs, const const_reference rhs) noexcept(/* see below */); // (2)\n\n// since C++20\nbool operator==(const_reference rhs) const noexcept;             // (1)\n\ntemplate<typename ScalarType>\nbool operator==(ScalarType rhs) const noexcept(/* see below */); // (2)\n
    1. Compares two JSON values for equality according to the following rules:

      • Two JSON values are equal if (1) neither value is discarded, and (2) they are of the same type and their stored values are the same according to their respective operator==.
      • Integer and floating-point numbers are compared by their exact values, without converting the integer to floating-point. For instance, 9007199254740993 and 9007199254740992.0 are not equal.
    2. Compares a JSON value and a scalar or a scalar and a JSON value for equality by converting the scalar to a JSON value and comparing both JSON values according to 1.

    "},{"location":"api/basic_json/operator_eq/#template-parameters","title":"Template parameters","text":"ScalarType a scalar type according to std::is_scalar<ScalarType>::value"},{"location":"api/basic_json/operator_eq/#parameters","title":"Parameters","text":"lhs (in) first value to consider rhs (in) second value to consider"},{"location":"api/basic_json/operator_eq/#return-value","title":"Return value","text":"

    whether the values lhs/*this and rhs are equal

    "},{"location":"api/basic_json/operator_eq/#exception-safety","title":"Exception safety","text":"
    1. No-throw guarantee: this function never throws exceptions.
    2. No-throw guarantee if converting the scalar to a JSON value cannot throw, as for numbers, Booleans, and nullptr; the function is noexcept exactly in that case. Otherwise, it throws what the conversion throws, for example std::bad_alloc when converting a string, or out_of_range.410 for an enum value not mapped by NLOHMANN_JSON_SERIALIZE_ENUM_STRICT.
    "},{"location":"api/basic_json/operator_eq/#complexity","title":"Complexity","text":"

    Linear.

    "},{"location":"api/basic_json/operator_eq/#notes","title":"Notes","text":"

    Comparing special values

    • NaN values are unordered within the domain of numbers. The following comparisons all yield false:
      1. Comparing a NaN with itself.
      2. Comparing a NaN with another NaN.
      3. Comparing a NaN and any other number.
    • JSON null values are all equal.
    • Discarded values never compare equal to themselves.

    Comparing floating-point numbers

    Floating-point numbers inside JSON values numbers are compared with json::number_float_t::operator== which is double::operator== by default. To compare floating-point while respecting an epsilon, an alternative comparison function could be used, for instance

    template<typename T, typename = typename std::enable_if<std::is_floating_point<T>::value, T>::type>\ninline bool is_same(T a, T b, T epsilon = std::numeric_limits<T>::epsilon()) noexcept\n{\n    return std::abs(a - b) <= epsilon;\n}\n

    Or you can define your own equality function like this:

    bool my_equal(const_reference lhs, const_reference rhs)\n{\n    const auto lhs_type = lhs.type();\n    const auto rhs_type = rhs.type();\n    if (lhs_type == rhs_type)\n    {\n        switch(lhs_type)\n            // self_defined case\n            case value_t::number_float:\n                return std::abs(lhs - rhs) <= std::numeric_limits<float>::epsilon();\n            // other cases remain the same with the original\n            ...\n    }\n...\n}\n

    Comparing different basic_json specializations

    Comparing different basic_json specializations can have surprising effects. For instance, the result of comparing the JSON objects

    {\n   \"version\": 1,\n   \"type\": \"integer\"\n}\n

    and

    {\n   \"type\": \"integer\",\n   \"version\": 1\n}\n

    depends on whether nlohmann::json or nlohmann::ordered_json is used:

    #include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    nlohmann::json uj1 = {{\"version\", 1}, {\"type\", \"integer\"}};\n    nlohmann::json uj2 = {{\"type\", \"integer\"}, {\"version\", 1}};\n\n    nlohmann::ordered_json oj1 = {{\"version\", 1}, {\"type\", \"integer\"}};\n    nlohmann::ordered_json oj2 = {{\"type\", \"integer\"}, {\"version\", 1}};\n\n    std::cout << std::boolalpha << (uj1 == uj2) << '\\n' << (oj1 == oj2) << '\\n';\n}\n

    Output:

    true\nfalse\n
    "},{"location":"api/basic_json/operator_eq/#examples","title":"Examples","text":"Example: (1) compare JSON values

    The example demonstrates comparing several JSON types.

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create several JSON values\n    json array_1 = {1, 2, 3};\n    json array_2 = {1, 2, 4};\n    json object_1 = {{\"A\", \"a\"}, {\"B\", \"b\"}};\n    json object_2 = {{\"B\", \"b\"}, {\"A\", \"a\"}};\n    json number_1 = 17;\n    json number_2 = 17.000000000000001L;\n    json string_1 = \"foo\";\n    json string_2 = \"bar\";\n\n    // output values and comparisons\n    std::cout << std::boolalpha;\n    std::cout << array_1 << \" == \" << array_2 << \" \" << (array_1 == array_2) << '\\n';\n    std::cout << object_1 << \" == \" << object_2 << \" \" << (object_1 == object_2) << '\\n';\n    std::cout << number_1 << \" == \" << number_2 << \" \" << (number_1 == number_2) << '\\n';\n    std::cout << string_1 << \" == \" << string_2 << \" \" << (string_1 == string_2) << '\\n';\n}\n

    Output:

    [1,2,3] == [1,2,4] false\n{\"A\":\"a\",\"B\":\"b\"} == {\"A\":\"a\",\"B\":\"b\"} true\n17 == 17.0 true\n\"foo\" == \"bar\" false\n
    Example: (2) compare JSON values with nullptr

    The example demonstrates comparing several JSON types against the null pointer (JSON null).

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create several JSON values\n    json array = {1, 2, 3};\n    json object = {{\"A\", \"a\"}, {\"B\", \"b\"}};\n    json number = 17;\n    json string = \"foo\";\n    json null;\n\n    // output values and comparisons\n    std::cout << std::boolalpha;\n    std::cout << array << \" == nullptr \" << (array == nullptr) << '\\n';\n    std::cout << object << \" == nullptr \" << (object == nullptr) << '\\n';\n    std::cout << number << \" == nullptr \" << (number == nullptr) << '\\n';\n    std::cout << string << \" == nullptr \" << (string == nullptr) << '\\n';\n    std::cout << null << \" == nullptr \" << (null == nullptr) << '\\n';\n}\n

    Output:

    [1,2,3] == nullptr false\n{\"A\":\"a\",\"B\":\"b\"} == nullptr false\n17 == nullptr false\n\"foo\" == nullptr false\nnull == nullptr true\n
    "},{"location":"api/basic_json/operator_eq/#see-also","title":"See also","text":"
    • operator!= - compare for inequality
    • operator<=> - comparison: 3-way (C++20)
    • basic_json_view::operator== - the same comparison on a zero-copy view, without building a basic_json value for it
    "},{"location":"api/basic_json/operator_eq/#version-history","title":"Version history","text":"
    1. Added in version 1.0.0. Added C++20 member functions in version 3.11.0.
    2. Added in version 1.0.0. Added C++20 member functions in version 3.11.0. Made conditionally noexcept in version 3.13.0 unreleased; before, a throwing conversion called std::terminate.
    "},{"location":"api/basic_json/operator_ge/","title":"nlohmann::basic_json::operator>=","text":"
    // until C++20\nbool operator>=(const_reference lhs, const_reference rhs) noexcept;   // (1)\n\ntemplate<typename ScalarType>\nbool operator>=(const_reference lhs, const ScalarType rhs) noexcept(/* see below */); // (2)\n\ntemplate<typename ScalarType>\nbool operator>=(ScalarType lhs, const const_reference rhs) noexcept(/* see below */); // (2)\n
    1. Compares whether one JSON value lhs is greater than or equal to another JSON value rhs according to the following rules:

      • The comparison always yields false if (1) either operand is discarded, or (2) either operand is NaN and the other operand is either NaN or any other number.
      • Otherwise, returns the result of !(lhs < rhs) (see operator<).
    2. Compares whether a JSON value is greater than or equal to a scalar or a scalar is greater than or equal to a JSON value by converting the scalar to a JSON value and comparing both JSON values according to 1.

    "},{"location":"api/basic_json/operator_ge/#template-parameters","title":"Template parameters","text":"ScalarType a scalar type according to std::is_scalar<ScalarType>::value"},{"location":"api/basic_json/operator_ge/#parameters","title":"Parameters","text":"lhs (in) first value to consider rhs (in) second value to consider"},{"location":"api/basic_json/operator_ge/#return-value","title":"Return value","text":"

    whether lhs is greater than or equal to rhs

    "},{"location":"api/basic_json/operator_ge/#exception-safety","title":"Exception safety","text":"
    1. No-throw guarantee: this function never throws exceptions.
    2. No-throw guarantee if converting the scalar to a JSON value cannot throw, as for numbers, Booleans, and nullptr; the function is noexcept exactly in that case. Otherwise, it throws what the conversion throws, for example std::bad_alloc when converting a string, or out_of_range.410 for an enum value not mapped by NLOHMANN_JSON_SERIALIZE_ENUM_STRICT.
    "},{"location":"api/basic_json/operator_ge/#complexity","title":"Complexity","text":"

    Linear.

    "},{"location":"api/basic_json/operator_ge/#notes","title":"Notes","text":"

    Comparing NaN

    NaN values are unordered within the domain of numbers. The following comparisons all yield false: 1. Comparing a NaN with itself. 2. Comparing a NaN with another NaN. 3. Comparing a NaN and any other number.

    Operator overload resolution

    Since C++20 overload resolution will consider the rewritten candidate generated from operator<=>.

    Deprecation

    If JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON is defined to 1, the library declares a member 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 for how to update existing code.

    "},{"location":"api/basic_json/operator_ge/#examples","title":"Examples","text":"Example

    The example demonstrates comparing several JSON types.

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create several JSON values\n    json array_1 = {1, 2, 3};\n    json array_2 = {1, 2, 4};\n    json object_1 = {{\"A\", \"a\"}, {\"B\", \"b\"}};\n    json object_2 = {{\"B\", \"b\"}, {\"A\", \"a\"}};\n    json number_1 = 17;\n    json number_2 = 17.0000000000001L;\n    json string_1 = \"foo\";\n    json string_2 = \"bar\";\n\n    // output values and comparisons\n    std::cout << std::boolalpha;\n    std::cout << array_1 << \" >= \" << array_2 << \" \" << (array_1 >= array_2) << '\\n';\n    std::cout << object_1 << \" >= \" << object_2 << \" \" << (object_1 >= object_2) << '\\n';\n    std::cout << number_1 << \" >= \" << number_2 << \" \" << (number_1 >= number_2) << '\\n';\n    std::cout << string_1 << \" >= \" << string_2 << \" \" << (string_1 >= string_2) << '\\n';\n}\n

    Output:

    [1,2,3] >= [1,2,4] false\n{\"A\":\"a\",\"B\":\"b\"} >= {\"A\":\"a\",\"B\":\"b\"} true\n17 >= 17.0000000000001 false\n\"foo\" >= \"bar\" true\n
    "},{"location":"api/basic_json/operator_ge/#see-also","title":"See also","text":"
    • operator<=> - comparison: 3-way
    "},{"location":"api/basic_json/operator_ge/#version-history","title":"Version history","text":"
    1. Added in version 1.0.0. Conditionally removed since C++20 in version 3.11.0.
    2. Added in version 1.0.0. Conditionally removed since C++20 in version 3.11.0. Made conditionally noexcept in version 3.13.0 unreleased; before, a throwing conversion called std::terminate.
    "},{"location":"api/basic_json/operator_gt/","title":"nlohmann::basic_json::operator>","text":"
    // until C++20\nbool operator>(const_reference lhs, const_reference rhs) noexcept;   // (1)\n\ntemplate<typename ScalarType>\nbool operator>(const_reference lhs, const ScalarType rhs) noexcept(/* see below */); // (2)\n\ntemplate<typename ScalarType>\nbool operator>(ScalarType lhs, const const_reference rhs) noexcept(/* see below */); // (2)\n
    1. Compares whether one JSON value lhs is greater than another JSON value rhs according to the following rules:

      • The comparison always yields false if (1) either operand is discarded, or (2) either operand is NaN and the other operand is either NaN or any other number.
      • Otherwise, returns the result of !(lhs <= rhs) (see operator<=).
    2. Compares whether a JSON value is greater than a scalar or a scalar is greater than a JSON value by converting the scalar to a JSON value and comparing both JSON values according to 1.

    "},{"location":"api/basic_json/operator_gt/#template-parameters","title":"Template parameters","text":"ScalarType a scalar type according to std::is_scalar<ScalarType>::value"},{"location":"api/basic_json/operator_gt/#parameters","title":"Parameters","text":"lhs (in) first value to consider rhs (in) second value to consider"},{"location":"api/basic_json/operator_gt/#return-value","title":"Return value","text":"

    whether lhs is greater than rhs

    "},{"location":"api/basic_json/operator_gt/#exception-safety","title":"Exception safety","text":"
    1. No-throw guarantee: this function never throws exceptions.
    2. No-throw guarantee if converting the scalar to a JSON value cannot throw, as for numbers, Booleans, and nullptr; the function is noexcept exactly in that case. Otherwise, it throws what the conversion throws, for example std::bad_alloc when converting a string, or out_of_range.410 for an enum value not mapped by NLOHMANN_JSON_SERIALIZE_ENUM_STRICT.
    "},{"location":"api/basic_json/operator_gt/#complexity","title":"Complexity","text":"

    Linear.

    "},{"location":"api/basic_json/operator_gt/#notes","title":"Notes","text":"

    Comparing NaN

    NaN values are unordered within the domain of numbers. The following comparisons all yield false: 1. Comparing a NaN with itself. 2. Comparing a NaN with another NaN. 3. Comparing a NaN and any other number.

    Operator overload resolution

    Since C++20 overload resolution will consider the rewritten candidate generated from operator<=>.

    "},{"location":"api/basic_json/operator_gt/#examples","title":"Examples","text":"Example

    The example demonstrates comparing several JSON types.

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create several JSON values\n    json array_1 = {1, 2, 3};\n    json array_2 = {1, 2, 4};\n    json object_1 = {{\"A\", \"a\"}, {\"B\", \"b\"}};\n    json object_2 = {{\"B\", \"b\"}, {\"A\", \"a\"}};\n    json number_1 = 17;\n    json number_2 = 17.0000000000001L;\n    json string_1 = \"foo\";\n    json string_2 = \"bar\";\n\n    // output values and comparisons\n    std::cout << std::boolalpha;\n    std::cout << array_1 << \" > \" << array_2 << \" \" << (array_1 > array_2) << '\\n';\n    std::cout << object_1 << \" > \" << object_2 << \" \" << (object_1 > object_2) << '\\n';\n    std::cout << number_1 << \" > \" << number_2 << \" \" << (number_1 > number_2) << '\\n';\n    std::cout << string_1 << \" > \" << string_2 << \" \" << (string_1 > string_2) << '\\n';\n}\n

    Output:

    [1,2,3] > [1,2,4] false\n{\"A\":\"a\",\"B\":\"b\"} > {\"A\":\"a\",\"B\":\"b\"} false\n17 > 17.0000000000001 false\n\"foo\" > \"bar\" true\n
    "},{"location":"api/basic_json/operator_gt/#see-also","title":"See also","text":"
    • operator<=> - comparison: 3-way
    "},{"location":"api/basic_json/operator_gt/#version-history","title":"Version history","text":"
    1. Added in version 1.0.0. Conditionally removed since C++20 in version 3.11.0.
    2. Added in version 1.0.0. Conditionally removed since C++20 in version 3.11.0. Made conditionally noexcept in version 3.13.0 unreleased; before, a throwing conversion called std::terminate.
    "},{"location":"api/basic_json/operator_le/","title":"nlohmann::basic_json::operator<=","text":"
    // until C++20\nbool operator<=(const_reference lhs, const_reference rhs) noexcept;   // (1)\n\ntemplate<typename ScalarType>\nbool operator<=(const_reference lhs, const ScalarType rhs) noexcept(/* see below */); // (2)\n\ntemplate<typename ScalarType>\nbool operator<=(ScalarType lhs, const const_reference rhs) noexcept(/* see below */); // (2)\n
    1. Compares whether one JSON value lhs is less than or equal to another JSON value rhs according to the following rules:

      • The comparison always yields false if (1) either operand is discarded, or (2) either operand is NaN and the other operand is either NaN or any other number.
      • Otherwise, returns the result of !(rhs < lhs) (see operator<).
    2. Compares whether a JSON value is less than or equal to a scalar or a scalar is less than or equal to a JSON value by converting the scalar to a JSON value and comparing both JSON values according to 1.

    "},{"location":"api/basic_json/operator_le/#template-parameters","title":"Template parameters","text":"ScalarType a scalar type according to std::is_scalar<ScalarType>::value"},{"location":"api/basic_json/operator_le/#parameters","title":"Parameters","text":"lhs (in) first value to consider rhs (in) second value to consider"},{"location":"api/basic_json/operator_le/#return-value","title":"Return value","text":"

    whether lhs is less than or equal to rhs

    "},{"location":"api/basic_json/operator_le/#exception-safety","title":"Exception safety","text":"
    1. No-throw guarantee: this function never throws exceptions.
    2. No-throw guarantee if converting the scalar to a JSON value cannot throw, as for numbers, Booleans, and nullptr; the function is noexcept exactly in that case. Otherwise, it throws what the conversion throws, for example std::bad_alloc when converting a string, or out_of_range.410 for an enum value not mapped by NLOHMANN_JSON_SERIALIZE_ENUM_STRICT.
    "},{"location":"api/basic_json/operator_le/#complexity","title":"Complexity","text":"

    Linear.

    "},{"location":"api/basic_json/operator_le/#notes","title":"Notes","text":"

    Comparing NaN

    NaN values are unordered within the domain of numbers. The following comparisons all yield false: 1. Comparing a NaN with itself. 2. Comparing a NaN with another NaN. 3. Comparing a NaN and any other number.

    Operator overload resolution

    Since C++20 overload resolution will consider the rewritten candidate generated from operator<=>.

    Deprecation

    If JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON is defined to 1, the library declares a member 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 for how to update existing code.

    "},{"location":"api/basic_json/operator_le/#examples","title":"Examples","text":"Example

    The example demonstrates comparing several JSON types.

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create several JSON values\n    json array_1 = {1, 2, 3};\n    json array_2 = {1, 2, 4};\n    json object_1 = {{\"A\", \"a\"}, {\"B\", \"b\"}};\n    json object_2 = {{\"B\", \"b\"}, {\"A\", \"a\"}};\n    json number_1 = 17;\n    json number_2 = 17.0000000000001L;\n    json string_1 = \"foo\";\n    json string_2 = \"bar\";\n\n    // output values and comparisons\n    std::cout << std::boolalpha;\n    std::cout << array_1 << \" <= \" << array_2 << \" \" << (array_1 <= array_2) << '\\n';\n    std::cout << object_1 << \" <= \" << object_2 << \" \" << (object_1 <= object_2) << '\\n';\n    std::cout << number_1 << \" <= \" << number_2 << \" \" << (number_1 <= number_2) << '\\n';\n    std::cout << string_1 << \" <= \" << string_2 << \" \" << (string_1 <= string_2) << '\\n';\n}\n

    Output:

    [1,2,3] <= [1,2,4] true\n{\"A\":\"a\",\"B\":\"b\"} <= {\"A\":\"a\",\"B\":\"b\"} true\n17 <= 17.0000000000001 true\n\"foo\" <= \"bar\" false\n
    "},{"location":"api/basic_json/operator_le/#see-also","title":"See also","text":"
    • operator<=> - comparison: 3-way
    "},{"location":"api/basic_json/operator_le/#version-history","title":"Version history","text":"
    1. Added in version 1.0.0. Conditionally removed since C++20 in version 3.11.0.
    2. Added in version 1.0.0. Conditionally removed since C++20 in version 3.11.0. Made conditionally noexcept in version 3.13.0 unreleased; before, a throwing conversion called std::terminate.
    "},{"location":"api/basic_json/operator_lt/","title":"nlohmann::basic_json::operator<","text":"
    // until C++20\nbool operator<(const_reference lhs, const_reference rhs) noexcept;   // (1)\n\ntemplate<typename ScalarType>\nbool operator<(const_reference lhs, const ScalarType rhs) noexcept(/* see below */); // (2)\n\ntemplate<typename ScalarType>\nbool operator<(ScalarType lhs, const const_reference rhs) noexcept(/* see below */); // (2)\n
    1. Compares whether one JSON value lhs is less than another JSON value rhs according to the following rules:

      • If either operand is discarded, the comparison yields false.
      • If both operands have the same type, the values are compared using their respective operator<.
      • Integer and floating-point numbers are compared by their exact values, without converting the integer to floating-point. For instance, 9007199254740992.0 is less than 9007199254740993.
      • In case lhs and rhs have different types, the values are ignored and the order of the types is considered, which is:
        1. null
        2. boolean
        3. number (all types)
        4. object
        5. array
        6. string
        7. binary For instance, any boolean value is considered less than any string.
    2. Compares whether a JSON value is less than a scalar or a scalar is less than a JSON value by converting the scalar to a JSON value and comparing both JSON values according to 1.

    "},{"location":"api/basic_json/operator_lt/#template-parameters","title":"Template parameters","text":"ScalarType a scalar type according to std::is_scalar<ScalarType>::value"},{"location":"api/basic_json/operator_lt/#parameters","title":"Parameters","text":"lhs (in) first value to consider rhs (in) second value to consider"},{"location":"api/basic_json/operator_lt/#return-value","title":"Return value","text":"

    whether lhs is less than rhs

    "},{"location":"api/basic_json/operator_lt/#exception-safety","title":"Exception safety","text":"
    1. No-throw guarantee: this function never throws exceptions.
    2. No-throw guarantee if converting the scalar to a JSON value cannot throw, as for numbers, Booleans, and nullptr; the function is noexcept exactly in that case. Otherwise, it throws what the conversion throws, for example std::bad_alloc when converting a string, or out_of_range.410 for an enum value not mapped by NLOHMANN_JSON_SERIALIZE_ENUM_STRICT.
    "},{"location":"api/basic_json/operator_lt/#complexity","title":"Complexity","text":"

    Linear.

    "},{"location":"api/basic_json/operator_lt/#notes","title":"Notes","text":"

    Comparing NaN

    NaN values are unordered within the domain of numbers. The following comparisons all yield false: 1. Comparing a NaN with itself. 2. Comparing a NaN with another NaN. 3. Comparing a NaN and any other number.

    Operator overload resolution

    Since C++20 overload resolution will consider the rewritten candidate generated from operator<=>.

    "},{"location":"api/basic_json/operator_lt/#examples","title":"Examples","text":"Example

    The example demonstrates comparing several JSON types.

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create several JSON values\n    json array_1 = {1, 2, 3};\n    json array_2 = {1, 2, 4};\n    json object_1 = {{\"A\", \"a\"}, {\"B\", \"b\"}};\n    json object_2 = {{\"B\", \"b\"}, {\"A\", \"a\"}};\n    json number_1 = 17;\n    json number_2 = 17.0000000000001L;\n    json string_1 = \"foo\";\n    json string_2 = \"bar\";\n\n    // output values and comparisons\n    std::cout << std::boolalpha;\n    std::cout << array_1 << \" == \" << array_2 << \" \" << (array_1 < array_2) << '\\n';\n    std::cout << object_1 << \" == \" << object_2 << \" \" << (object_1 < object_2) << '\\n';\n    std::cout << number_1 << \" == \" << number_2 << \" \" << (number_1 < number_2) << '\\n';\n    std::cout << string_1 << \" == \" << string_2 << \" \" << (string_1 < string_2) << '\\n';\n}\n

    Output:

    [1,2,3] == [1,2,4] true\n{\"A\":\"a\",\"B\":\"b\"} == {\"A\":\"a\",\"B\":\"b\"} false\n17 == 17.0000000000001 true\n\"foo\" == \"bar\" false\n
    "},{"location":"api/basic_json/operator_lt/#see-also","title":"See also","text":"
    • operator<=> - comparison: 3-way
    "},{"location":"api/basic_json/operator_lt/#version-history","title":"Version history","text":"
    1. Added in version 1.0.0. Conditionally removed since C++20 in version 3.11.0.
    2. Added in version 1.0.0. Conditionally removed since C++20 in version 3.11.0. Made conditionally noexcept in version 3.13.0 unreleased; before, a throwing conversion called std::terminate.
    "},{"location":"api/basic_json/operator_ne/","title":"nlohmann::basic_json::operator!=","text":"
    // until C++20\nbool operator!=(const_reference lhs, const_reference rhs) noexcept;   // (1)\n\ntemplate<typename ScalarType>\nbool operator!=(const_reference lhs, const ScalarType rhs) noexcept(/* see below */); // (2)\n\ntemplate<typename ScalarType>\nbool operator!=(ScalarType lhs, const const_reference rhs) noexcept(/* see below */); // (2)\n
    1. Compares two JSON values for inequality. Returns !(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 value and comparing both JSON values according to 1.

    "},{"location":"api/basic_json/operator_ne/#template-parameters","title":"Template parameters","text":"ScalarType a scalar type according to std::is_scalar<ScalarType>::value"},{"location":"api/basic_json/operator_ne/#parameters","title":"Parameters","text":"lhs (in) first value to consider rhs (in) second value to consider"},{"location":"api/basic_json/operator_ne/#return-value","title":"Return value","text":"

    whether the values lhs/*this and rhs are not equal

    "},{"location":"api/basic_json/operator_ne/#exception-safety","title":"Exception safety","text":"
    1. No-throw guarantee: this function never throws exceptions.
    2. No-throw guarantee if converting the scalar to a JSON value cannot throw, as for numbers, Booleans, and nullptr; the function is noexcept exactly in that case. Otherwise, it throws what the conversion throws, for example std::bad_alloc when converting a string, or out_of_range.410 for an enum value not mapped by NLOHMANN_JSON_SERIALIZE_ENUM_STRICT.
    "},{"location":"api/basic_json/operator_ne/#complexity","title":"Complexity","text":"

    Linear.

    "},{"location":"api/basic_json/operator_ne/#notes","title":"Notes","text":"

    C++20

    Since C++20, basic_json declares no operator!=. The compiler rewrites a != b as !(a == b) using operator==, so the result is the same as described above.

    Comparing NaN and discarded

    Since operator!= is defined as !(a == b), the behavior for special values follows that of operator==:

    • For NaN values: NaN == NaN yields false, so NaN != NaN yields true.
    • For discarded values: discarded == x yields false for any x, so discarded != x yields true.
    "},{"location":"api/basic_json/operator_ne/#examples","title":"Examples","text":"Example: (1) compare JSON values

    The example demonstrates comparing several JSON types.

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create several JSON values\n    json array_1 = {1, 2, 3};\n    json array_2 = {1, 2, 4};\n    json object_1 = {{\"A\", \"a\"}, {\"B\", \"b\"}};\n    json object_2 = {{\"B\", \"b\"}, {\"A\", \"a\"}};\n    json number_1 = 17;\n    json number_2 = 17.000000000000001L;\n    json string_1 = \"foo\";\n    json string_2 = \"bar\";\n\n    // output values and comparisons\n    std::cout << std::boolalpha;\n    std::cout << array_1 << \" != \" << array_2 << \" \" << (array_1 != array_2) << '\\n';\n    std::cout << object_1 << \" != \" << object_2 << \" \" << (object_1 != object_2) << '\\n';\n    std::cout << number_1 << \" != \" << number_2 << \" \" << (number_1 != number_2) << '\\n';\n    std::cout << string_1 << \" != \" << string_2 << \" \" << (string_1 != string_2) << '\\n';\n}\n

    Output:

    [1,2,3] != [1,2,4] true\n{\"A\":\"a\",\"B\":\"b\"} != {\"A\":\"a\",\"B\":\"b\"} false\n17 != 17.0 false\n\"foo\" != \"bar\" true\n
    Example: (2) compare JSON values with nullptr

    The example demonstrates comparing several JSON types against the null pointer (JSON null).

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create several JSON values\n    json array = {1, 2, 3};\n    json object = {{\"A\", \"a\"}, {\"B\", \"b\"}};\n    json number = 17;\n    json string = \"foo\";\n    json null;\n\n    // output values and comparisons\n    std::cout << std::boolalpha;\n    std::cout << array << \" != nullptr \" << (array != nullptr) << '\\n';\n    std::cout << object << \" != nullptr \" << (object != nullptr) << '\\n';\n    std::cout << number << \" != nullptr \" << (number != nullptr) << '\\n';\n    std::cout << string << \" != nullptr \" << (string != nullptr) << '\\n';\n    std::cout << null << \" != nullptr \" << (null != nullptr) << '\\n';\n}\n

    Output:

    [1,2,3] != nullptr true\n{\"A\":\"a\",\"B\":\"b\"} != nullptr true\n17 != nullptr true\n\"foo\" != nullptr true\nnull != nullptr false\n
    "},{"location":"api/basic_json/operator_ne/#see-also","title":"See also","text":"
    • operator== - comparison: equal
    • operator<=> - comparison: 3-way (C++20)
    • basic_json_view::operator!= - the same comparison on a zero-copy view, without building a basic_json value for it
    "},{"location":"api/basic_json/operator_ne/#version-history","title":"Version history","text":"
    1. Added in version 1.0.0. Added a C++20 member function in version 3.11.0. Changed in version 3.13.0 unreleased 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 unreleased; since C++20, the compiler rewrites a != b using operator==.
    2. Added in version 1.0.0. Changed in version 3.13.0 unreleased 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==. Made conditionally noexcept in version 3.13.0 unreleased; before, a throwing conversion called std::terminate.
    "},{"location":"api/basic_json/operator_spaceship/","title":"nlohmann::basic_json::operator<=>","text":"
    // since C++20\nstd::partial_ordering operator<=>(const_reference rhs) const noexcept;                   // (1)\n\ntemplate<typename ScalarType>\nstd::partial_ordering operator<=>(const ScalarType rhs) const noexcept(/* see below */); // (2)\n
    1. 3-way compares two JSON values producing a result of type std::partial_ordering according to the following rules:

      • Two JSON values compare with a result of std::partial_ordering::unordered if either value is discarded.
      • If both JSON values are of the same type, the result is produced by 3-way comparing their stored values using their respective operator<=>.
      • Integer and floating-point numbers are 3-way compared by their exact values, without converting the integer to floating-point. For instance, 9007199254740993 compares greater than 9007199254740992.0.
      • Otherwise, yields a result by comparing the type (see value_t).
    2. 3-way compares a JSON value and a scalar or a scalar and a JSON value by converting the scalar to a JSON value and 3-way comparing both JSON values (see 1).

    "},{"location":"api/basic_json/operator_spaceship/#template-parameters","title":"Template parameters","text":"ScalarType a scalar type according to std::is_scalar<ScalarType>::value"},{"location":"api/basic_json/operator_spaceship/#parameters","title":"Parameters","text":"rhs (in) second value to consider"},{"location":"api/basic_json/operator_spaceship/#return-value","title":"Return value","text":"

    the std::partial_ordering of the 3-way comparison of *this and rhs

    "},{"location":"api/basic_json/operator_spaceship/#exception-safety","title":"Exception safety","text":"
    1. No-throw guarantee: this function never throws exceptions.
    2. No-throw guarantee if converting the scalar to a JSON value cannot throw, as for numbers, Booleans, and nullptr; the function is noexcept exactly in that case. Otherwise, it throws what the conversion throws, for example std::bad_alloc when converting a string, or out_of_range.410 for an enum value not mapped by NLOHMANN_JSON_SERIALIZE_ENUM_STRICT.
    "},{"location":"api/basic_json/operator_spaceship/#complexity","title":"Complexity","text":"

    Linear.

    "},{"location":"api/basic_json/operator_spaceship/#notes","title":"Notes","text":"

    Comparing NaN

    • NaN values are unordered within the domain of numbers. The following comparisons all yield std::partial_ordering::unordered:
      1. Comparing a NaN with itself.
      2. Comparing a NaN with another NaN.
      3. Comparing a NaN and any other number.
    "},{"location":"api/basic_json/operator_spaceship/#examples","title":"Examples","text":"Example: (1) comparing JSON values

    The example demonstrates comparing several JSON values.

    #include <compare>\n#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nconst char* to_string(const std::partial_ordering& po)\n{\n    if (std::is_lt(po))\n    {\n        return \"less\";\n    }\n    else if (std::is_gt(po))\n    {\n        return \"greater\";\n    }\n    else if (std::is_eq(po))\n    {\n        return \"equivalent\";\n    }\n    return \"unordered\";\n}\n\nint main()\n{\n    // create several JSON values\n    json array_1 = {1, 2, 3};\n    json array_2 = {1, 2, 4};\n    json object_1 = {{\"A\", \"a\"}, {\"B\", \"b\"}};\n    json object_2 = {{\"B\", \"b\"}, {\"A\", \"a\"}};\n    json number = 17;\n    json string = \"foo\";\n    json discarded = json(json::value_t::discarded);\n\n    // output values and comparisons\n    std::cout << array_1 << \" <=> \" << array_2 << \" := \" << to_string(array_1 <=> array_2) << '\\n'; // *NOPAD*\n    std::cout << object_1 << \" <=> \" << object_2 << \" := \" << to_string(object_1 <=> object_2) << '\\n'; // *NOPAD*\n    std::cout << string << \" <=> \" << number << \" := \" << to_string(string <=> number) << '\\n'; // *NOPAD*\n    std::cout << string << \" <=> \" << discarded << \" := \" << to_string(string <=> discarded) << '\\n'; // *NOPAD*\n}\n

    Output:

    [1,2,3] <=> [1,2,4] := less\n{\"A\":\"a\",\"B\":\"b\"} <=> {\"A\":\"a\",\"B\":\"b\"} := equivalent\n\"foo\" <=> 17 := greater\n\"foo\" <=> <discarded> := unordered\n
    Example: (2) comparing JSON values and scalars

    The example demonstrates comparing several JSON values and scalars.

    #include <compare>\n#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nconst char* to_string(const std::partial_ordering& po)\n{\n    if (std::is_lt(po))\n    {\n        return \"less\";\n    }\n    else if (std::is_gt(po))\n    {\n        return \"greater\";\n    }\n    else if (std::is_eq(po))\n    {\n        return \"equivalent\";\n    }\n    return \"unordered\";\n}\n\nint main()\n{\n    using float_limits = std::numeric_limits<json::number_float_t>;\n    constexpr auto nan = float_limits::quiet_NaN();\n\n    // create several JSON values\n    json boolean = false;\n    json number = 17;\n    json string = \"17\";\n\n    // output values and comparisons\n    std::cout << std::boolalpha << std::fixed;\n    std::cout << boolean << \" <=> \" << true << \" := \" << to_string(boolean <=> true) << '\\n'; // *NOPAD*\n    std::cout << number << \" <=> \" << 17.0 << \" := \" << to_string(number <=> 17.0) << '\\n'; // *NOPAD*\n    std::cout << number << \" <=> \" << nan << \" := \" << to_string(number <=> nan) << '\\n'; // *NOPAD*\n    std::cout << string << \" <=> \" << 17 << \" := \" << to_string(string <=> 17) << '\\n'; // *NOPAD*\n}\n

    Output:

    false <=> true := less\n17 <=> 17.000000 := equivalent\n17 <=> nan := unordered\n\"17\" <=> 17 := greater\n
    "},{"location":"api/basic_json/operator_spaceship/#see-also","title":"See also","text":"
    • operator== - comparison: equal
    • operator!= - comparison: not equal
    • operator< - comparison: less than
    • operator<= - comparison: less than or equal
    • operator> - comparison: greater than
    • operator>= - comparison: greater than or equal
    "},{"location":"api/basic_json/operator_spaceship/#version-history","title":"Version history","text":"
    1. Added in version 3.11.0.
    2. Added in version 3.11.0. Made conditionally noexcept in version 3.13.0 unreleased; before, a throwing conversion called std::terminate.
    "},{"location":"api/basic_json/operator_value_t/","title":"nlohmann::basic_json::operator value_t","text":"
    constexpr operator value_t() const noexcept;\n

    Return the type of the JSON value as a value from the value_t enumeration.

    "},{"location":"api/basic_json/operator_value_t/#return-value","title":"Return value","text":"

    the type of the JSON value

    Value type return value null value_t::null boolean value_t::boolean string value_t::string number (integer) value_t::number_integer number (unsigned integer) value_t::number_unsigned number (floating-point) value_t::number_float object value_t::object array value_t::array binary value_t::binary discarded value_t::discarded"},{"location":"api/basic_json/operator_value_t/#exception-safety","title":"Exception safety","text":"

    No-throw guarantee: this member function never throws exceptions.

    "},{"location":"api/basic_json/operator_value_t/#complexity","title":"Complexity","text":"

    Constant.

    "},{"location":"api/basic_json/operator_value_t/#examples","title":"Examples","text":"Example

    The following code exemplifies operator value_t() for all JSON types.

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create JSON values\n    json j_null;\n    json j_boolean = true;\n    json j_number_integer = -17;\n    json j_number_unsigned = 42u;\n    json j_number_float = 23.42;\n    json j_object = {{\"one\", 1}, {\"two\", 2}};\n    json j_array = {1, 2, 4, 8, 16};\n    json j_string = \"Hello, world\";\n\n    // call operator value_t()\n    json::value_t t_null = j_null;\n    json::value_t t_boolean = j_boolean;\n    json::value_t t_number_integer = j_number_integer;\n    json::value_t t_number_unsigned = j_number_unsigned;\n    json::value_t t_number_float = j_number_float;\n    json::value_t t_object = j_object;\n    json::value_t t_array = j_array;\n    json::value_t t_string = j_string;\n\n    // print types\n    std::cout << std::boolalpha;\n    std::cout << (t_null == json::value_t::null) << '\\n';\n    std::cout << (t_boolean == json::value_t::boolean) << '\\n';\n    std::cout << (t_number_integer == json::value_t::number_integer) << '\\n';\n    std::cout << (t_number_unsigned == json::value_t::number_unsigned) << '\\n';\n    std::cout << (t_number_float == json::value_t::number_float) << '\\n';\n    std::cout << (t_object == json::value_t::object) << '\\n';\n    std::cout << (t_array == json::value_t::array) << '\\n';\n    std::cout << (t_string == json::value_t::string) << '\\n';\n}\n

    Output:

    true\ntrue\ntrue\ntrue\ntrue\ntrue\ntrue\ntrue\n
    "},{"location":"api/basic_json/operator_value_t/#see-also","title":"See also","text":"
    • type - named member function equivalent to this implicit conversion operator
    • value_t - the enumeration of JSON types
    • Types - the JSON value types
    "},{"location":"api/basic_json/operator_value_t/#version-history","title":"Version history","text":"
    • Added in version 1.0.0.
    • Added unsigned integer type in version 2.0.0.
    • Added binary type in version 3.8.0.
    "},{"location":"api/basic_json/other_error/","title":"nlohmann::basic_json::other_error","text":"
    class other_error : public exception;\n

    This exception is thrown in case of errors that cannot be classified with the other exception types.

    Exceptions have ids 5xx (see list of other errors).

    classDiagram\n  direction LR\n\n    class std_exception [\"std::exception\"] {\n        <<interface>>\n    }\n\n    class json_exception [\"basic_json::exception\"] {\n        +const int id\n        +const char* what() const\n    }\n\n    class json_parse_error [\"basic_json::parse_error\"] {\n        +const std::size_t byte\n    }\n\n    class json_invalid_iterator [\"basic_json::invalid_iterator\"]\n    class json_type_error [\"basic_json::type_error\"]\n    class json_out_of_range [\"basic_json::out_of_range\"]\n    class json_other_error [\"basic_json::other_error\"]\n\n    std_exception <|-- json_exception\n    json_exception <|-- json_parse_error\n    json_exception <|-- json_invalid_iterator\n    json_exception <|-- json_type_error\n    json_exception <|-- json_out_of_range\n    json_exception <|-- json_other_error\n\n    style json_other_error fill:#CCCCFF

    Class hierarchy of the library's exceptions; arrows point from a derived class to its base class, and the highlighted box is basic_json::other_error.

    "},{"location":"api/basic_json/other_error/#member-functions","title":"Member functions","text":"
    • what - returns explanatory string
    "},{"location":"api/basic_json/other_error/#member-variables","title":"Member variables","text":"
    • id - the id of the exception
    "},{"location":"api/basic_json/other_error/#examples","title":"Examples","text":"Example

    The following code shows how a other_error exception can be caught.

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\nusing namespace nlohmann::literals;\n\nint main()\n{\n    try\n    {\n        // executing a failing JSON Patch operation\n        json value = R\"({\n            \"best_biscuit\": {\n                \"name\": \"Oreo\"\n            }\n        })\"_json;\n        json patch = R\"([{\n            \"op\": \"test\",\n            \"path\": \"/best_biscuit/name\",\n            \"value\": \"Choco Leibniz\"\n        }])\"_json;\n        value.patch(patch);\n    }\n    catch (const json::other_error& e)\n    {\n        // output exception information\n        std::cout << \"message: \" << e.what() << '\\n'\n                  << \"exception id: \" << e.id << '\\n';\n    }\n}\n

    Output:

    message: [json.exception.other_error.501] unsuccessful: {\"op\":\"test\",\"path\":\"/best_biscuit/name\",\"value\":\"Choco Leibniz\"}\nexception id: 501\n
    "},{"location":"api/basic_json/other_error/#see-also","title":"See also","text":"
    • exception - the base class of all exceptions thrown by the library
    • List of other errors - overview of further errors (other_error)
    • parse_error - exceptions indicating a parse error
    • invalid_iterator - exceptions indicating errors with iterators
    • type_error - exceptions indicating executing a member function with a wrong type
    • out_of_range - exceptions indicating access out of the defined range
    • Exceptions - all exceptions and their error codes
    • JSON_DIAGNOSTICS - extended exception messages with the path of the failing value
    "},{"location":"api/basic_json/other_error/#version-history","title":"Version history","text":"
    • Added in version 3.0.0.
    "},{"location":"api/basic_json/out_of_range/","title":"nlohmann::basic_json::out_of_range","text":"
    class out_of_range : public exception;\n

    This exception is thrown in case a library function is called on an input parameter that exceeds the expected range, for instance, in the case of array indices or nonexisting object keys.

    Exceptions have ids 4xx (see list of out-of-range errors).

    classDiagram\n  direction LR\n\n    class std_exception [\"std::exception\"] {\n        <<interface>>\n    }\n\n    class json_exception [\"basic_json::exception\"] {\n        +const int id\n        +const char* what() const\n    }\n\n    class json_parse_error [\"basic_json::parse_error\"] {\n        +const std::size_t byte\n    }\n\n    class json_invalid_iterator [\"basic_json::invalid_iterator\"]\n    class json_type_error [\"basic_json::type_error\"]\n    class json_out_of_range [\"basic_json::out_of_range\"]\n    class json_other_error [\"basic_json::other_error\"]\n\n    std_exception <|-- json_exception\n    json_exception <|-- json_parse_error\n    json_exception <|-- json_invalid_iterator\n    json_exception <|-- json_type_error\n    json_exception <|-- json_out_of_range\n    json_exception <|-- json_other_error\n\n    style json_out_of_range fill:#CCCCFF

    Class hierarchy of the library's exceptions; arrows point from a derived class to its base class, and the highlighted box is basic_json::out_of_range.

    "},{"location":"api/basic_json/out_of_range/#member-functions","title":"Member functions","text":"
    • what - returns explanatory string
    "},{"location":"api/basic_json/out_of_range/#member-variables","title":"Member variables","text":"
    • id - the id of the exception
    "},{"location":"api/basic_json/out_of_range/#examples","title":"Examples","text":"Example

    The following code shows how a out_of_range exception can be caught.

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    try\n    {\n        // calling at() for an invalid index\n        json j = {1, 2, 3, 4};\n        j.at(4) = 10;\n    }\n    catch (const json::out_of_range& e)\n    {\n        // output exception information\n        std::cout << \"message: \" << e.what() << '\\n'\n                  << \"exception id: \" << e.id << '\\n';\n    }\n}\n

    Output:

    message: [json.exception.out_of_range.401] array index 4 is out of range\nexception id: 401\n
    "},{"location":"api/basic_json/out_of_range/#see-also","title":"See also","text":"
    • exception - the base class of all exceptions thrown by the library
    • List of out-of-range errors - overview of out-of-range errors (out_of_range)
    • parse_error - exceptions indicating a parse error
    • invalid_iterator - exceptions indicating errors with iterators
    • type_error - exceptions indicating executing a member function with a wrong type
    • other_error - exceptions indicating other library errors
    • Exceptions - all exceptions and their error codes
    • JSON_DIAGNOSTICS - extended exception messages with the path of the failing value
    "},{"location":"api/basic_json/out_of_range/#version-history","title":"Version history","text":"
    • Added in version 3.0.0.
    "},{"location":"api/basic_json/parse/","title":"nlohmann::basic_json::parse","text":"
    // (1)\ntemplate<typename InputType>\nstatic basic_json parse(InputType&& i,\n                        const parser_callback_t cb = nullptr,\n                        const bool allow_exceptions = true,\n                        const bool ignore_comments = false,\n                        const bool ignore_trailing_commas = false);\n\n// (2)\ntemplate<typename IteratorType, typename SentinelType = IteratorType>\nstatic basic_json parse(IteratorType first, SentinelType last,\n                        const parser_callback_t cb = nullptr,\n                        const bool allow_exceptions = true,\n                        const bool ignore_comments = false,\n                        const bool ignore_trailing_commas = false);\n
    1. Deserialize from a compatible input.
    2. Deserialize from a pair of character iterators, or an iterator and a sentinel of a different type (C++20 ranges support)

      The value_type of the iterator must be an integral type with size of 1, 2, or 4 bytes, which will be interpreted respectively as UTF-8, UTF-16, and UTF-32. If SentinelType differs from IteratorType, it must be comparable to the iterator type with operator!=.

      Ill-formed UTF-16 and UTF-32 sequences are rejected: a lone surrogate, a high surrogate that is not followed by its low surrogate, and a code point above U+10FFFF all yield a parse_error.101.

    "},{"location":"api/basic_json/parse/#template-parameters","title":"Template parameters","text":"InputType

    A compatible input, for instance:

    • an std::istream object
    • a FILE pointer (throws if null)
    • a C-style array of characters
    • a pointer to a null-terminated string of single byte characters (throws if null)
    • a std::string or a std::string_view (C++17)
    • a container obj for which begin(obj) and end(obj) produce a valid pair of iterators (as found via ADL or member functions, with semantics compatible to std::begin and std::end)
    • wide characters (wchar_t, char16_t, char32_t), which are converted to UTF-8: a wide string object (std::wstring, std::u16string, std::u32string) or an array (e.g. a wide string literal); a pointer to a null-terminated wide string (e.g. std::u16string::c_str()) is not supported
    IteratorType

    a compatible iterator type, for instance.

    • a pair of std::string::iterator or std::vector<std::uint8_t>::iterator
    • a pair of pointers such as ptr and ptr + len
    SentinelType

    defaults to IteratorType; may be a different type comparable to IteratorType via operator!=, for instance.

    • a custom sentinel type for C++20 ranges
    • std::default_sentinel_t, when IteratorType is std::counted_iterator
    "},{"location":"api/basic_json/parse/#parameters","title":"Parameters","text":"i (in) Input to parse from. cb (in) a parser callback function of type parser_callback_t which is used to control the deserialization by filtering unwanted values (optional) allow_exceptions (in) whether to throw exceptions in case of a parse error (optional, true by default) ignore_comments (in) whether comments should be ignored and treated like whitespace (true) or yield a parse error (false); (optional, false by default) ignore_trailing_commas (in) whether trailing commas in arrays or objects should be ignored and treated like whitespace (true) or yield a parse error (false); (optional, false by default) first (in) iterator to the start of a character range last (in) iterator to the end of a character range, or a sentinel value that compares equal to the end iterator with operator!="},{"location":"api/basic_json/parse/#return-value","title":"Return value","text":"

    Deserialized JSON value; in case of a parse error and allow_exceptions set to false, the return value will be value_t::discarded. The latter can be checked with is_discarded.

    "},{"location":"api/basic_json/parse/#exception-safety","title":"Exception safety","text":"

    Strong guarantee: if an exception is thrown, there are no changes in the JSON value.

    "},{"location":"api/basic_json/parse/#exceptions","title":"Exceptions","text":"
    • Throws parse_error.101 in case of an unexpected token, or empty input like a null FILE* or char* pointer, or an std::istream without a stream buffer (i.rdbuf() == nullptr, for instance std::istream(nullptr)).
    • If reading from an std::istream reaches the end of the input and eofbit is part of the stream's 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.
    "},{"location":"api/basic_json/parse/#complexity","title":"Complexity","text":"

    Linear in the length of the input. The parser is a predictive LL(1) parser. The complexity can be higher if the parser callback function cb or reading from (1) the input i or (2) the iterator range [first, last] has a super-linear complexity.

    "},{"location":"api/basic_json/parse/#notes","title":"Notes","text":"

    A UTF-8 byte order mark is silently ignored.

    Invalid Unicode escapes and unpaired surrogates in the input are reported as parse_error.101 with a detailed message.

    By default, a '\\0' (NUL) byte anywhere in the input is treated as end of input, rather than as an ordinary (and, outside of a string, invalid) byte; see the FAQ entry for details and the JSON_STRICT_NUL_HANDLING macro to opt into rejecting it instead.

    Parsing into a document instead of a value

    basic_json_document::parse accepts the same inputs and the same options, but keeps the result as a flat index of the parsed values instead of a tree of basic_json values. It is faster and uses less memory when only parts of the document are read, and it also accepts a pointer to a null-terminated wide string, which parse() does not. See Zero-copy JSON views.

    Performance

    Contiguous inputs (strings, string views, vectors, arrays, pointer ranges) are the fastest to parse. A std::istream comes close: the parser scans the characters its stream buffer holds in bulk, without reading ahead, so the stream is left exactly where it would be after reading one character at a time. A FILE* is read one character at a time, but the file is locked only once, so other threads that use the same FILE object wait until parsing is done. See input sources and performance, JSON_DISABLE_STREAM_BULK_SCAN, and JSON_DISABLE_UNLOCKED_FILE_IO.

    "},{"location":"api/basic_json/parse/#examples","title":"Examples","text":"Example: (1) parse from a character array

    The example below demonstrates the parse() function reading from an array.

    #include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // a JSON text\n    char text[] = R\"(\n    {\n        \"Image\": {\n            \"Width\":  800,\n            \"Height\": 600,\n            \"Title\":  \"View from 15th Floor\",\n            \"Thumbnail\": {\n                \"Url\":    \"http://www.example.com/image/481989943\",\n                \"Height\": 125,\n                \"Width\":  100\n            },\n            \"Animated\" : false,\n            \"IDs\": [116, 943, 234, 38793]\n        }\n    }\n    )\";\n\n    // parse and serialize JSON\n    json j_complete = json::parse(text);\n    std::cout << std::setw(4) << j_complete << \"\\n\\n\";\n}\n

    Output:

    {\n    \"Image\": {\n        \"Animated\": false,\n        \"Height\": 600,\n        \"IDs\": [\n            116,\n            943,\n            234,\n            38793\n        ],\n        \"Thumbnail\": {\n            \"Height\": 125,\n            \"Url\": \"http://www.example.com/image/481989943\",\n            \"Width\": 100\n        },\n        \"Title\": \"View from 15th Floor\",\n        \"Width\": 800\n    }\n}\n
    Example: (1) parse from a string

    The example below demonstrates the parse() function with and without callback function.

    #include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // a JSON text\n    const auto* text = R\"(\n    {\n        \"Image\": {\n            \"Width\":  800,\n            \"Height\": 600,\n            \"Title\":  \"View from 15th Floor\",\n            \"Thumbnail\": {\n                \"Url\":    \"http://www.example.com/image/481989943\",\n                \"Height\": 125,\n                \"Width\":  100\n            },\n            \"Animated\" : false,\n            \"IDs\": [116, 943, 234, 38793]\n        }\n    }\n    )\";\n\n    // parse and serialize JSON\n    json j_complete = json::parse(text);\n    std::cout << std::setw(4) << j_complete << \"\\n\\n\";\n\n    // define parser callback\n    json::parser_callback_t cb = [](int depth, json::parse_event_t event, json & parsed)\n    {\n        // skip object elements with key \"Thumbnail\"\n        if (event == json::parse_event_t::key and parsed == json(\"Thumbnail\"))\n        {\n            return false;\n        }\n        else\n        {\n            return true;\n        }\n    };\n\n    // parse (with callback) and serialize JSON\n    json j_filtered = json::parse(text, cb);\n    std::cout << std::setw(4) << j_filtered << '\\n';\n}\n

    Output:

    {\n    \"Image\": {\n        \"Animated\": false,\n        \"Height\": 600,\n        \"IDs\": [\n            116,\n            943,\n            234,\n            38793\n        ],\n        \"Thumbnail\": {\n            \"Height\": 125,\n            \"Url\": \"http://www.example.com/image/481989943\",\n            \"Width\": 100\n        },\n        \"Title\": \"View from 15th Floor\",\n        \"Width\": 800\n    }\n}\n\n{\n    \"Image\": {\n        \"Animated\": false,\n        \"Height\": 600,\n        \"IDs\": [\n            116,\n            943,\n            234,\n            38793\n        ],\n        \"Title\": \"View from 15th Floor\",\n        \"Width\": 800\n    }\n}\n
    Example: (1) parse from an input stream

    The example below demonstrates the parse() function with and without callback function.

    #include <iostream>\n#include <iomanip>\n#include <sstream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // a JSON text\n    const auto* text = R\"(\n    {\n        \"Image\": {\n            \"Width\":  800,\n            \"Height\": 600,\n            \"Title\":  \"View from 15th Floor\",\n            \"Thumbnail\": {\n                \"Url\":    \"http://www.example.com/image/481989943\",\n                \"Height\": 125,\n                \"Width\":  100\n            },\n            \"Animated\" : false,\n            \"IDs\": [116, 943, 234, 38793]\n        }\n    }\n    )\";\n\n    // fill a stream with JSON text\n    std::stringstream ss;\n    ss << text;\n\n    // parse and serialize JSON\n    json j_complete = json::parse(ss);\n    std::cout << std::setw(4) << j_complete << \"\\n\\n\";\n\n    // define parser callback\n    json::parser_callback_t cb = [](int depth, json::parse_event_t event, json & parsed)\n    {\n        // skip object elements with key \"Thumbnail\"\n        if (event == json::parse_event_t::key and parsed == json(\"Thumbnail\"))\n        {\n            return false;\n        }\n        else\n        {\n            return true;\n        }\n    };\n\n    // fill a stream with JSON text\n    ss.clear();\n    ss << text;\n\n    // parse (with callback) and serialize JSON\n    json j_filtered = json::parse(ss, cb);\n    std::cout << std::setw(4) << j_filtered << '\\n';\n}\n

    Output:

    {\n    \"Image\": {\n        \"Animated\": false,\n        \"Height\": 600,\n        \"IDs\": [\n            116,\n            943,\n            234,\n            38793\n        ],\n        \"Thumbnail\": {\n            \"Height\": 125,\n            \"Url\": \"http://www.example.com/image/481989943\",\n            \"Width\": 100\n        },\n        \"Title\": \"View from 15th Floor\",\n        \"Width\": 800\n    }\n}\n\n{\n    \"Image\": {\n        \"Animated\": false,\n        \"Height\": 600,\n        \"IDs\": [\n            116,\n            943,\n            234,\n            38793\n        ],\n        \"Title\": \"View from 15th Floor\",\n        \"Width\": 800\n    }\n}\n
    Example: (1) parse from a contiguous container

    The example below demonstrates the parse() function reading from a contiguous container.

    #include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // a JSON text given as std::vector\n    std::vector<std::uint8_t> text = {'[', '1', ',', '2', ',', '3', ']', '\\0'};\n\n    // parse and serialize JSON\n    json j_complete = json::parse(text);\n    std::cout << std::setw(4) << j_complete << \"\\n\\n\";\n}\n

    Output:

    [\n    1,\n    2,\n    3\n]\n
    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.

    #include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // a JSON text given as string that is not null-terminated\n    const char* ptr = \"[1,2,3]another value\";\n\n    // parse and serialize JSON\n    json j_complete = json::parse(ptr, ptr + 7);\n    std::cout << std::setw(4) << j_complete << \"\\n\\n\";\n}\n

    Output:

    [\n    1,\n    2,\n    3\n]\n
    Example: (2) parse from an iterator pair

    The example below demonstrates the parse() function reading from an iterator pair.

    #include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // a JSON text given an input with other values\n    std::vector<std::uint8_t> input = {'[', '1', ',', '2', ',', '3', ']', 'o', 't', 'h', 'e', 'r'};\n\n    // parse and serialize JSON\n    json j_complete = json::parse(input.begin(), input.begin() + 7);\n    std::cout << std::setw(4) << j_complete << \"\\n\\n\";\n}\n

    Output:

    [\n    1,\n    2,\n    3\n]\n
    Example: effect of allow_exceptions parameter

    The example below demonstrates the effect of the allow_exceptions parameter in the parse() function.

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // an invalid JSON text\n    std::string text = R\"(\n    {\n        \"key\": \"value without closing quotes\n    }\n    )\";\n\n    // parse with exceptions\n    try\n    {\n        json j = json::parse(text);\n    }\n    catch (const json::parse_error& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n\n    // parse without exceptions\n    json j = json::parse(text, nullptr, false);\n\n    if (j.is_discarded())\n    {\n        std::cout << \"the input is invalid JSON\" << '\\n';\n    }\n    else\n    {\n        std::cout << \"the input is valid JSON: \" << j << '\\n';\n    }\n}\n

    Output:

    [json.exception.parse_error.101] parse error at line 4, column 0: syntax error while parsing value - invalid string: control character U+000A (LF) must be escaped to \\u000A or \\n; last read: '\"value without closing quotes<U+000A>'\nthe input is invalid JSON\n
    Example: effect of ignore_comments parameter

    The example below demonstrates the effect of the ignore_comments parameter in the parse() function.

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    std::string s = R\"(\n    {\n        // update in 2006: removed Pluto\n        \"planets\": [\"Mercury\", \"Venus\", \"Earth\", \"Mars\",\n                    \"Jupiter\", \"Uranus\", \"Neptune\" /*, \"Pluto\" */]\n    }\n    )\";\n\n    try\n    {\n        json j = json::parse(s);\n    }\n    catch (json::exception& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n\n    json j = json::parse(s,\n                         /* callback */ nullptr,\n                         /* allow exceptions */ true,\n                         /* ignore_comments */ true);\n    std::cout << j.dump(2) << '\\n';\n}\n

    Output:

    [json.exception.parse_error.101] parse error at line 3, column 9: syntax error while parsing object key - invalid literal; last read: '<U+000A>    {<U+000A>        /'; expected string literal\n{\n  \"planets\": [\n    \"Mercury\",\n    \"Venus\",\n    \"Earth\",\n    \"Mars\",\n    \"Jupiter\",\n    \"Uranus\",\n    \"Neptune\"\n  ]\n}\n
    Example: effect of ignore_trailing_commas parameter

    The example below demonstrates the effect of the ignore_trailing_commas parameter in the parse() function.

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    std::string s = R\"(\n    {\n        \"planets\": [\n            \"Mercury\",\n            \"Venus\",\n            \"Earth\",\n            \"Mars\",\n            \"Jupiter\",\n            \"Uranus\",\n            \"Neptune\",\n        ]\n    }\n    )\";\n\n    try\n    {\n        json j = json::parse(s);\n    }\n    catch (json::exception& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n\n    json j = json::parse(s,\n                         /* callback */ nullptr,\n                         /* allow exceptions */ true,\n                         /* ignore_comments */ false,\n                         /* ignore_trailing_commas */ true);\n    std::cout << j.dump(2) << '\\n';\n}\n

    Output:

    [json.exception.parse_error.101] parse error at line 11, column 9: syntax error while parsing value - unexpected ']'; expected '[', '{', or a literal\n{\n  \"planets\": [\n    \"Mercury\",\n    \"Venus\",\n    \"Earth\",\n    \"Mars\",\n    \"Jupiter\",\n    \"Uranus\",\n    \"Neptune\"\n  ]\n}\n
    Example: parse from UTF-16, UTF-32, and wide strings

    The encoding is deduced from the character type of the input; std::u16string and std::u32string are interpreted as UTF-16 and UTF-32, and std::wstring uses the platform's wchar_t width. String literals like u\"...\", U\"...\", and L\"...\" work as well, as do iterators over wide characters.

    #include <iostream>\n#include <string>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // the same JSON text, given in different encodings\n    const std::string utf8 = \"{\\\"name\\\":\\\"\\u00e9\\\"}\";\n    const std::u16string utf16 = u\"{\\\"name\\\":\\\"\\u00e9\\\"}\";\n    const std::u32string utf32 = U\"{\\\"name\\\":\\\"\\u00e9\\\"}\";\n    const std::wstring wide = L\"{\\\"name\\\":\\\"\\u00e9\\\"}\";\n\n    // the encoding is deduced from the character type of the input, and all\n    // of them yield the same value\n    std::cout << json::parse(utf8) << '\\n'\n              << json::parse(utf16) << '\\n'\n              << json::parse(utf32) << '\\n'\n              << json::parse(wide) << '\\n';\n\n    // a wide string literal works as well: u\"...\" is UTF-16, U\"...\" is UTF-32\n    std::cout << json::parse(u\"[1, 2, 3]\") << '\\n';\n\n    // iterators over wide characters work as well\n    std::cout << json::parse(utf16.begin(), utf16.end()) << '\\n';\n}\n

    Output:

    {\"name\":\"\u00e9\"}\n{\"name\":\"\u00e9\"}\n{\"name\":\"\u00e9\"}\n{\"name\":\"\u00e9\"}\n[1,2,3]\n{\"name\":\"\u00e9\"}\n
    "},{"location":"api/basic_json/parse/#see-also","title":"See also","text":"
    • accept - check if the input is valid JSON
    • sax_parse - parse input using the SAX interface
    • operator>> - deserialize from stream
    • JSON_STRICT_NUL_HANDLING - opt in to rejecting a NUL byte in the input instead of treating it as end of input
    • JSON_DISABLE_STREAM_BULK_SCAN - read a std::istream one character at a time
    • JSON_DISABLE_UNLOCKED_FILE_IO - read a FILE* with the locking stdio functions
    • Parsing - overview of the parsing functions
    • Comments - ignore // and /* */ comments while parsing
    • Trailing Commas - accept trailing commas in arrays and objects
    • Parser Callbacks - filter or inspect values while parsing
    • Parsing and Exceptions - handling parse errors and locating them in the input
    • Parsing Untrusted Input - limits and checks for input you do not control
    "},{"location":"api/basic_json/parse/#version-history","title":"Version history","text":"
    • Added in version 1.0.0.
    • Overload for contiguous containers (1) added in version 2.0.3.
    • Ignoring comments via ignore_comments added in version 3.9.0.
    • Changed runtime assertion in case of FILE* null pointers to exception in version 3.12.0.
    • Added ignore_trailing_commas in version 3.13.0 unreleased.
    • Extended container support (1) to include types with lvalue-only ADL begin/end (matching std::begin/std::end semantics) in version 3.13.0 unreleased.
    • Extended overload (2) to accept heterogeneous iterator+sentinel pairs (C++20 ranges support) in version 3.13.0 unreleased.
    • JSON_STRICT_NUL_HANDLING added in version 3.13.0 unreleased 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 unreleased.
    • Parsing from an std::istream scans the characters in its stream buffer in bulk in version 3.13.0 unreleased (JSON_DISABLE_STREAM_BULK_SCAN restores reading one character at a time).
    • Parsing from a FILE* locks the file once instead of once per character in version 3.13.0 unreleased (JSON_DISABLE_UNLOCKED_FILE_IO restores std::fgetc).
    • Ill-formed UTF-16 and UTF-32 input (a lone surrogate, a high surrogate that is not followed by its low surrogate, or a code point above U+10FFFF) is rejected with parse_error.101 in version 3.13.0 unreleased; before that, some such sequences were accepted or ended the input silently.

    Deprecation

    Overload (2) replaces calls to 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 parse({ptr, ptr+len}, ...); with parse(ptr, ptr+len, ...);.

    You should be warned by your compiler with a -Wdeprecated-declarations warning if you are using a deprecated function.

    See the migration guide for how to update existing code.

    "},{"location":"api/basic_json/parse_error/","title":"nlohmann::basic_json::parse_error","text":"
    class parse_error : public exception;\n

    The library throws this exception when a parse error occurs. Parse errors can occur during the deserialization of JSON text, BJData, BON8, BSON, CBOR, MessagePack, UBJSON, as well as when using JSON Patch.

    Member byte holds the byte index of the last read character in the input file (see note below).

    Exceptions have ids 1xx (see list of parse errors).

    classDiagram\n  direction LR\n\n    class std_exception [\"std::exception\"] {\n        <<interface>>\n    }\n\n    class json_exception [\"basic_json::exception\"] {\n        +const int id\n        +const char* what() const\n    }\n\n    class json_parse_error [\"basic_json::parse_error\"] {\n        +const std::size_t byte\n    }\n\n    class json_invalid_iterator [\"basic_json::invalid_iterator\"]\n    class json_type_error [\"basic_json::type_error\"]\n    class json_out_of_range [\"basic_json::out_of_range\"]\n    class json_other_error [\"basic_json::other_error\"]\n\n    std_exception <|-- json_exception\n    json_exception <|-- json_parse_error\n    json_exception <|-- json_invalid_iterator\n    json_exception <|-- json_type_error\n    json_exception <|-- json_out_of_range\n    json_exception <|-- json_other_error\n\n    style json_parse_error fill:#CCCCFF

    Class hierarchy of the library's exceptions; arrows point from a derived class to its base class, and the highlighted box is basic_json::parse_error.

    "},{"location":"api/basic_json/parse_error/#member-functions","title":"Member functions","text":"
    • what - returns explanatory string
    "},{"location":"api/basic_json/parse_error/#member-variables","title":"Member variables","text":"
    • id - the id of the exception
    • byte - byte index of the parse error
    "},{"location":"api/basic_json/parse_error/#notes","title":"Notes","text":"

    For an input with n bytes, 1 is the index of the first character and n+1 is the index of the terminating null byte or the end of file. This also holds true when reading a byte vector for binary formats.

    "},{"location":"api/basic_json/parse_error/#examples","title":"Examples","text":"Example

    The following code shows how a parse_error exception can be caught.

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    try\n    {\n        // parsing input with a syntax error\n        json j = json::parse(\"[1,2,3,]\");\n    }\n    catch (const json::parse_error& e)\n    {\n        // output exception information\n        std::cout << \"message: \" << e.what() << '\\n'\n                  << \"exception id: \" << e.id << '\\n'\n                  << \"byte position of error: \" << e.byte << '\\n';\n    }\n}\n

    Output:

    message: [json.exception.parse_error.101] parse error at line 1, column 8: syntax error while parsing value - unexpected ']'; expected '[', '{', or a literal\nexception id: 101\nbyte position of error: 8\n
    "},{"location":"api/basic_json/parse_error/#see-also","title":"See also","text":"
    • exception - the base class of all exceptions thrown by the library
    • List of parse errors - overview of parse errors (parse_error)
    • invalid_iterator - exceptions indicating errors with iterators
    • type_error - exceptions indicating executing a member function with a wrong type
    • out_of_range - exceptions indicating access out of the defined range
    • other_error - exceptions indicating other library errors
    • Parsing and Exceptions - handling parse errors and locating them in the input
    • Working Without Exceptions - error handling when exceptions are disabled
    "},{"location":"api/basic_json/parse_error/#version-history","title":"Version history","text":"
    • Added in version 3.0.0.
    "},{"location":"api/basic_json/parse_event_t/","title":"nlohmann::basic_json::parse_event_t","text":"
    enum class parse_event_t : std::uint8_t {\n    object_start,\n    object_end,\n    array_start,\n    array_end,\n    key,\n    value\n};\n

    The parser callback distinguishes the following events:

    • object_start: the parser read { and started to process a JSON object
    • key: the parser read a key of a value in an object
    • object_end: the parser read } and finished processing a JSON object
    • array_start: the parser read [ and started to process a JSON array
    • array_end: the parser read ] and finished processing a JSON array
    • value: the parser finished reading a JSON value
    "},{"location":"api/basic_json/parse_event_t/#examples","title":"Examples","text":"

    Example of the parse events a callback sees for the J\u200bSON text {\"name\": \"Berlin\", \"location\": [52.519444, 13.406667]}: object_start after the opening brace, key after each key, array_start after the opening bracket, value after each value, array_end after the closing bracket, and object_end after the closing brace. Every array and object also produces a value event when it is complete. J\u200bSON to parse callback events { \"name\" : \"Berlin\" , \"location\" : [ 52.519444 , 13.406667 ] } object_start key object_end array_start array_end value

    Each coloured dot marks where the parser reports a parse_event_t event while reading the JSON text on the left; the legend on the right names the event per colour.

    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 true).

    #include <iostream>\n#include <string>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\n// translate a parse_event_t to a human-readable name\nstd::string event_name(json::parse_event_t event)\n{\n    switch (event)\n    {\n        case json::parse_event_t::object_start:\n            return \"object_start\";\n        case json::parse_event_t::object_end:\n            return \"object_end\";\n        case json::parse_event_t::array_start:\n            return \"array_start\";\n        case json::parse_event_t::array_end:\n            return \"array_end\";\n        case json::parse_event_t::key:\n            return \"key\";\n        case json::parse_event_t::value:\n            return \"value\";\n        default:\n            return \"unknown\";\n    }\n}\n\nint main()\n{\n    // a small JSON text\n    const auto* text = R\"({\"pi\": 3.141, \"numbers\": [1, 2]})\";\n\n    // parse the text and report every event together with its depth;\n    // returning true keeps every value unchanged\n    json j = json::parse(text, [](int depth, json::parse_event_t event, json& /*parsed*/)\n    {\n        std::cout << depth << \" \" << event_name(event) << '\\n';\n        return true;\n    });\n\n    // the callback did not change anything, so the parsed value is unaffected\n    std::cout << j << '\\n';\n}\n

    Output:

    0 object_start\n1 key\n1 value\n1 key\n1 array_start\n2 value\n2 value\n1 array_end\n0 object_end\n{\"numbers\":[1,2],\"pi\":3.141}\n
    "},{"location":"api/basic_json/parse_event_t/#see-also","title":"See also","text":"
    • parser_callback_t - callback function type for the parser
    • parse - deserialize from a compatible input
    • Parser Callbacks - filter or inspect values while parsing
    "},{"location":"api/basic_json/parse_event_t/#version-history","title":"Version history","text":"
    • Added in version 1.0.0.
    "},{"location":"api/basic_json/parser_callback_t/","title":"nlohmann::basic_json::parser_callback_t","text":"
    template<typename BasicJsonType>\nusing parser_callback_t =\n    std::function<bool(int depth, parse_event_t event, BasicJsonType& parsed)>;\n

    With a parser callback function, the result of parsing a JSON text can be influenced. When passed to parse, it is called on certain events (passed as parse_event_t via parameter event) with a set recursion depth depth and context JSON value parsed. The return value of the callback function is a boolean indicating whether the element that emitted the callback shall be kept or not.

    We distinguish six scenarios (determined by the event type) in which the callback function can be called. The following table describes the values of the parameters depth, event, and parsed.

    parameter event description parameter depth parameter parsed parse_event_t::object_start the parser read { and started to process a JSON object depth of the parent of the JSON object a JSON value with type discarded parse_event_t::key the parser read a key of a value in an object depth of the currently parsed JSON object a JSON string containing the key parse_event_t::object_end the parser read } and finished processing a JSON object depth of the parent of the JSON object the parsed JSON object parse_event_t::array_start the parser read [ and started to process a JSON array depth of the parent of the JSON array a JSON value with type discarded parse_event_t::array_end the parser read ] and finished processing a JSON array depth of the parent of the JSON array the parsed JSON array parse_event_t::value the parser finished reading a JSON value depth of the value the parsed JSON value

    Example of the parse events a callback sees for the J\u200bSON text {\"name\": \"Berlin\", \"location\": [52.519444, 13.406667]}: object_start after the opening brace, key after each key, array_start after the opening bracket, value after each value, array_end after the closing bracket, and object_end after the closing brace. Every array and object also produces a value event when it is complete. J\u200bSON to parse callback events { \"name\" : \"Berlin\" , \"location\" : [ 52.519444 , 13.406667 ] } object_start key object_end array_start array_end value

    Parse events for a small JSON text: each coloured dot marks the position at which the parser calls the callback, and the legend on the right names the event per colour.

    Discarding a value (i.e., returning false) has different effects depending on the context in which function was called:

    • Discarded values in structured types are skipped. That is, the parser will behave as if the discarded value was never read. This holds for every value type and for both kinds of parent: a discarded element is removed from the surrounding array, and a discarded member is removed from the surrounding object together with its key.
    • Arrays and objects can be discarded either at their parse_event_t::array_start/parse_event_t::object_start event or at their parse_event_t::array_end/parse_event_t::object_end event, and both remove the whole value. Discarding it at the start event also means the callback is called neither for the content of the value nor for its matching end event.
    • Discarding a parse_event_t::key event discards the whole object member. The callback is still called for the associated value, but its return value has no further effect.
    • In case a value outside a structured type is skipped, it is replaced with null. This case happens if the top-level element is skipped.
    "},{"location":"api/basic_json/parser_callback_t/#parameters","title":"Parameters","text":"depth (in) the depth of the recursion during parsing event (in) an event of type parse_event_t indicating the context in the callback function has been called parsed (in, out) the current intermediate parse result; note that writing to this value has no effect for parse_event_t::key events"},{"location":"api/basic_json/parser_callback_t/#return-value","title":"Return value","text":"

    Whether the JSON value which called the function during parsing should be kept (true) or not (false). In the latter case, it is skipped completely, or replaced by null if it is the top-level value.

    "},{"location":"api/basic_json/parser_callback_t/#examples","title":"Examples","text":"Example: skip an object key while parsing

    The example below demonstrates the parse() function with and without callback function.

    #include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // a JSON text\n    const auto* text = R\"(\n    {\n        \"Image\": {\n            \"Width\":  800,\n            \"Height\": 600,\n            \"Title\":  \"View from 15th Floor\",\n            \"Thumbnail\": {\n                \"Url\":    \"http://www.example.com/image/481989943\",\n                \"Height\": 125,\n                \"Width\":  100\n            },\n            \"Animated\" : false,\n            \"IDs\": [116, 943, 234, 38793]\n        }\n    }\n    )\";\n\n    // parse and serialize JSON\n    json j_complete = json::parse(text);\n    std::cout << std::setw(4) << j_complete << \"\\n\\n\";\n\n    // define parser callback\n    json::parser_callback_t cb = [](int depth, json::parse_event_t event, json & parsed)\n    {\n        // skip object elements with key \"Thumbnail\"\n        if (event == json::parse_event_t::key and parsed == json(\"Thumbnail\"))\n        {\n            return false;\n        }\n        else\n        {\n            return true;\n        }\n    };\n\n    // parse (with callback) and serialize JSON\n    json j_filtered = json::parse(text, cb);\n    std::cout << std::setw(4) << j_filtered << '\\n';\n}\n

    Output:

    {\n    \"Image\": {\n        \"Animated\": false,\n        \"Height\": 600,\n        \"IDs\": [\n            116,\n            943,\n            234,\n            38793\n        ],\n        \"Thumbnail\": {\n            \"Height\": 125,\n            \"Url\": \"http://www.example.com/image/481989943\",\n            \"Width\": 100\n        },\n        \"Title\": \"View from 15th Floor\",\n        \"Width\": 800\n    }\n}\n\n{\n    \"Image\": {\n        \"Animated\": false,\n        \"Height\": 600,\n        \"IDs\": [\n            116,\n            943,\n            234,\n            38793\n        ],\n        \"Title\": \"View from 15th Floor\",\n        \"Width\": 800\n    }\n}\n
    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.

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // a JSON text with an array and a number inside an object\n    const auto* text = R\"({\"IDs\": [116, 943], \"Width\": 800})\";\n\n    // discard the array when the parser reads its opening bracket\n    json j_array_start = json::parse(text, [](int /*depth*/, json::parse_event_t event, json& /*parsed*/)\n    {\n        return event != json::parse_event_t::array_start;\n    });\n\n    // discard the same array when the parser reads its closing bracket\n    json j_array_end = json::parse(text, [](int /*depth*/, json::parse_event_t event, json& /*parsed*/)\n    {\n        return event != json::parse_event_t::array_end;\n    });\n\n    // discard the number, but keep its key\n    json j_value = json::parse(text, [](int /*depth*/, json::parse_event_t event, json & parsed)\n    {\n        return !(event == json::parse_event_t::value && parsed == json(800));\n    });\n\n    // discard the key of the number\n    json j_key = json::parse(text, [](int /*depth*/, json::parse_event_t event, json & parsed)\n    {\n        return !(event == json::parse_event_t::key && parsed == json(\"Width\"));\n    });\n\n    // discard the top-level object\n    json j_root = json::parse(text, [](int /*depth*/, json::parse_event_t event, json& /*parsed*/)\n    {\n        return event != json::parse_event_t::object_end;\n    });\n\n    // in every case, the discarded value is removed together with its key\n    std::cout << j_array_start << '\\n'\n              << j_array_end << '\\n'\n              << j_value << '\\n'\n              << j_key << '\\n'\n              << j_root << '\\n';\n}\n

    Output:

    {\"Width\":800}\n{\"Width\":800}\n{\"IDs\":[116,943]}\n{\"IDs\":[116,943]}\nnull\n
    "},{"location":"api/basic_json/parser_callback_t/#see-also","title":"See also","text":"
    • parse - deserialize from a compatible input
    • parse_event_t - enumeration of parser events
    • Parser Callbacks - filter or inspect values while parsing
    "},{"location":"api/basic_json/parser_callback_t/#version-history","title":"Version history","text":"
    • Added in version 1.0.0.
    • Fixed in version 3.13.0 unreleased 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 unreleased 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.
    "},{"location":"api/basic_json/patch/","title":"nlohmann::basic_json::patch","text":"
    basic_json patch(const basic_json& json_patch) const;\n

    JSON Patch defines a JSON document structure for expressing a sequence of operations to apply to a JSON document. With this function, a JSON Patch is applied to the current JSON value by executing all operations from the patch.

    "},{"location":"api/basic_json/patch/#parameters","title":"Parameters","text":"json_patch (in) JSON patch document"},{"location":"api/basic_json/patch/#return-value","title":"Return value","text":"

    patched document

    "},{"location":"api/basic_json/patch/#exception-safety","title":"Exception safety","text":"

    Strong guarantee: if an exception is thrown, there are no changes in the JSON value.

    "},{"location":"api/basic_json/patch/#exceptions","title":"Exceptions","text":"
    • Throws parse_error.104 if the JSON patch does not consist of an array of objects.
    • Throws parse_error.105 if the JSON patch is malformed (e.g., mandatory attributes are missing); example: \"operation 'add' must have member 'path'\".
    • Throws out_of_range.401 if an array index is out of range.
    • Throws parse_error.106 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 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 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 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 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 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 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 if JSON pointer has no parent (\"remove\", \"move\")
    • Throws out_of_range.411 if an \"add\" operation's target location has a parent that is neither an object nor an array.
    • Throws out_of_range.413 if a \"remove\" operation's target location has a parent that is neither an object nor an array.
    • Throws out_of_range.414 if a \"move\" operation's \"from\" location is a proper prefix of its \"path\" location.
    • Throws other_error.501 if \"test\" operation was unsuccessful. A \"test\" operation whose \"path\" does not exist is unsuccessful, too: the failed lookup is reported as a failed test, even if the operation has no \"value\" member (which would otherwise be parse_error.105). Which of the two errors is reported for this combination depends on the order in which the operands of a comparison are evaluated, so do not rely on it.
    "},{"location":"api/basic_json/patch/#complexity","title":"Complexity","text":"

    Linear in the size of the JSON value and the length of the JSON patch. As usually the patch affects only a fraction of the JSON value, the complexity can usually be neglected.

    "},{"location":"api/basic_json/patch/#notes","title":"Notes","text":"

    The application of a patch is atomic: Either all operations succeed and the patched document is returned or an exception is thrown. In any case, the original value is not changed: the patch is applied to a copy of the value.

    Duplicate member names inside an operation object are resolved by the parser before the patch is applied (the last one is kept, see object_t), so {\"op\": \"add\", \"op\": \"remove\", \"path\": \"/a\"} is a remove operation.

    "},{"location":"api/basic_json/patch/#examples","title":"Examples","text":"Example: apply a JSON patch

    The following code shows how a JSON patch is applied to a value.

    #include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\nusing namespace nlohmann::literals;\n\nint main()\n{\n    // the original document\n    json doc = R\"(\n        {\n          \"baz\": \"qux\",\n          \"foo\": \"bar\"\n        }\n    )\"_json;\n\n    // the patch\n    json patch = R\"(\n        [\n          { \"op\": \"replace\", \"path\": \"/baz\", \"value\": \"boo\" },\n          { \"op\": \"add\", \"path\": \"/hello\", \"value\": [\"world\"] },\n          { \"op\": \"remove\", \"path\": \"/foo\"}\n        ]\n    )\"_json;\n\n    // apply the patch\n    json patched_doc = doc.patch(patch);\n\n    // output original and patched document\n    std::cout << std::setw(4) << doc << \"\\n\\n\"\n              << std::setw(4) << patched_doc << '\\n';\n}\n

    Output:

    {\n    \"baz\": \"qux\",\n    \"foo\": \"bar\"\n}\n\n{\n    \"baz\": \"boo\",\n    \"hello\": [\n        \"world\"\n    ]\n}\n
    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.

    #include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\nusing namespace nlohmann::literals;\n\nint main()\n{\n    // the original document\n    json doc = R\"(\n        {\n          \"a\": { \"b\": 1 }\n        }\n    )\"_json;\n\n    // a patch that tries to move \"/a\" into one of its own children\n    json patch = R\"(\n        [\n          { \"op\": \"move\", \"from\": \"/a\", \"path\": \"/a/b\" }\n        ]\n    )\"_json;\n\n    // exception out_of_range.414\n    try\n    {\n        json patched_doc = doc.patch(patch);\n    }\n    catch (const json::out_of_range& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n\n    // the original document is unchanged\n    std::cout << std::setw(4) << doc << '\\n';\n}\n

    Output:

    [json.exception.out_of_range.414] cannot move value: 'from' path '/a' is a proper prefix of 'path' '/a/b'\n{\n    \"a\": {\n        \"b\": 1\n    }\n}\n
    "},{"location":"api/basic_json/patch/#see-also","title":"See also","text":"
    • RFC 6902 (JSON Patch) - specification of JSON Patch
    • RFC 6901 (JSON Pointer) - specification of JSON Pointer
    • patch_inplace - applies a JSON Patch without creating a copy of the document
    • merge_patch - applies a JSON Merge Patch
    • JSON Patch and Diff - the article on JSON Patch
    • JSON Pointer - the addressing scheme used for patch paths
    "},{"location":"api/basic_json/patch/#version-history","title":"Version history","text":"
    • Added in version 2.0.0.
    • Added out_of_range.411 and stopped relying on an internal assertion when an \"add\" operation's target location has a non-object/non-array parent in version 3.13.0 unreleased. This includes a null parent, which was previously silently converted to an object, in version 3.13.0 unreleased.
    • Added out_of_range.413 and stopped silently ignoring a \"remove\" operation whose target location has a non-object/non-array parent in version 3.13.0 unreleased.
    • Added out_of_range.414 and rejected a \"move\" operation whose \"from\" location is a proper prefix of its \"path\" location instead of silently producing a corrupted result in version 3.13.0 unreleased.
    • Throws parse_error.109 instead of out_of_range.404 for a one-character array index that is not a digit (e.g., /x) in version 3.13.0 unreleased, as it already did for longer ones.
    "},{"location":"api/basic_json/patch_inplace/","title":"nlohmann::basic_json::patch_inplace","text":"
    void patch_inplace(const basic_json& json_patch);\n

    JSON Patch defines a JSON document structure for expressing a sequence of operations to apply to a JSON document. With this function, a JSON Patch is applied to the current JSON value by executing all operations from the patch. This function applies a JSON patch in place and returns void.

    "},{"location":"api/basic_json/patch_inplace/#parameters","title":"Parameters","text":"json_patch (in) JSON patch document"},{"location":"api/basic_json/patch_inplace/#exception-safety","title":"Exception safety","text":"

    No guarantees, value may be corrupted by an unsuccessful patch operation.

    "},{"location":"api/basic_json/patch_inplace/#exceptions","title":"Exceptions","text":"
    • Throws parse_error.104 if the JSON patch does not consist of an array of objects.
    • Throws parse_error.105 if the JSON patch is malformed (e.g., mandatory attributes are missing); example: \"operation 'add' must have member 'path'\".
    • Throws out_of_range.401 if an array index is out of range.
    • Throws parse_error.106 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 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 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 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 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 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 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 if JSON pointer has no parent (\"remove\", \"move\")
    • Throws out_of_range.411 if an \"add\" operation's target location has a parent that is neither an object nor an array.
    • Throws out_of_range.413 if a \"remove\" operation's target location has a parent that is neither an object nor an array.
    • Throws out_of_range.414 if a \"move\" operation's \"from\" location is a proper prefix of its \"path\" location.
    • Throws other_error.501 if \"test\" operation was unsuccessful. A \"test\" operation whose \"path\" does not exist is unsuccessful, too: the failed lookup is reported as a failed test, even if the operation has no \"value\" member (which would otherwise be parse_error.105). Which of the two errors is reported for this combination depends on the order in which the operands of a comparison are evaluated, so do not rely on it.
    "},{"location":"api/basic_json/patch_inplace/#complexity","title":"Complexity","text":"

    Linear in the size of the JSON value and the length of the JSON patch. As usually the patch affects only a fraction of the JSON value, the complexity can usually be neglected.

    "},{"location":"api/basic_json/patch_inplace/#notes","title":"Notes","text":"

    Unlike patch, patch_inplace applies the operation \"in place\" and no copy of the JSON value is created. That makes it faster for large documents by avoiding the copy. However, the JSON value might be corrupted if the function throws an exception.

    Duplicate member names inside an operation object are resolved by the parser before the patch is applied (the last one is kept, see object_t), so {\"op\": \"add\", \"op\": \"remove\", \"path\": \"/a\"} is a remove operation.

    The JSON patch may be the JSON value itself (j.patch_inplace(j)): the operations are then read from a copy of the patch made before the first operation is applied, so the result is the same as that of j = j.patch(j), and the exception safety is the same as above.

    If JSON_DIAGNOSTICS is enabled, the same holds for a JSON patch stored inside the JSON value (e.g., j.patch_inplace(j[\"patch\"])): it is detected via the parent pointers.

    Undefined behavior

    Without JSON_DIAGNOSTICS, the JSON patch must not be a value stored inside the JSON value (e.g., j.patch_inplace(j[\"patch\"])), as the operations may change or destroy it while it is read. Pass a copy (j.patch_inplace(json(j[\"patch\"]))) or use patch instead.

    "},{"location":"api/basic_json/patch_inplace/#examples","title":"Examples","text":"Example: apply a JSON patch in place

    The following code shows how a JSON patch is applied to a value.

    #include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\nusing namespace nlohmann::literals;\n\nint main()\n{\n    // the original document\n    json doc = R\"(\n        {\n          \"baz\": \"qux\",\n          \"foo\": \"bar\"\n        }\n    )\"_json;\n\n    // the patch\n    json patch = R\"(\n        [\n          { \"op\": \"replace\", \"path\": \"/baz\", \"value\": \"boo\" },\n          { \"op\": \"add\", \"path\": \"/hello\", \"value\": [\"world\"] },\n          { \"op\": \"remove\", \"path\": \"/foo\"}\n        ]\n    )\"_json;\n\n    // output original document\n    std::cout << \"Before\\n\" << std::setw(4) << doc << '\\n';\n\n    // apply the patch\n    doc.patch_inplace(patch);\n\n    // output patched document\n    std::cout << \"\\nAfter\\n\" << std::setw(4) << doc << '\\n';\n}\n

    Output:

    Before\n{\n    \"baz\": \"qux\",\n    \"foo\": \"bar\"\n}\n\nAfter\n{\n    \"baz\": \"boo\",\n    \"hello\": [\n        \"world\"\n    ]\n}\n
    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.

    #include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\nusing namespace nlohmann::literals;\n\nint main()\n{\n    // the original document\n    json doc = R\"(\n        {\n          \"a\": 1,\n          \"b\": 2\n        }\n    )\"_json;\n\n    // a patch whose second operation fails\n    json patch = R\"(\n        [\n          { \"op\": \"replace\", \"path\": \"/a\", \"value\": 99 },\n          { \"op\": \"remove\", \"path\": \"/nonexistent\" }\n        ]\n    )\"_json;\n\n    // exception out_of_range.403\n    try\n    {\n        doc.patch_inplace(patch);\n    }\n    catch (const json::out_of_range& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n\n    // the first operation has already been applied to doc\n    std::cout << std::setw(4) << doc << '\\n';\n}\n

    Output:

    [json.exception.out_of_range.403] key 'nonexistent' not found\n{\n    \"a\": 99,\n    \"b\": 2\n}\n
    "},{"location":"api/basic_json/patch_inplace/#see-also","title":"See also","text":"
    • RFC 6902 (JSON Patch) - specification of JSON Patch
    • RFC 6901 (JSON Pointer) - specification of JSON Pointer
    • patch - applies a JSON Patch
    • merge_patch - applies a JSON Merge Patch
    • JSON Patch and Diff - the article on JSON Patch
    "},{"location":"api/basic_json/patch_inplace/#version-history","title":"Version history","text":"
    • Added in version 3.11.0.
    • Added out_of_range.411 and stopped relying on an internal assertion when an \"add\" operation's target location has a non-object/non-array parent in version 3.13.0 unreleased. This includes a null parent, which was previously silently converted to an object, in version 3.13.0 unreleased.
    • Added out_of_range.413 and stopped silently ignoring a \"remove\" operation whose target location has a non-object/non-array parent in version 3.13.0 unreleased.
    • Added out_of_range.414 and rejected a \"move\" operation whose \"from\" location is a proper prefix of its \"path\" location instead of silently producing a corrupted result in version 3.13.0 unreleased.
    • Throws parse_error.109 instead of out_of_range.404 for a one-character array index that is not a digit (e.g., /x) in version 3.13.0 unreleased, as it already did for longer ones.
    • Applying a JSON value as patch to itself (or, with JSON_DIAGNOSTICS, to a value stored inside it) no longer results in undefined behavior in version 3.13.0 unreleased.
    "},{"location":"api/basic_json/push_back/","title":"nlohmann::basic_json::push_back","text":"
    // (1)\nvoid push_back(basic_json&& val);\nvoid push_back(const basic_json& val);\n\n// (2)\nvoid push_back(const typename object_t::value_type& val);\n\n// (3)\nvoid push_back(initializer_list_t init);\n
    1. Appends the given element val to the end of the JSON array. If the function is called on a JSON null value, an empty array is created before appending val.

    2. Inserts the given element val to the JSON object. If the function is called on a JSON null value, an empty object is created before inserting val.

    3. This function allows using push_back with an initializer list. In case

      1. the current value is an object,
      2. the initializer list init contains only two elements, and
      3. the first element of init is a string,

      init is converted into an object element and added using push_back(const typename object_t::value_type&). Otherwise, init is converted to a JSON value and added using push_back(basic_json&&).

    "},{"location":"api/basic_json/push_back/#iterator-invalidation","title":"Iterator invalidation","text":"

    For all cases where an element is added to an array, a reallocation can happen, in which case all iterators (including the end() iterator) and all references to the elements are invalidated. Otherwise, only the end() iterator is invalidated.

    For ordered_json, also adding an element to an object can yield a reallocation which again invalidates all iterators and all references.

    "},{"location":"api/basic_json/push_back/#parameters","title":"Parameters","text":"val (in) the value to add to the JSON array/object init (in) an initializer list"},{"location":"api/basic_json/push_back/#exception-safety","title":"Exception safety","text":"

    Strong guarantee: if an exception is thrown, there are no changes to any JSON value. As an exception, a null value is converted to an empty array or object before the element is added and keeps that type if adding the element throws.

    "},{"location":"api/basic_json/push_back/#exceptions","title":"Exceptions","text":"
    1. Throws type_error.308 when called on a type other than JSON array or null; example: \"cannot use push_back() with number\"
    2. Throws type_error.308 when called on a type other than JSON object or null; example: \"cannot use push_back() with number\"
    3. Throws type_error.308 when called on a type other than JSON array or null; example: \"cannot use push_back() with number\"
    "},{"location":"api/basic_json/push_back/#complexity","title":"Complexity","text":"
    1. Amortized constant.
    2. Logarithmic in the size of the container, O(log(size())).
    3. Linear in the size of the initializer list init.
    "},{"location":"api/basic_json/push_back/#notes","title":"Notes","text":"

    (3) This function is required to resolve an ambiguous overload error, because pairs like {\"key\", \"value\"} can be both interpreted as object_t::value_type or std::initializer_list<basic_json>, see #235 for more information.

    "},{"location":"api/basic_json/push_back/#examples","title":"Examples","text":"Example: (1) add element to array

    The example shows how push_back() and += can be used to add elements to a JSON array. Note how the null value was silently converted to a JSON array.

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create JSON values\n    json array = {1, 2, 3, 4, 5};\n    json null;\n\n    // print values\n    std::cout << array << '\\n';\n    std::cout << null << '\\n';\n\n    // add values\n    array.push_back(6);\n    array += 7;\n    null += \"first\";\n    null += \"second\";\n\n    // print values\n    std::cout << array << '\\n';\n    std::cout << null << '\\n';\n}\n

    Output:

    [1,2,3,4,5]\nnull\n[1,2,3,4,5,6,7]\n[\"first\",\"second\"]\n
    Example: (2) add element to object

    The example shows how push_back() and += can be used to add elements to a JSON object. Note how the null value was silently converted to a JSON object.

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create JSON values\n    json object = {{\"one\", 1}, {\"two\", 2}};\n    json null;\n\n    // print values\n    std::cout << object << '\\n';\n    std::cout << null << '\\n';\n\n    // add values\n    object.push_back(json::object_t::value_type(\"three\", 3));\n    object += json::object_t::value_type(\"four\", 4);\n    null += json::object_t::value_type(\"A\", \"a\");\n    null += json::object_t::value_type(\"B\", \"b\");\n\n    // print values\n    std::cout << object << '\\n';\n    std::cout << null << '\\n';\n}\n

    Output:

    {\"one\":1,\"two\":2}\nnull\n{\"four\":4,\"one\":1,\"three\":3,\"two\":2}\n{\"A\":\"a\",\"B\":\"b\"}\n
    Example: (3) add to object from initializer list

    The example shows how initializer lists are treated as objects when possible.

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create JSON values\n    json object = {{\"one\", 1}, {\"two\", 2}};\n    json null;\n\n    // print values\n    std::cout << object << '\\n';\n    std::cout << null << '\\n';\n\n    // add values:\n    object.push_back({\"three\", 3});  // object is extended\n    object += {\"four\", 4};           // object is extended\n    null.push_back({\"five\", 5});     // null is converted to array\n\n    // print values\n    std::cout << object << '\\n';\n    std::cout << null << '\\n';\n\n    // would throw:\n    //object.push_back({1, 2, 3});\n}\n

    Output:

    {\"one\":1,\"two\":2}\nnull\n{\"four\":4,\"one\":1,\"three\":3,\"two\":2}\n[[\"five\",5]]\n
    "},{"location":"api/basic_json/push_back/#see-also","title":"See also","text":"
    • emplace_back - add a value to an array
    • operator+= - add a value to an array/object
    • Modifying values - the article on modifying values
    "},{"location":"api/basic_json/push_back/#version-history","title":"Version history","text":"
    1. Added in version 1.0.0.
    2. Added in version 1.0.0.
    3. Added in version 2.0.0.
    "},{"location":"api/basic_json/rbegin/","title":"nlohmann::basic_json::rbegin","text":"
    reverse_iterator rbegin() noexcept;\nconst_reverse_iterator rbegin() const noexcept;\n

    Returns an iterator to the reverse-beginning; that is, the last element.

    Two rows of sixteen cells. The upper row shows the reversed sequence: rend() points to a dashed position before the first element and rbegin() to the last element. The lower row shows the forward sequence: begin() points to the first element and end() to a dashed position after the last element. A reverse iterator stores an iterator to the next element, so rend() corresponds to begin() and rbegin() to end(). rend rbegin Reverse past-the-last element A reverse iterator stores an iterator to the next element begin end Past-the-last element

    rbegin() points to the last element and rend() to the position before the first element. The upper row is the reversed sequence and the lower row the forward sequence; dashed arrows link each reverse iterator to the forward iterator it stores, and dashed cells are past-the-last positions.

    "},{"location":"api/basic_json/rbegin/#return-value","title":"Return value","text":"

    reverse iterator to the last element

    "},{"location":"api/basic_json/rbegin/#exception-safety","title":"Exception safety","text":"

    No-throw guarantee: this member function never throws exceptions.

    "},{"location":"api/basic_json/rbegin/#complexity","title":"Complexity","text":"

    Constant.

    "},{"location":"api/basic_json/rbegin/#examples","title":"Examples","text":"Example

    The following code shows an example for rbegin().

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create an array value\n    json array = {1, 2, 3, 4, 5};\n\n    // get an iterator to the reverse-beginning\n    json::reverse_iterator it = array.rbegin();\n\n    // serialize the element that the iterator points to\n    std::cout << *it << '\\n';\n}\n

    Output:

    5\n
    "},{"location":"api/basic_json/rbegin/#see-also","title":"See also","text":"
    • rend - returns a reverse iterator to one before the first element
    • crbegin - returns a const reverse iterator to the last element
    • begin - returns an iterator to the first element
    • Iterators - the article on iterators
    "},{"location":"api/basic_json/rbegin/#version-history","title":"Version history","text":"
    • Added in version 1.0.0.
    "},{"location":"api/basic_json/rend/","title":"nlohmann::basic_json::rend","text":"
    reverse_iterator rend() noexcept;\nconst_reverse_iterator rend() const noexcept;\n

    Returns an iterator to the reverse-end; that is, one before the first element. This element acts as a placeholder, attempting to access it results in undefined behavior.

    Two rows of sixteen cells. The upper row shows the reversed sequence: rend() points to a dashed position before the first element and rbegin() to the last element. The lower row shows the forward sequence: begin() points to the first element and end() to a dashed position after the last element. A reverse iterator stores an iterator to the next element, so rend() corresponds to begin() and rbegin() to end(). rend rbegin Reverse past-the-last element A reverse iterator stores an iterator to the next element begin end Past-the-last element

    rend() points to the position before the first element and rbegin() to the last element. The upper row is the reversed sequence and the lower row the forward sequence; dashed arrows link each reverse iterator to the forward iterator it stores, and dashed cells are past-the-last positions.

    "},{"location":"api/basic_json/rend/#return-value","title":"Return value","text":"

    reverse iterator to the element following the last element

    "},{"location":"api/basic_json/rend/#exception-safety","title":"Exception safety","text":"

    No-throw guarantee: this member function never throws exceptions.

    "},{"location":"api/basic_json/rend/#complexity","title":"Complexity","text":"

    Constant.

    "},{"location":"api/basic_json/rend/#examples","title":"Examples","text":"Example

    The following code shows an example for rend().

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create an array value\n    json array = {1, 2, 3, 4, 5};\n\n    // get an iterator to the reverse-end\n    json::reverse_iterator it = array.rend();\n\n    // increment the iterator to point to the first element\n    --it;\n\n    // serialize the element that the iterator points to\n    std::cout << *it << '\\n';\n}\n

    Output:

    1\n
    "},{"location":"api/basic_json/rend/#see-also","title":"See also","text":"
    • rbegin - returns a reverse iterator to the last element
    • crend - returns a const reverse iterator to one before the first element
    • end - returns an iterator to one past the last element
    • Iterators - the article on iterators
    "},{"location":"api/basic_json/rend/#version-history","title":"Version history","text":"
    • Added in version 1.0.0.
    "},{"location":"api/basic_json/sax_parse/","title":"nlohmann::basic_json::sax_parse","text":"
    // (1)\ntemplate <typename InputType, typename SAX>\nstatic bool sax_parse(InputType&& i,\n                      SAX* sax,\n                      input_format_t format = input_format_t::json,\n                      const bool strict = true,\n                      const bool ignore_comments = false,\n                      const bool ignore_trailing_commas = false,\n                      const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error);\n\n// (2)\ntemplate<class IteratorType, class SAX, class SentinelType = IteratorType>\nstatic bool sax_parse(IteratorType first, SentinelType last,\n                      SAX* sax,\n                      input_format_t format = input_format_t::json,\n                      const bool strict = true,\n                      const bool ignore_comments = false,\n                      const bool ignore_trailing_commas = false,\n                      const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error);\n

    Read from input and generate SAX events

    1. Read from a compatible input.
    2. Read from a pair of character iterators, or an iterator and a sentinel of a different type (C++20 ranges support).

      The value_type of the iterator must be an integral type with a size of 1, 2, or 4 bytes, which will be interpreted respectively as UTF-8, UTF-16, and UTF-32. If SentinelType differs from IteratorType, it must be comparable to the iterator type with operator!=.

      Ill-formed UTF-16 and UTF-32 sequences are rejected: a lone surrogate, a high surrogate that is not followed by its low surrogate, and a code point above U+10FFFF all yield a parse_error.101.

    The SAX event lister must follow the interface of json_sax.

    "},{"location":"api/basic_json/sax_parse/#template-parameters","title":"Template parameters","text":"InputType

    A compatible input, for instance:

    • an std::istream object
    • a FILE pointer
    • a C-style array of characters
    • a pointer to a null-terminated string of single byte characters
    • a std::string or a std::string_view (C++17)
    • a container obj for which begin(obj) and end(obj) produce a valid pair of iterators (as found via ADL or member functions, with semantics compatible to std::begin and std::end)
    • wide characters (wchar_t, char16_t, char32_t), which are converted to UTF-8: a wide string object (std::wstring, std::u16string, std::u32string) or an array (e.g. a wide string literal); a pointer to a null-terminated wide string (e.g. std::u16string::c_str()) is not supported
    IteratorType a compatible iterator type for overload (2); a pair of character iterators whose value_type is an integral type with a size of 1, 2, or 4 bytes (interpreted respectively as UTF-8, UTF-16, and UTF-32) SentinelType

    defaults to IteratorType; may be a different type comparable to IteratorType via operator!=, for overload (2), for instance.

    • a custom sentinel type for C++20 ranges
    • std::default_sentinel_t, when IteratorType is std::counted_iterator
    SAX a class fulfilling the SAX event listener interface; see json_sax"},{"location":"api/basic_json/sax_parse/#parameters","title":"Parameters","text":"i (in) Input to parse from sax (in) SAX event listener (must not be null) format (in) the format to parse (JSON, BJData, BON8, BSON, CBOR, MessagePack, or UBJSON) (optional, input_format_t::json by default), see input_format_t for more information strict (in) whether the input has to be consumed completely (optional, true by default); when false and the input is a std::istream, the character that terminates a number is consumed unless JSON_PRECISE_STREAM_POSITION is defined to 1; see operator>> ignore_comments (in) whether comments should be ignored and treated like whitespace (true) or yield a parse error (false); (optional, false by default) ignore_trailing_commas (in) whether trailing commas in arrays or objects should be ignored and treated like whitespace (true) or yield a parse error (false); (optional, false by default) tag_handler (in) how to handle CBOR tags; see cbor_tag_handler_t. Ignored for formats other than CBOR (optional, cbor_tag_handler_t::error by default). first (in) iterator to the start of a character range last (in) iterator to the end of a character range, or a sentinel value that compares equal to the end iterator with operator!="},{"location":"api/basic_json/sax_parse/#return-value","title":"Return value","text":"

    return value of the last processed SAX event

    "},{"location":"api/basic_json/sax_parse/#exception-safety","title":"Exception safety","text":"

    Strong guarantee: if an exception is thrown, there are no changes in the JSON value.

    "},{"location":"api/basic_json/sax_parse/#exceptions","title":"Exceptions","text":"
    • Throws parse_error.101 in case of an unexpected token, or empty input like a null FILE* or char* pointer.
    "},{"location":"api/basic_json/sax_parse/#complexity","title":"Complexity","text":"

    Linear in the length of the input. The parser is a predictive LL(1) parser. The complexity can be higher if the SAX consumer sax has a super-linear complexity.

    "},{"location":"api/basic_json/sax_parse/#notes","title":"Notes","text":"

    A UTF-8 byte order mark is silently ignored.

    When reading from a FILE*, the file is locked while it is parsed. The lock is recursive, so the SAX handler may use the same file with stdio functions, but it must not wait for another thread that uses the same FILE object; see JSON_DISABLE_UNLOCKED_FILE_IO.

    "},{"location":"api/basic_json/sax_parse/#examples","title":"Examples","text":"Example

    The example below demonstrates the sax_parse() function reading from string and processing the events with a user-defined SAX event consumer.

    #include <iostream>\n#include <iomanip>\n#include <sstream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\n// a simple event consumer that collects string representations of the passed\n// values; note inheriting from json::json_sax_t is not required, but can\n// help not to forget a required function\nclass sax_event_consumer : public json::json_sax_t\n{\n  public:\n    std::vector<std::string> events;\n\n    bool null() override\n    {\n        events.push_back(\"null()\");\n        return true;\n    }\n\n    bool boolean(bool val) override\n    {\n        events.push_back(\"boolean(val=\" + std::string(val ? \"true\" : \"false\") + \")\");\n        return true;\n    }\n\n    bool number_integer(number_integer_t val) override\n    {\n        events.push_back(\"number_integer(val=\" + std::to_string(val) + \")\");\n        return true;\n    }\n\n    bool number_unsigned(number_unsigned_t val) override\n    {\n        events.push_back(\"number_unsigned(val=\" + std::to_string(val) + \")\");\n        return true;\n    }\n\n    bool number_float(number_float_t val, const string_t& s) override\n    {\n        events.push_back(\"number_float(val=\" + std::to_string(val) + \", s=\" + s + \")\");\n        return true;\n    }\n\n    bool string(string_t& val) override\n    {\n        events.push_back(\"string(val=\" + val + \")\");\n        return true;\n    }\n\n    bool start_object(std::size_t elements) override\n    {\n        events.push_back(\"start_object(elements=\" + std::to_string(elements) + \")\");\n        return true;\n    }\n\n    bool end_object() override\n    {\n        events.push_back(\"end_object()\");\n        return true;\n    }\n\n    bool start_array(std::size_t elements) override\n    {\n        events.push_back(\"start_array(elements=\" + std::to_string(elements) + \")\");\n        return true;\n    }\n\n    bool end_array() override\n    {\n        events.push_back(\"end_array()\");\n        return true;\n    }\n\n    bool key(string_t& val) override\n    {\n        events.push_back(\"key(val=\" + val + \")\");\n        return true;\n    }\n\n    bool binary(json::binary_t& val) override\n    {\n        events.push_back(\"binary(val=[...])\");\n        return true;\n    }\n\n    bool parse_error(std::size_t position, const std::string& last_token, const json::exception& ex) override\n    {\n        events.push_back(\"parse_error(position=\" + std::to_string(position) + \", last_token=\" + last_token + \",\\n            ex=\" + std::string(ex.what()) + \")\");\n        return false;\n    }\n};\n\nint main()\n{\n    // a JSON text\n    const auto* text = R\"(\n    {\n        \"Image\": {\n            \"Width\":  800,\n            \"Height\": 600,\n            \"Title\":  \"View from 15th Floor\",\n            \"Thumbnail\": {\n                \"Url\":    \"http://www.example.com/image/481989943\",\n                \"Height\": 125,\n                \"Width\":  100\n            },\n            \"Animated\" : false,\n            \"IDs\": [116, 943, 234, -38793],\n            \"DeletionDate\": null,\n            \"Distance\": 12.723374634\n        }\n    }]\n    )\";\n\n    // create a SAX event consumer object\n    sax_event_consumer sec;\n\n    // parse JSON\n    bool result = json::sax_parse(text, &sec);\n\n    // output the recorded events\n    for (auto& event : sec.events)\n    {\n        std::cout << event << \"\\n\";\n    }\n\n    // output the result of sax_parse\n    std::cout << \"\\nresult: \" << std::boolalpha << result << '\\n';\n}\n

    Output:

    start_object(elements=18446744073709551615)\nkey(val=Image)\nstart_object(elements=18446744073709551615)\nkey(val=Width)\nnumber_unsigned(val=800)\nkey(val=Height)\nnumber_unsigned(val=600)\nkey(val=Title)\nstring(val=View from 15th Floor)\nkey(val=Thumbnail)\nstart_object(elements=18446744073709551615)\nkey(val=Url)\nstring(val=http://www.example.com/image/481989943)\nkey(val=Height)\nnumber_unsigned(val=125)\nkey(val=Width)\nnumber_unsigned(val=100)\nend_object()\nkey(val=Animated)\nboolean(val=false)\nkey(val=IDs)\nstart_array(elements=18446744073709551615)\nnumber_unsigned(val=116)\nnumber_unsigned(val=943)\nnumber_unsigned(val=234)\nnumber_integer(val=-38793)\nend_array()\nkey(val=DeletionDate)\nnull()\nkey(val=Distance)\nnumber_float(val=12.723375, s=12.723374634)\nend_object()\nend_object()\nparse_error(position=460, last_token=12.723374634<U+000A>        }<U+000A>    }],\n            ex=[json.exception.parse_error.101] parse error at line 17, column 6: syntax error while parsing value - unexpected ']'; expected end of input)\n\nresult: false\n
    "},{"location":"api/basic_json/sax_parse/#see-also","title":"See also","text":"
    • parse - deserialize from a compatible input
    • accept - check if the input is valid JSON
    • JSON_DISABLE_STREAM_BULK_SCAN - read a std::istream one character at a time
    • JSON_DISABLE_UNLOCKED_FILE_IO - read a FILE* with the locking stdio functions
    • SAX Interface - guide to event-based parsing
    • Large, Streamed, and Partial Input - chunked, concatenated, and very large input
    "},{"location":"api/basic_json/sax_parse/#version-history","title":"Version history","text":"
    • Added in version 3.2.0.
    • Ignoring comments via ignore_comments added in version 3.9.0.
    • Added ignore_trailing_commas in version 3.13.0 unreleased.
    • Added tag_handler in version 3.13.0 unreleased.
    • Extended container support (1) to include types with lvalue-only ADL begin/end (matching std::begin/std::end semantics) in version 3.13.0 unreleased.
    • Extended overload (2) to accept heterogeneous iterator+sentinel pairs (C++20 ranges support) in version 3.13.0 unreleased.
    • JSON_PRECISE_STREAM_POSITION added in version 3.13.0 unreleased to optionally leave a std::istream positioned right after the parsed value when strict is false.
    • Parsing from an std::istream scans the characters in its stream buffer in bulk in version 3.13.0 unreleased (JSON_DISABLE_STREAM_BULK_SCAN).
    • Parsing from a FILE* locks the file once instead of once per character in version 3.13.0 unreleased (JSON_DISABLE_UNLOCKED_FILE_IO).
    • Ill-formed UTF-16 and UTF-32 input (a lone surrogate, a high surrogate that is not followed by its low surrogate, or a code point above U+10FFFF) is rejected with parse_error.101 in version 3.13.0 unreleased; before that, some such sequences were accepted or ended the input silently.

    Deprecation

    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 sax_parse({ptr, ptr+len}); with sax_parse(ptr, ptr+len);.

    See the migration guide for how to update existing code.

    "},{"location":"api/basic_json/size/","title":"nlohmann::basic_json::size","text":"
    size_type size() const noexcept;\n

    Returns the number of elements in a JSON value.

    "},{"location":"api/basic_json/size/#return-value","title":"Return value","text":"

    The return value depends on the different types and is defined as follows:

    Value type return value null 0 boolean 1 string 1 number 1 binary 1 object result of function object_t::size() array result of function array_t::size()"},{"location":"api/basic_json/size/#exception-safety","title":"Exception safety","text":"

    No-throw guarantee: this function never throws exceptions.

    "},{"location":"api/basic_json/size/#complexity","title":"Complexity","text":"

    Constant, as long as array_t and object_t satisfy the Container concept; that is, their size() functions have constant complexity.

    "},{"location":"api/basic_json/size/#notes","title":"Notes","text":"

    This function does not return the length of a string stored as JSON value \u2014 it returns the number of elements in the JSON value which is 1 in the case of a string.

    "},{"location":"api/basic_json/size/#examples","title":"Examples","text":"Example

    The following code calls size() on the different value types.

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create JSON values\n    json j_null;\n    json j_boolean = true;\n    json j_number_integer = 17;\n    json j_number_float = 23.42;\n    json j_object = {{\"one\", 1}, {\"two\", 2}};\n    json j_object_empty(json::value_t::object);\n    json j_array = {1, 2, 4, 8, 16};\n    json j_array_empty(json::value_t::array);\n    json j_string = \"Hello, world\";\n\n    // call size()\n    std::cout << j_null.size() << '\\n';\n    std::cout << j_boolean.size() << '\\n';\n    std::cout << j_number_integer.size() << '\\n';\n    std::cout << j_number_float.size() << '\\n';\n    std::cout << j_object.size() << '\\n';\n    std::cout << j_object_empty.size() << '\\n';\n    std::cout << j_array.size() << '\\n';\n    std::cout << j_array_empty.size() << '\\n';\n    std::cout << j_string.size() << '\\n';\n}\n

    Output:

    0\n1\n1\n1\n2\n0\n5\n0\n1\n
    "},{"location":"api/basic_json/size/#see-also","title":"See also","text":"
    • empty - checks whether the JSON value has no elements
    • max_size - returns the maximum possible number of elements
    • basic_json_view::size - the same function on a zero-copy view
    "},{"location":"api/basic_json/size/#version-history","title":"Version history","text":"
    • Added in version 1.0.0.
    • Extended to return 1 for binary types in version 3.8.0.
    "},{"location":"api/basic_json/start_pos/","title":"nlohmann::basic_json::start_pos","text":"
    #if JSON_DIAGNOSTIC_POSITIONS\nconstexpr std::size_t start_pos() const noexcept;\n#endif\n

    Returns the position of the first character in the JSON string from which the value was parsed from.

    JSON type return value object position of the opening { array position of the opening [ string position of the opening \" number position of the first character boolean position of t for true and f for false null position of n"},{"location":"api/basic_json/start_pos/#return-value","title":"Return value","text":"

    the position of the first character of the value in the parsed JSON string, if the value was created by the parse function, or std::string::npos if the value was constructed otherwise

    "},{"location":"api/basic_json/start_pos/#exception-safety","title":"Exception safety","text":"

    No-throw guarantee: this member function never throws exceptions.

    "},{"location":"api/basic_json/start_pos/#complexity","title":"Complexity","text":"

    Constant.

    "},{"location":"api/basic_json/start_pos/#notes","title":"Notes","text":"

    Note

    The function is only available if macro JSON_DIAGNOSTIC_POSITIONS has been defined to 1 before including the library header.

    Invalidation

    The returned positions are only valid as long as the JSON value is not changed. The positions are not updated when the JSON value is changed.

    "},{"location":"api/basic_json/start_pos/#examples","title":"Examples","text":"Example
    #include <iostream>\n\n#define JSON_DIAGNOSTIC_POSITIONS 1\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    std::string json_string = R\"(\n    {\n        \"address\": {\n            \"street\": \"Fake Street\",\n            \"housenumber\": 1\n        }\n    }\n    )\";\n    json j = json::parse(json_string);\n\n    std::cout << \"Root diagnostic positions: \\n\";\n    std::cout << \"\\tstart_pos: \" << j.start_pos() << '\\n';\n    std::cout << \"\\tend_pos:\" << j.end_pos() << \"\\n\";\n    std::cout << \"Original string: \\n\";\n    std::cout << \"{\\n        \\\"address\\\": {\\n            \\\"street\\\": \\\"Fake Street\\\",\\n            \\\"housenumber\\\": 1\\n        }\\n    }\" << \"\\n\";\n    std::cout << \"Parsed string: \\n\";\n    std::cout << json_string.substr(j.start_pos(), j.end_pos() - j.start_pos()) << \"\\n\\n\";\n\n    std::cout << \"address diagnostic positions: \\n\";\n    std::cout << \"\\tstart_pos:\" << j[\"address\"].start_pos() << '\\n';\n    std::cout << \"\\tend_pos:\" << j[\"address\"].end_pos() << \"\\n\\n\";\n    std::cout << \"Original string: \\n\";\n    std::cout << \"{            \\\"street\\\": \\\"Fake Street\\\",\\n            \\\"housenumber\\\": 1\\n        }\" << \"\\n\";\n    std::cout << \"Parsed string: \\n\";\n    std::cout << json_string.substr(j[\"address\"].start_pos(), j[\"address\"].end_pos() - j[\"address\"].start_pos()) << \"\\n\\n\";\n\n    std::cout << \"street diagnostic positions: \\n\";\n    std::cout << \"\\tstart_pos:\" << j[\"address\"][\"street\"].start_pos() << '\\n';\n    std::cout << \"\\tend_pos:\" << j[\"address\"][\"street\"].end_pos() << \"\\n\\n\";\n    std::cout << \"Original string: \\n\";\n    std::cout << \"\\\"Fake Street\\\"\" << \"\\n\";\n    std::cout << \"Parsed string: \\n\";\n    std::cout << json_string.substr(j[\"address\"][\"street\"].start_pos(), j[\"address\"][\"street\"].end_pos() - j[\"address\"][\"street\"].start_pos()) << \"\\n\\n\";\n\n    std::cout << \"housenumber diagnostic positions: \\n\";\n    std::cout << \"\\tstart_pos:\" << j[\"address\"][\"housenumber\"].start_pos() << '\\n';\n    std::cout << \"\\tend_pos:\" << j[\"address\"][\"housenumber\"].end_pos() << \"\\n\\n\";\n    std::cout << \"Original string: \\n\";\n    std::cout << \"1\" << \"\\n\";\n    std::cout << \"Parsed string: \\n\";\n    std::cout << json_string.substr(j[\"address\"][\"housenumber\"].start_pos(), j[\"address\"][\"housenumber\"].end_pos() - j[\"address\"][\"housenumber\"].start_pos()) << \"\\n\\n\";\n}\n

    Output:

    Root diagnostic positions: \n    start_pos: 5\n    end_pos:109\nOriginal string: \n{\n        \"address\": {\n            \"street\": \"Fake Street\",\n            \"housenumber\": 1\n        }\n    }\nParsed string: \n{\n        \"address\": {\n            \"street\": \"Fake Street\",\n            \"housenumber\": 1\n        }\n    }\n\naddress diagnostic positions: \n    start_pos:26\n    end_pos:103\n\nOriginal string: \n{            \"street\": \"Fake Street\",\n            \"housenumber\": 1\n        }\nParsed string: \n{\n            \"street\": \"Fake Street\",\n            \"housenumber\": 1\n        }\n\nstreet diagnostic positions: \n    start_pos:50\n    end_pos:63\n\nOriginal string: \n\"Fake Street\"\nParsed string: \n\"Fake Street\"\n\nhousenumber diagnostic positions: \n    start_pos:92\n    end_pos:93\n\nOriginal string: \n1\nParsed string: \n1\n

    The output shows the start/end positions of all the objects and fields in the JSON string.

    "},{"location":"api/basic_json/start_pos/#see-also","title":"See also","text":"
    • end_pos - to access the end position
    • JSON_DIAGNOSTIC_POSITIONS - overview of the supported conversions
    • Parsing and Exceptions - handling parse errors and locating them in the input
    "},{"location":"api/basic_json/start_pos/#version-history","title":"Version history","text":"
    • Added in version 3.12.0.
    "},{"location":"api/basic_json/std_formatter/","title":"std::formatter<nlohmann::basic_json>","text":"
    namespace std {\n    template <>\n    struct formatter<nlohmann::basic_json, char>;\n}\n

    Specialization to make JSON values formattable with std::format (and the other members of C++20's <format> header, such as std::format_to).

    A subset of the standard format spec grammar is supported, repurposed for JSON pretty-printing; any other spec component (sign, the 0 flag, precision, L, a dynamic width such as \"{:{}}\", or a trailing type character) throws std::format_error:

    • \"{}\" serializes the value the same way as dump() (compact, no whitespace).
    • \"{:#}\" (\"alternate form\") serializes the value the same way as dump(4) (pretty-printed with an indent of 4).
    • A width, with or without \"#\" (e.g. \"{:2}\" or \"{:#2}\"), serializes the value the same way as dump(width) \u2014 a width on its own implies pretty-printing, since an indent size has no meaning for compact output.
    • fill-and-align (e.g. \"{:.>#}\" or \"{:.>3}\") picks a custom indent character, the same way as dump(indent, indent_char). The alignment direction itself ('<', '>', '^') has no separate meaning for JSON values \u2014 only the fill character before it is used, and any of the three directions is accepted.

    This specialization is only available for char-based JSON values and only if the standard library provides <format>, controlled by the JSON_HAS_STD_FORMAT macro.

    "},{"location":"api/basic_json/std_formatter/#examples","title":"Examples","text":"Example

    The example shows how to format JSON values with std::format.

    #include <format>\n#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    json j = {{\"one\", 1}, {\"two\", 2}};\n\n    // compact formatting, like dump()\n    std::cout << std::format(\"{}\", j) << \"\\n\\n\";\n\n    // pretty-printed formatting, like dump(4)\n    std::cout << std::format(\"{:#}\", j) << \"\\n\\n\";\n\n    // a width sets the indent, like dump(2)\n    std::cout << std::format(\"{:2}\", j) << \"\\n\\n\";\n\n    // fill-and-align sets the indent character, like dump(4, '.')\n    std::cout << std::format(\"{:.>#}\", j) << std::endl;\n}\n

    Output:

    {\"one\":1,\"two\":2}\n\n{\n    \"one\": 1,\n    \"two\": 2\n}\n\n{\n  \"one\": 1,\n  \"two\": 2\n}\n\n{\n....\"one\": 1,\n....\"two\": 2\n}\n
    "},{"location":"api/basic_json/std_formatter/#see-also","title":"See also","text":"
    • dump - serialization
    • operator<<(std::ostream&) - serialize to stream
    • format_as - customization point used by fmt::format (fmtlib)
    • Serialization - the serialization article
    "},{"location":"api/basic_json/std_formatter/#version-history","title":"Version history","text":"
    • Added in version 3.13.0 unreleased.
    "},{"location":"api/basic_json/std_hash/","title":"std::hash<nlohmann::basic_json>","text":"
    namespace std {\n    struct hash<nlohmann::basic_json>;\n}\n

    Return a hash value for a JSON object. The hash function tries to rely on std::hash where possible. Furthermore, the type of the JSON value is taken into account, so null, false, and numbers may hash differently from each other. Numbers that compare equal under operator== always hash equally, regardless of whether they are stored as signed integer, unsigned integer, or floating-point number.

    Numbers are hashed by their value converted to number_float_t. Converting an integer to number_float_t therefore keeps its hash, but converting a floating-point number to an integer type is lossy and can change it: 0.5 converts to 0, which need not have the same hash. Unequal numbers can also share a hash value, for example two large integers that convert to the same number_float_t.

    "},{"location":"api/basic_json/std_hash/#examples","title":"Examples","text":"Example

    The example shows how to calculate hash values for different JSON values.

    #include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\nusing namespace nlohmann::literals;\n\nint main()\n{\n    std::cout << \"hash(null) = \" << std::hash<json> {}(json(nullptr)) << '\\n'\n              << \"hash(false) = \" << std::hash<json> {}(json(false)) << '\\n'\n              << \"hash(0) = \" << std::hash<json> {}(json(0)) << '\\n'\n              << \"hash(0U) = \" << std::hash<json> {}(json(0U)) << '\\n'\n              << \"hash(0.0) = \" << std::hash<json> {}(json(0.0)) << '\\n'\n              << \"hash(\\\"\\\") = \" << std::hash<json> {}(json(\"\")) << '\\n'\n              << \"hash({}) = \" << std::hash<json> {}(json::object()) << '\\n'\n              << \"hash([]) = \" << std::hash<json> {}(json::array()) << '\\n'\n              << \"hash({\\\"hello\\\": \\\"world\\\"}) = \" << std::hash<json> {}(\"{\\\"hello\\\": \\\"world\\\"}\"_json)\n              << '\\n';\n}\n

    Output:

    hash(null) = 2654435769\nhash(false) = 2654436030\nhash(0) = 2654436221\nhash(0U) = 2654436221\nhash(0.0) = 2654436221\nhash(\"\") = 11160318156688833227\nhash({}) = 2654435832\nhash([]) = 2654435899\nhash({\"hello\": \"world\"}) = 3701319991624763853\n

    The hash values shown are examples only. They depend on the platform, the compiler, and the compiler version, and they can change between versions of this library. Do not persist them or rely on specific values.

    "},{"location":"api/basic_json/std_hash/#see-also","title":"See also","text":"
    • operator== - compares two JSON values for equality, consistent with equal hash values
    • Types - the JSON value types and how they compare
    "},{"location":"api/basic_json/std_hash/#version-history","title":"Version history","text":"
    • Added in version 1.0.0.
    • Extended for arbitrary basic_json types in version 3.10.5.
    • Numbers that compare equal hash equally since version 3.13.0 unreleased; before, 0, 0U, and 0.0 had different hash values.
    "},{"location":"api/basic_json/std_swap/","title":"std::swap<basic_json>","text":"
    namespace std {\n    void swap(nlohmann::basic_json& j1, nlohmann::basic_json& j2);\n}\n

    Exchanges the values of two JSON objects.

    "},{"location":"api/basic_json/std_swap/#parameters","title":"Parameters","text":"j1 (in, out) value to be replaced by j2 j2 (in, out) value to be replaced by j1"},{"location":"api/basic_json/std_swap/#exception-safety","title":"Exception safety","text":"

    No-throw guarantee: this function never throws exceptions.

    "},{"location":"api/basic_json/std_swap/#complexity","title":"Complexity","text":"

    Constant.

    "},{"location":"api/basic_json/std_swap/#possible-implementation","title":"Possible implementation","text":"
    void swap(nlohmann::basic_json& j1, nlohmann::basic_json& j2)\n{\n    j1.swap(j2);\n}\n
    "},{"location":"api/basic_json/std_swap/#examples","title":"Examples","text":"Example

    The following code shows how two values are swapped with std::swap.

    #include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create JSON values\n    json j1 = {{\"one\", 1}, {\"two\", 2}};\n    json j2 = {1, 2, 4, 8, 16};\n\n    std::cout << \"j1 = \" << j1 << \" | j2 = \" << j2 << '\\n';\n\n    // swap values\n    std::swap(j1, j2);\n\n    std::cout << \"j1 = \" << j1 << \" | j2 = \" << j2 << '\\n';\n}\n

    Output:

    j1 = {\"one\":1,\"two\":2} | j2 = [1,2,4,8,16]\nj1 = [1,2,4,8,16] | j2 = {\"one\":1,\"two\":2}\n
    "},{"location":"api/basic_json/std_swap/#see-also","title":"See also","text":"
    • swap - exchange the contents of two JSON values
    "},{"location":"api/basic_json/std_swap/#version-history","title":"Version history","text":"
    • Added in version 1.0.0.
    • Extended for arbitrary basic_json types in version 3.10.5.
    "},{"location":"api/basic_json/string_t/","title":"nlohmann::basic_json::string_t","text":"
    using string_t = StringType;\n

    The type used to store JSON strings.

    RFC 8259 describes JSON strings as follows:

    A string is a sequence of zero or more Unicode characters.

    To store strings in C++, a type is defined by the template parameter described below. Unicode values are split by the JSON class into byte-sized characters during deserialization.

    "},{"location":"api/basic_json/string_t/#template-parameters","title":"Template parameters","text":"StringType

    the container to store strings (e.g., std::string). Note this container is used for keys/names in objects, see object_t.

    StringType must have a char-compatible value_type: the library relies on UTF-8/char-based storage and processing internally, so std::wstring, std::u16string, and std::u32string are not valid choices for StringType. To work with wide-character data, convert it to/from UTF-8 at the boundary instead \u2014 see the FAQ's wide string handling section for a conversion recipe.

    Beyond the character type, the library expects a substantial part of the std::string interface (contiguous null-terminated data(), substr(), find(), append(), ...). See Template Parameter Requirements for the full list and for the string types that are known to work.

    "},{"location":"api/basic_json/string_t/#notes","title":"Notes","text":""},{"location":"api/basic_json/string_t/#default-type","title":"Default type","text":"

    With the default values for StringType (std::string), the default type for string_t is std::string.

    "},{"location":"api/basic_json/string_t/#encoding","title":"Encoding","text":"

    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.

    "},{"location":"api/basic_json/string_t/#string-comparison","title":"String comparison","text":"

    RFC 8259 states:

    Software implementations are typically required to test names of object members for equality. Implementations that transform the textual representation into sequences of Unicode code units and then perform the comparison numerically, code unit by code unit, are interoperable in the sense that implementations will agree in all cases on equality or inequality of two strings. For example, implementations that compare strings with escaped characters unconverted may incorrectly find that \"a\\\\b\" and \"a\\u005Cb\" are not equal.

    This implementation is interoperable as it does compare strings code unit by code unit.

    "},{"location":"api/basic_json/string_t/#storage","title":"Storage","text":"

    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.

    "},{"location":"api/basic_json/string_t/#cross-basic_json-conversion-requirements","title":"Cross-basic_json conversion requirements","text":"

    When converting a string value from one basic_json specialization to another via the converting constructor (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 for details and an example.

    "},{"location":"api/basic_json/string_t/#examples","title":"Examples","text":"Example

    The following code shows that string_t is by default, a typedef to std::string.

    #include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    std::cout << std::boolalpha << std::is_same<std::string, json::string_t>::value << '\\n';\n}\n

    Output:

    true\n
    "},{"location":"api/basic_json/string_t/#see-also","title":"See also","text":"
    • object_t - the type used to store JSON objects (and their keys, which are also string_t)
    • binary_t - the type used to store binary values
    • get_ptr - returns a pointer to the stored string value
    • Types - how strings are stored
    • Template Parameter Requirements - requirements on the StringType template parameter
    "},{"location":"api/basic_json/string_t/#version-history","title":"Version history","text":"
    • Added in version 1.0.0.
    • Removed the requirement that string_t be implicitly convertible from std::string, which the BSON writer and the UBJSON reader relied on, in version 3.13.0 unreleased.
    "},{"location":"api/basic_json/swap/","title":"nlohmann::basic_json::swap","text":"
    // (1)\nvoid swap(reference other) noexcept (\n    std::is_nothrow_move_constructible<value_t>::value &&\n    std::is_nothrow_move_assignable<value_t>::value &&\n    std::is_nothrow_move_constructible<json_value>::value &&\n    std::is_nothrow_move_assignable<json_value>::value &&\n    std::is_nothrow_move_constructible<json_base_class_t>::value &&\n    std::is_nothrow_move_assignable<json_base_class_t>::value\n);\n\n// (2)\nfriend void swap(reference left, reference right) noexcept (\n    std::is_nothrow_move_constructible<value_t>::value &&\n    std::is_nothrow_move_assignable<value_t>::value &&\n    std::is_nothrow_move_constructible<json_value>::value &&\n    std::is_nothrow_move_assignable<json_value>::value &&\n    std::is_nothrow_move_constructible<json_base_class_t>::value &&\n    std::is_nothrow_move_assignable<json_base_class_t>::value\n);\n\n// (3)\nvoid swap(array_t& other);\n\n// (4)\nvoid swap(object_t& other);\n\n// (5)\nvoid swap(string_t& other);\n\n// (6)\nvoid swap(binary_t& other);\n\n// (7)\nvoid swap(typename binary_t::container_type& other);\n
    1. Exchanges the contents of the JSON value 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. If macro JSON_DIAGNOSTIC_POSITIONS is defined to 1, the start_pos()/end_pos() diagnostic positions are exchanged along with the value. The json_base_class_t 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 is defined to 1, the start_pos()/end_pos() diagnostic positions are exchanged along with the value. The json_base_class_t 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 individual elements. All iterators and references remain valid. The past-the-end iterator is invalidated.
    5. Exchanges the contents of a JSON string 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.
    6. Exchanges the contents of a binary value 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.
    7. Exchanges the contents of a binary value 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. Unlike version (6), no binary subtype is involved.
    "},{"location":"api/basic_json/swap/#parameters","title":"Parameters","text":"other (in, out) value to exchange the contents with left (in, out) value to exchange the contents with right (in, out) value to exchange the contents with"},{"location":"api/basic_json/swap/#exception-safety","title":"Exception safety","text":"
    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.
    "},{"location":"api/basic_json/swap/#exceptions","title":"Exceptions","text":"
    1. No-throw guarantee: this function never throws exceptions.
    2. No-throw guarantee: this function never throws exceptions.
    3. Throws type_error.310 if called on JSON values other than arrays; example: \"cannot use swap(array_t&) with boolean\"
    4. Throws type_error.310 if called on JSON values other than objects; example: \"cannot use swap(object_t&) with boolean\"
    5. Throws type_error.310 if called on JSON values other than strings; example: \"cannot use swap(string_t&) with boolean\"
    6. Throws type_error.310 if called on JSON values other than binaries; example: \"cannot use swap(binary_t&) with boolean\"
    7. Throws type_error.310 if called on JSON values other than binaries; example: \"cannot use swap(binary_t::container_type&) with boolean\"
    "},{"location":"api/basic_json/swap/#complexity","title":"Complexity","text":"

    Constant.

    "},{"location":"api/basic_json/swap/#examples","title":"Examples","text":"Example: (1, 2) swap JSON values

    The example below shows how JSON values can be swapped with swap().

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create two JSON values\n    json j1 = {1, 2, 3, 4, 5};\n    json j2 = {{\"pi\", 3.141592653589793}, {\"e\", 2.718281828459045}};\n\n    // swap the values\n    j1.swap(j2);\n\n    // output the values\n    std::cout << \"j1 = \" << j1 << '\\n';\n    std::cout << \"j2 = \" << j2 << '\\n';\n}\n

    Output:

    j1 = {\"e\":2.718281828459045,\"pi\":3.141592653589793}\nj2 = [1,2,3,4,5]\n
    Example: (3) swap array

    The example below shows how arrays can be swapped with swap().

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create a JSON value\n    json value = {{\"array\", {1, 2, 3, 4}}};\n\n    // create an array_t\n    json::array_t array = {\"Snap\", \"Crackle\", \"Pop\"};\n\n    // swap the array stored in the JSON value\n    value[\"array\"].swap(array);\n\n    // output the values\n    std::cout << \"value = \" << value << '\\n';\n    std::cout << \"array = \" << array << '\\n';\n}\n

    Output:

    value = {\"array\":[\"Snap\",\"Crackle\",\"Pop\"]}\narray = [1,2,3,4]\n
    Example: (4) swap object

    The example below shows how objects can be swapped with swap().

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create a JSON value\n    json value = { {\"translation\", {{\"one\", \"eins\"}, {\"two\", \"zwei\"}}} };\n\n    // create an object_t\n    json::object_t object = {{\"cow\", \"Kuh\"}, {\"dog\", \"Hund\"}};\n\n    // swap the object stored in the JSON value\n    value[\"translation\"].swap(object);\n\n    // output the values\n    std::cout << \"value = \" << value << '\\n';\n    std::cout << \"object = \" << object << '\\n';\n}\n

    Output:

    value = {\"translation\":{\"cow\":\"Kuh\",\"dog\":\"Hund\"}}\nobject = {\"one\":\"eins\",\"two\":\"zwei\"}\n
    Example: (5) swap string

    The example below shows how strings can be swapped with swap().

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create a JSON value\n    json value = { \"the good\", \"the bad\", \"the ugly\" };\n\n    // create string_t\n    json::string_t string = \"the fast\";\n\n    // swap the object stored in the JSON value\n    value[1].swap(string);\n\n    // output the values\n    std::cout << \"value = \" << value << '\\n';\n    std::cout << \"string = \" << string << '\\n';\n}\n

    Output:

    value = [\"the good\",\"the fast\",\"the ugly\"]\nstring = the bad\n
    Example: (6) swap binary

    The example below shows how binary values can be swapped with swap().

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create a binary value\n    json value = json::binary({1, 2, 3});\n\n    // create a binary_t\n    json::binary_t binary = {{4, 5, 6}};\n\n    // swap the object stored in the JSON value\n    value.swap(binary);\n\n    // output the values\n    std::cout << \"value = \" << value << '\\n';\n    std::cout << \"binary = \" << json(binary) << '\\n';\n}\n

    Output:

    value = {\"bytes\":[4,5,6],\"subtype\":null}\nbinary = {\"bytes\":[1,2,3],\"subtype\":null}\n
    "},{"location":"api/basic_json/swap/#see-also","title":"See also","text":"
    • std::swap<basic_json\\> - specialization of std::swap for JSON values
    • operator= - copy assignment
    • basic_json - create a JSON value
    "},{"location":"api/basic_json/swap/#version-history","title":"Version history","text":"
    1. Added in version 1.0.0. Exchanges the json_base_class_t subobject along with the value since version 3.13.0 unreleased.
    2. Added in version 1.0.0. Exchanges the json_base_class_t subobject along with the value since version 3.13.0 unreleased.
    3. Added in version 1.0.0.
    4. Added in version 1.0.0.
    5. Added in version 1.0.0.
    6. Added in version 3.8.0.
    7. Added in version 3.8.0.
    "},{"location":"api/basic_json/to_bjdata/","title":"nlohmann::basic_json::to_bjdata","text":"
    // (1)\nstatic std::vector<std::uint8_t> to_bjdata(const basic_json& j,\n                                           const bool use_size = false,\n                                           const bool use_type = false,\n                                           const bjdata_version_t version = bjdata_version_t::draft2,\n                                           const error_handler_t error_handler = error_handler_t::keep);\n\n// (2)\nstatic void to_bjdata(const basic_json& j, detail::output_adapter<std::uint8_t> o,\n                      const bool use_size = false, const bool use_type = false,\n                      const bjdata_version_t version = bjdata_version_t::draft2,\n                      const error_handler_t error_handler = error_handler_t::keep);\nstatic void to_bjdata(const basic_json& j, detail::output_adapter<char> o,\n                      const bool use_size = false, const bool use_type = false,\n                      const bjdata_version_t version = bjdata_version_t::draft2,\n                      const error_handler_t error_handler = error_handler_t::keep);\n

    Serializes a given JSON value j to a byte vector using the BJData (Binary JData) serialization format. BJData aims to be more compact than JSON itself, yet more efficient to parse.

    1. Returns a byte vector containing the BJData serialization.
    2. Writes the BJData serialization to an output adapter.

    The exact mapping and its limitations are described on a dedicated page.

    "},{"location":"api/basic_json/to_bjdata/#parameters","title":"Parameters","text":"j (in) JSON value to serialize o (in) output adapter to write serialization to use_size (in) whether to add size annotations to container types; optional, false by default. use_type (in) whether to add type annotations to container types (must be combined with use_size = true); optional, false by default. version (in) which version of BJData to use, see bjdata_version_t and the note on \"Binary values\" on BJData; optional, bjdata_version_t::draft2 by default. error_handler (in) how to treat a string or object key in j that is not valid UTF-8; see error_handler_t. The default, keep, writes the ill-formed bytes to the output as is, as every version of to_bjdata did before this parameter was added; strict throws; replace/ignore sanitize it the same way dump would. If JSON_STRICT_BINARY_UTF8 is enabled, the default is strict instead."},{"location":"api/basic_json/to_bjdata/#return-value","title":"Return value","text":"
    1. BJData serialization as byte vector
    2. (none)
    "},{"location":"api/basic_json/to_bjdata/#exception-safety","title":"Exception safety","text":"

    Strong guarantee: if an exception is thrown, there are no changes in the JSON value.

    "},{"location":"api/basic_json/to_bjdata/#exceptions","title":"Exceptions","text":"
    • Throws other_error.502 if use_type is true and use_size is false, and j contains a non-empty array or object, or a non-empty binary value (with version = bjdata_version_t::draft3, any binary value, including an empty one). Scalars, empty arrays, and empty objects do not throw.
    • Throws type_error.316 if a string or object key in j is not valid UTF-8 and error_handler is strict (the default only if JSON_STRICT_BINARY_UTF8 is enabled)
    • Throws type_error.321 if j or a value nested in it is discarded; example: \"cannot serialize discarded value to BJData\"
    "},{"location":"api/basic_json/to_bjdata/#complexity","title":"Complexity","text":"

    Linear in the size of the JSON value j.

    "},{"location":"api/basic_json/to_bjdata/#examples","title":"Examples","text":"Example: serialize a JSON value to BJData

    The example shows the serialization of a JSON value to a byte vector in BJData format.

    #include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\nusing namespace nlohmann::literals;\n\n// function to print BJData's diagnostic format\nvoid print_byte(uint8_t byte)\n{\n    if (32 < byte and byte < 128)\n    {\n        std::cout << static_cast<char>(byte);\n    }\n    else\n    {\n        std::cout << static_cast<int>(byte);\n    }\n}\n\nint main()\n{\n    // create a JSON value\n    json j = R\"({\"compact\": true, \"schema\": false})\"_json;\n\n    // serialize it to BJData\n    std::vector<std::uint8_t> v = json::to_bjdata(j);\n\n    // print the vector content\n    for (auto& byte : v)\n    {\n        print_byte(byte);\n    }\n    std::cout << '\\n';\n\n    // create an array of numbers\n    json array = {1, 2, 3, 4, 5, 6, 7, 8};\n\n    // serialize it to BJData using default representation\n    std::vector<std::uint8_t> v_array = json::to_bjdata(array);\n    // serialize it to BJData using size optimization\n    std::vector<std::uint8_t> v_array_size = json::to_bjdata(array, true);\n    // serialize it to BJData using type optimization\n    std::vector<std::uint8_t> v_array_size_and_type = json::to_bjdata(array, true, true);\n\n    // print the vector contents\n    for (auto& byte : v_array)\n    {\n        print_byte(byte);\n    }\n    std::cout << '\\n';\n\n    for (auto& byte : v_array_size)\n    {\n        print_byte(byte);\n    }\n    std::cout << '\\n';\n\n    for (auto& byte : v_array_size_and_type)\n    {\n        print_byte(byte);\n    }\n    std::cout << '\\n';\n}\n

    Output:

    {i7compactTi6schemaF}\n[i1i2i3i4i5i6i7i8]\n[#i8i1i2i3i4i5i6i7i8\n[$i#i812345678\n
    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.

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create a non-empty JSON array\n    json j = {1, 2, 3};\n\n    // exception other_error.502\n    try\n    {\n        json::to_bjdata(j, false, true);\n    }\n    catch (const json::other_error& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n}\n

    Output:

    [json.exception.other_error.502] use_type requires use_size = true\n
    "},{"location":"api/basic_json/to_bjdata/#see-also","title":"See also","text":"
    • BJData - the format, its byte layout and how values are mapped
    • Binary formats - overview and comparison of the supported binary formats
    • Binary values - how binary values and subtypes are handled
    • from_bjdata - create a JSON value from an input in BJData format
    • to_cbor - create a CBOR serialization of a JSON value
    • to_msgpack - create a MessagePack serialization of a JSON value
    • to_bson - create a BSON serialization of a JSON value
    • to_ubjson - create a UBJSON serialization of a JSON value
    • to_bon8 - create a BON8 serialization of a JSON value
    "},{"location":"api/basic_json/to_bjdata/#version-history","title":"Version history","text":"
    • Added in version 3.11.0.
    • BJData version parameter (for draft3 binary encoding) added in version 3.12.0.
    • Added error_handler parameter in version 3.13.0 unreleased. Its default, keep, writes the bytes of a string or object key that is not valid UTF-8 unchanged, as before; strict (the default if JSON_STRICT_BINARY_UTF8 is enabled) throws type_error.316.
    • Throws type_error.321 for a discarded value since version 3.13.0 unreleased; previously, a discarded value nested in an array or object was silently skipped, producing invalid BJData.
    "},{"location":"api/basic_json/to_bon8/","title":"nlohmann::basic_json::to_bon8","text":"
    // (1)\nstatic std::vector<std::uint8_t> to_bon8(const basic_json& j);\n\n// (2)\nstatic void to_bon8(const basic_json& j, detail::output_adapter<std::uint8_t> o);\nstatic void to_bon8(const basic_json& j, detail::output_adapter<char> o);\n

    Serializes a given JSON value j to a byte vector using the BON8 (Binary Object Notation 8) serialization format. BON8 is a compact binary serialization format that stores strings as UTF-8 without a length prefix.

    1. Returns a byte vector containing the BON8 serialization.
    2. Writes the BON8 serialization to an output adapter.

    The exact mapping and its limitations are described on a dedicated page.

    "},{"location":"api/basic_json/to_bon8/#parameters","title":"Parameters","text":"j (in) JSON value to serialize o (in) output adapter to write serialization to"},{"location":"api/basic_json/to_bon8/#return-value","title":"Return value","text":"
    1. BON8 serialization as a byte vector
    2. (none)
    "},{"location":"api/basic_json/to_bon8/#exception-safety","title":"Exception safety","text":"

    Strong guarantee: if an exception is thrown, there are no changes in the JSON value j, which is never modified. With (2), the bytes written before the exception remain in the output adapter.

    "},{"location":"api/basic_json/to_bon8/#exceptions","title":"Exceptions","text":"
    • Throws out_of_range.407 if j contains an integer outside the range of int64 (an unsigned integer above 9223372036854775807, or, with a number type wider than 64 bits, any integer beyond int64), which BON8 cannot represent
    • Throws type_error.316 if j contains a string that is not valid UTF-8
    • Throws type_error.321 if j or a value nested in it is discarded; example: \"cannot serialize discarded value to BON8\"
    "},{"location":"api/basic_json/to_bon8/#complexity","title":"Complexity","text":"

    Linear in the size of the JSON value j.

    "},{"location":"api/basic_json/to_bon8/#examples","title":"Examples","text":"Example: serialize a JSON value to BON8

    The example shows the serialization of a JSON value to a byte vector in BON8 format.

    #include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\nusing namespace nlohmann::literals;\n\nint main()\n{\n    // create a JSON value\n    json j = R\"({\"compact\": true, \"format\": \"BON8\", \"schema\": 0})\"_json;\n\n    // serialize it to BON8\n    std::vector<std::uint8_t> v = json::to_bon8(j);\n\n    // print the vector content\n    for (auto& byte : v)\n    {\n        std::cout << \"0x\" << std::hex << std::setw(2) << std::setfill('0') << static_cast<int>(byte) << \" \";\n    }\n    std::cout << '\\n';\n}\n

    Output:

    0x89 0x63 0x6f 0x6d 0x70 0x61 0x63 0x74 0xf9 0x66 0x6f 0x72 0x6d 0x61 0x74 0xff 0x42 0x4f 0x4e 0x38 0xff 0x73 0x63 0x68 0x65 0x6d 0x61 0x90 \n
    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.

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create a JSON string that is not valid UTF-8\n    std::string invalid_utf8;\n    invalid_utf8.push_back(static_cast<char>(0xFF));\n    json j = invalid_utf8;\n\n    // exception type_error.316\n    try\n    {\n        json::to_bon8(j);\n    }\n    catch (const json::type_error& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n}\n

    Output:

    [json.exception.type_error.316] invalid UTF-8 byte at index 0: 0xFF\n
    "},{"location":"api/basic_json/to_bon8/#see-also","title":"See also","text":"
    • BON8 - the format, its byte layout and how values are mapped
    • Binary formats - overview and comparison of the supported binary formats
    • from_bon8 - create a JSON value from an input in BON8 format
    • to_cbor - create a CBOR serialization of a JSON value
    • to_msgpack - create a MessagePack serialization of a JSON value
    • to_bson - create a BSON serialization of a JSON value
    • to_ubjson - create a UBJSON serialization of a JSON value
    • to_bjdata - create a BJData serialization of a JSON value
    "},{"location":"api/basic_json/to_bon8/#version-history","title":"Version history","text":"
    • Added in version 3.13.0 unreleased.
    "},{"location":"api/basic_json/to_bson/","title":"nlohmann::basic_json::to_bson","text":"
    // (1)\nstatic std::vector<std::uint8_t> to_bson(const basic_json& j,\n                                         const error_handler_t error_handler = error_handler_t::keep);\n\n// (2)\nstatic void to_bson(const basic_json& j, detail::output_adapter<std::uint8_t> o,\n                    const error_handler_t error_handler = error_handler_t::keep);\nstatic void to_bson(const basic_json& j, detail::output_adapter<char> o,\n                    const error_handler_t error_handler = error_handler_t::keep);\n

    BSON (Binary JSON) is a binary format in which zero or more ordered key/value pairs are stored as a single entity (a so-called document). The members of an object are written in the order in which iteration visits them.

    1. Returns a byte vector containing the BSON serialization.
    2. Writes the BSON serialization to an output adapter.

    The exact mapping and its limitations are described on a dedicated page.

    "},{"location":"api/basic_json/to_bson/#parameters","title":"Parameters","text":"j (in) JSON value to serialize o (in) output adapter to write serialization to error_handler (in) how to treat a string or object key in j that is not valid UTF-8; see error_handler_t. The default, keep, writes the ill-formed bytes to the output as is, as every version of to_bson did before this parameter was added; strict throws; replace/ignore sanitize it the same way dump would. If JSON_STRICT_BINARY_UTF8 is enabled, the default is strict instead."},{"location":"api/basic_json/to_bson/#return-value","title":"Return value","text":"
    1. BSON serialization as a byte vector
    2. (none)
    "},{"location":"api/basic_json/to_bson/#exception-safety","title":"Exception safety","text":"

    Strong guarantee: if an exception is thrown, there are no changes in the JSON value.

    "},{"location":"api/basic_json/to_bson/#exceptions","title":"Exceptions","text":"
    • Throws type_error.317 if the top-level type of the JSON value is not an object; example: \"to serialize to BSON, top-level type must be object, but is string\"
    • Throws out_of_range.407 if j contains a signed integer outside the range of int64 or an unsigned integer outside the range of uint64, which is only possible with a number type wider than 64 bits; example: \"integer number 9223372036854775808 cannot be represented by BSON as it does not fit int64\"
    • Throws out_of_range.409 if a key in the JSON object contains a null byte (code point U+0000); example: \"BSON key cannot contain code point U+0000 (at byte 2)\"
    • Throws out_of_range.412 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 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)\"
    • Throws type_error.316 if a string or object key is not valid UTF-8 and error_handler is strict (the default only if JSON_STRICT_BINARY_UTF8 is enabled)
    • Throws type_error.321 if a value nested in j is discarded (the top-level value itself is covered by type_error.317 above, since it must be an object); example: \"cannot serialize discarded value to BSON\"
    "},{"location":"api/basic_json/to_bson/#complexity","title":"Complexity","text":"

    Linear in the size of the JSON value j. The length prefixes of all nested documents and arrays are computed in one pass before anything is written.

    "},{"location":"api/basic_json/to_bson/#examples","title":"Examples","text":"Example: serialize a JSON value to BSON

    The example shows the serialization of a JSON value to a byte vector in BSON format.

    #include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\nusing namespace nlohmann::literals;\n\nint main()\n{\n    // create a JSON value\n    json j = R\"({\"compact\": true, \"schema\": 0})\"_json;\n\n    // serialize it to BSON\n    std::vector<std::uint8_t> v = json::to_bson(j);\n\n    // print the vector content\n    for (auto& byte : v)\n    {\n        std::cout << \"0x\" << std::hex << std::setw(2) << std::setfill('0') << static_cast<int>(byte) << \" \";\n    }\n    std::cout << '\\n';\n}\n

    Output:

    0x1b 0x00 0x00 0x00 0x08 0x63 0x6f 0x6d 0x70 0x61 0x63 0x74 0x00 0x01 0x10 0x73 0x63 0x68 0x65 0x6d 0x61 0x00 0x00 0x00 0x00 0x00 0x00 \n
    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.

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create a JSON object whose key contains a null byte (U+0000)\n    std::string key = \"ab\";\n    key.push_back('\\0');\n    key.push_back('c');\n    json j = {{key, 1}};\n\n    // exception out_of_range.409\n    try\n    {\n        json::to_bson(j);\n    }\n    catch (const json::out_of_range& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n}\n

    Output:

    [json.exception.out_of_range.409] BSON key cannot contain code point U+0000 (at byte 2)\n
    "},{"location":"api/basic_json/to_bson/#see-also","title":"See also","text":"
    • BSON - the format, its byte layout and how values are mapped
    • Binary formats - overview and comparison of the supported binary formats
    • Binary values - how binary values and subtypes are handled
    • from_bson - create a JSON value from an input in BSON format
    • to_cbor - create a CBOR serialization of a JSON value
    • to_msgpack - create a MessagePack serialization of a JSON value
    • to_ubjson - create a UBJSON serialization of a JSON value
    • to_bjdata - create a BJData serialization of a JSON value
    • to_bon8 - create a BON8 serialization of a JSON value
    "},{"location":"api/basic_json/to_bson/#version-history","title":"Version history","text":"
    • Added in version 3.4.0.
    • Throws out_of_range.412 and out_of_range.415 since version 3.13.0 unreleased.
    • Linear in the size of j, and no longer limited by the call stack for deeply nested values, since version 3.13.0 unreleased.
    • out_of_range.415 is now detected before anything is written, like the other exceptions above, since version 3.13.0 unreleased.
    • Throws type_error.321 for a discarded value nested in j since version 3.13.0 unreleased; previously, it was silently skipped, producing a document whose declared size did not match what was actually written.
    • Added error_handler parameter in version 3.13.0 unreleased. Its default, keep, writes the bytes of a string or object key that is not valid UTF-8 unchanged, as before; strict (the default if JSON_STRICT_BINARY_UTF8 is enabled) throws type_error.316 before anything is written.
    • Throws out_of_range.407 for integers that do not fit 64 bits since version 3.13.0 unreleased; previously, integers of a number type wider than 64 bits were silently truncated.
    "},{"location":"api/basic_json/to_cbor/","title":"nlohmann::basic_json::to_cbor","text":"
    // (1)\nstatic std::vector<std::uint8_t> to_cbor(const basic_json& j,\n                                          const error_handler_t error_handler = error_handler_t::keep);\n\n// (2)\nstatic void to_cbor(const basic_json& j, detail::output_adapter<std::uint8_t> o,\n                     const error_handler_t error_handler = error_handler_t::keep);\nstatic void to_cbor(const basic_json& j, detail::output_adapter<char> o,\n                     const error_handler_t error_handler = error_handler_t::keep);\n

    Serializes a given JSON value j to a byte vector using the CBOR (Concise Binary Object Representation) serialization format. CBOR is a binary serialization format that aims to be more compact than JSON itself, yet more efficient to parse.

    1. Returns a byte vector containing the CBOR serialization.
    2. Writes the CBOR serialization to an output adapter.

    The exact mapping and its limitations are described on a dedicated page.

    "},{"location":"api/basic_json/to_cbor/#parameters","title":"Parameters","text":"j (in) JSON value to serialize o (in) output adapter to write serialization to error_handler (in) how to treat a string or object key in j that is not valid UTF-8; see error_handler_t. The default, keep, writes the ill-formed bytes to the output as is, as every version of to_cbor did before this parameter was added; strict throws; replace/ignore sanitize it the same way dump would. If JSON_STRICT_BINARY_UTF8 is enabled, the default is strict instead."},{"location":"api/basic_json/to_cbor/#return-value","title":"Return value","text":"
    1. CBOR serialization as a byte vector
    2. (none)
    "},{"location":"api/basic_json/to_cbor/#exception-safety","title":"Exception safety","text":"

    Strong guarantee: if an exception is thrown, there are no changes in the JSON value. Bytes that were already written to the output adapter are not taken back.

    "},{"location":"api/basic_json/to_cbor/#exceptions","title":"Exceptions","text":"
    • Throws out_of_range.407 if j contains an integer outside [-2^64, 2^64-1], which is only possible with a number type wider than 64 bits; example: \"integer number 18446744073709551616 cannot be represented by CBOR as it does not fit [-2^64, 2^64-1]\"
    • Throws type_error.316 if a string or object key in j is not valid UTF-8 and error_handler is strict (the default only if JSON_STRICT_BINARY_UTF8 is enabled)
    • Throws type_error.321 if j or a value nested in it is discarded; example: \"cannot serialize discarded value to CBOR\"
    "},{"location":"api/basic_json/to_cbor/#complexity","title":"Complexity","text":"

    Linear in the size of the JSON value j.

    "},{"location":"api/basic_json/to_cbor/#examples","title":"Examples","text":"Example

    The example shows the serialization of a JSON value to a byte vector in CBOR format.

    #include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\nusing namespace nlohmann::literals;\n\nint main()\n{\n    // create a JSON value\n    json j = R\"({\"compact\": true, \"schema\": 0})\"_json;\n\n    // serialize it to CBOR\n    std::vector<std::uint8_t> v = json::to_cbor(j);\n\n    // print the vector content\n    for (auto& byte : v)\n    {\n        std::cout << \"0x\" << std::hex << std::setw(2) << std::setfill('0') << static_cast<int>(byte) << \" \";\n    }\n    std::cout << '\\n';\n}\n

    Output:

    0xa2 0x67 0x63 0x6f 0x6d 0x70 0x61 0x63 0x74 0xf5 0x66 0x73 0x63 0x68 0x65 0x6d 0x61 0x00 \n
    "},{"location":"api/basic_json/to_cbor/#see-also","title":"See also","text":"
    • CBOR - the format, its byte layout and how values are mapped
    • Binary formats - overview and comparison of the supported binary formats
    • Binary values - how binary values and subtypes are handled
    • from_cbor - create a JSON value from an input in CBOR format
    • to_msgpack - create a MessagePack serialization of a JSON value
    • to_bson - create a BSON serialization of a JSON value
    • to_ubjson - create a UBJSON serialization of a JSON value
    • to_bjdata - create a BJData serialization of a JSON value
    • to_bon8 - create a BON8 serialization of a JSON value
    "},{"location":"api/basic_json/to_cbor/#version-history","title":"Version history","text":"
    • Added in version 2.0.9.
    • Compact representation of floating-point numbers added in version 3.8.0.
    • Added error_handler parameter in version 3.13.0 unreleased. Its default, keep, writes the bytes of a string or object key that is not valid UTF-8 unchanged, as before; strict (the default if JSON_STRICT_BINARY_UTF8 is enabled) throws type_error.316.
    • Throws type_error.321 for a discarded value since version 3.13.0 unreleased; previously, a discarded value nested in an array or object was silently skipped, producing invalid CBOR.
    • Throws out_of_range.407 for integers that do not fit 64 bits since version 3.13.0 unreleased; previously, integers of a number type wider than 64 bits were silently truncated.
    "},{"location":"api/basic_json/to_msgpack/","title":"nlohmann::basic_json::to_msgpack","text":"
    // (1)\nstatic std::vector<std::uint8_t> to_msgpack(const basic_json& j,\n                                            const error_handler_t error_handler = error_handler_t::keep);\n\n// (2)\nstatic void to_msgpack(const basic_json& j, detail::output_adapter<std::uint8_t> o,\n                       const error_handler_t error_handler = error_handler_t::keep);\nstatic void to_msgpack(const basic_json& j, detail::output_adapter<char> o,\n                       const error_handler_t error_handler = error_handler_t::keep);\n

    Serializes a given JSON value j to a byte vector using the MessagePack serialization format. MessagePack is a binary serialization format that aims to be more compact than JSON itself, yet more efficient to parse.

    1. Returns a byte vector containing the MessagePack serialization.
    2. Writes the MessagePack serialization to an output adapter.

    The exact mapping and its limitations are described on a dedicated page.

    "},{"location":"api/basic_json/to_msgpack/#parameters","title":"Parameters","text":"j (in) JSON value to serialize o (in) output adapter to write serialization to error_handler (in) how to treat a string or object key in j that is not valid UTF-8; see error_handler_t. The default, keep, writes the ill-formed bytes to the output as is, as every version of to_msgpack did before this parameter was added and as the MessagePack specification allows; strict throws; replace/ignore sanitize it the same way dump would. Unlike the other binary writers, the default stays keep even if JSON_STRICT_BINARY_UTF8 is enabled."},{"location":"api/basic_json/to_msgpack/#return-value","title":"Return value","text":"
    1. MessagePack serialization as a byte vector
    2. (none)
    "},{"location":"api/basic_json/to_msgpack/#exception-safety","title":"Exception safety","text":"

    Strong guarantee: if an exception is thrown, there are no changes in the JSON value.

    "},{"location":"api/basic_json/to_msgpack/#exceptions","title":"Exceptions","text":"
    • Throws out_of_range.407 if j contains an integer outside [-2^63, 2^64-1], which is only possible with a number type wider than 64 bits; example: \"integer number 18446744073709551616 cannot be represented by MessagePack as it does not fit [-2^63, 2^64-1]\"
    • Throws out_of_range.412 if the length of a string, binary value, array, or object exceeds 4294967295, the maximum MessagePack can store; example: \"MessagePack length 4294967296 exceeds maximum of 4294967295\"
    • Throws out_of_range.415 if the subtype of a binary value exceeds 255, the largest value the library can store in the one-byte MessagePack ext type; example: \"subtype 70000 is too large for the MessagePack ext type (max 255)\"
    • Throws type_error.316 if a string or object key in j is not valid UTF-8 and error_handler is strict
    • Throws type_error.321 if j or a value nested in it is discarded; example: \"cannot serialize discarded value to MessagePack\"
    "},{"location":"api/basic_json/to_msgpack/#complexity","title":"Complexity","text":"

    Linear in the size of the JSON value j.

    "},{"location":"api/basic_json/to_msgpack/#examples","title":"Examples","text":"Example: serialize a JSON value to MessagePack

    The example shows the serialization of a JSON value to a byte vector in MessagePack format.

    #include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\nusing namespace nlohmann::literals;\n\nint main()\n{\n    // create a JSON value\n    json j = R\"({\"compact\": true, \"schema\": 0})\"_json;\n\n    // serialize it to MessagePack\n    std::vector<std::uint8_t> v = json::to_msgpack(j);\n\n    // print the vector content\n    for (auto& byte : v)\n    {\n        std::cout << \"0x\" << std::hex << std::setw(2) << std::setfill('0') << static_cast<int>(byte) << \" \";\n    }\n    std::cout << '\\n';\n}\n

    Output:

    0x82 0xa7 0x63 0x6f 0x6d 0x70 0x61 0x63 0x74 0xc3 0xa6 0x73 0x63 0x68 0x65 0x6d 0x61 0x00 \n
    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.

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create a JSON value with a binary subtype that exceeds 255\n    json j = json::binary({1, 2, 3}, 300);\n\n    // exception out_of_range.415\n    try\n    {\n        json::to_msgpack(j);\n    }\n    catch (const json::out_of_range& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n}\n

    Output:

    [json.exception.out_of_range.415] subtype 300 is too large for the MessagePack ext type (max 255)\n
    "},{"location":"api/basic_json/to_msgpack/#see-also","title":"See also","text":"
    • MessagePack - the format, its byte layout and how values are mapped
    • Binary formats - overview and comparison of the supported binary formats
    • Binary values - how binary values and subtypes are handled
    • from_msgpack - create a JSON value from an input in MessagePack format
    • to_cbor - create a CBOR serialization of a JSON value
    • to_bson - create a BSON serialization of a JSON value
    • to_ubjson - create a UBJSON serialization of a JSON value
    • to_bjdata - create a BJData serialization of a JSON value
    • to_bon8 - create a BON8 serialization of a JSON value
    "},{"location":"api/basic_json/to_msgpack/#version-history","title":"Version history","text":"
    • Added in version 2.0.9.
    • Throws out_of_range.412 and out_of_range.415 since version 3.13.0 unreleased.
    • Added error_handler parameter in version 3.13.0 unreleased. Its default, keep, writes the bytes of a string or object key that is not valid UTF-8 unchanged, as before.
    • Fixed in version 3.13.0 unreleased to serialize number_integer_t/number_unsigned_t pairs of different width correctly; before, integers could be serialized with the wrong value if number_integer_t was narrower than number_unsigned_t.
    • Throws type_error.321 for a discarded value since version 3.13.0 unreleased; previously, a discarded value nested in an array or object was silently skipped, producing invalid MessagePack.
    • Throws out_of_range.407 for integers that do not fit 64 bits since version 3.13.0 unreleased; previously, integers of a number type wider than 64 bits were silently truncated.
    "},{"location":"api/basic_json/to_string/","title":"to_string(basic_json)","text":"
    template <typename BasicJsonType>\nstd::string to_string(const BasicJsonType& j);\n

    This function implements a user-defined to_string for JSON objects.

    "},{"location":"api/basic_json/to_string/#template-parameters","title":"Template parameters","text":"BasicJsonType a specialization of basic_json whose string_t is convertible to std::string; for other string types, use dump, which returns a string_t"},{"location":"api/basic_json/to_string/#return-value","title":"Return value","text":"

    string containing the serialization of the JSON value

    "},{"location":"api/basic_json/to_string/#exception-safety","title":"Exception safety","text":"

    Strong guarantee: if an exception is thrown, there are no changes to any JSON value.

    "},{"location":"api/basic_json/to_string/#exceptions","title":"Exceptions","text":"

    Throws type_error.316 if a string stored inside the JSON value is not UTF-8 encoded

    "},{"location":"api/basic_json/to_string/#complexity","title":"Complexity","text":"

    Linear.

    "},{"location":"api/basic_json/to_string/#possible-implementation","title":"Possible implementation","text":"
    template <typename BasicJsonType>\nstd::string to_string(const BasicJsonType& j)\n{\n    return j.dump();\n}\n
    "},{"location":"api/basic_json/to_string/#examples","title":"Examples","text":"Example

    The following code shows how the library's to_string() function integrates with others, allowing argument-dependent lookup.

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\nusing std::to_string;\n\nint main()\n{\n    // create values\n    json j = {{\"one\", 1}, {\"two\", 2}};\n    int i = 42;\n\n    // use ADL to select best to_string function\n    auto j_str = to_string(j);  // calling nlohmann::to_string\n    auto i_str = to_string(i);  // calling std::to_string\n\n    // serialize without indentation\n    std::cout << j_str << \"\\n\\n\"\n              << i_str << '\\n';\n}\n

    Output:

    {\"one\":1,\"two\":2}\n\n42\n
    "},{"location":"api/basic_json/to_string/#see-also","title":"See also","text":"
    • dump - serialize a JSON value to a string
    • Serialization - the serialization article
    "},{"location":"api/basic_json/to_string/#version-history","title":"Version history","text":"

    Added in version 3.7.0.

    "},{"location":"api/basic_json/to_ubjson/","title":"nlohmann::basic_json::to_ubjson","text":"
    // (1)\nstatic std::vector<std::uint8_t> to_ubjson(const basic_json& j,\n                                           const bool use_size = false,\n                                           const bool use_type = false,\n                                           const error_handler_t error_handler = error_handler_t::keep);\n\n// (2)\nstatic void to_ubjson(const basic_json& j, detail::output_adapter<std::uint8_t> o,\n                      const bool use_size = false, const bool use_type = false,\n                      const error_handler_t error_handler = error_handler_t::keep);\nstatic void to_ubjson(const basic_json& j, detail::output_adapter<char> o,\n                      const bool use_size = false, const bool use_type = false,\n                      const error_handler_t error_handler = error_handler_t::keep);\n

    Serializes a given JSON value j to a byte vector using the UBJSON (Universal Binary JSON) serialization format. UBJSON aims to be more compact than JSON itself, yet more efficient to parse.

    1. Returns a byte vector containing the UBJSON serialization.
    2. Writes the UBJSON serialization to an output adapter.

    The exact mapping and its limitations are described on a dedicated page.

    "},{"location":"api/basic_json/to_ubjson/#parameters","title":"Parameters","text":"j (in) JSON value to serialize o (in) output adapter to write serialization to use_size (in) whether to add size annotations to container types; optional, false by default. use_type (in) whether to add type annotations to container types (must be combined with use_size = true); optional, false by default. error_handler (in) how to treat a string or object key in j that is not valid UTF-8; see error_handler_t. The default, keep, writes the ill-formed bytes to the output as is, as every version of to_ubjson did before this parameter was added; strict throws; replace/ignore sanitize it the same way dump would. If JSON_STRICT_BINARY_UTF8 is enabled, the default is strict instead."},{"location":"api/basic_json/to_ubjson/#return-value","title":"Return value","text":"
    1. UBJSON serialization as a byte vector
    2. (none)
    "},{"location":"api/basic_json/to_ubjson/#exception-safety","title":"Exception safety","text":"

    Strong guarantee: if an exception is thrown, there are no changes in the JSON value.

    "},{"location":"api/basic_json/to_ubjson/#exceptions","title":"Exceptions","text":"
    • Throws other_error.502 if use_type is true and use_size is false, and j contains a non-empty array, object, or binary value.
    • Throws type_error.316 if a string or object key in j is not valid UTF-8 and error_handler is strict (the default only if JSON_STRICT_BINARY_UTF8 is enabled)
    • Throws type_error.321 if j or a value nested in it is discarded; example: \"cannot serialize discarded value to UBJSON\"
    "},{"location":"api/basic_json/to_ubjson/#complexity","title":"Complexity","text":"

    Linear in the size of the JSON value j.

    "},{"location":"api/basic_json/to_ubjson/#examples","title":"Examples","text":"Example: serialize a JSON value to UBJSON

    The example shows the serialization of a JSON value to a byte vector in UBJSON format.

    #include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\nusing namespace nlohmann::literals;\n\n// function to print UBJSON's diagnostic format\nvoid print_byte(uint8_t byte)\n{\n    if (32 < byte and byte < 128)\n    {\n        std::cout << static_cast<char>(byte);\n    }\n    else\n    {\n        std::cout << static_cast<int>(byte);\n    }\n}\n\nint main()\n{\n    // create a JSON value\n    json j = R\"({\"compact\": true, \"schema\": false})\"_json;\n\n    // serialize it to UBJSON\n    std::vector<std::uint8_t> v = json::to_ubjson(j);\n\n    // print the vector content\n    for (auto& byte : v)\n    {\n        print_byte(byte);\n    }\n    std::cout << '\\n';\n\n    // create an array of numbers\n    json array = {1, 2, 3, 4, 5, 6, 7, 8};\n\n    // serialize it to UBJSON using default representation\n    std::vector<std::uint8_t> v_array = json::to_ubjson(array);\n    // serialize it to UBJSON using size optimization\n    std::vector<std::uint8_t> v_array_size = json::to_ubjson(array, true);\n    // serialize it to UBJSON using type optimization\n    std::vector<std::uint8_t> v_array_size_and_type = json::to_ubjson(array, true, true);\n\n    // print the vector contents\n    for (auto& byte : v_array)\n    {\n        print_byte(byte);\n    }\n    std::cout << '\\n';\n\n    for (auto& byte : v_array_size)\n    {\n        print_byte(byte);\n    }\n    std::cout << '\\n';\n\n    for (auto& byte : v_array_size_and_type)\n    {\n        print_byte(byte);\n    }\n    std::cout << '\\n';\n}\n

    Output:

    {i7compactTi6schemaF}\n[i1i2i3i4i5i6i7i8]\n[#i8i1i2i3i4i5i6i7i8\n[$i#i812345678\n
    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.

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create a non-empty JSON array\n    json j = {1, 2, 3};\n\n    // exception other_error.502\n    try\n    {\n        json::to_ubjson(j, false, true);\n    }\n    catch (const json::other_error& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n}\n

    Output:

    [json.exception.other_error.502] use_type requires use_size = true\n
    "},{"location":"api/basic_json/to_ubjson/#see-also","title":"See also","text":"
    • UBJSON - the format, its byte layout and how values are mapped
    • Binary formats - overview and comparison of the supported binary formats
    • Binary values - how binary values and subtypes are handled
    • from_ubjson - create a JSON value from an input in UBJSON format
    • to_cbor - create a CBOR serialization of a JSON value
    • to_msgpack - create a MessagePack serialization of a JSON value
    • to_bson - create a BSON serialization of a JSON value
    • to_bjdata - create a BJData serialization of a JSON value
    • to_bon8 - create a BON8 serialization of a JSON value
    "},{"location":"api/basic_json/to_ubjson/#version-history","title":"Version history","text":"
    • Added in version 3.1.0.
    • Added error_handler parameter in version 3.13.0 unreleased. Its default, keep, writes the bytes of a string or object key that is not valid UTF-8 unchanged, as before; strict (the default if JSON_STRICT_BINARY_UTF8 is enabled) throws type_error.316.
    • Throws type_error.321 for a discarded value since version 3.13.0 unreleased; previously, a discarded value nested in an array or object was silently skipped, producing invalid UBJSON.
    "},{"location":"api/basic_json/type/","title":"nlohmann::basic_json::type","text":"
    constexpr value_t type() const noexcept;\n

    Return the type of the JSON value as a value from the value_t enumeration.

    "},{"location":"api/basic_json/type/#return-value","title":"Return value","text":"

    the type of the JSON value

    Value type return value null value_t::null boolean value_t::boolean string value_t::string number (integer) value_t::number_integer number (unsigned integer) value_t::number_unsigned number (floating-point) value_t::number_float object value_t::object array value_t::array binary value_t::binary discarded value_t::discarded"},{"location":"api/basic_json/type/#exception-safety","title":"Exception safety","text":"

    No-throw guarantee: this member function never throws exceptions.

    "},{"location":"api/basic_json/type/#complexity","title":"Complexity","text":"

    Constant.

    "},{"location":"api/basic_json/type/#examples","title":"Examples","text":"Example

    The following code exemplifies type() for all JSON types.

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create JSON values\n    json j_null;\n    json j_boolean = true;\n    json j_number_integer = -17;\n    json j_number_unsigned = 42u;\n    json j_number_float = 23.42;\n    json j_object = {{\"one\", 1}, {\"two\", 2}};\n    json j_array = {1, 2, 4, 8, 16};\n    json j_string = \"Hello, world\";\n\n    // call type()\n    std::cout << std::boolalpha;\n    std::cout << (j_null.type() == json::value_t::null) << '\\n';\n    std::cout << (j_boolean.type() == json::value_t::boolean) << '\\n';\n    std::cout << (j_number_integer.type() == json::value_t::number_integer) << '\\n';\n    std::cout << (j_number_unsigned.type() == json::value_t::number_unsigned) << '\\n';\n    std::cout << (j_number_float.type() == json::value_t::number_float) << '\\n';\n    std::cout << (j_object.type() == json::value_t::object) << '\\n';\n    std::cout << (j_array.type() == json::value_t::array) << '\\n';\n    std::cout << (j_string.type() == json::value_t::string) << '\\n';\n}\n

    Output:

    true\ntrue\ntrue\ntrue\ntrue\ntrue\ntrue\ntrue\n
    "},{"location":"api/basic_json/type/#see-also","title":"See also","text":"
    • operator value_t - implicit conversion operator equivalent to this named member function
    • type_name - returns the type as a string, for use in error messages
    • value_t - the enumeration of JSON types
    • basic_json_view::type - the same function on a zero-copy view
    • Types - the JSON value types and how they are stored
    "},{"location":"api/basic_json/type/#version-history","title":"Version history","text":"
    • Added in version 1.0.0.
    • Added unsigned integer type in version 2.0.0.
    • Added binary type in version 3.8.0.
    "},{"location":"api/basic_json/type_error/","title":"nlohmann::basic_json::type_error","text":"
    class type_error : public exception;\n

    This exception is thrown in case of a type error; that is, a library function is executed on a JSON value whose type does not match the expected semantics.

    Exceptions have ids 3xx (see list of type errors).

    classDiagram\n  direction LR\n\n    class std_exception [\"std::exception\"] {\n        <<interface>>\n    }\n\n    class json_exception [\"basic_json::exception\"] {\n        +const int id\n        +const char* what() const\n    }\n\n    class json_parse_error [\"basic_json::parse_error\"] {\n        +const std::size_t byte\n    }\n\n    class json_invalid_iterator [\"basic_json::invalid_iterator\"]\n    class json_type_error [\"basic_json::type_error\"]\n    class json_out_of_range [\"basic_json::out_of_range\"]\n    class json_other_error [\"basic_json::other_error\"]\n\n    std_exception <|-- json_exception\n    json_exception <|-- json_parse_error\n    json_exception <|-- json_invalid_iterator\n    json_exception <|-- json_type_error\n    json_exception <|-- json_out_of_range\n    json_exception <|-- json_other_error\n\n    style json_type_error fill:#CCCCFF

    Class hierarchy of the library's exceptions; arrows point from a derived class to its base class, and the highlighted box is basic_json::type_error.

    "},{"location":"api/basic_json/type_error/#member-functions","title":"Member functions","text":"
    • what - returns explanatory string
    "},{"location":"api/basic_json/type_error/#member-variables","title":"Member variables","text":"
    • id - the id of the exception
    "},{"location":"api/basic_json/type_error/#examples","title":"Examples","text":"Example

    The following code shows how a type_error exception can be caught.

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    try\n    {\n        // calling push_back() on a string value\n        json j = \"string\";\n        j.push_back(\"another string\");\n    }\n    catch (const json::type_error& e)\n    {\n        // output exception information\n        std::cout << \"message: \" << e.what() << '\\n'\n                  << \"exception id: \" << e.id << '\\n';\n    }\n}\n

    Output:

    message: [json.exception.type_error.308] cannot use push_back() with string\nexception id: 308\n
    "},{"location":"api/basic_json/type_error/#see-also","title":"See also","text":"
    • exception - the base class of all exceptions thrown by the library
    • List of type errors - overview of type errors (type_error)
    • parse_error - exceptions indicating a parse error
    • invalid_iterator - exceptions indicating errors with iterators
    • out_of_range - exceptions indicating access out of the defined range
    • other_error - exceptions indicating other library errors
    • Exceptions - all exceptions and their error codes
    • JSON_DIAGNOSTICS - extended exception messages with the path of the failing value
    "},{"location":"api/basic_json/type_error/#version-history","title":"Version history","text":"
    • Added in version 3.0.0.
    "},{"location":"api/basic_json/type_name/","title":"nlohmann::basic_json::type_name","text":"
    const char* type_name() const noexcept;\n

    Returns the type name as string to be used in error messages \u2014 usually to indicate that a function was called on a wrong JSON type.

    "},{"location":"api/basic_json/type_name/#return-value","title":"Return value","text":"

    a string representation of the type (value_t):

    Value type return value null \"null\" boolean \"boolean\" string \"string\" number (integer, unsigned integer, floating-point) \"number\" object \"object\" array \"array\" binary \"binary\" discarded \"discarded\" invalid (corrupted value) \"invalid\"

    The \\\"invalid\\\" type

    The \"invalid\" return value indicates a corrupted JSON value \u2014 this can occur if an enum value falls outside the range of valid value_t values. This is useful for diagnosing data corruption or internal errors.

    "},{"location":"api/basic_json/type_name/#exception-safety","title":"Exception safety","text":"

    No-throw guarantee: this member function never throws exceptions.

    "},{"location":"api/basic_json/type_name/#complexity","title":"Complexity","text":"

    Constant.

    "},{"location":"api/basic_json/type_name/#examples","title":"Examples","text":"Example

    The following code exemplifies type_name() for all JSON types.

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create JSON values\n    json j_null;\n    json j_boolean = true;\n    json j_number_integer = -17;\n    json j_number_unsigned = 42u;\n    json j_number_float = 23.42;\n    json j_object = {{\"one\", 1}, {\"two\", 2}};\n    json j_array = {1, 2, 4, 8, 16};\n    json j_string = \"Hello, world\";\n\n    // call type_name()\n    std::cout << j_null << \" is a \" << j_null.type_name() << '\\n';\n    std::cout << j_boolean << \" is a \" << j_boolean.type_name() << '\\n';\n    std::cout << j_number_integer << \" is a \" << j_number_integer.type_name() << '\\n';\n    std::cout << j_number_unsigned << \" is a \" << j_number_unsigned.type_name() << '\\n';\n    std::cout << j_number_float << \" is a \" << j_number_float.type_name() << '\\n';\n    std::cout << j_object << \" is an \" << j_object.type_name() << '\\n';\n    std::cout << j_array << \" is an \" << j_array.type_name() << '\\n';\n    std::cout << j_string << \" is a \" << j_string.type_name() << '\\n';\n}\n

    Output:

    null is a null\ntrue is a boolean\n-17 is a number\n42 is a number\n23.42 is a number\n{\"one\":1,\"two\":2} is an object\n[1,2,4,8,16] is an array\n\"Hello, world\" is a string\n
    "},{"location":"api/basic_json/type_name/#see-also","title":"See also","text":"
    • type - returns the type of the JSON value
    • value_t - the enumeration of JSON types
    • basic_json_view::type_name - the same function on a zero-copy view
    • Types - the JSON value types and how they are stored
    "},{"location":"api/basic_json/type_name/#version-history","title":"Version history","text":"
    • Added in version 1.0.0.
    • Part of the public API version since 2.1.0.
    • Changed return value to const char* and added noexcept in version 3.0.0.
    • Added support for binary type in version 3.8.0.
    • Added \"invalid\" return value for corrupted JSON values in version 3.13.0 unreleased.
    "},{"location":"api/basic_json/unflatten/","title":"nlohmann::basic_json::unflatten","text":"
    basic_json unflatten() const;\n

    The function restores the arbitrary nesting of a JSON value that has been flattened before using the flatten() function. The JSON value must meet certain constraints:

    1. The value must be an object.
    2. The keys must be JSON pointers (see RFC 6901)
    3. The mapped values must be primitive JSON types.
    "},{"location":"api/basic_json/unflatten/#return-value","title":"Return value","text":"

    the original JSON from a flattened version

    "},{"location":"api/basic_json/unflatten/#exception-safety","title":"Exception safety","text":"

    Strong exception safety: if an exception occurs, the original value stays intact.

    "},{"location":"api/basic_json/unflatten/#exceptions","title":"Exceptions","text":"

    The function can throw the following exceptions:

    • Throws type_error.314 if value is not an object
    • Throws type_error.315 if object values are not primitive
    • Throws type_error.313 if a key (JSON pointer) leads to a conflicting nesting; example: \"invalid value to unflatten\"
    • Throws parse_error.106 if an array index in a key begins with '0'; example: \"array index '01' must not begin with '0'\"
    • Throws parse_error.107 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 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 if an array index in a key is not a number; example: \"array index 'one' is not a number\"
    • Throws out_of_range.404 if a level becomes an array (because one of its keys is 0) and another key at that level is empty (as in /a/), is -, or begins with a digit but is not a valid array index (such as 1a); examples: \"unresolved reference token '-'\", \"unresolved reference token ''\"
    "},{"location":"api/basic_json/unflatten/#complexity","title":"Complexity","text":"

    Linear in the size of the JSON value.

    "},{"location":"api/basic_json/unflatten/#notes","title":"Notes","text":"

    Empty objects and arrays are flattened by flatten() to null values and cannot be unflattened to their original type.

    A flattened array and a flattened object whose keys are array indices are indistinguishable, because both are described by the same JSON pointers. A value is therefore restored as an array if and only if one of its keys is the reference token 0, and as an object otherwise: {\"2\": 1} is restored unchanged, whereas {\"0\": 1} is restored as [1]. This decision does not depend on the order in which the flattened object is iterated.

    A third case is an object that has the key 0 next to a key that is not a valid array index: {\"0\": 1, \"b\": 2} is flattened to {\"/0\": 1, \"/b\": 2}, and unflatten treats the level as an array and throws parse_error.109 because b is not a number. (For the keys -, 1a, or the empty key instead of b, it throws out_of_range.404.)

    Apart from these three cases, for a JSON value j, the following is always true: j == j.flatten().unflatten().

    "},{"location":"api/basic_json/unflatten/#examples","title":"Examples","text":"Example

    The following code shows how a flattened JSON object is unflattened into the original nested JSON object.

    #include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create JSON value\n    json j_flattened =\n    {\n        {\"/answer/everything\", 42},\n        {\"/happy\", true},\n        {\"/list/0\", 1},\n        {\"/list/1\", 0},\n        {\"/list/2\", 2},\n        {\"/name\", \"Niels\"},\n        {\"/nothing\", nullptr},\n        {\"/object/currency\", \"USD\"},\n        {\"/object/value\", 42.99},\n        {\"/pi\", 3.141}\n    };\n\n    // call unflatten()\n    std::cout << std::setw(4) << j_flattened.unflatten() << '\\n';\n}\n

    Output:

    {\n    \"answer\": {\n        \"everything\": 42\n    },\n    \"happy\": true,\n    \"list\": [\n        1,\n        0,\n        2\n    ],\n    \"name\": \"Niels\",\n    \"nothing\": null,\n    \"object\": {\n        \"currency\": \"USD\",\n        \"value\": 42.99\n    },\n    \"pi\": 3.141\n}\n
    "},{"location":"api/basic_json/unflatten/#see-also","title":"See also","text":"
    • flatten - the reverse function
    • JSON Pointer - the article on JSON Pointer and flattening
    "},{"location":"api/basic_json/unflatten/#version-history","title":"Version history","text":"
    • Added in version 2.0.0.
    • Made the array/object decision independent of the object's iteration order in version 3.13.0 unreleased.
    • Throws parse_error.109 instead of out_of_range.404 for a one-character array index that is not a digit (e.g., /x) in version 3.13.0 unreleased, as it already did for longer ones.
    "},{"location":"api/basic_json/update/","title":"nlohmann::basic_json::update","text":"
    // (1)\nvoid update(const_reference j, bool merge_objects = false);\n\n// (2)\nvoid update(const_iterator first, const_iterator last, bool merge_objects = false);\n
    1. Inserts all values from JSON object j.
    2. Inserts all values from range [first, last)

    When merge_objects is false (default), existing keys are overwritten. When merge_objects is true, recursively merges objects with common keys.

    If the JSON value is null, it is implicitly converted to an empty object before the values are inserted.

    The function is motivated by Python's dict.update function.

    "},{"location":"api/basic_json/update/#iterator-invalidation","title":"Iterator invalidation","text":"

    For ordered_json, adding a value to an object can yield a reallocation, in which case all iterators (including the end() iterator) and all references to the elements are invalidated.

    "},{"location":"api/basic_json/update/#parameters","title":"Parameters","text":"j (in) JSON object to read values from merge_objects (in) when true, keys that exist in both objects and whose value in the source is itself an object are merged recursively; all other values are overwritten as usual (default: false) first (in) the beginning of the range of elements to insert last (in) the end of the range of elements to insert"},{"location":"api/basic_json/update/#exception-safety","title":"Exception safety","text":"

    Basic guarantee: if an exception is thrown during the operation, the JSON value may be partially modified.

    "},{"location":"api/basic_json/update/#exceptions","title":"Exceptions","text":"
    1. The function can throw the following exceptions:
      • Throws type_error.312 if called on JSON values other than objects; example: \"cannot use update() with string\"
    2. The function can throw the following exceptions:
      • Throws type_error.312 if called on JSON values other than objects; example: \"cannot use update() with string\"
      • Throws invalid_iterator.210 if first and last do not belong to the same JSON value; example: \"iterators do not fit\"
    "},{"location":"api/basic_json/update/#complexity","title":"Complexity","text":"
    1. O(N*log(size() + N)), where N is the number of elements to insert.
    2. O(N*log(size() + N)), where N is the number of elements to insert.
    "},{"location":"api/basic_json/update/#notes","title":"Notes","text":"

    The argument j (or, for overload (2), the range [first, last)) may be *this itself or refer to a value contained in *this (for example, a subobject returned by (*this)[key]); it is read as it was when update() was called, before any modification of *this.

    "},{"location":"api/basic_json/update/#examples","title":"Examples","text":"Example: (1) update with another object

    The example shows how update() is used.

    #include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\nusing namespace nlohmann::literals;\n\nint main()\n{\n    // create two JSON objects\n    json o1 = R\"( {\"color\": \"red\", \"price\": 17.99, \"names\": {\"de\": \"Flugzeug\"}} )\"_json;\n    json o2 = R\"( {\"color\": \"blue\", \"speed\": 100, \"names\": {\"en\": \"plane\"}} )\"_json;\n    json o3 = o1;\n\n    // add all keys from o2 to o1 (updating \"color\", replacing \"names\")\n    o1.update(o2);\n\n    // add all keys from o2 to o1 (updating \"color\", merging \"names\")\n    o3.update(o2, true);\n\n    // output updated object o1 and o3\n    std::cout << std::setw(2) << o1 << '\\n';\n    std::cout << std::setw(2) << o3 << '\\n';\n}\n

    Output:

    {\n  \"color\": \"blue\",\n  \"names\": {\n    \"en\": \"plane\"\n  },\n  \"price\": 17.99,\n  \"speed\": 100\n}\n{\n  \"color\": \"blue\",\n  \"names\": {\n    \"de\": \"Flugzeug\",\n    \"en\": \"plane\"\n  },\n  \"price\": 17.99,\n  \"speed\": 100\n}\n
    Example: (2) update with an iterator range

    The example shows how update() is used.

    #include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\nusing namespace nlohmann::literals;\n\nint main()\n{\n    // create two JSON objects\n    json o1 = R\"( {\"color\": \"red\", \"price\": 17.99, \"names\": {\"de\": \"Flugzeug\"}} )\"_json;\n    json o2 = R\"( {\"color\": \"blue\", \"speed\": 100, \"names\": {\"en\": \"plane\"}} )\"_json;\n    json o3 = o1;\n\n    // add all keys from o2 to o1 (updating \"color\", replacing \"names\")\n    o1.update(o2.begin(), o2.end());\n\n    // add all keys from o2 to o1 (updating \"color\", merging \"names\")\n    o3.update(o2.begin(), o2.end(), true);\n\n    // output updated object o1 and o3\n    std::cout << std::setw(2) << o1 << '\\n';\n    std::cout << std::setw(2) << o3 << '\\n';\n}\n

    Output:

    {\n  \"color\": \"blue\",\n  \"names\": {\n    \"en\": \"plane\"\n  },\n  \"price\": 17.99,\n  \"speed\": 100\n}\n{\n  \"color\": \"blue\",\n  \"names\": {\n    \"de\": \"Flugzeug\",\n    \"en\": \"plane\"\n  },\n  \"price\": 17.99,\n  \"speed\": 100\n}\n
    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:

    {\n    \"color\": \"red\",\n    \"active\": true,\n    \"name\": {\"de\": \"Maus\", \"en\": \"mouse\"}\n}\n

    The user may override the default settings selectively:

    {\n    \"color\": \"blue\",\n    \"name\": {\"es\": \"rat\u00f3n\"},\n}\n

    Then update manages the merging of default settings and user settings:

    auto user_settings = json::parse(\"config.json\");\nauto effective_settings = get_default_settings();\neffective_settings.update(user_settings);\n

    Now effective_settings contains the default settings, but those keys set by the user are overwritten:

    {\n    \"color\": \"blue\",\n    \"active\": true,\n    \"name\": {\"es\": \"rat\u00f3n\"}\n}\n

    Note existing keys were just overwritten. To merge objects, merge_objects setting should be set to true:

    auto user_settings = json::parse(\"config.json\");\nauto effective_settings = get_default_settings();\neffective_settings.update(user_settings, true);\n
    {\n    \"color\": \"blue\",\n    \"active\": true,\n    \"name\": {\"de\": \"Maus\", \"en\": \"mouse\", \"es\": \"rat\u00f3n\"}\n}\n
    "},{"location":"api/basic_json/update/#see-also","title":"See also","text":"
    • insert - add values to an array/object
    • merge_patch - applies a JSON Merge Patch
    • Modifying values - the article on modifying values
    "},{"location":"api/basic_json/update/#version-history","title":"Version history","text":"
    • Added in version 3.0.0.
    • Added merge_objects parameter in 3.10.5.
    • Fixed use of freed or relocated memory when the argument is *this or refers to a value contained in *this, in version 3.13.0 unreleased.
    "},{"location":"api/basic_json/value/","title":"nlohmann::basic_json::value","text":"
    // (1)\ntemplate<class ValueType>\nValueType value(const typename object_t::key_type& key,\n                ValueType&& default_value) const;\n\n// (2)\ntemplate<class ValueType, class KeyType>\nValueType value(KeyType&& key,\n                ValueType&& default_value) const;\n\n// (3)\ntemplate<class ValueType>\nValueType value(const json_pointer& ptr,\n                const ValueType& default_value) const;\n

    This is equivalent to Python's dict.get(key, default).

    1. Returns either a copy of an object's element at the specified key key or a given default value if no element with key key exists.

      The function is basically equivalent to executing

      try {\n   return at(key);\n} catch(out_of_range) {\n   return default_value;\n}\n

    2. See 1. This overload is only available if KeyType is comparable with typename object_t::key_type and typename object_comparator_t::is_transparent denotes a type.

    3. Returns either a copy of an object's element at the specified JSON pointer ptr or a given default value if no value at ptr exists.

      The function is basically equivalent to executing

      try {\n   return at(ptr);\n} catch(out_of_range) {\n   return default_value;\n}\n
      with one exception: if the JSON value is neither an array nor an object, the function throws type_error.306 before looking at ptr, even for the empty pointer, whereas at returns the value itself for the empty pointer.

    Differences to at and operator[]

    • Unlike at, this function does not throw if the given key/ptr was not found.
    • Unlike operator[], 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.

    Integer keys

    Calling this function with an integer key argument (for example, 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 const char* and, from there, cause undefined behavior when constructing a std::string for the object key. To access an array element with a default value, use at together with a try/catch block, or compare against size instead.

    "},{"location":"api/basic_json/value/#template-parameters","title":"Template parameters","text":"KeyType A type for an object key other than json_pointer that is comparable with string_t using object_comparator_t. This can also be a string view (C++17). ValueType type compatible to JSON values, for instance int for JSON integer numbers, bool for JSON booleans, or std::vector types for JSON arrays. Note the type of the expected value at key/ptr and the default value default_value must be compatible."},{"location":"api/basic_json/value/#parameters","title":"Parameters","text":"key (in) key of the element to access default_value (in) the value to return if key/ptr found no value ptr (in) a JSON pointer to the element to access"},{"location":"api/basic_json/value/#return-value","title":"Return value","text":"
    1. copy of the element at key key or default_value if key is not found
    2. copy of the element at key key or default_value if key is not found
    3. copy of the element at JSON Pointer ptr or default_value if no value for ptr is found
    "},{"location":"api/basic_json/value/#exception-safety","title":"Exception safety","text":"

    Strong guarantee: if an exception is thrown, there are no changes to any JSON value.

    "},{"location":"api/basic_json/value/#exceptions","title":"Exceptions","text":"
    1. The function can throw the following exceptions:
      • Throws type_error.302 if default_value does not match the type of the value at key
      • Throws type_error.306 if the JSON value is not an object; in that case, using value() with a key makes no sense.
    2. See 1.
    3. The function can throw the following exceptions:
      • Throws type_error.302 if default_value does not match the type of the value at ptr
      • Throws type_error.306 if the JSON value is not an array or object; in that case, using value() with a JSON pointer makes no sense.
      • Throws parse_error.106 if an array index in the passed JSON pointer ptr begins with '0'.
      • Throws parse_error.109 if an array index in the passed JSON pointer ptr is not a number.
    "},{"location":"api/basic_json/value/#complexity","title":"Complexity","text":"
    1. Logarithmic in the size of the container.
    2. Logarithmic in the size of the container.
    3. Logarithmic in the size of the container.
    "},{"location":"api/basic_json/value/#notes","title":"Notes","text":"

    null members are not missing

    The default value is used only if the key (or JSON Pointer) does not exist. A member that exists but is null is converted like any other value, so j.value(\"k\", 0) throws a type_error.302 if \"k\" is null. See Access with default value for alternatives.

    Return type

    The value function is a template, and the return type of the function is determined by the type of the provided default value unless otherwise specified. This can have unexpected effects. In the example below, we store a 64-bit unsigned integer. We get exactly that value when using operator[]. However, when we call value and provide 0 as default value, then -1 is returned. This occurs, because 0 has type int which overflows when handling the value 18446744073709551615.

    To address this issue, either provide a correctly typed default value or use the template parameter to specify the desired return type. Note that this issue occurs even when a value is stored at the provided key, and the default value is not used as the return value.

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    json j = json::parse(R\"({\"uint64\": 18446744073709551615})\");\n\n    std::cout << \"operator[]:                \" << j[\"uint64\"] << '\\n'\n              << \"default value (int):       \" << j.value(\"uint64\", 0) << '\\n'\n              << \"default value (uint64_t):  \" << j.value(\"uint64\", static_cast<std::uint64_t>(0)) << '\\n'\n              << \"explicit return value type: \" << j.value<std::uint64_t>(\"uint64\", 0) << '\\n';\n}\n

    Output:

    operator[]:                18446744073709551615\ndefault value (int):       -1\ndefault value (uint64_t):  18446744073709551615\nexplicit return value type: 18446744073709551615\n

    Deprecation

    Overload (3) also accepts a json_pointer 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 for how to update existing code.

    "},{"location":"api/basic_json/value/#examples","title":"Examples","text":"Example: (1) access specified object element with default value

    The example below shows how object elements can be queried with a default value.

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create a JSON object with different entry types\n    json j =\n    {\n        {\"integer\", 1},\n        {\"floating\", 42.23},\n        {\"string\", \"hello world\"},\n        {\"boolean\", true},\n        {\"object\", {{\"key1\", 1}, {\"key2\", 2}}},\n        {\"array\", {1, 2, 3}}\n    };\n\n    // access existing values\n    int v_integer = j.value(\"integer\", 0);\n    double v_floating = j.value(\"floating\", 47.11);\n\n    // access nonexisting values and rely on default value\n    std::string v_string = j.value(\"nonexisting\", \"oops\");\n    bool v_boolean = j.value(\"nonexisting\", false);\n\n    // output values\n    std::cout << std::boolalpha << v_integer << \" \" << v_floating\n              << \" \" << v_string << \" \" << v_boolean << \"\\n\";\n}\n

    Output:

    1 42.23 oops false\n
    Example: (2) access specified object element using string_view with default value

    The example below shows how object elements can be queried with a default value.

    #include <iostream>\n#include <string_view>\n#include <nlohmann/json.hpp>\n\nusing namespace std::string_view_literals;\nusing nlohmann::json;\n\nint main()\n{\n    // create a JSON object with different entry types\n    json j =\n    {\n        {\"integer\", 1},\n        {\"floating\", 42.23},\n        {\"string\", \"hello world\"},\n        {\"boolean\", true},\n        {\"object\", {{\"key1\", 1}, {\"key2\", 2}}},\n        {\"array\", {1, 2, 3}}\n    };\n\n    // access existing values\n    int v_integer = j.value(\"integer\"sv, 0);\n    double v_floating = j.value(\"floating\"sv, 47.11);\n\n    // access nonexisting values and rely on default value\n    std::string v_string = j.value(\"nonexisting\"sv, \"oops\");\n    bool v_boolean = j.value(\"nonexisting\"sv, false);\n\n    // output values\n    std::cout << std::boolalpha << v_integer << \" \" << v_floating\n              << \" \" << v_string << \" \" << v_boolean << \"\\n\";\n}\n

    Output:

    1 42.23 oops false\n
    Example: (3) access specified object element via JSON Pointer with default value

    The example below shows how object elements can be queried with a default value.

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\nusing namespace nlohmann::literals;\n\nint main()\n{\n    // create a JSON object with different entry types\n    json j =\n    {\n        {\"integer\", 1},\n        {\"floating\", 42.23},\n        {\"string\", \"hello world\"},\n        {\"boolean\", true},\n        {\"object\", {{\"key1\", 1}, {\"key2\", 2}}},\n        {\"array\", {1, 2, 3}}\n    };\n\n    // access existing values\n    int v_integer = j.value(\"/integer\"_json_pointer, 0);\n    double v_floating = j.value(\"/floating\"_json_pointer, 47.11);\n\n    // access nonexisting values and rely on default value\n    std::string v_string = j.value(\"/nonexisting\"_json_pointer, \"oops\");\n    bool v_boolean = j.value(\"/nonexisting\"_json_pointer, false);\n\n    // output values\n    std::cout << std::boolalpha << v_integer << \" \" << v_floating\n              << \" \" << v_string << \" \" << v_boolean << \"\\n\";\n}\n

    Output:

    1 42.23 oops false\n
    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.

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create a JSON object with a string value\n    json j = {{\"name\", \"the good\"}};\n\n    // exception type_error.302\n    try\n    {\n        int v = j.value(\"name\", 0);\n        std::cout << v << '\\n';\n    }\n    catch (const json::type_error& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n\n    // exception type_error.306\n    try\n    {\n        json str = \"I am a string\";\n        auto v = str.value(\"name\", 0);\n        std::cout << v << '\\n';\n    }\n    catch (const json::type_error& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n}\n

    Output:

    [json.exception.type_error.302] type must be number, but is string\n[json.exception.type_error.306] cannot use value() with string\n
    "},{"location":"api/basic_json/value/#see-also","title":"See also","text":"
    • at - access by reference with range checking
    • operator[] - unchecked access by reference
    • basic_json_view::value - the same access on a zero-copy view
    • Access with default value: value - the article on value
    • JSON Pointer - access nested values with a pointer
    "},{"location":"api/basic_json/value/#version-history","title":"Version history","text":"
    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 unreleased 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. Support for keys convertible to std::string_view added in version 3.13.0 unreleased, consistently across the lookup functions.
    3. Added in version 2.0.2. Extended to work with arrays in version 3.13.0 unreleased. Throws parse_error.109 instead of returning default_value for a one-character array index that is not a digit (e.g., /x) in version 3.13.0, as it already did for longer ones.
    "},{"location":"api/basic_json/value_t/","title":"nlohmann::basic_json::value_t","text":"
    enum class value_t : std::uint8_t {\n    null,\n    object,\n    array,\n    string,\n    boolean,\n    number_integer,\n    number_unsigned,\n    number_float,\n    binary,\n    discarded\n};\n

    This enumeration collects the different JSON types. It is internally used to distinguish the stored values, and the functions is_null, is_object, is_array, is_string, is_boolean, is_number (with is_number_integer, is_number_unsigned, and is_number_float), is_discarded, is_binary, is_primitive, and is_structured rely on it.

    "},{"location":"api/basic_json/value_t/#notes","title":"Notes","text":"

    Ordering

    The order of types is as follows:

    1. null
    2. boolean
    3. number_integer, number_unsigned, number_float
    4. object
    5. array
    6. string
    7. binary

    discarded is unordered.

    flowchart LR\n    A[null] --> B[boolean]\n    B --> C[\"number_integer / number_unsigned / number_float\"]\n    C --> D[object]\n    D --> E[array]\n    E --> F[string]\n    F --> G[binary]

    Arrows point from a type to the next greater type in the ordering used by operator<.

    Types of numbers

    There are three enumerators for numbers (number_integer, number_unsigned, and number_float) to distinguish between different types of numbers:

    • number_unsigned_t for unsigned integers
    • number_integer_t for signed integers
    • number_float_t for floating-point numbers or to approximate integers which do not fit into the limits of their respective type

    Comparison operators

    operator< and operator<=> (since C++20) are overloaded and compare according to the ordering described above. Until C++20 all other relational and equality operators yield results according to the integer value of each enumerator. Since C++20 some compilers consider the rewritten candidates generated from operator<=> during overload resolution, while others do not. For predictable and portable behavior use:

    • operator< or operator<=> when wanting to compare according to the order described above
    • operator== or operator!= when wanting to compare according to each enumerators integer value
    "},{"location":"api/basic_json/value_t/#examples","title":"Examples","text":"Example

    The following code how type() queries the value_t for all JSON types.

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create JSON values\n    json j_null;\n    json j_boolean = true;\n    json j_number_integer = -17;\n    json j_number_unsigned = 42u;\n    json j_number_float = 23.42;\n    json j_object = {{\"one\", 1}, {\"two\", 2}};\n    json j_array = {1, 2, 4, 8, 16};\n    json j_string = \"Hello, world\";\n\n    // call type()\n    std::cout << std::boolalpha;\n    std::cout << (j_null.type() == json::value_t::null) << '\\n';\n    std::cout << (j_boolean.type() == json::value_t::boolean) << '\\n';\n    std::cout << (j_number_integer.type() == json::value_t::number_integer) << '\\n';\n    std::cout << (j_number_unsigned.type() == json::value_t::number_unsigned) << '\\n';\n    std::cout << (j_number_float.type() == json::value_t::number_float) << '\\n';\n    std::cout << (j_object.type() == json::value_t::object) << '\\n';\n    std::cout << (j_array.type() == json::value_t::array) << '\\n';\n    std::cout << (j_string.type() == json::value_t::string) << '\\n';\n}\n

    Output:

    true\ntrue\ntrue\ntrue\ntrue\ntrue\ntrue\ntrue\n
    "},{"location":"api/basic_json/value_t/#see-also","title":"See also","text":"
    • type - return the type of the JSON value
    • type_name - return the type as string
    • operator value_t - return the type of the JSON value
    • is_primitive - return whether the type is primitive
    • is_structured - return whether the type is structured
    • Types - the JSON value types and how they are stored
    "},{"location":"api/basic_json/value_t/#version-history","title":"Version history","text":"
    • Added in version 1.0.0.
    • Added unsigned integer type in version 2.0.0.
    • Added binary type in version 3.8.0.
    "},{"location":"api/basic_json/with_t/","title":"nlohmann::basic_json::with_t","text":"

    Member alias templates with_object_t, with_array_t, with_string_t, with_boolean_t, with_integers_t, with_float_t, with_allocator_t, with_json_serializer_t, with_binary_t, and with_base_class_t.

    template<template<typename, typename, typename...> class ObjectType2>\nusing with_object_t = basic_json<ObjectType2, ArrayType, StringType, BooleanType,\n      NumberIntegerType, NumberUnsignedType, NumberFloatType,\n      AllocatorType, JSONSerializer, BinaryType, CustomBaseClass>;\n\ntemplate<template<typename, typename...> class ArrayType2>\nusing with_array_t = basic_json<ObjectType, ArrayType2, StringType, BooleanType,\n      NumberIntegerType, NumberUnsignedType, NumberFloatType,\n      AllocatorType, JSONSerializer, BinaryType, CustomBaseClass>;\n\ntemplate<class StringType2>\nusing with_string_t = basic_json<ObjectType, ArrayType, StringType2, BooleanType,\n      NumberIntegerType, NumberUnsignedType, NumberFloatType,\n      AllocatorType, JSONSerializer, BinaryType, CustomBaseClass>;\n\ntemplate<class BooleanType2>\nusing with_boolean_t = basic_json<ObjectType, ArrayType, StringType, BooleanType2,\n      NumberIntegerType, NumberUnsignedType, NumberFloatType,\n      AllocatorType, JSONSerializer, BinaryType, CustomBaseClass>;\n\ntemplate<class NumberIntegerType2, class NumberUnsignedType2>\nusing with_integers_t = basic_json<ObjectType, ArrayType, StringType, BooleanType,\n      NumberIntegerType2, NumberUnsignedType2, NumberFloatType,\n      AllocatorType, JSONSerializer, BinaryType, CustomBaseClass>;\n\ntemplate<class NumberFloatType2>\nusing with_float_t = basic_json<ObjectType, ArrayType, StringType, BooleanType,\n      NumberIntegerType, NumberUnsignedType, NumberFloatType2,\n      AllocatorType, JSONSerializer, BinaryType, CustomBaseClass>;\n\ntemplate<template<typename> class AllocatorType2>\nusing with_allocator_t = basic_json<ObjectType, ArrayType, StringType, BooleanType,\n      NumberIntegerType, NumberUnsignedType, NumberFloatType,\n      AllocatorType2, JSONSerializer, BinaryType, CustomBaseClass>;\n\ntemplate<template<typename, typename = void> class JSONSerializer2>\nusing with_json_serializer_t = basic_json<ObjectType, ArrayType, StringType, BooleanType,\n      NumberIntegerType, NumberUnsignedType, NumberFloatType,\n      AllocatorType, JSONSerializer2, BinaryType, CustomBaseClass>;\n\ntemplate<class BinaryType2>\nusing with_binary_t = basic_json<ObjectType, ArrayType, StringType, BooleanType,\n      NumberIntegerType, NumberUnsignedType, NumberFloatType,\n      AllocatorType, JSONSerializer, BinaryType2, CustomBaseClass>;\n\ntemplate<class CustomBaseClass2>\nusing with_base_class_t = basic_json<ObjectType, ArrayType, StringType, BooleanType,\n      NumberIntegerType, NumberUnsignedType, NumberFloatType,\n      AllocatorType, JSONSerializer, BinaryType, CustomBaseClass2>;\n

    These member alias templates make it easier to create a basic_json type that is identical to the current type except for one (or, in the case of with_integers_t, two) of its template parameters. Spelling out all 11 template parameters of basic_json just to change a single one is verbose and error-prone; these aliases only require the replacement type(s).

    with_object_t<ObjectType2> replaces ObjectType with_array_t<ArrayType2> replaces ArrayType with_string_t<StringType2> replaces StringType with_boolean_t<BooleanType2> replaces BooleanType with_integers_t<NumberIntegerType2, NumberUnsignedType2> replaces both NumberIntegerType and NumberUnsignedType; the two are combined into a single alias because they are usually changed together (for instance, when switching to fixed-width integer types) with_float_t<NumberFloatType2> replaces NumberFloatType with_allocator_t<AllocatorType2> replaces AllocatorType with_json_serializer_t<JSONSerializer2> replaces JSONSerializer with_binary_t<BinaryType2> replaces BinaryType with_base_class_t<CustomBaseClass2> replaces CustomBaseClass; see also json_base_class_t"},{"location":"api/basic_json/with_t/#notes","title":"Notes","text":"

    All other template parameters are kept unchanged, so the resulting type still uses, for instance, the same ObjectType unless with_object_t itself is used.

    The aliases are members of every basic_json specialization, including ordered_json, and the type they produce is again a basic_json specialization. They can therefore be chained to replace several template parameters at once:

    using my_json = nlohmann::json::with_integers_t<int, unsigned int>::with_float_t<float>;\nusing my_ordered_json = nlohmann::ordered_json::with_string_t<std::wstring>;\n

    The result is the same type as spelling out all template parameters, so the order of the chained aliases does not matter. For instance, nlohmann::json::with_object_t<nlohmann::ordered_map> is nlohmann::ordered_json.

    "},{"location":"api/basic_json/with_t/#examples","title":"Examples","text":"Example

    The following code shows how with_object_t can be used to create a JSON type that stores object elements in a std::map and therefore keeps them sorted by key, unlike the default type which preserves insertion order only when nlohmann::ordered_json is used.

    #include <iostream>\n#include <map>\n#include <nlohmann/json.hpp>\n\n// a JSON type that stores objects in a std::map (which keeps keys sorted)\n// instead of the default ordered associative container\nusing sorted_json = nlohmann::json::with_object_t<std::map>;\n\nint main()\n{\n    sorted_json j;\n    j[\"c\"] = 1;\n    j[\"a\"] = 2;\n    j[\"b\"] = 3;\n\n    // keys are sorted, because std::map is used to store the object\n    std::cout << j.dump() << '\\n';\n}\n

    Output:

    {\"a\":2,\"b\":3,\"c\":1}\n
    "},{"location":"api/basic_json/with_t/#see-also","title":"See also","text":"
    • basic_json - the template parameters that can be replaced
    • json_base_class_t - the type used for CustomBaseClass
    • Template Parameter Requirements - requirements on the template parameters
    "},{"location":"api/basic_json/with_t/#version-history","title":"Version history","text":"
    • Added in version 3.13.0 unreleased.
    "},{"location":"api/basic_json/~basic_json/","title":"nlohmann::basic_json::~basic_json","text":"
    ~basic_json() noexcept;\n

    Destroys the JSON value and frees all allocated memory.

    "},{"location":"api/basic_json/~basic_json/#exception-safety","title":"Exception safety","text":"

    No-throw guarantee: this member function never throws exceptions.

    "},{"location":"api/basic_json/~basic_json/#complexity","title":"Complexity","text":"

    Linear.

    "},{"location":"api/basic_json/~basic_json/#see-also","title":"See also","text":"
    • basic_json - constructs a JSON value
    • clear - clears the content of a JSON value without destroying it
    "},{"location":"api/basic_json/~basic_json/#version-history","title":"Version history","text":"
    • Added in version 1.0.0.
    "},{"location":"api/basic_json_document/","title":"nlohmann::basic_json_document","text":"

    Defined in header <nlohmann/json_view.hpp>

    template<typename BasicJsonType, view_mode Mode = view_mode::read_only>\nclass basic_json_document;\n

    A parsed JSON text, held as a flat index of its values (16 bytes per value) instead of a tree of BasicJsonType values. Strings and floating-point numbers stay in the source text; integers are converted while parsing, and strings that contain escapes are decoded into one buffer owned by the document. basic_json_view is a read-only handle to one value of a basic_json_document; materialize() turns a subtree into the BasicJsonType value that BasicJsonType::parse() would have produced for it.

    A document may borrow the text it was parsed from (the caller's buffer must then outlive the document) or own it (a copy, or an rvalue std::string that was moved in); see owns_source. basic_json_document is move-only: a copy would duplicate the whole index, the decoded-string buffer, and the owned text, and a move is enough in every use we know of. The index, the decoded strings, and the owned text live in one heap block that the document holds through a std::unique_ptr; this is also why views survive a move of the document.

    With Mode == view_mode::editable, the document also offers set, push_back, insert, and erase to change values in place, see Edits below. The source text itself is never written; a read-only document (view_mode::read_only, the default) does not carry any of the bookkeeping edits need, and calling any of them on one fails to compile (static_assert).

    "},{"location":"api/basic_json_document/#template-parameters","title":"Template parameters","text":"BasicJsonType a specialization of basic_json, for instance json or ordered_json. Only 64-bit number_integer_t/number_unsigned_t types are supported; this is checked with a static_assert. Mode a view_mode: view_mode::editable if the document supports set, push_back, insert, and erase (optional, view_mode::read_only by default). See Edits below."},{"location":"api/basic_json_document/#specializations","title":"Specializations","text":"
    • json_document - read-only documents of the default specialization json
    • ordered_json_document - read-only documents of ordered_json
    • json_editable_document - editable documents of json
    • ordered_json_editable_document - editable documents of ordered_json
    "},{"location":"api/basic_json_document/#member-types","title":"Member types","text":"
    • view_type - the type of view returned by root() (basic_json_view<BasicJsonType, Mode>)
    • value_t - the JSON type enumeration, see basic_json::value_t
    • image_check - how load() validates an image (full, bounds, none), see image_check
    "},{"location":"api/basic_json_document/#member-functions","title":"Member functions","text":"
    • (constructor)
    "},{"location":"api/basic_json_document/#parsing","title":"Parsing","text":"
    • parse (static) - deserialize from a compatible input, borrowing or owning it as appropriate
    • parse_copy (static) - deserialize a copy of a compatible input
    • accept (static) - check whether the input is valid JSON
    • read - (re-)parse into this document, reusing its memory
    "},{"location":"api/basic_json_document/#access","title":"Access","text":"
    • root - the view of the root value
    • is_discarded - return whether the last parse failed
    • source - the parsed text
    • owns_source - return whether the document holds its own copy of the text
    • node_count - the number of index entries (values plus object keys)
    • memory_usage - the number of bytes held by the document
    • shrink_to_fit - release unused index capacity
    "},{"location":"api/basic_json_document/#images","title":"Images","text":"
    • save - the document as an image that load() reads without parsing
    • load (static) - read an image written by save()
    "},{"location":"api/basic_json_document/#edits","title":"Edits","text":"
    • set - replace a value, or set an object member, an array element, or the value a JSON pointer refers to (editable documents only)
    • push_back - append to an array (editable documents only)
    • insert - insert an element into an array before a given position (editable documents only)
    • erase - remove an object member, an array element, or the value a JSON pointer refers to (editable documents only)
    "},{"location":"api/basic_json_document/#edits_1","title":"Edits","text":"

    An editable document (view_mode::editable) can be changed after parsing, with set, push_back, insert, and erase; json_editable_document and ordered_json_editable_document are the corresponding specializations. A few points apply to every edit:

    • The source text is never written, and the parsed index never moves: every value keeps the node it was parsed into, so views taken before an edit stay valid, including root(). New values (and the element sequences of an edited array/object) go to storage owned by the document, allocated on demand.
    • A view keeps referring to the same value. After set replaces the value a view refers to, that view sees the new value; a view of a value that a later edit replaces or drops keeps showing what it last held. An edit of an array or object, however, invalidates the iterators taken over it (its members may now live in a different sequence), and a string obtained with get_string() stays valid even as further edits happen (earlier buffers of edited text are kept alive, not overwritten).
    • Values are accepted three ways: a basic_json_view of any document (read-only or editable; it is copied, nothing is shared with the source document), a BasicJsonType value, or anything BasicJsonType can be constructed from (numbers, strings, bool, nullptr, containers, ...).
    • dump() writes an edited document with members in document order, new members at the end, and, with number_format::source, keeps the spelling of every number that was not itself edited \u2014 see Editing a document for why this matters.
    • read() discards all edits, shrink_to_fit() does not move the node index once there are edits, and memory_usage() includes the memory edits use. source_offset() of a value introduced by an edit is static_cast<std::size_t>(-1), the same value it reports for a decoded string.
    "},{"location":"api/basic_json_document/#see-also","title":"See also","text":"
    • Zero-copy JSON views - guide to documents and views
    • basic_json_view - the non-owning handle to a value in a document
    • json_document - and json_editable_document - the default specializations
    • materialize - build a basic_json value from a view
    "},{"location":"api/basic_json_document/#version-history","title":"Version history","text":"
    • Added in version 3.13.0 unreleased.
    "},{"location":"api/basic_json_document/accept/","title":"nlohmann::basic_json_document::accept","text":"
    template<typename InputType>\nstatic bool accept(InputType&& input,\n                   const bool ignore_comments = false,\n                   const bool ignore_trailing_commas = false);\n

    Checks whether the input is valid JSON, accepting and rejecting exactly what BasicJsonType::accept() does, with the same options. Unlike parse(), this function never throws an exception for invalid input, and the returned bool is the only result \u2014 no document is returned.

    The result is the same as that of BasicJsonType::accept() by design; the difference is how the check is made. This function runs the document's index builder (and discards the index), while BasicJsonType::accept() runs the SAX parser with a handler that ignores every event. Use this one if you go on to parse the same input with parse() anyway, so that both use the same code; either is fine for a plain yes/no answer.

    "},{"location":"api/basic_json_document/accept/#template-parameters","title":"Template parameters","text":"InputType A compatible input; see parse."},{"location":"api/basic_json_document/accept/#parameters","title":"Parameters","text":"input (in) Input to check. ignore_comments (in) whether comments should be ignored and treated like whitespace (true) or yield a parse error (false); (optional, false by default) ignore_trailing_commas (in) whether trailing commas in arrays or objects should be ignored and treated like whitespace (true) or yield a parse error (false); (optional, false by default)"},{"location":"api/basic_json_document/accept/#return-value","title":"Return value","text":"

    Whether the input is valid JSON.

    "},{"location":"api/basic_json_document/accept/#exception-safety","title":"Exception safety","text":"

    Strong guarantee: this function itself never throws for an invalid input; it can only throw what allocating the input's own copy (for inputs that are always read into a buffer) throws.

    "},{"location":"api/basic_json_document/accept/#complexity","title":"Complexity","text":"

    Linear in the length of the input.

    "},{"location":"api/basic_json_document/accept/#notes","title":"Notes","text":"

    An integer argument that is not a bool where the flags are expected, such as accept(ptr, len), does not compile; see parse.

    "},{"location":"api/basic_json_document/accept/#examples","title":"Examples","text":"Example
    #include <iostream>\n#include <nlohmann/json.hpp>\n#include <nlohmann/json_view.hpp>\n\nusing nlohmann::json_document;\n\nint main()\n{\n    std::cout << std::boolalpha;\n\n    // accept() behaves exactly like basic_json::accept(): the same inputs are\n    // accepted or rejected, with the same ignore_comments/ignore_trailing_commas\n    // options\n    std::cout << json_document::accept(R\"({\"a\": 1})\") << '\\n';\n    std::cout << json_document::accept(R\"({\"a\": 1,})\") << '\\n'; // trailing comma: rejected by default\n    std::cout << json_document::accept(R\"({\"a\": 1,})\", false, true) << '\\n'; // ignore_trailing_commas\n\n    std::cout << (json_document::accept(R\"({\"a\": 1})\") == nlohmann::json::accept(R\"({\"a\": 1})\")) << '\\n';\n}\n

    Output:

    true\nfalse\ntrue\ntrue\n
    "},{"location":"api/basic_json_document/accept/#see-also","title":"See also","text":"
    • parse - deserialize from a compatible input
    • BasicJsonType::accept - the corresponding function of basic_json
    • Zero-copy JSON views - how parsing a document differs from, and matches, basic_json::parse
    "},{"location":"api/basic_json_document/accept/#version-history","title":"Version history","text":"
    • Added in version 3.13.0 unreleased.
    "},{"location":"api/basic_json_document/basic_json_document/","title":"nlohmann::basic_json_document::basic_json_document","text":"
    // (1)\nbasic_json_document() = default;\n\n// (2)\nbasic_json_document(basic_json_document&& other) noexcept = default;\n\n// (3)\nbasic_json_document(const basic_json_document&) = delete;\n
    1. Creates an empty (discarded) document: root() returns a discarded view, and is_discarded() is true.
    2. Move constructor. Takes over other's index and, if owned, its text; other is left as an empty document. Views taken from other before the move remain valid, because the index is heap-allocated independently of the basic_json_document object.
    3. basic_json_document is move-only. Copying is disabled because of its cost: a copy would duplicate the whole index, the decoded-string buffer, and the owned text, while a move is enough in every use we know of.
    "},{"location":"api/basic_json_document/basic_json_document/#parameters","title":"Parameters","text":"other (in) another document to move the index and text from"},{"location":"api/basic_json_document/basic_json_document/#exception-safety","title":"Exception safety","text":"

    No-throw guarantee: the default and move constructors never throw exceptions.

    "},{"location":"api/basic_json_document/basic_json_document/#complexity","title":"Complexity","text":"

    Constant.

    "},{"location":"api/basic_json_document/basic_json_document/#examples","title":"Examples","text":"Example

    The example below shows the default constructor and demonstrates that basic_json_document is move-only.

    #include <iostream>\n#include <utility>\n#include <nlohmann/json_view.hpp>\n\nusing nlohmann::json_document;\n\nint main()\n{\n    std::cout << std::boolalpha;\n\n    // the default constructor creates an empty (discarded) document\n    json_document empty;\n    std::cout << empty.is_discarded() << '\\n';\n\n    // json_document is move-only: parse() itself returns by value (moved out),\n    // and a document can be moved again, e.g. into a container\n    json_document doc = json_document::parse(R\"({\"a\": 1})\");\n    json_document moved = std::move(doc);\n    std::cout << moved.root().is_object() << '\\n';\n\n    // copying is disabled at compile time:\n    // json_document another = moved; // does not compile\n}\n

    Output:

    true\ntrue\n
    "},{"location":"api/basic_json_document/basic_json_document/#see-also","title":"See also","text":"
    • parse - deserialize from a compatible input
    • is_discarded - return whether the last parse failed
    • Zero-copy JSON views - who owns the source text and for how long
    "},{"location":"api/basic_json_document/basic_json_document/#version-history","title":"Version history","text":"
    • Added in version 3.13.0 unreleased.
    "},{"location":"api/basic_json_document/erase/","title":"nlohmann::basic_json_document::erase","text":"
    // (1)\nstd::size_t erase(view_type object, string_view_t key);\n\n// (2)\ntemplate<typename I>\nvoid erase(view_type array, I idx);\n\n// (3)\nstd::size_t erase(const json_pointer& ptr);\n

    Only an editable document (view_mode::editable, e.g. json_editable_document) has erase; calling it on a read-only basic_json_document fails to compile (static_assert).

    1. Removes every member of object whose key is key (see Notes on duplicate keys) and returns how many were removed; 0 if object has no member with this key.
    2. Removes the element at index idx of array, which must already exist (idx < array.size()).
    3. Removes the value the JSON pointer ptr refers to, relative to root(). ptr must not be empty (root() itself cannot be erased), and the parent of the target must already exist. The target is removed as in 1. if the parent is an object (returns the number of removed members, 0 or more) and as in 2. if it is an array (always returns 1).
    "},{"location":"api/basic_json_document/erase/#template-parameters","title":"Template parameters","text":"I an integral type other than bool, deduced (overloads taking a bool or a non-integral type for idx do not participate in overload resolution)."},{"location":"api/basic_json_document/erase/#parameters","title":"Parameters","text":"object (in) the object to remove a member of array (in) the array to remove an element of key (in) the key of the member(s) to remove idx (in) the index of the element to remove; a negative value throws (see Exceptions) ptr (in) a JSON pointer to the value to remove, relative to root()"},{"location":"api/basic_json_document/erase/#return-value","title":"Return value","text":"
    1. the number of removed members (0 if object had none with this key)
    2. (nothing)
    3. the number of removed values (0 or more for an object member, always 1 for an array element)
    "},{"location":"api/basic_json_document/erase/#exceptions","title":"Exceptions","text":"
    1. Throws type_error.307 if object is not an object \u2014 the same message BasicJsonType::erase throws for the same type.
    2. Throws type_error.307 if array is not an array. Throws out_of_range.401 if idx is negative, or if idx >= array.size().
    3. Throws out_of_range.405 (\"JSON pointer has no parent\") if ptr is empty. Throws what at throws (overload 3) for resolving ptr's parent. For the last reference token itself: if the parent is an array, throws what 2. throws for an index that is out of range, or, for a token that is not a valid array index, parse_error.106 (a leading '0'), parse_error.109 (not a number), out_of_range.410 (too large for size_type), or out_of_range.404 (an empty token); otherwise (an object, or a primitive value the pointer's parent resolves to) throws what 1. throws.

    Overloads 1. and 2. also throw invalid_iterator.202 (\"view does not belong to this document\") if object/array is a discarded view or a view of a different document. Overload 3. never throws invalid_iterator.202: it takes no view, and it always starts from this document's own root().

    "},{"location":"api/basic_json_document/erase/#complexity","title":"Complexity","text":"
    1. Linear in the number of members of object.
    2. Linear in the number of elements of array at or after idx (they move one slot over).
    3. Linear in the number of reference tokens of ptr and, for each token, in the number of members of the object at that level or the index into the array (as at), plus the complexity of 1. or 2. for the last token.
    "},{"location":"api/basic_json_document/erase/#notes","title":"Notes","text":"

    Duplicate keys

    Overload 1. removes every member with key, not just the first \u2014 unlike set, which assigns the first occurrence and drops the rest. This is why it returns a count rather than a single view: there may be more than one member removed, or none.

    Like set and push_back, erase never moves an element's value: a view still referring to a removed member or element keeps showing what it last held (see Edits) \u2014 it just no longer appears when array/object is read, dumped, or iterated. What does change is the container's sequence of links to its elements: removing an element of array (2.) shifts the links to the elements after it by one, as insert does in the other direction. Every iterator already taken over array/object is invalidated by an erase, not only those at or after the removed element, since the container may now use a different sequence.

    "},{"location":"api/basic_json_document/erase/#examples","title":"Examples","text":"Example

    The example below drops a deprecated field and a decommissioned entry from a configuration document \u2014 using all three overloads \u2014 and shows what stays intact that would not with a plain json/ordered_json value: the order of the fields around the ones removed, and the exact spelling of a number that was never touched.

    #include <iostream>\n#include <nlohmann/json_view.hpp>\n\nusing nlohmann::json;\nusing nlohmann::json_editable_document;\nusing nlohmann::json_editable_view;\n\nint main()\n{\n    // a deprecated field is dropped from a configuration file, and a\n    // decommissioned replica is removed from the list -- \"price\" keeps its\n    // trailing zero, and the fields around the removed ones keep their order\n    const std::string text = R\"({\n  \"name\": \"cache\",\n  \"legacy_host\": \"db0\",\n  \"host\": \"db1\",\n  \"price\": 19.90,\n  \"replicas\": [\"db2\", \"db3\", \"db4\"]\n})\";\n\n    json_editable_document doc = json_editable_document::parse(text);\n\n    doc.erase(doc.root(), \"legacy_host\");                                      // (1) an object member\n    doc.erase(doc.root()[\"replicas\"], 1);                                      // (2) an array element (\"db3\")\n    const std::size_t removed = doc.erase(json::json_pointer(\"/replicas/0\"));  // (3) via a JSON pointer\n\n    std::cout << removed << '\\n';\n    std::cout << doc.root().dump(2, ' ', false, json_editable_view::number_format::source) << \"\\n\\n\";\n\n    // the same edits on a plain json value: object_t is a std::map, so\n    // parsing already sorted the keys, and dump() rewrites every number to\n    // its shortest form, even \"price\", which was never touched\n    json plain = json::parse(text);\n    plain.erase(\"legacy_host\");\n    plain[\"replicas\"].erase(1);\n    plain[\"replicas\"].erase(0);\n    std::cout << plain.dump(2) << '\\n';\n}\n

    Output:

    1\n{\n  \"name\": \"cache\",\n  \"host\": \"db1\",\n  \"price\": 19.90,\n  \"replicas\": [\n    \"db4\"\n  ]\n}\n\n{\n  \"host\": \"db1\",\n  \"name\": \"cache\",\n  \"price\": 19.9,\n  \"replicas\": [\n    \"db4\"\n  ]\n}\n
    "},{"location":"api/basic_json_document/erase/#see-also","title":"See also","text":"
    • insert - insert an element into an array
    • set - replace a value, or set an object member, an array element, or the value a JSON pointer refers to
    • push_back - append to an array
    • root - the view of the root value, the starting point of overload 3
    • BasicJsonType::erase - the corresponding function of basic_json
    • Edits - what an edit guarantees, for every overload
    • Zero-copy JSON views - what an edit guarantees and costs
    "},{"location":"api/basic_json_document/erase/#version-history","title":"Version history","text":"
    • Added in version 3.13.0 unreleased.
    "},{"location":"api/basic_json_document/insert/","title":"nlohmann::basic_json_document::insert","text":"
    template<typename I, typename V>\nview_type insert(view_type array, I idx, V&& value);\n

    Only an editable document (view_mode::editable, e.g. json_editable_document) has insert; calling it on a read-only basic_json_document fails to compile (static_assert).

    Inserts value into array as a new element before position idx, which must not be past the end (idx <= array.size(); idx == array.size() appends, like push_back). Unlike push_back, a null array does not first become an empty array: array must already be an array.

    value is accepted three ways: a basic_json_view of any document \u2014 read-only or editable, and it does not have to be array's own document \u2014 which is copied so that nothing is shared with the source document afterward; a BasicJsonType value; or anything BasicJsonType can be constructed from (numbers, strings, bool, nullptr, containers, ...).

    "},{"location":"api/basic_json_document/insert/#template-parameters","title":"Template parameters","text":"I an integral type other than bool, deduced (overloads taking a bool or a non-integral type for idx do not participate in overload resolution). V the type of value, deduced; see above for what is accepted."},{"location":"api/basic_json_document/insert/#parameters","title":"Parameters","text":"array (in) the array to insert into idx (in) the position to insert value before; a negative value throws (see Exceptions) value (in) the value to insert"},{"location":"api/basic_json_document/insert/#return-value","title":"Return value","text":"

    a view of the new element, now holding value

    "},{"location":"api/basic_json_document/insert/#exception-safety","title":"Exception safety","text":"

    Basic exception safety: value is fully encoded \u2014 including the checks below \u2014 into storage owned by the document before anything already reachable from root() is touched, so a failure while encoding value (an invalid argument, or std::bad_alloc) leaves the document completely unchanged, other than memory allocated for the encoding that is not reclaimed. A failure of a later allocation \u2014 while array switches from its parsed layout to a growable block, or while that block grows, see Notes \u2014 can still leave array already switched to that layout even though value itself was not inserted.

    "},{"location":"api/basic_json_document/insert/#exceptions","title":"Exceptions","text":"

    Throws type_error.309 if array is not an array \u2014 the same message BasicJsonType::insert throws for the same type; a null array throws this too (see above). Throws out_of_range.401 if idx is negative, or if idx > array.size(). Throws invalid_iterator.202 (\"view does not belong to this document\") if array is a discarded view or a view of a different document. Throws type_error.302 if value is a discarded view or a discarded BasicJsonType value, and type_error.319 if value is (or contains) a binary value \u2014 BasicJsonType can hold one, but a json_document cannot. Throws type_error.316 if value is (or contains) a string that is not valid UTF-8, with the same message BasicJsonType::dump() gives for that string.

    "},{"location":"api/basic_json_document/insert/#complexity","title":"Complexity","text":"

    Linear in the number of elements of array at or after idx (they move one slot over), plus time linear in the size of value to encode it into the document's storage (constant for a scalar, linear in the number of nested values for an array or object): like push_back, the elements of array move to a growable block of links the first time it is inserted into (or set/push_back on), and that block grows in amortized constant time; inserting before the end within that block still shifts every later element.

    "},{"location":"api/basic_json_document/insert/#notes","title":"Notes","text":"

    Like set on a member or an element, insert never moves an existing element's value \u2014 only where array's links to its elements live \u2014 so a view of an existing element of array stays valid across an insert, and keeps referring to the same element even though its index shifts. Any iterator already taken over array is invalidated, since it was walking the old layout. See Edits for what stays valid across an edit in general.

    "},{"location":"api/basic_json_document/insert/#examples","title":"Examples","text":"Example

    The example below inserts a step into the middle of a deployment plan, without touching the steps that come after it, and shows that a view taken before the insert keeps referring to the same element even though its index shifts \u2014 something a plain json/ordered_json array, or its std::vector-based storage, has no equivalent for.

    #include <iostream>\n#include <nlohmann/json_view.hpp>\n\nusing nlohmann::json;\nusing nlohmann::json_editable_document;\nusing nlohmann::json_editable_view;\n\nint main()\n{\n    // a deployment plan -- \"budget\" is written with a trailing zero that has\n    // no effect on its value\n    const std::string text = R\"({\n  \"release\": \"2026.09\",\n  \"steps\": [\"build\", \"test\", \"deploy\"],\n  \"budget\": 19.90\n})\";\n\n    json_editable_document doc = json_editable_document::parse(text);\n\n    const std::size_t deploy_index = 2;\n    const auto deploy = doc.root()[\"steps\"][deploy_index];  // held across the insert\n\n    doc.insert(doc.root()[\"steps\"], deploy_index, \"smoke-test\"); // insert before \"deploy\"\n\n    // the held view still refers to \"deploy\", even though its index moved\n    // from 2 to 3, and nothing else in the document was touched\n    std::cout << deploy.dump() << '\\n';\n    std::cout << doc.root().dump(2, ' ', false, json_editable_view::number_format::source) << \"\\n\\n\";\n\n    // the same edit on a plain json value: an index held from before the\n    // insert now refers to whatever moved into that slot, and dump()\n    // rewrites \"budget\" to its shortest form even though it was never\n    // touched\n    json plain = json::parse(text);\n    plain[\"steps\"].insert(plain[\"steps\"].begin() + static_cast<std::ptrdiff_t>(deploy_index), \"smoke-test\");\n    std::cout << plain[\"steps\"][deploy_index].dump() << '\\n';\n    std::cout << plain.dump(2) << '\\n';\n}\n

    Output:

    \"deploy\"\n{\n  \"release\": \"2026.09\",\n  \"steps\": [\n    \"build\",\n    \"test\",\n    \"smoke-test\",\n    \"deploy\"\n  ],\n  \"budget\": 19.90\n}\n\n\"smoke-test\"\n{\n  \"budget\": 19.9,\n  \"release\": \"2026.09\",\n  \"steps\": [\n    \"build\",\n    \"test\",\n    \"smoke-test\",\n    \"deploy\"\n  ]\n}\n
    "},{"location":"api/basic_json_document/insert/#see-also","title":"See also","text":"
    • push_back - append to an array
    • erase - remove an object member, an array element, or the value a JSON pointer refers to
    • set - replace a value, or set an object member, an array element, or the value a JSON pointer refers to
    • BasicJsonType::insert - the corresponding function of basic_json
    • Edits - what an edit guarantees, for every overload
    • Zero-copy JSON views - what an edit guarantees and costs
    "},{"location":"api/basic_json_document/insert/#version-history","title":"Version history","text":"
    • Added in version 3.13.0 unreleased.
    "},{"location":"api/basic_json_document/is_discarded/","title":"nlohmann::basic_json_document::is_discarded","text":"
    bool is_discarded() const noexcept;\n

    Returns whether the document holds no value, either because it was default-constructed or because the last call to parse(), parse_copy(), or read() failed with allow_exceptions set to false.

    "},{"location":"api/basic_json_document/is_discarded/#return-value","title":"Return value","text":"

    true if the document is discarded, false otherwise.

    "},{"location":"api/basic_json_document/is_discarded/#exception-safety","title":"Exception safety","text":"

    No-throw guarantee: this function never throws exceptions.

    "},{"location":"api/basic_json_document/is_discarded/#complexity","title":"Complexity","text":"

    Constant.

    "},{"location":"api/basic_json_document/is_discarded/#notes","title":"Notes","text":"

    When the document is discarded, root() returns a discarded view (its is_discarded() is also true).

    "},{"location":"api/basic_json_document/is_discarded/#examples","title":"Examples","text":"Example
    #include <iostream>\n#include <nlohmann/json_view.hpp>\n\nusing nlohmann::json_document;\n\nint main()\n{\n    std::cout << std::boolalpha;\n\n    // with allow_exceptions == false, a parse error produces a discarded\n    // document instead of throwing -- exactly like basic_json::parse()\n    json_document doc = json_document::parse(R\"({\"a\": )\", /* allow_exceptions */ false);\n    std::cout << doc.is_discarded() << '\\n';\n    std::cout << doc.root().is_discarded() << '\\n';\n\n    // a successful parse is never discarded\n    json_document ok = json_document::parse(R\"({\"a\": 1})\", false);\n    std::cout << ok.is_discarded() << '\\n';\n}\n

    Output:

    true\ntrue\nfalse\n
    "},{"location":"api/basic_json_document/is_discarded/#see-also","title":"See also","text":"
    • parse - deserialize from a compatible input
    • basic_json_view::is_discarded - return whether a view is invalid
    • Zero-copy JSON views - how a discarded document arises
    "},{"location":"api/basic_json_document/is_discarded/#version-history","title":"Version history","text":"
    • Added in version 3.13.0 unreleased.
    "},{"location":"api/basic_json_document/load/","title":"nlohmann::basic_json_document::load","text":"
    // (1)\nstatic basic_json_document load(const std::uint8_t* image, std::size_t size,\n                                 const image_check check = image_check::full);\n\n// (2)\nstatic basic_json_document load(const std::vector<std::uint8_t>& image,\n                                 const image_check check = image_check::full);\n\n// (3)\nstatic basic_json_document load(std::vector<std::uint8_t>&& image,\n                                 const image_check check = image_check::full);\n
    1. Reads an image save() wrote, from a pointer and a byte count. The image is borrowed: image must stay alive and unchanged for as long as the returned document, and any view taken from it, is used.
    2. Reads an image from a std::vector. Also borrowed \u2014 equivalent to overload 1 called with image.data() and image.size().
    3. Reads an image, keeping the vector instead of copying it: image is moved into the document (no copy), which then owns it for as long as it needs the text and the decoded strings. owns_source() is true afterward.

    In every overload, the node index is copied into storage the document itself owns \u2014 so that it is properly aligned, and, for an editable document, can be edited \u2014 while the text and the decoded strings stay in image. The hash indexes large objects use for lookup are rebuilt, exactly as after parsing.

    "},{"location":"api/basic_json_document/load/#parameters","title":"Parameters","text":"image (in) the image save() wrote (overloads 1 and 2), or one to take ownership of (overload 3) size (in) the number of bytes at image (overload 1) check (in) how thoroughly to validate image before trusting it; see image_check below (optional, image_check::full by default)"},{"location":"api/basic_json_document/load/#return-value","title":"Return value","text":"

    The document read from the image.

    "},{"location":"api/basic_json_document/load/#exception-safety","title":"Exception safety","text":"

    Overloads 1 and 2 give the strong guarantee: image is only read, never written, so a thrown exception leaves the caller's buffer untouched.

    Overload 3 moves image into the document before validating it, so that a good image is kept without a copy. If loading then fails, the partially built document \u2014 and the vector now inside it \u2014 is discarded along with the exception, and image itself is left empty, not restored to what was passed in. Move a copy in instead, or validate with overload 2 first, if the original vector must survive a failed load.

    "},{"location":"api/basic_json_document/load/#exceptions","title":"Exceptions","text":"

    Throws parse_error.116 if image is not one save() could have written, or fails the requested check:

    message when too short image is nullptr, or size is smaller than the 64-byte header unknown format the header's magic bytes or version do not match, or a reserved header field is not zero sizes out of range the node count, text size, or decoded-string size the header describes does not fit size, or the '\\0' after the text or after the decoded strings is missing the check failed check is not image_check::none, and the image fails it \u2014 see image_check

    Example messages

    [json.exception.parse_error.116] parse error: invalid json_document image: too short\n
    [json.exception.parse_error.116] parse error: invalid json_document image: unknown format\n
    [json.exception.parse_error.116] parse error: invalid json_document image: sizes out of range\n
    [json.exception.parse_error.116] parse error: invalid json_document image: the check failed\n

    "},{"location":"api/basic_json_document/load/#complexity","title":"Complexity","text":"

    Linear in the number of nodes, which are always copied into the document. image_check::none does not read the text or the decoded strings. image_check::bounds reads one byte of the text for each float token (its sign, to check the recorded digits against the token's length), and nothing else of the text or the decoded strings.

    With image_check::full, linear in the size of the image (the nodes, the text, and the decoded strings), plus sorting the ranges of the strings and of the float tokens (at most one per node): the contents of each distinct range are checked once, however many nodes refer to it.

    "},{"location":"api/basic_json_document/load/#notes","title":"Notes","text":"

    Little-endian targets only. On a big-endian target, load() does not exist, just like save(): the image format is little-endian, so a call fails to compile.

    "},{"location":"api/basic_json_document/load/#image_check","title":"image_check","text":"
    using image_check = detail::view::image_check;\n\nenum class image_check\n{\n    full,\n    bounds,\n    none\n};\n

    How thoroughly load() validates image before trusting it.

    full (the default) Checks everything the parser itself guarantees: structure and bounds; that every string is valid UTF-8 (and, for a string still in the source text, that it contains no quote, backslash, or control character); and that every number token is well-formed and matches the value stored for it. Strings and float tokens may share a range only if the ranges are identical (as nodes that share a value do), and never overlap otherwise. Reading and serializing a checked image is safe and always produces valid JSON, exactly as for a parsed document. This is the right choice for an image from anything you do not fully control \u2014 a file, a cache shared with other processes, a peer on the network. bounds Checks structure and bounds only: that every offset and count in the node index stays inside the image. So load(), root(), element access, and materialize() can never read outside the image, even on a damaged one. It does not guarantee that the image describes valid JSON: a string that a full check would have rejected can make dump() write invalid UTF-8 or invalid JSON, or throw type_error.316, and a number can read back with a value that does not match how it is spelled. An editable document does not take such a string over: set, push_back and insert throw type_error.316 when they copy it from a view of the loaded document, and leave the editable document unchanged. bounds skips scanning the text and the decoded strings, so it fits a cache your own process just wrote and reads straight back, where damage would mean a bug or a hardware fault rather than adversarial input. none Checks nothing. Reading a damaged image is undefined behavior, so use it only for an image you trust as much as your own memory.

    Lifetime. Overloads 1 and 2 borrow image: it must stay alive and byte-for-byte unchanged for as long as the returned document, and any view taken from it, is used \u2014 exactly like a document parse() borrowed its input for. Overload 3 avoids this by keeping the vector itself; see owns_source.

    Experimental

    The image format is versioned but not yet stable, and may change in an incompatible way before it is declared stable; load() already rejects an image written by a different format version with parse_error.116 (\"unknown format\"). Use images to cache a document within one build of the library, or to hand one to another process running the same build on the same (little-endian) machine \u2014 not as a long-term storage format.

    "},{"location":"api/basic_json_document/load/#examples","title":"Examples","text":"Caching a document, ownership, and a rejected image

    The example below saves a parsed document as an image, checks that load() reproduces the original dump() without parsing, and shows the difference between load(std::move(image)) (owned) and load(image) (borrowed). It then damages one byte of the image and shows image_check::full rejecting it with parse_error.116, while image_check::bounds \u2014 meant for a cache the process already trusts \u2014 still reads it without going out of bounds.

    #include <cstdint>\n#include <iostream>\n#include <string>\n#include <vector>\n#include <nlohmann/json_view.hpp>\n\nusing nlohmann::json;\nusing nlohmann::json_document;\nusing image_check = json_document::image_check;\n\nint main()\n{\n    std::cout << std::boolalpha;\n\n    // the image of a parsed document -- as if read back from a cache file or\n    // received from another process running the same build of the library\n    const std::string text = R\"({\"name\": \"cache\", \"note\": \"caf\\u00e9\", \"replicas\": [\"db2\", \"db3\"]})\";\n    const json_document parsed = json_document::parse(text);\n    const std::vector<std::uint8_t> image = parsed.save();\n\n    // (1)/(2) load() needs no parsing, yet dumps exactly what parsing did\n    const json_document borrowed = json_document::load(image);\n    std::cout << (borrowed.root().dump() == parsed.root().dump()) << '\\n';\n    std::cout << borrowed.owns_source() << '\\n'; // borrowed: still points into `image`\n\n    // (3) load(std::move(image)) keeps the vector instead of copying it\n    std::vector<std::uint8_t> to_move = image;\n    const json_document owned = json_document::load(std::move(to_move));\n    std::cout << owned.owns_source() << '\\n';\n\n    // a damaged image -- the last byte of the decoded string \"note\" holds\n    // (an escape sequence, so it was unescaped into the document's own\n    // buffer), flipped, as storage or transport corruption might do\n    std::vector<std::uint8_t> damaged = image;\n    damaged[damaged.size() - 2] = 0xFF;\n\n    // image_check::full inspects strings and numbers, so it catches the damage\n    try\n    {\n        static_cast<void>(json_document::load(damaged, image_check::full));\n    }\n    catch (const json::parse_error& e)\n    {\n        std::cout << e.id << '\\n';\n    }\n\n    // image_check::bounds only checks structure and bounds, so a cache the\n    // process already trusts loads without the extra scan -- reading a value\n    // the damage did not touch is still safe\n    const json_document trusted = json_document::load(damaged, image_check::bounds);\n    std::cout << trusted.root()[\"name\"].get<std::string>() << '\\n';\n}\n

    Output:

    true\nfalse\ntrue\n116\ncache\n
    "},{"location":"api/basic_json_document/load/#see-also","title":"See also","text":"
    • save - write the document as an image
    • owns_source - return whether the document holds its own copy of the text
    • parse - deserialize from JSON text instead of an image
    • Images - why and when to use images
    "},{"location":"api/basic_json_document/load/#version-history","title":"Version history","text":"
    • Added in version 3.13.0 unreleased.
    "},{"location":"api/basic_json_document/memory_usage/","title":"nlohmann::basic_json_document::memory_usage","text":"
    std::size_t memory_usage() const noexcept;\n

    Returns the number of bytes held by the document: the node index, the decoded-string buffer (for strings that contain escapes), and, for an owned document, its copy of the source text.

    "},{"location":"api/basic_json_document/memory_usage/#return-value","title":"Return value","text":"

    The number of bytes the document holds, 0 for a discarded document.

    "},{"location":"api/basic_json_document/memory_usage/#exception-safety","title":"Exception safety","text":"

    No-throw guarantee: this function never throws exceptions.

    "},{"location":"api/basic_json_document/memory_usage/#complexity","title":"Complexity","text":"

    Constant.

    "},{"location":"api/basic_json_document/memory_usage/#notes","title":"Notes","text":"

    The exact value depends on the platform, the allocator, and the library's own layout, and may change between versions; do not rely on it being a specific number, and do not compare it across different builds or platforms. Compare it for the same document over time, or between documents built with the same binary, instead \u2014 for instance to observe the effect of shrink_to_fit().

    "},{"location":"api/basic_json_document/memory_usage/#examples","title":"Examples","text":"Example
    #include <iostream>\n#include <string>\n#include <nlohmann/json_view.hpp>\n\nusing nlohmann::json_document;\n\nint main()\n{\n    std::cout << std::boolalpha;\n\n    // long enough that copying it needs a real (heap) allocation, so the\n    // comparison below does not depend on the standard library's small\n    // string optimization threshold\n    const std::string text = std::string(200, ' ') + \"[1, 2, 3, 4, 5]\";\n\n    // memory_usage() is not portable across platforms/allocators/compilers, so\n    // compare it relatively instead of printing the raw byte count\n    json_document borrowed = json_document::parse(text);\n    json_document owned = json_document::parse_copy(text);\n\n    // the owned document additionally stores its own copy of the source text\n    std::cout << (owned.memory_usage() > borrowed.memory_usage()) << '\\n';\n\n    // a document with more values needs a larger index\n    json_document small = json_document::parse(std::string(\"[1]\"));\n    json_document large = json_document::parse(std::string(\"[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]\"));\n    std::cout << (large.memory_usage() > small.memory_usage()) << '\\n';\n}\n

    Output:

    true\ntrue\n
    "},{"location":"api/basic_json_document/memory_usage/#see-also","title":"See also","text":"
    • node_count - the number of index entries
    • shrink_to_fit - release unused index capacity
    • Zero-copy JSON views - the flat node index and its memory
    "},{"location":"api/basic_json_document/memory_usage/#version-history","title":"Version history","text":"
    • Added in version 3.13.0 unreleased.
    "},{"location":"api/basic_json_document/node_count/","title":"nlohmann::basic_json_document::node_count","text":"
    std::size_t node_count() const noexcept;\n

    Returns the number of entries in the document's flat index.

    "},{"location":"api/basic_json_document/node_count/#return-value","title":"Return value","text":"

    The number of index entries: one per value (of any type, at any nesting depth) plus one per object key. 0 for a discarded document.

    "},{"location":"api/basic_json_document/node_count/#exception-safety","title":"Exception safety","text":"

    No-throw guarantee: this function never throws exceptions.

    "},{"location":"api/basic_json_document/node_count/#complexity","title":"Complexity","text":"

    Constant.

    "},{"location":"api/basic_json_document/node_count/#notes","title":"Notes","text":"

    Each index entry is 16 bytes, so node_count() * 16 is the size of the index itself (part, but not all, of memory_usage(), which also counts decoded strings and, for an owned document, the text).

    "},{"location":"api/basic_json_document/node_count/#examples","title":"Examples","text":"Example
    #include <iostream>\n#include <nlohmann/json_view.hpp>\n\nusing nlohmann::json_document;\n\nint main()\n{\n    // node_count() is the size of the flat index: one 16-byte node per value,\n    // plus one per object key (values and keys are all the index stores)\n    json_document scalar = json_document::parse(\"42\");\n    std::cout << scalar.node_count() << '\\n';\n\n    json_document doc = json_document::parse(R\"({\"a\": 1, \"b\": [1, 2]})\");\n    std::cout << doc.node_count() << '\\n';\n}\n

    Output:

    1\n7\n
    "},{"location":"api/basic_json_document/node_count/#see-also","title":"See also","text":"
    • memory_usage - the number of bytes held by the document
    • shrink_to_fit - release unused index capacity
    • Zero-copy JSON views - the flat node index and its memory
    "},{"location":"api/basic_json_document/node_count/#version-history","title":"Version history","text":"
    • Added in version 3.13.0 unreleased.
    "},{"location":"api/basic_json_document/owns_source/","title":"nlohmann::basic_json_document::owns_source","text":"
    bool owns_source() const noexcept;\n

    Returns whether the document holds its own copy of the parsed text or is borrowing the caller's buffer.

    "},{"location":"api/basic_json_document/owns_source/#return-value","title":"Return value","text":"

    true if the document owns the text returned by source(), false if it borrows it (or if the document is discarded).

    "},{"location":"api/basic_json_document/owns_source/#exception-safety","title":"Exception safety","text":"

    No-throw guarantee: this function never throws exceptions.

    "},{"location":"api/basic_json_document/owns_source/#complexity","title":"Complexity","text":"

    Constant.

    "},{"location":"api/basic_json_document/owns_source/#notes","title":"Notes","text":"

    See the ownership table on parse for which inputs are borrowed and which are owned. A borrowed document (owns_source() == false) is only valid while the buffer it was parsed from is still alive.

    "},{"location":"api/basic_json_document/owns_source/#examples","title":"Examples","text":"Example
    #include <iostream>\n#include <string>\n#include <nlohmann/json_view.hpp>\n\nusing nlohmann::json_document;\n\nint main()\n{\n    std::cout << std::boolalpha;\n\n    std::string text = R\"({\"a\": 1})\";\n\n    // borrowed: the document only points into `text`; `text` must outlive it\n    json_document borrowed = json_document::parse(text);\n    std::cout << borrowed.owns_source() << '\\n';\n\n    // owned: parse_copy() always takes its own copy\n    json_document copied = json_document::parse_copy(text);\n    std::cout << copied.owns_source() << '\\n';\n\n    // owned: an rvalue std::string is moved in, not copied, but still owned\n    json_document moved_in = json_document::parse(std::string(text));\n    std::cout << moved_in.owns_source() << '\\n';\n}\n

    Output:

    false\ntrue\ntrue\n
    "},{"location":"api/basic_json_document/owns_source/#see-also","title":"See also","text":"
    • parse - deserialize from a compatible input
    • parse_copy - deserialize a copy of a compatible input, always owned
    • source - the parsed text
    • Zero-copy JSON views - who owns the source text and for how long
    "},{"location":"api/basic_json_document/owns_source/#version-history","title":"Version history","text":"
    • Added in version 3.13.0 unreleased.
    "},{"location":"api/basic_json_document/parse/","title":"nlohmann::basic_json_document::parse","text":"
    // (1)\ntemplate<typename InputType>\nstatic basic_json_document parse(InputType&& input,\n                                 const bool allow_exceptions = true,\n                                 const bool ignore_comments = false,\n                                 const bool ignore_trailing_commas = false);\n\n// (2)\ntemplate<typename IteratorType>\nstatic basic_json_document parse(IteratorType first, IteratorType last,\n                                 const bool allow_exceptions = true,\n                                 const bool ignore_comments = false,\n                                 const bool ignore_trailing_commas = false);\n
    1. Deserialize from a compatible input, borrowing or owning it depending on its value category and type (see Notes).
    2. Deserialize from a pair of input iterators.

    Both overloads accept the same JSON text as BasicJsonType::parse(), with the same ignore_comments/ignore_trailing_commas options, but build a basic_json_document (a flat index into the input) instead of a tree of BasicJsonType values. They accept every input BasicJsonType::parse() takes, and in addition a pointer to a null-terminated wide string (which BasicJsonType::parse() rejects). Contiguous inputs of single-byte characters that stay alive can be borrowed; all others (streams, FILE*, wide characters, which must be converted to UTF-8, and non-contiguous iterators) are read into a copy that the document owns \u2014 see the Notes. Use parse_copy() to get an owned copy of a borrowable input as well.

    "},{"location":"api/basic_json_document/parse/#template-parameters","title":"Template parameters","text":"InputType

    A compatible input, for instance:

    • a std::string, a std::string_view (C++17), or a C-style array of single-byte characters
    • a pointer to a null-terminated string of single-byte characters (char, signed char, unsigned char, std::uint8_t)
    • a container for which obj.data() and obj.size() give contiguous single-byte access, e.g. std::vector<char> or std::vector<std::uint8_t>
    • an std::istream object
    • a FILE* pointer
    • wide characters (wchar_t, char16_t, char32_t), which are converted to UTF-8: a wide string object (std::wstring, std::u16string, std::u32string), an array (e.g. a wide string literal), or a pointer to a null-terminated wide string
    IteratorType an input iterator type, for instance a pair of pointers such as ptr and ptr + len, or a pair of std::string::iterator; the iterators of single-byte characters are borrowed or read like the byte inputs above, those of wide characters are converted to UTF-8

    Ill-formed UTF-16 and UTF-32 sequences are rejected: a lone surrogate, a high surrogate that is not followed by its low surrogate, and a code point above U+10FFFF all yield a parse_error.101.

    "},{"location":"api/basic_json_document/parse/#parameters","title":"Parameters","text":"input (in) Input to parse from. allow_exceptions (in) whether to throw exceptions in case of a parse error (optional, true by default) ignore_comments (in) whether comments should be ignored and treated like whitespace (true) or yield a parse error (false); (optional, false by default) ignore_trailing_commas (in) whether trailing commas in arrays or objects should be ignored and treated like whitespace (true) or yield a parse error (false); (optional, false by default) first (in) iterator to the start of a character range last (in) iterator to the end of a character range"},{"location":"api/basic_json_document/parse/#return-value","title":"Return value","text":"

    The parsed document. If allow_exceptions is false and the input is not valid JSON, the returned document is discarded; see is_discarded.

    "},{"location":"api/basic_json_document/parse/#exceptions","title":"Exceptions","text":"

    Throws the same exception BasicJsonType::parse() throws for the same input and options \u2014 the same exception id, message, and position \u2014 because on a failing input the library's own parser is run on the same bytes to produce the diagnostic. This replay runs only for a failing input, and costs about a lexing pass up to the error (its SAX handler builds no values); with allow_exceptions set to false, it is skipped and a discarded document is returned instead. Additionally throws out_of_range.416 if the input is 4294967280 bytes (4 GiB minus 16 bytes) or larger, a size BasicJsonType::parse() does not reject.

    "},{"location":"api/basic_json_document/parse/#complexity","title":"Complexity","text":"

    Linear in the length of the input.

    "},{"location":"api/basic_json_document/parse/#notes","title":"Notes","text":"

    Ownership. Whether the document borrows input or owns a copy of it depends on its value category and type:

    input ownership lvalue byte container (std::string, std::vector<char>, ...), std::string_view, C string, character array borrowed \u2014 input must outlive the document non-const rvalue std::string owned, moved in without a copy other rvalue byte container (including a const rvalue std::string) owned, copied stream, FILE*, wide characters, or anything else read through the general input adapter owned, read into a buffer (a stream is read to its end)

    For overload (2), a pair of pointers to single-byte integers (e.g. const char*, std::uint8_t*) is borrowed. From C++20 on, so is any other contiguous iterator over single bytes, such as std::vector<char>::iterator or std::string::const_iterator. Before C++20 these iterators cannot be told apart from other class-type iterators, so their range is read into an owned buffer, as is any non-contiguous range (e.g. of a std::list<char>).

    See owns_source to check which happened after a call, and the feature page for the reasoning.

    Numbers. As for BasicJsonType::parse(), an integer literal too large for the 64-bit integer type becomes a floating-point value.

    No lengths. An integer argument that is not a bool where the flags are expected \u2014 for example parse(ptr, len) \u2014 does not compile (the overload is deleted). Such a call would convert len to allow_exceptions and read ptr as a null-terminated string, past the end of a buffer that has none. To parse a buffer of a given length, pass a pair of pointers: parse(ptr, ptr + len). The same holds for parse_copy, accept, and read.

    "},{"location":"api/basic_json_document/parse/#examples","title":"Examples","text":"Example: (1) borrowed vs. owned input, and errors identical to BasicJsonType::parse()
    #include <iostream>\n#include <string>\n#include <nlohmann/json.hpp>\n#include <nlohmann/json_view.hpp>\n\nusing nlohmann::json_document;\n\nint main()\n{\n    std::cout << std::boolalpha;\n\n    // an lvalue std::string is BORROWED: the document only stores a pointer\n    // into `text`, so `text` must outlive `borrowed`\n    std::string text = R\"({\"count\": 3})\";\n    json_document borrowed = json_document::parse(text);\n    std::cout << borrowed.owns_source() << '\\n'; // false\n\n    // an rvalue std::string is MOVED into the document -- no copy of the text\n    json_document owned = json_document::parse(std::string(R\"({\"count\": 3})\"));\n    std::cout << owned.owns_source() << '\\n'; // true\n\n    // errors are identical to basic_json::parse: same exception id, message,\n    // and position, because the library parser runs on the same bytes on a\n    // failing input\n    try\n    {\n        static_cast<void>(json_document::parse(R\"({\"count\": )\"));\n    }\n    catch (const nlohmann::json::parse_error& e)\n    {\n        std::cout << e.id << '\\n';\n    }\n}\n

    Output:

    false\ntrue\n101\n
    Example: (2) parse an iterator range (no NUL terminator required)
    #include <iostream>\n#include <vector>\n#include <nlohmann/json_view.hpp>\n\nusing nlohmann::json_document;\n\nint main()\n{\n    std::cout << std::boolalpha;\n\n    // a JSON value embedded in a larger, non-null-terminated buffer (e.g. a\n    // slice received over the network)\n    std::vector<char> buffer = {'[', '1', ',', '2', ']', 'j', 'u', 'n', 'k'};\n\n    // a pointer pair is BORROWED, exactly like a byte container lvalue: the\n    // document points into the buffer. (From C++20 on, std::vector<char>\n    // iterators are borrowed as well; before, they are copied.)\n    const char* first = buffer.data();\n    json_document doc = json_document::parse(first, first + 5);\n    std::cout << doc.root().is_array() << ' ' << doc.root().size() << '\\n';\n    std::cout << doc.owns_source() << '\\n'; // false: borrowed\n}\n

    Output:

    true 2\nfalse\n
    "},{"location":"api/basic_json_document/parse/#see-also","title":"See also","text":"
    • parse_copy - deserialize a copy of a compatible input
    • accept - check whether the input is valid JSON
    • read - (re-)parse into this document, reusing its memory
    • owns_source - return whether the document holds its own copy of the text
    • load - read a document from an image instead of parsing JSON text
    • BasicJsonType::parse - the corresponding function of basic_json
    "},{"location":"api/basic_json_document/parse/#version-history","title":"Version history","text":"
    • Added in version 3.13.0 unreleased.
    • Ill-formed UTF-16 and UTF-32 input (a lone surrogate, a high surrogate that is not followed by its low surrogate, or a code point above U+10FFFF) is rejected with parse_error.101.
    "},{"location":"api/basic_json_document/parse_copy/","title":"nlohmann::basic_json_document::parse_copy","text":"
    template<typename InputType>\nstatic basic_json_document parse_copy(InputType&& input,\n                                      const bool allow_exceptions = true,\n                                      const bool ignore_comments = false,\n                                      const bool ignore_trailing_commas = false);\n

    Deserialize from a compatible input, always taking the document's own copy of it, regardless of the value category or type of input. Unlike parse(), the returned document never depends on input staying alive.

    "},{"location":"api/basic_json_document/parse_copy/#template-parameters","title":"Template parameters","text":"InputType A compatible input; see parse."},{"location":"api/basic_json_document/parse_copy/#parameters","title":"Parameters","text":"input (in) Input to parse from. allow_exceptions (in) whether to throw exceptions in case of a parse error (optional, true by default) ignore_comments (in) whether comments should be ignored and treated like whitespace (true) or yield a parse error (false); (optional, false by default) ignore_trailing_commas (in) whether trailing commas in arrays or objects should be ignored and treated like whitespace (true) or yield a parse error (false); (optional, false by default)"},{"location":"api/basic_json_document/parse_copy/#return-value","title":"Return value","text":"

    The parsed document, with owns_source() true. If allow_exceptions is false and the input is not valid JSON, the returned document is discarded; see is_discarded.

    "},{"location":"api/basic_json_document/parse_copy/#exceptions","title":"Exceptions","text":"

    Same as parse.

    "},{"location":"api/basic_json_document/parse_copy/#complexity","title":"Complexity","text":"

    Linear in the length of the input.

    "},{"location":"api/basic_json_document/parse_copy/#notes","title":"Notes","text":"

    parse_copy() accepts and rejects exactly what parse() does, and classifies numbers the same way; it only differs in that the input is always copied rather than sometimes borrowed. Prefer parse() when the input's lifetime already covers the document's, since it avoids the copy for borrowed inputs.

    An integer argument that is not a bool where the flags are expected, such as parse_copy(ptr, len), does not compile; see parse.

    "},{"location":"api/basic_json_document/parse_copy/#examples","title":"Examples","text":"Example

    The example below returns a document from a function whose local buffer would otherwise not outlive it.

    #include <iostream>\n#include <nlohmann/json_view.hpp>\n\nusing nlohmann::json_document;\n\njson_document parse_from_temporary_buffer()\n{\n    char buffer[] = R\"({\"a\": 1})\";\n    // parse() would borrow `buffer`, which is about to go out of scope;\n    // parse_copy() takes its own copy instead, so the returned document does\n    // not depend on `buffer` afterward\n    return json_document::parse_copy(buffer);\n}\n\nint main()\n{\n    std::cout << std::boolalpha;\n\n    json_document doc = parse_from_temporary_buffer();\n    std::cout << doc.owns_source() << '\\n';\n    std::cout << doc.root().is_object() << '\\n';\n}\n

    Output:

    true\ntrue\n
    "},{"location":"api/basic_json_document/parse_copy/#see-also","title":"See also","text":"
    • parse - deserialize from a compatible input, borrowing it where possible
    • owns_source - return whether the document holds its own copy of the text
    • Zero-copy JSON views - borrowing or copying the source text
    "},{"location":"api/basic_json_document/parse_copy/#version-history","title":"Version history","text":"
    • Added in version 3.13.0 unreleased.
    "},{"location":"api/basic_json_document/push_back/","title":"nlohmann::basic_json_document::push_back","text":"
    template<typename V>\nview_type push_back(view_type array, V&& value);\n

    Appends value as a new last element of array. A null array first becomes an empty array, the same way set turns a null object into an empty object.

    value is accepted three ways: a basic_json_view of any document \u2014 read-only or editable, and it does not have to be array's own document \u2014 which is copied so that nothing is shared with the source document afterward; a BasicJsonType value; or anything BasicJsonType can be constructed from (numbers, strings, bool, nullptr, containers, ...).

    Only an editable document (view_mode::editable, e.g. json_editable_document) has push_back; calling it on a read-only basic_json_document fails to compile (static_assert).

    "},{"location":"api/basic_json_document/push_back/#template-parameters","title":"Template parameters","text":"V the type of value, deduced; see above for what is accepted."},{"location":"api/basic_json_document/push_back/#parameters","title":"Parameters","text":"array (in) the array (or null value) to append to value (in) the value to append"},{"location":"api/basic_json_document/push_back/#return-value","title":"Return value","text":"

    a view of the new last element of array, now holding value

    "},{"location":"api/basic_json_document/push_back/#exception-safety","title":"Exception safety","text":"

    Basic exception safety: value is fully encoded \u2014 including the checks below \u2014 into storage owned by the document before anything already reachable from root() is touched, so a failure while encoding value (an invalid argument, or std::bad_alloc) leaves the document completely unchanged, other than memory allocated for the encoding that is not reclaimed. A failure of a later allocation \u2014 while array switches from its parsed layout to a growable block, or while that block grows, see Notes \u2014 can still leave a partial effect, such as a null array argument already turned into an empty array even though value itself was not appended.

    "},{"location":"api/basic_json_document/push_back/#exceptions","title":"Exceptions","text":"

    Throws type_error.308 if array is neither an array nor null \u2014 the same message BasicJsonType::push_back throws for the same type. Throws invalid_iterator.202 (\"view does not belong to this document\") if array is a discarded view or a view of a different document. Throws type_error.302 if value is a discarded view or a discarded BasicJsonType value, and type_error.319 if value is (or contains) a binary value \u2014 BasicJsonType can hold one, but a json_document cannot. Throws type_error.316 if value is (or contains) a string that is not valid UTF-8, with the same message BasicJsonType::dump() gives for that string.

    "},{"location":"api/basic_json_document/push_back/#complexity","title":"Complexity","text":"

    Amortized constant, plus time linear in the size of value to encode it into the document's storage (constant for a scalar, linear in the number of nested values for an array or object): the elements of array move to a growable block of links the first time it is appended to (or set on), and that block itself grows \u2014 doubling its capacity, so the cost of growing it amortizes to constant per element \u2014 only once it runs out of room. See Notes.

    "},{"location":"api/basic_json_document/push_back/#notes","title":"Notes","text":"

    Like set on a member or an element, push_back never moves an existing element itself \u2014 only where array's links to its elements live \u2014 so a view of an existing element of array stays valid across a push_back, but any iterator already taken over array is invalidated, since it was walking the old layout. See Edits for what stays valid across an edit in general.

    "},{"location":"api/basic_json_document/push_back/#examples","title":"Examples","text":"Example

    The example below appends records to an array one at a time, as they might arrive from a stream of events, without ever building a BasicJsonType value for the array or for the records already in it, and shows that a view taken from an earlier push_back still refers to the same element once later ones have run.

    #include <iostream>\n#include <nlohmann/json_view.hpp>\n\nusing nlohmann::json;\nusing nlohmann::json_editable_document;\n\nint main()\n{\n    // \"events\" starts out null -- the first push_back() turns it into an\n    // array, exactly like set() turns a null object member into an object\n    json_editable_document doc = json_editable_document::parse(R\"({\"source\": \"sensor-1\", \"events\": null})\");\n\n    const auto first = doc.push_back(doc.root()[\"events\"], json{{\"type\", \"start\"}, {\"t\", 0}});\n    for (int t = 1; t <= 3; ++t)\n    {\n        doc.push_back(doc.root()[\"events\"], json{{\"type\", \"tick\"}, {\"t\", t}});\n    }\n\n    // push_back() never moves an existing element: a view taken from an\n    // earlier call still refers to the same element after later ones\n    std::cout << first.dump() << '\\n';\n    std::cout << doc.root()[\"events\"].size() << '\\n';\n    std::cout << doc.root().dump(2) << '\\n';\n}\n

    Output:

    {\"t\":0,\"type\":\"start\"}\n4\n{\n  \"source\": \"sensor-1\",\n  \"events\": [\n    {\n      \"t\": 0,\n      \"type\": \"start\"\n    },\n    {\n      \"t\": 1,\n      \"type\": \"tick\"\n    },\n    {\n      \"t\": 2,\n      \"type\": \"tick\"\n    },\n    {\n      \"t\": 3,\n      \"type\": \"tick\"\n    }\n  ]\n}\n
    "},{"location":"api/basic_json_document/push_back/#see-also","title":"See also","text":"
    • set - replace a value, or set an object member, an array element, or the value a JSON pointer refers to
    • insert - insert an element into an array before a given position
    • erase - remove an object member, an array element, or the value a JSON pointer refers to
    • root - the view of the root value
    • BasicJsonType::push_back - the corresponding function of basic_json
    • Edits - what an edit guarantees, for every overload
    • Zero-copy JSON views - what an edit guarantees and costs
    "},{"location":"api/basic_json_document/push_back/#version-history","title":"Version history","text":"
    • Added in version 3.13.0 unreleased.
    "},{"location":"api/basic_json_document/read/","title":"nlohmann::basic_json_document::read","text":"
    template<typename InputType>\nvoid read(InputType&& input,\n         const bool allow_exceptions = true,\n         const bool ignore_comments = false,\n         const bool ignore_trailing_commas = false);\n

    (Re-)parses input into *this, discarding the document's previous value and reusing its memory (the node index, the decoded-string buffer, and, if applicable, the owned copy of the text) rather than allocating a fresh document. parse() is implemented in terms of this function, applied to a default-constructed document.

    "},{"location":"api/basic_json_document/read/#template-parameters","title":"Template parameters","text":"InputType A compatible input; see parse."},{"location":"api/basic_json_document/read/#parameters","title":"Parameters","text":"input (in) Input to parse from. allow_exceptions (in) whether to throw exceptions in case of a parse error (optional, true by default) ignore_comments (in) whether comments should be ignored and treated like whitespace (true) or yield a parse error (false); (optional, false by default) ignore_trailing_commas (in) whether trailing commas in arrays or objects should be ignored and treated like whitespace (true) or yield a parse error (false); (optional, false by default)"},{"location":"api/basic_json_document/read/#exceptions","title":"Exceptions","text":"

    Same as parse.

    "},{"location":"api/basic_json_document/read/#complexity","title":"Complexity","text":"

    Linear in the length of the input.

    "},{"location":"api/basic_json_document/read/#notes","title":"Notes","text":"

    Every view taken from *this before the call \u2014 including the previous root() \u2014 is invalidated, whether or not the new parse succeeds; take fresh views from root() afterward.

    input is borrowed or owned by the same rules as parse(); a document can borrow on one call and own on the next, since ownership is decided freshly each time. An input that is copied (see the table in parse()) is written into the document's previous owned copy, reusing its memory; a moved-in std::string replaces it.

    Reusing a document matters most for large inputs: the operating system provides the memory of a fresh node index one page at a time, and every page costs a page fault the first time it is written. On x86-64 Linux (4 KiB pages), parsing a 55 MB document into a reused document took about 40 % less time than parsing it into a fresh one. Programs that parse many documents of similar size should therefore keep one document and call read().

    An integer argument that is not a bool where the flags are expected, such as read(ptr, len), does not compile; see parse.

    "},{"location":"api/basic_json_document/read/#examples","title":"Examples","text":"Example

    The example below parses a sequence of messages into the same document, reusing its memory instead of allocating a new document for each one.

    #include <iostream>\n#include <string>\n#include <vector>\n#include <nlohmann/json_view.hpp>\n\nusing nlohmann::json_document;\n\nint main()\n{\n    std::cout << std::boolalpha;\n\n    std::vector<std::string> messages =\n    {\n        R\"({\"id\": 1})\", R\"({\"id\": 2, \"tag\": \"x\"})\", R\"({\"id\": 3})\"\n    };\n\n    // parse into the same document over and over: its node index and decode\n    // buffer are reused instead of being freed and reallocated for each message\n    json_document doc;\n    std::size_t total = 0;\n    for (const auto& msg : messages)\n    {\n        doc.read(msg);\n        total += doc.root().size();\n    }\n    std::cout << total << '\\n';\n\n    // read() can also change what kind of input is owned/borrowed between calls\n    doc.read(std::string(R\"({\"owned\": true})\"));\n    std::cout << doc.owns_source() << '\\n';\n}\n

    Output:

    4\ntrue\n
    "},{"location":"api/basic_json_document/read/#see-also","title":"See also","text":"
    • parse - deserialize from a compatible input
    • root - the view of the root value
    • load - read a document from an image instead of parsing JSON text
    • Zero-copy JSON views - reusing a document and what it invalidates
    "},{"location":"api/basic_json_document/read/#version-history","title":"Version history","text":"
    • Added in version 3.13.0 unreleased.
    "},{"location":"api/basic_json_document/root/","title":"nlohmann::basic_json_document::root","text":"
    // (1)\nview_type root() const& noexcept;\n\n// (2)\nview_type root() const&& = delete;\n
    1. Returns a view of the root value of the document.
    2. Deleted: the view of a temporary document would dangle.
    "},{"location":"api/basic_json_document/root/#return-value","title":"Return value","text":"

    A view_type (i.e. basic_json_view<BasicJsonType>) for the root value, or a discarded view if the document is discarded.

    "},{"location":"api/basic_json_document/root/#exception-safety","title":"Exception safety","text":"

    No-throw guarantee: this function never throws exceptions.

    "},{"location":"api/basic_json_document/root/#complexity","title":"Complexity","text":"

    Constant.

    "},{"location":"api/basic_json_document/root/#notes","title":"Notes","text":"

    Lifetime. A view refers into the document, so the document must outlive it. root() can therefore only be called on a document that has a name (an lvalue); calling it on a temporary does not compile:

    auto v = json_document::parse(text).root();  // error: the document is destroyed at the end of the statement\n\nauto doc = json_document::parse(text);       // OK: keep the document alive\nauto v = doc.root();\n

    root() is a cheap handle into the document's index, not a copy of anything; call it as often as needed. The returned view is valid under the same conditions as any other view of the document \u2014 see Object inspection \u2014 in particular, it is invalidated by the next read() or shrink_to_fit() on this document. A view can dangle, like a std::string_view; see Ownership and lifetime.

    "},{"location":"api/basic_json_document/root/#examples","title":"Examples","text":"Example
    #include <iostream>\n#include <nlohmann/json_view.hpp>\n\nusing nlohmann::json_document;\n\nint main()\n{\n    std::cout << std::boolalpha;\n\n    json_document doc = json_document::parse(R\"({\"greeting\": \"hi\"})\");\n    std::cout << doc.root().is_object() << '\\n';\n\n    // root() is a cheap handle, not a copy: repeated calls observe the same value\n    std::cout << (doc.root().type() == doc.root().type()) << '\\n';\n\n    // the root of a failed parse (allow_exceptions == false) is discarded\n    json_document failed = json_document::parse(\"{\", false);\n    std::cout << failed.root().is_discarded() << '\\n';\n}\n

    Output:

    true\ntrue\ntrue\n
    "},{"location":"api/basic_json_document/root/#see-also","title":"See also","text":"
    • is_discarded - return whether the last parse failed
    • materialize - build the BasicJsonType value of a subtree
    "},{"location":"api/basic_json_document/root/#version-history","title":"Version history","text":"
    • Added in version 3.13.0 unreleased.
    "},{"location":"api/basic_json_document/save/","title":"nlohmann::basic_json_document::save","text":"
    std::vector<std::uint8_t> save() const;\n

    Writes the document as an image: a byte buffer that load reads back without parsing. The image holds the node index, the source text (plus, for an edited document, the number tokens edits wrote), and the decoded strings (plus the strings edits wrote) \u2014 everything root() needs, with nothing left to parse.

    An edited document is written in its current state, with its values in document order, the way the library's own parser would have produced them for that JSON text: a member set added goes at the end, an erased member leaves no trace, and a float that is not finite (NaN or positive/negative infinity) becomes null, the same substitution dump() makes. The same document always saves to the same bytes \u2014 also across BasicJsonType and the view_mode, since the image reflects document order and values only, not which specialization produced them.

    "},{"location":"api/basic_json_document/save/#return-value","title":"Return value","text":"

    The image, as a std::vector<std::uint8_t>. Pass it, or a pointer to its data together with its size, to load to read the document back.

    "},{"location":"api/basic_json_document/save/#exception-safety","title":"Exception safety","text":"

    Strong guarantee: save() does not modify *this (it is const), so if it throws, the document is left exactly as it was, and the partially built image is discarded with the exception.

    "},{"location":"api/basic_json_document/save/#exceptions","title":"Exceptions","text":"

    Throws type_error.320 if the document is discarded \u2014 a default-constructed document, or one a failed parse()/ read() with allow_exceptions == false left discarded.

    Throws out_of_range.416 if the node count, the text, or the decoded strings of the image would individually reach 4 GiB \u2014 the same 32-bit offsets parse() and, for edits, set/push_back are already limited to.

    Example messages

    [json.exception.type_error.320] cannot save a discarded json_document\n
    [json.exception.out_of_range.416] images of 4 GiB or more are not supported by json_document\n

    "},{"location":"api/basic_json_document/save/#complexity","title":"Complexity","text":"

    Linear in the size of the document: the number of nodes, plus the length of the text and the decoded strings that end up in the image.

    "},{"location":"api/basic_json_document/save/#notes","title":"Notes","text":"

    Format. The image begins with a 64-byte header (the magic bytes \"NJVI\", a version number, the node count, and the sizes of the text and the decoded strings, all little-endian), followed by the nodes (16 bytes each), the text and a '\\0', and the decoded strings and a '\\0'. load checks the header, and the sizes it describes, before reading anything else \u2014 see load's Exceptions.

    Experimental

    The image format is versioned but not yet stable: it may change in an incompatible way before it is declared stable. Use images to cache a document within one build of the library, or to hand one to another process running the same build on the same (little-endian) machine \u2014 not as a long-term storage format. Keep the original JSON text if you need to read a saved document back with a future library version.

    Little-endian targets only. The image is written as raw little-endian bytes, with no byte-swapping. On a big-endian target, save() and load do not exist: a call fails to compile rather than produce bytes a big-endian reader could not interpret correctly.

    "},{"location":"api/basic_json_document/save/#examples","title":"Examples","text":"Caching a parsed document as an image

    The example below saves a parsed configuration as an image \u2014 the way a service might cache one to answer later requests without parsing the text again \u2014 and confirms that loading it back gives exactly the same result as parsing did, and that saving is deterministic.

    #include <cstdint>\n#include <iostream>\n#include <string>\n#include <vector>\n#include <nlohmann/json_view.hpp>\n\nusing nlohmann::json_document;\n\nint main()\n{\n    std::cout << std::boolalpha;\n\n    // a configuration a service parses once and then caches as an image, so\n    // that later requests can load() it instead of parsing the text again\n    const std::string text = R\"({\"name\": \"cache\", \"host\": \"db1\", \"port\": 6379, \"replicas\": [\"db2\", \"db3\"]})\";\n    const json_document config = json_document::parse(text);\n\n    // save() turns the parsed document into a byte buffer: a 64-byte header,\n    // the node index, the source text, and the decoded strings\n    const std::vector<std::uint8_t> image = config.save();\n    std::cout << image.size() << '\\n';\n\n    // the same document always saves to the same bytes\n    std::cout << (image == json_document::parse(text).save()) << '\\n';\n\n    // loading the image back needs no parsing, yet dumps exactly what\n    // parsing the text produced\n    const json_document reloaded = json_document::load(image);\n    std::cout << (reloaded.root().dump() == config.root().dump()) << '\\n';\n}\n

    Output:

    316\ntrue\ntrue\n
    "},{"location":"api/basic_json_document/save/#see-also","title":"See also","text":"
    • load - read an image written by save()
    • owns_source - return whether the document holds its own copy of the text
    • basic_json_view::dump - serialize the document to JSON text instead of an image
    • Images - why and when to use images
    "},{"location":"api/basic_json_document/save/#version-history","title":"Version history","text":"
    • Added in version 3.13.0 unreleased.
    "},{"location":"api/basic_json_document/set/","title":"nlohmann::basic_json_document::set","text":"
    // (1)\ntemplate<typename V>\nview_type set(view_type target, V&& value);\n\n// (2)\ntemplate<typename V>\nview_type set(view_type object, string_view_t key, V&& value);\n\n// (3)\ntemplate<typename I, typename V>\nview_type set(view_type array, I idx, V&& value);\n\n// (4)\ntemplate<typename V>\nview_type set(const json_pointer& ptr, V&& value);\n

    Only an editable document (view_mode::editable, e.g. json_editable_document) has set; calling it on a read-only basic_json_document fails to compile (static_assert).

    1. Replaces the value target refers to with value.
    2. Sets the member key of the object object to value: assigns it if object already has a member with this key \u2014 the first one, should the key occur more than once, and the later duplicates are then dropped (see the Notes below) \u2014 or appends a new member at the end otherwise. A null object first becomes an empty object.
    3. Assigns value to the element at index idx of the array array, which must already exist (idx < array.size()).
    4. Sets the value the JSON pointer ptr refers to, relative to root(), to value. The parent of the target must already exist: an object member is set as in 2. (added if it does not exist yet), an array element is assigned as in 3., and a last reference token of \"-\", or equal to the size of the array, appends value instead, exactly as push_back would. A null parent becomes what basic_json::operator[] with a JSON pointer makes of it: an array if the last reference token is \"-\" or consists of digits only (for an index beyond 0, the array is first filled with null values up to that index), an object otherwise. An empty ptr sets root() itself, as in 1.

    In every overload, value is accepted three ways: a basic_json_view of any document \u2014 read-only or editable, and it does not have to be target's/object's/array's own document \u2014 which is copied so that nothing is shared with the source document afterward; a BasicJsonType value; or anything BasicJsonType can be constructed from (numbers, strings, bool, nullptr, containers, ...).

    "},{"location":"api/basic_json_document/set/#template-parameters","title":"Template parameters","text":"V the type of value, deduced; see above for what is accepted. I an integral type other than bool, deduced (overloads taking a bool or a non-integral type for idx do not participate in overload resolution)."},{"location":"api/basic_json_document/set/#parameters","title":"Parameters","text":"target (in) the value to replace object (in) the object (or null value) whose member to set array (in) the array whose element to assign key (in) the key of the member to set idx (in) the index of the element to assign; a negative value throws (see Exceptions) ptr (in) a JSON pointer to the value to set, relative to root() value (in) the new value"},{"location":"api/basic_json_document/set/#return-value","title":"Return value","text":"
    1. a view of target, now holding value
    2. a view of the member key of object, now holding value
    3. a view of the element idx of array, now holding value
    4. a view of the value ptr refers to, now holding value
    "},{"location":"api/basic_json_document/set/#exception-safety","title":"Exception safety","text":"

    Basic exception safety: value is fully encoded \u2014 including the checks below \u2014 into storage owned by the document before anything already reachable from root() is touched, so a failure while encoding value (an invalid argument, or std::bad_alloc) leaves the document completely unchanged, other than memory allocated for the encoding that is not reclaimed. A failure of a later allocation \u2014 while an edited array or object switches from its parsed layout to a growable block, see Notes \u2014 can still leave a partial effect, such as a null object/array argument already turned into an empty object/array even though value itself was not linked in. Likewise, a failure of value in 4. leaves a null parent that is set with an index beyond 0 already filled with the null values before the index.

    "},{"location":"api/basic_json_document/set/#exceptions","title":"Exceptions","text":"
    1. Throws type_error.302 if value is a discarded view, or a discarded BasicJsonType value (e.g. BasicJsonType(value_t::discarded)) \u2014 an object or array value, of either kind, is fine and is encoded as a whole subtree.
    2. Throws type_error.305 if object is neither an object nor null \u2014 the same message operator[] throws for a string argument on such a value. Throws type_error.316 if key is not valid UTF-8, with the same message BasicJsonType::dump() gives for that string. Also throws what 1. throws for value.
    3. Throws type_error.305 if array is not an array \u2014 the same message operator[] throws for a numeric argument on such a value. Throws out_of_range.401 if idx is negative, or if idx >= array.size(). Also throws what 1. throws for value.
    4. Throws what at throws (overload 3) for resolving ptr's parent, except that a missing object member or an array index equal to the array's size at the very last reference token is not an error there (it becomes a new member or an appended element) instead of out_of_range.403/out_of_range.402. For the last reference token itself: if the parent is an object (or a primitive value, where it throws type_error.305), throws what 2. throws; if the parent is an array, throws what 3. throws for an index that is out of range, or, for a token that is not a valid array index, parse_error.106 (a leading '0'), parse_error.109 (not a number), out_of_range.410 (too large for size_type), or out_of_range.404 (an empty token); the same errors are thrown for a null parent and a token of digits (the parent is not changed then), and out_of_range.401 if the index is 4294967295 or more. Also throws what 1. throws for value.

    Every overload also throws type_error.319 if value is (or contains) a binary value \u2014 BasicJsonType can hold one, but a json_document cannot \u2014 and invalid_iterator.202 (\"view does not belong to this document\") if target/object/array is a discarded view or a view of a different document (overloads 1-3 only; overload 4 always starts from this document's own root()).

    "},{"location":"api/basic_json_document/set/#complexity","title":"Complexity","text":"
    1. Linear in the size of value (encoding it into the document's storage): constant for a scalar, linear in the number of nested values for an array or object. If target is itself an array or object that spans more than one node in its parent's original, unedited layout, and value is a scalar, replacing it additionally costs time linear in the size of the document, the first time (the parent of target is looked up from root(), and then switches to links) \u2014 see Notes. Once the parent has links, target is replaced in constant time: setting every element of a large array one after the other is linear overall. To avoid the lookup altogether, use 3. (or 2. for an object), which know the parent.
    2. Linear in the number of members of object, to find an existing member with key, plus the complexity of 1. for value.
    3. Constant, plus the complexity of 1. for value.
    4. Linear in the number of reference tokens of ptr and, for each token, in the number of members of the object at that level or the index into the array (as at), plus the complexity of 2. or 3. for the last token; for a null parent and an index, linear in the index.
    "},{"location":"api/basic_json_document/set/#notes","title":"Notes","text":"

    Duplicate keys

    If object already has more than one member with key (2.), the first one is assigned value and every later member with the same key is removed \u2014 so that a lookup, an iteration, and materialize() of object afterward all agree on a single value for key, the same way operator[] already picks the first occurrence of a duplicate key for reading. See the Notes on duplicate keys of operator[].

    Setting a member (2.) or an element (3., through 4.) of an array or object whose elements have not been edited before switches it from its parsed layout to a growable block holding links to its elements; a later push_back or set on the same container reuses that block, growing it (amortized constant time) only once it runs out of room. This never moves an element itself \u2014 only where the container's links to its elements live \u2014 so a view of an element stays valid, but any iterator already taken over the container is invalidated, since it was walking the old layout. See Edits for what stays valid across an edit in general.

    The same switch happens, for the same reason, when overload 1. replaces a multi-node array/object value with a scalar: the parent's element sequence is what has to switch to links, not target itself, because the parent originally stepped over target's whole subtree by its node count, which no longer applies once target is a one-node scalar.

    "},{"location":"api/basic_json_document/set/#examples","title":"Examples","text":"Example: (1)/(2)/(3)/(4) replace a value, set a member, assign an element, set via a JSON pointer

    The example below edits a small configuration document \u2014 replacing a value, adding an object member, assigning an array element, and reaching a field through a JSON pointer \u2014 and shows what dump() preserves that is lost once the same edits are made on a BasicJsonType value instead: the order object members were written in, and the exact spelling of a number that was never touched.

    #include <iostream>\n#include <nlohmann/json_view.hpp>\n\nusing nlohmann::json;\nusing nlohmann::json_editable_document;\nusing nlohmann::json_editable_view;\n\nint main()\n{\n    // a configuration file, as it might be read from disk -- \"price\" is\n    // written with a trailing zero that has no effect on its value\n    const std::string text = R\"({\n  \"name\": \"cache\",\n  \"host\": \"db1\",\n  \"port\": 6379,\n  \"price\": 19.90,\n  \"replicas\": [\"db2\", \"db3\"],\n  \"timeout\": 30\n})\";\n\n    json_editable_document doc = json_editable_document::parse(text);\n\n    doc.set(doc.root()[\"port\"], 6380);                    // (1) replace a value\n    doc.set(doc.root(), \"region\", \"us-east\");              // (2) add a member\n    doc.set(doc.root()[\"replicas\"], 0, \"db4\");             // (3) assign an element\n    doc.set(json::json_pointer(\"/timeout\"), 45);           // (4) via a JSON pointer\n\n    // members stay in document order (the new one at the end), and a number\n    // that was not itself edited keeps its exact spelling\n    std::cout << doc.root().dump(2, ' ', false, json_editable_view::number_format::source) << \"\\n\\n\";\n\n    // the same edits on a plain json value: object_t is a std::map, so\n    // parsing already sorted the keys, and dump() rewrites every number to\n    // its shortest form, even \"price\", which was never touched\n    json plain = json::parse(text);\n    plain[\"port\"] = 6380;\n    plain[\"region\"] = \"us-east\";\n    plain[\"replicas\"][0] = \"db4\";\n    plain[json::json_pointer(\"/timeout\")] = 45;\n    std::cout << plain.dump(2) << '\\n';\n}\n

    Output:

    {\n  \"name\": \"cache\",\n  \"host\": \"db1\",\n  \"port\": 6380,\n  \"price\": 19.90,\n  \"replicas\": [\n    \"db4\",\n    \"db3\"\n  ],\n  \"timeout\": 45,\n  \"region\": \"us-east\"\n}\n\n{\n  \"host\": \"db1\",\n  \"name\": \"cache\",\n  \"port\": 6380,\n  \"price\": 19.9,\n  \"region\": \"us-east\",\n  \"replicas\": [\n    \"db4\",\n    \"db3\"\n  ],\n  \"timeout\": 45\n}\n
    "},{"location":"api/basic_json_document/set/#see-also","title":"See also","text":"
    • push_back - append to an array
    • insert - insert an element into an array
    • erase - remove an object member, an array element, or the value a JSON pointer refers to
    • root - the view of the root value, the starting point of overload 4
    • basic_json_view::dump - serialize the document, keeping an untouched number's spelling with number_format::source
    • Edits - what an edit guarantees, for every overload
    • Editing a document - why editable documents keep the source text's order and number spelling
    "},{"location":"api/basic_json_document/set/#version-history","title":"Version history","text":"
    • Added in version 3.13.0 unreleased.
    "},{"location":"api/basic_json_document/shrink_to_fit/","title":"nlohmann::basic_json_document::shrink_to_fit","text":"
    void shrink_to_fit();\n

    Releases capacity that is no longer needed, both of the node index and of the buffer for decoded strings (strings that contained escape sequences), e.g. after read() replaced a large document with a much smaller one. Like std::vector::shrink_to_fit(), this is a non-binding request: the library may keep more capacity than strictly necessary.

    "},{"location":"api/basic_json_document/shrink_to_fit/#exception-safety","title":"Exception safety","text":"

    Strong guarantee: if an exception is thrown, there are no changes to the document.

    "},{"location":"api/basic_json_document/shrink_to_fit/#exceptions","title":"Exceptions","text":"

    May throw std::bad_alloc if the reallocation fails; on exception, the document is unchanged.

    "},{"location":"api/basic_json_document/shrink_to_fit/#complexity","title":"Complexity","text":"

    Linear in node_count() plus the length of the decoded strings.

    "},{"location":"api/basic_json_document/shrink_to_fit/#notes","title":"Notes","text":"

    The node index of a small document (an estimate of up to 1024 nodes, which is up to about 4 KiB of minified text) is allocated together with the document's header, so that parsing needs one allocation. That part cannot be released separately: shrink_to_fit() only trims a node index that has its own allocation, and the decoded strings.

    Invalidates views

    Unlike moving the document, shrink_to_fit() invalidates every view taken from this document before the call, including a previously obtained root(): the node index is moved into a new, smaller allocation, and the old one is freed. Take a fresh view from root() after calling this function.

    This is unlike std::vector::shrink_to_fit(), which promises nothing about validity but in practice often leaves iterators alone when it did not need to reallocate; here, an implementation that avoids a reallocation when possible would be an internal optimization only, not a guarantee to rely on.

    "},{"location":"api/basic_json_document/shrink_to_fit/#examples","title":"Examples","text":"Example
    #include <iostream>\n#include <sstream>\n#include <string>\n#include <nlohmann/json_view.hpp>\n\nusing nlohmann::json_document;\n\nint main()\n{\n    std::cout << std::boolalpha;\n\n    // build a large array (many nodes), then read a small one into the same\n    // document: the index grown for the large input is still allocated\n    std::ostringstream big;\n    big << '[';\n    for (int i = 0; i < 500; ++i)\n    {\n        if (i != 0)\n        {\n            big << ',';\n        }\n        big << i;\n    }\n    big << ']';\n\n    json_document doc;\n    doc.read(big.str());\n    const std::size_t big_nodes = doc.node_count();\n\n    doc.read(std::string(\"[1]\"));\n    std::cout << (doc.node_count() < big_nodes) << '\\n'; // far fewer live nodes now\n    const std::size_t before = doc.memory_usage();\n\n    // shrink_to_fit() moves the index into a block sized for what is actually\n    // used. This INVALIDATES every view taken from this document before the\n    // call (they point into the old, now-freed block) -- take fresh ones from\n    // root() afterward.\n    doc.shrink_to_fit();\n    const std::size_t after = doc.memory_usage();\n    std::cout << (after <= before) << '\\n';\n\n    // a freshly taken view is valid and correct\n    std::cout << doc.root().is_array() << ' ' << doc.root().size() << '\\n';\n}\n

    Output:

    true\ntrue\ntrue 1\n
    "},{"location":"api/basic_json_document/shrink_to_fit/#see-also","title":"See also","text":"
    • node_count - the number of index entries
    • memory_usage - the number of bytes held by the document
    • root - the view of the root value
    • Zero-copy JSON views - what releasing memory invalidates
    "},{"location":"api/basic_json_document/shrink_to_fit/#version-history","title":"Version history","text":"
    • Added in version 3.13.0 unreleased.
    "},{"location":"api/basic_json_document/source/","title":"nlohmann::basic_json_document::source","text":"
    view_type::string_view_t source() const noexcept;\n

    Returns the parsed text, whether it is borrowed from the caller or owned by the document.

    "},{"location":"api/basic_json_document/source/#return-value","title":"Return value","text":"

    A string_view_t (std::string_view on C++17 and newer) over the parsed text, or an empty one if the document is discarded.

    "},{"location":"api/basic_json_document/source/#exception-safety","title":"Exception safety","text":"

    No-throw guarantee: this function never throws exceptions.

    "},{"location":"api/basic_json_document/source/#complexity","title":"Complexity","text":"

    Constant.

    "},{"location":"api/basic_json_document/source/#notes","title":"Notes","text":"

    For a borrowed document, source() points directly into the caller's buffer, so it is only valid while that buffer is; see owns_source.

    "},{"location":"api/basic_json_document/source/#examples","title":"Examples","text":"Example
    #include <iostream>\n#include <string>\n#include <nlohmann/json_view.hpp>\n\nusing nlohmann::json_document;\n\nint main()\n{\n    std::cout << std::boolalpha;\n\n    std::string text = R\"({\"a\": 1})\";\n    json_document doc = json_document::parse(text);\n\n    // source() is the parsed text, whether borrowed or owned\n    std::cout << (doc.source().size() == text.size()) << '\\n';\n    std::cout << std::string(doc.source().data(), doc.source().size()) << '\\n';\n\n    // for a borrowed document, source() points right into the caller's buffer\n    std::cout << (doc.source().data() == text.data()) << '\\n';\n}\n

    Output:

    true\n{\"a\": 1}\ntrue\n
    "},{"location":"api/basic_json_document/source/#see-also","title":"See also","text":"
    • owns_source - return whether the document holds its own copy of the text
    • source_offset - byte offset of a value in the source text
    • Zero-copy JSON views - who owns the source text and for how long
    "},{"location":"api/basic_json_document/source/#version-history","title":"Version history","text":"
    • Added in version 3.13.0 unreleased.
    "},{"location":"api/basic_json_view/","title":"nlohmann::basic_json_view","text":"

    Defined in header <nlohmann/json_view.hpp>

    template<typename BasicJsonType, view_mode Mode = view_mode::read_only>\nclass basic_json_view;\n

    A read-only handle to one value of a basic_json_document: two pointers (a pointer to the document and a pointer into its index), trivially copyable. A view is valid as long as

    • the document is alive,
    • the document has not been re-parsed with read() (or parse() into it) or shrunk with shrink_to_fit() since the view was taken, and
    • if the document borrows its source text, that text is still alive and unmodified (floating-point values and unescaped strings are read from it lazily).

    Moving the document itself does not invalidate its views: the index is heap-allocated independently of the basic_json_document object.

    basic_json_view provides the read-only part of the BasicJsonType interface:

    • the type-inspection functions
    • element access
    • lookup
    • iteration
    • conversion: get<T>(), get_string(), number_token(), and materialize() to build the BasicJsonType value of a subtree on demand
    • comparison: operator== and operator!= compare two views, or a view and a BasicJsonType value, without ever building a BasicJsonType value for a view; no ordering comparison (operator<) is provided

    operator[], at, contains, and value also accept a json_pointer. Unlike basic_json, there are no implicit conversion operators (no operator ValueType()), and no get_ptr() or get_ref(); see get.

    basic_json_view itself is always read-only \u2014 it never has a set or push_back of its own. A view of an editable document (view_mode::editable) sees every edit made through basic_json_document::set and basic_json_document::push_back: once a value is changed, every view that still refers to it \u2014 including ones taken before the change \u2014 reads the new value. See Edits.

    "},{"location":"api/basic_json_view/#template-parameters","title":"Template parameters","text":"BasicJsonType a specialization of basic_json, matching the basic_json_document the view was taken from. Mode a view_mode: whether the view is of an editable document, matching the basic_json_document it was taken from (optional, view_mode::read_only by default). See Edits."},{"location":"api/basic_json_view/#specializations","title":"Specializations","text":"
    • json_view - views of a json_document
    • ordered_json_view - views of an ordered_json_document
    • json_editable_view - views of a json_editable_document
    • ordered_json_editable_view - views of an ordered_json_editable_document
    "},{"location":"api/basic_json_view/#member-types","title":"Member types","text":"
    • basic_json_type - BasicJsonType (it also marks the class for is_json_view)
    • value_t - the JSON type enumeration, see basic_json::value_t
    • string_t, number_integer_t, number_unsigned_t, number_float_t, json_pointer - the corresponding member types of BasicJsonType
    • size_type - std::size_t
    • string_view_t - std::string_view on C++17 and newer, a minimal internal substitute otherwise
    • iterator, const_iterator - a forward iterator over the elements of an array or the member values of an object, in document order; both names refer to the same type, since a view is always read-only
    • number_format - how dump() writes numbers
    "},{"location":"api/basic_json_view/#member-functions","title":"Member functions","text":"
    • (constructor)
    "},{"location":"api/basic_json_view/#object-inspection","title":"Object inspection","text":"
    • type - return the type of the value
    • type_name - return the type as string
    • is_null - return whether the value is null
    • is_boolean - return whether the value is a boolean
    • is_number - return whether the value is a number
    • is_number_integer - return whether the value is an integer number
    • is_number_unsigned - return whether the value is an unsigned integer number
    • is_number_float - return whether the value is a floating-point number
    • is_string - return whether the value is a string
    • is_array - return whether the value is an array
    • is_object - return whether the value is an object
    • is_binary - return whether the value is a binary array (always false)
    • is_primitive - return whether the type is primitive
    • is_structured - return whether the type is structured
    • is_discarded - return whether the view is invalid
    "},{"location":"api/basic_json_view/#element-access","title":"Element access","text":"
    • at - access specified element with bounds checking
    • operator[] - access specified element
    • value - access specified element with default value
    • front - access the first element
    • back - access the last element
    "},{"location":"api/basic_json_view/#lookup","title":"Lookup","text":"
    • find - find an element in an object
    • count - returns the number of occurrences of a key in an object
    • contains - check the existence of an element in an object
    "},{"location":"api/basic_json_view/#iterators","title":"Iterators","text":"
    • begin - returns an iterator to the first element
    • cbegin - returns a const iterator to the first element
    • end - returns an iterator to one past the last element
    • cend - returns a const iterator to one past the last element
    • items - wrapper to access iterator member functions in range-based for
    "},{"location":"api/basic_json_view/#capacity","title":"Capacity","text":"
    • size - return the number of elements
    • empty - return whether the value has no elements
    "},{"location":"api/basic_json_view/#conversion","title":"Conversion","text":"
    • get - get a value
    • get_to - get a value and write it to a destination
    • get_string - get a string value without a copy
    • number_token - get a number's token text without a copy
    • materialize - build the BasicJsonType value of this subtree
    "},{"location":"api/basic_json_view/#comparison","title":"Comparison","text":"
    • operator== - comparison: equal
    • operator!= - comparison: not equal
    "},{"location":"api/basic_json_view/#serialization","title":"Serialization","text":"
    • dump - serialize to a JSON-formatted string
    • operator<< - serialize to stream
    "},{"location":"api/basic_json_view/#source-access","title":"Source access","text":"
    • source_offset - byte offset of this value in the document's source text
    "},{"location":"api/basic_json_view/#see-also","title":"See also","text":"
    • Zero-copy JSON views - guide to documents and views
    • basic_json_document - the document that owns the parsed data
    • json_view - and json_editable_view - the default specializations
    • materialize - build a basic_json value from a view
    "},{"location":"api/basic_json_view/#version-history","title":"Version history","text":"
    • Added in version 3.13.0 unreleased.
    "},{"location":"api/basic_json_view/at/","title":"nlohmann::basic_json_view::at","text":"
    // (1)\nbasic_json_view at(string_view_t key) const;\nbasic_json_view at(const char* key) const;\nbasic_json_view at(const string_t& key) const;\n\n// (2)\nbasic_json_view at(size_type idx) const;\ntemplate<typename IntegerType>\nbasic_json_view at(IntegerType idx) const;\n\n// (3)\nbasic_json_view at(const json_pointer& ptr) const;\n
    1. Returns the value of the object member with key key \u2014 the first one, should the key occur more than once (see Notes on duplicate keys).
    2. Returns the array element at index idx. The template accepts every integer type except bool and std::size_t and forwards to the size_type overload, as for operator[]; a negative idx is out of range.
    3. Returns the value a JSON pointer ptr refers to, starting at this value.
    "},{"location":"api/basic_json_view/at/#parameters","title":"Parameters","text":"key (in) object key of the element to access idx (in) index of the element to access ptr (in) JSON pointer to the element to access"},{"location":"api/basic_json_view/at/#return-value","title":"Return value","text":"
    1. the value of the first member with key key
    2. the element at index idx
    3. the value ptr resolves to, starting at this value
    "},{"location":"api/basic_json_view/at/#exception-safety","title":"Exception safety","text":"

    Strong guarantee: there are no changes to the view or the document it refers to.

    "},{"location":"api/basic_json_view/at/#exceptions","title":"Exceptions","text":"
    1. The function can throw the following exceptions, both with the same message as the corresponding call to BasicJsonType::at:
      • Throws type_error.304 if the value is not an object.
      • Throws out_of_range.403 if no member has key key.
    2. The function can throw the following exceptions, both with the same message as the corresponding call to BasicJsonType::at:
      • Throws type_error.304 if the value is not an array.
      • Throws out_of_range.401 if idx >= size().
    3. The function can throw the following exceptions, all with the same message as the corresponding call to BasicJsonType::at:
      • Throws parse_error.106 if an array index in ptr begins with '0'.
      • Throws parse_error.109 if an array index in ptr is not a number.
      • Throws out_of_range.401 if an array index in ptr is out of range.
      • Throws out_of_range.402 if a reference token is \"-\" at an array \u2014 at never inserts an element, so \"-\" is always invalid.
      • Throws out_of_range.403 if a reference token names an object member that does not exist.
      • Throws out_of_range.404 if ptr cannot be resolved because a reference token is used on a primitive value.

    None of these exceptions carry a JSON_DIAGNOSTICS path: the view has no BasicJsonType value to point at, so the exception is created without one, even if BasicJsonType was built with JSON_DIAGNOSTICS enabled.

    "},{"location":"api/basic_json_view/at/#complexity","title":"Complexity","text":"
    1. Linear in the number of members: as for ordered_json, members are compared one after another, in document order, stopping at the first match. Each comparison first checks the key's length \u2014 already known from the index, without reading the key bytes \u2014 before comparing its content. Objects with 128 or more members get a hash index of their keys while parsing, so that a lookup in them takes constant time on average.
    2. Linear in idx: elements are skipped one at a time from the first one, since they are not a fixed size in the index (unlike BasicJsonType's array, which is random-access). Constant if no element of the array is an array or object, since the elements are then adjacent in the index.
    3. Linear in the number of reference tokens of ptr and, for each token, in the number of members of the object at that level (as 1.) or the index into the array (as 2.).
    "},{"location":"api/basic_json_view/at/#notes","title":"Notes","text":"

    Duplicate keys: the first member wins

    If the source text repeats a key, this resolves to the first member with it, not to the last one that materialize() and parse() keep. See the Notes on duplicate keys of operator[] and Duplicate keys for the reasons and for how to get the last value.

    Unlike operator[], which returns a discarded view for a missing key or an out-of-range index, at always throws \u2014 exactly as BasicJsonType::at does, and with the same messages, so existing error handling written against BasicJsonType::at keeps working unchanged when switched to a view. This also holds for overload 3: unlike operator[] with a JSON pointer, which returns a discarded view for a missing key or an out-of-range index, at throws for those too (out_of_range.403/out_of_range.401).

    "},{"location":"api/basic_json_view/at/#examples","title":"Examples","text":"Example: (1)/(2) access specified element with bounds checking

    The example below reads required fields out of a service configuration with at, and shows that the exceptions it throws \u2014 for a wrong type and for a missing key \u2014 carry the same messages BasicJsonType::at would produce for the same JSON text.

    #include <iostream>\n#include <nlohmann/json_view.hpp>\n\nusing nlohmann::json_document;\nusing nlohmann::json_view;\n\nint main()\n{\n    // required fields of a service configuration -- at() reports a missing\n    // or wrong-typed field with the very same exception basic_json::at()\n    // would throw for the equivalent nlohmann::json value, so error\n    // handling written against basic_json::at() keeps working unchanged\n    json_document config = json_document::parse(R\"({\"name\": \"cache\", \"port\": \"6379\"})\");\n    const json_view service = config.root();\n\n    std::cout << service.at(\"port\").materialize().dump() << '\\n';\n\n    try\n    {\n        // \"port\" is a string, not an array\n        static_cast<void>(service.at(\"port\").at(0));\n    }\n    catch (const nlohmann::json::type_error& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n\n    try\n    {\n        static_cast<void>(service.at(\"timeout\"));\n    }\n    catch (const nlohmann::json::out_of_range& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n}\n

    Output:

    \"6379\"\n[json.exception.type_error.304] cannot use at() with string\n[json.exception.out_of_range.403] key 'timeout' not found\n
    Example: (3) access specified element via JSON pointer with bounds checking

    The example below shows that at with a JSON pointer throws exactly the exceptions, with exactly the messages, that BasicJsonType::at throws for the same pointer and the same document.

    #include <iostream>\n#include <nlohmann/json_view.hpp>\n\nusing nlohmann::json_document;\nusing json_pointer = nlohmann::json::json_pointer;\n\nint main()\n{\n    json_document doc = json_document::parse(R\"({\"region\": \"eu\", \"servers\": [\"eu-1\", \"eu-2\"]})\");\n    const auto root = doc.root();\n\n    std::cout << root.at(json_pointer(\"/servers/1\")).materialize().dump() << '\\n';\n\n    // at() throws for every resolution failure -- with the very same\n    // message json::at(ptr) would throw for the same pointer and the same\n    // document\n    try\n    {\n        static_cast<void>(root.at(json_pointer(\"/servers/5\")));\n    }\n    catch (const nlohmann::json::out_of_range& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n\n    try\n    {\n        static_cast<void>(root.at(json_pointer(\"/missing\")));\n    }\n    catch (const nlohmann::json::out_of_range& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n}\n

    Output:

    \"eu-2\"\n[json.exception.out_of_range.401] array index 5 is out of range\n[json.exception.out_of_range.403] key 'missing' not found\n
    "},{"location":"api/basic_json_view/at/#see-also","title":"See also","text":"
    • operator[] - access specified element (returns a discarded view instead of throwing)
    • front, back - access the first or last element
    • BasicJsonType::at - the corresponding function of basic_json
    • json_pointer - JSON pointer type used by overload 3
    "},{"location":"api/basic_json_view/at/#version-history","title":"Version history","text":"
    • Added in version 3.13.0 unreleased.
    "},{"location":"api/basic_json_view/back/","title":"nlohmann::basic_json_view::back","text":"
    basic_json_view back() const;\n

    Returns the last element of an array, the last member value of an object, or the value itself if it is primitive (as for BasicJsonType::back(), a primitive value is a range of one element).

    "},{"location":"api/basic_json_view/back/#return-value","title":"Return value","text":"

    The last element or member value. For a primitive value (number, string, boolean), the value itself.

    "},{"location":"api/basic_json_view/back/#exception-safety","title":"Exception safety","text":"

    Strong guarantee: there are no changes to the view or the document it refers to.

    "},{"location":"api/basic_json_view/back/#exceptions","title":"Exceptions","text":"

    Throws invalid_iterator.214 if the view is null or discarded, or if it is an empty array or object.

    This exception does not carry a JSON_DIAGNOSTICS path: the view has no BasicJsonType value to point at, so the exception is created without one, even if BasicJsonType was built with JSON_DIAGNOSTICS enabled.

    "},{"location":"api/basic_json_view/back/#complexity","title":"Complexity","text":"

    Linear in the size of the array or object: unlike front(), which only ever looks at the first element, back() has to walk every element to find where they end, since elements are not a fixed size in the index. Constant if no element of the array is an array or object, since the elements are then adjacent in the index.

    "},{"location":"api/basic_json_view/back/#notes","title":"Notes","text":"

    Unlike BasicJsonType::back(), which has undefined behavior for an empty array or object, back() throws invalid_iterator.214 for an empty array, an empty object, a null value, or a discarded view.

    "},{"location":"api/basic_json_view/back/#examples","title":"Examples","text":"Example

    The example below reads only the final status of a build log with back(). Even though back() is linear in the number of events (unlike front(), which is constant), it still avoids building a BasicJsonType value for the events that are not needed.

    #include <iostream>\n#include <nlohmann/json_view.hpp>\n\nusing nlohmann::json_document;\n\nint main()\n{\n    // the same build log; back() reads only the final status. It is linear\n    // in the number of events (unlike front(), which is constant), but\n    // still far less work than materializing the whole array\n    json_document log = json_document::parse(R\"([\"queued\", \"started\", \"compiling\", \"linking\", \"done\"])\");\n    std::cout << log.root().back().materialize().dump() << '\\n';\n\n    // an empty log -- back() throws instead of the undefined behavior\n    // basic_json::back() has for an empty array\n    json_document empty_log = json_document::parse(\"[]\");\n    try\n    {\n        static_cast<void>(empty_log.root().back());\n    }\n    catch (const nlohmann::json::invalid_iterator& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n}\n

    Output:

    \"done\"\n[json.exception.invalid_iterator.214] cannot get value\n
    "},{"location":"api/basic_json_view/back/#see-also","title":"See also","text":"
    • front - access the first element
    • BasicJsonType::back - the corresponding function of basic_json
    "},{"location":"api/basic_json_view/back/#version-history","title":"Version history","text":"
    • Added in version 3.13.0 unreleased.
    "},{"location":"api/basic_json_view/basic_json_view/","title":"nlohmann::basic_json_view::basic_json_view","text":"
    // (1)\nbasic_json_view() noexcept = default;\n\n// (2) only for Mode == view_mode::editable\nbasic_json_view(const basic_json_view<BasicJsonType, view_mode::read_only>& other) noexcept;\n
    1. Creates an invalid (discarded) view: type() is value_t::discarded and is_discarded() is true.
    2. Converts a view of a read-only document into a view of an editable document (implicitly), so that a function taking a json_editable_view accepts both. The result is a view of the same value of the same read-only document. See view_mode for why there is no conversion the other way.
    "},{"location":"api/basic_json_view/basic_json_view/#parameters","title":"Parameters","text":"other (in) a view of a read-only document with the same BasicJsonType

    Apart from these, a view is obtained from a basic_json_document, via root() or by navigating into a container with operator[], at, front, back, find, or iteration.

    "},{"location":"api/basic_json_view/basic_json_view/#exception-safety","title":"Exception safety","text":"

    No-throw guarantee: these constructors never throw exceptions.

    "},{"location":"api/basic_json_view/basic_json_view/#complexity","title":"Complexity","text":"

    Constant.

    "},{"location":"api/basic_json_view/basic_json_view/#notes","title":"Notes","text":"

    basic_json_view is trivially copyable (it holds two pointers), so a default-constructed view can be used as a placeholder for \"no value yet\" and later be assigned a real view.

    "},{"location":"api/basic_json_view/basic_json_view/#examples","title":"Examples","text":"Example

    The example below shows the default constructor and that a basic_json_view is a small, copyable handle.

    #include <iostream>\n#include <nlohmann/json_view.hpp>\n\nint main()\n{\n    std::cout << std::boolalpha;\n\n    // the default constructor is the only public one: it creates an invalid\n    // (discarded) view, useful as a \"no value yet\" placeholder\n    nlohmann::json_view v;\n    std::cout << v.is_discarded() << '\\n';\n\n    // views are trivially copyable handles (two pointers); the document owns\n    // the actual data\n    nlohmann::json_view copy = v;\n    std::cout << copy.is_discarded() << '\\n';\n}\n

    Output:

    true\ntrue\n
    "},{"location":"api/basic_json_view/basic_json_view/#see-also","title":"See also","text":"
    • is_discarded - return whether the view is invalid
    • root - the view of a document's root value
    • view_mode - whether a document and its views can be edited
    • Zero-copy JSON views - how long a view stays valid
    "},{"location":"api/basic_json_view/basic_json_view/#version-history","title":"Version history","text":"
    • Added in version 3.13.0 unreleased.
    "},{"location":"api/basic_json_view/begin/","title":"nlohmann::basic_json_view::begin","text":"
    iterator begin() const noexcept;\n

    Returns an iterator to the first element of an array, or the first member value of an object, in document order \u2014 the order the values appear in the source text, not sorted by key. A primitive value iterates as a range of one element (itself), and a null value or a discarded view iterates as an empty range.

    "},{"location":"api/basic_json_view/begin/#return-value","title":"Return value","text":"

    Iterator to the first element.

    "},{"location":"api/basic_json_view/begin/#exception-safety","title":"Exception safety","text":"

    No-throw guarantee: this function never throws exceptions.

    "},{"location":"api/basic_json_view/begin/#complexity","title":"Complexity","text":"

    Constant.

    "},{"location":"api/basic_json_view/begin/#notes","title":"Notes","text":"

    For an object, iteration visits every member, including all occurrences of a duplicate key \u2014 unlike operator[], at, find, and contains, which all resolve to the first member with a given key. See the Notes on duplicate keys of operator[].

    Because objects are iterated in document order rather than sorted by key, the order seen here can differ from what iterating the materialize()d BasicJsonType value would produce: a basic_json object (std::map-backed by default) sorts its keys, while a view does not.

    An ordered_json value also keeps document order, but it keeps only one entry per key: as parse() does, it keeps the last value, at the position of the key's first occurrence. The view, in contrast, visits every member, including the duplicates.

    "},{"location":"api/basic_json_view/begin/#examples","title":"Examples","text":"Example

    The example below iterates a log record's members with begin()/end() and prints them in the order they were written. Materializing the record into a BasicJsonType object and iterating that would instead print the members sorted by key.

    #include <iostream>\n#include <nlohmann/json_view.hpp>\n\nusing nlohmann::json_document;\n\nint main()\n{\n    // a log record: the fields matter in the order they were written, e.g.\n    // to reproduce the record as it was logged. A nlohmann::json object\n    // sorts its keys, so materializing and iterating it would instead print\n    // them alphabetically (\"level\", \"message\", \"time\")\n    json_document record = json_document::parse(R\"({\"time\": \"10:00:01\", \"level\": \"info\", \"message\": \"started\"})\");\n\n    for (auto it = record.root().begin(); it != record.root().end(); ++it)\n    {\n        std::cout << it.key() << '=' << it->materialize().dump() << '\\n';\n    }\n}\n

    Output:

    time=\"10:00:01\"\nlevel=\"info\"\nmessage=\"started\"\n
    "},{"location":"api/basic_json_view/begin/#see-also","title":"See also","text":"
    • end - returns an iterator to one past the last element
    • cbegin - returns a const iterator to the first element
    • items - access iterator member functions in range-based for
    • BasicJsonType::begin - the corresponding function of basic_json
    "},{"location":"api/basic_json_view/begin/#version-history","title":"Version history","text":"
    • Added in version 3.13.0 unreleased.
    "},{"location":"api/basic_json_view/cbegin/","title":"nlohmann::basic_json_view::cbegin","text":"
    iterator cbegin() const noexcept;\n

    Returns an iterator to the first element, in document order. Equivalent to begin(): a view is always read-only, so const_iterator and iterator are the same type, and cbegin() exists only so that generic code that expects a cbegin()/cend() pair works with a view too.

    "},{"location":"api/basic_json_view/cbegin/#return-value","title":"Return value","text":"

    Iterator to the first element; identical to what begin() returns.

    "},{"location":"api/basic_json_view/cbegin/#exception-safety","title":"Exception safety","text":"

    No-throw guarantee: this function never throws exceptions.

    "},{"location":"api/basic_json_view/cbegin/#complexity","title":"Complexity","text":"

    Constant.

    "},{"location":"api/basic_json_view/cbegin/#examples","title":"Examples","text":"Example

    The example below sums many measurements with std::accumulate, using cbegin()/cend() as the range \u2014 the same way it would for any standard container \u2014 without ever materializing the whole array into a BasicJsonType value.

    #include <iostream>\n#include <numeric>\n#include <nlohmann/json_view.hpp>\n\nusing nlohmann::json_document;\nusing nlohmann::json_view;\n\nint main()\n{\n    // sum many measurements with std::accumulate; cbegin()/cend() (identical\n    // to begin()/end() here -- the view is always read-only) let the view be\n    // used with standard algorithms without ever materializing the whole\n    // array into a nlohmann::json value\n    json_document measurements = json_document::parse(\"[3, 1, 4, 1, 5, 9, 2, 6]\");\n    const auto values = measurements.root();\n\n    const int sum = std::accumulate(values.cbegin(), values.cend(), 0,\n                                    [](int total, const json_view & v)\n    {\n        return total + v.materialize().get<int>();\n    });\n\n    std::cout << sum << '\\n';\n}\n

    Output:

    31\n
    "},{"location":"api/basic_json_view/cbegin/#see-also","title":"See also","text":"
    • begin - returns an iterator to the first element
    • cend - returns a const iterator to one past the last element
    • BasicJsonType::cbegin - the corresponding function of basic_json
    "},{"location":"api/basic_json_view/cbegin/#version-history","title":"Version history","text":"
    • Added in version 3.13.0 unreleased.
    "},{"location":"api/basic_json_view/cend/","title":"nlohmann::basic_json_view::cend","text":"
    iterator cend() const noexcept;\n

    Returns an iterator to one past the last element, in document order. Equivalent to end(): a view is always read-only, so const_iterator and iterator are the same type, and cend() exists only so that generic code that expects a cbegin()/cend() pair works with a view too.

    "},{"location":"api/basic_json_view/cend/#return-value","title":"Return value","text":"

    Iterator one past the last element; identical to what end() returns.

    "},{"location":"api/basic_json_view/cend/#exception-safety","title":"Exception safety","text":"

    No-throw guarantee: this function never throws exceptions.

    "},{"location":"api/basic_json_view/cend/#complexity","title":"Complexity","text":"

    Constant.

    "},{"location":"api/basic_json_view/cend/#examples","title":"Examples","text":"Example

    The example below checks that every record of a batch is an object with std::all_of, using cbegin()/cend() as the range \u2014 the same way it would for any standard container \u2014 before materializing any record of the batch.

    #include <algorithm>\n#include <iostream>\n#include <nlohmann/json_view.hpp>\n\nusing nlohmann::json_document;\nusing nlohmann::json_view;\n\nint main()\n{\n    // check that every element of a (possibly large) batch is an object,\n    // before materializing any of them -- cbegin()/cend() (identical to\n    // begin()/end() here) work as the range for std::all_of like they would\n    // for any standard container\n    json_document batch = json_document::parse(R\"([{\"id\": 1}, {\"id\": 2}, {\"id\": 3}])\");\n    const auto records = batch.root();\n\n    const bool all_objects = std::all_of(records.cbegin(), records.cend(),\n                                         [](const json_view & v)\n    {\n        return v.is_object();\n    });\n\n    std::cout << std::boolalpha << all_objects << '\\n';\n}\n

    Output:

    true\n
    "},{"location":"api/basic_json_view/cend/#see-also","title":"See also","text":"
    • end - returns an iterator to one past the last element
    • cbegin - returns a const iterator to the first element
    • BasicJsonType::cend - the corresponding function of basic_json
    "},{"location":"api/basic_json_view/cend/#version-history","title":"Version history","text":"
    • Added in version 3.13.0 unreleased.
    "},{"location":"api/basic_json_view/contains/","title":"nlohmann::basic_json_view::contains","text":"
    // (1)\nbool contains(string_view_t key) const;\nbool contains(const char* key) const;\nbool contains(const string_t& key) const;\n\n// (2)\nbool contains(const json_pointer& ptr) const;\n
    1. Checks whether the value is an object with a member with key key.
    2. Checks whether a JSON pointer ptr can be resolved, starting at this value.
    "},{"location":"api/basic_json_view/contains/#parameters","title":"Parameters","text":"key (in) key value to check its existence ptr (in) JSON pointer to check its existence"},{"location":"api/basic_json_view/contains/#return-value","title":"Return value","text":"
    1. true if the value is an object and has a member with key key, false otherwise
    2. true if ptr can be resolved to a value starting at this view, false otherwise
    "},{"location":"api/basic_json_view/contains/#exception-safety","title":"Exception safety","text":"

    No-throw guarantee: this function never throws exceptions.

    "},{"location":"api/basic_json_view/contains/#complexity","title":"Complexity","text":"
    1. Linear in the number of members: as for ordered_json, members are compared one after another, in document order, stopping at the first match. Each comparison first checks the key's length \u2014 already known from the index, without reading the key bytes \u2014 before comparing its content. Objects with 128 or more members get a hash index of their keys while parsing, so that a lookup in them takes constant time on average.
    2. Linear in the number of reference tokens of ptr and, for each token, in the number of members of the object at that level or the index into the array \u2014 as for operator[] and at with a JSON pointer.
    "},{"location":"api/basic_json_view/contains/#notes","title":"Notes","text":"

    Duplicate keys: the first member wins

    If the source text repeats a key, this resolves to the first member with it, not to the last one that materialize() and parse() keep. See the Notes on duplicate keys of operator[] and Duplicate keys for the reasons and for how to get the last value.

    Overload 1 always returns false when the value is not an object \u2014 including a discarded view.

    Postconditions

    If v.contains(key) returns true, then v[key] is not discarded and v.at(key) does not throw. If v.contains(ptr) returns true, then v[ptr] is not discarded and v.at(ptr) does not throw.

    Overload 2 never throws

    Unlike BasicJsonType::contains(const json_pointer&), which can throw for certain malformed pointers (for instance an empty array-index reference token), overload 2 never throws: a missing key, an out-of-range or malformed array index, a \"-\" index, or a reference token used on a primitive all simply make it return false.

    "},{"location":"api/basic_json_view/contains/#examples","title":"Examples","text":"Example: (1) check with key

    The example below counts how many of a batch of records carry an optional retry_of field, using contains() to check without ever materializing a single record of the batch.

    #include <iostream>\n#include <nlohmann/json_view.hpp>\n\nusing nlohmann::json_document;\n\nint main()\n{\n    // count how many of many incoming records carry an optional \"retry_of\"\n    // field -- contains() only walks the flat index, so scanning a large\n    // batch like this never builds a single nlohmann::json value\n    json_document batch = json_document::parse(R\"(\n      [\n        {\"id\": 1},\n        {\"id\": 2, \"retry_of\": 1},\n        {\"id\": 3},\n        {\"id\": 4, \"retry_of\": 3}\n      ]\n    )\");\n\n    const auto records = batch.root();\n    std::size_t retries = 0;\n    for (std::size_t i = 0; i < records.size(); ++i)\n    {\n        if (records[i].contains(\"retry_of\"))\n        {\n            ++retries;\n        }\n    }\n    std::cout << retries << \" of \" << records.size() << \" records are retries\\n\";\n}\n

    Output:

    2 of 4 records are retries\n
    Example: (2) check with JSON pointer

    The example below checks an optional, nested field with a JSON pointer, and shows two pointers that contains() resolves to false without throwing.

    #include <iostream>\n#include <nlohmann/json_view.hpp>\n\nusing nlohmann::json_document;\nusing json_pointer = nlohmann::json::json_pointer;\n\nint main()\n{\n    // \"retry_of\" is only present on some records, nested a level down\n    // inside \"meta\"\n    json_document batch = json_document::parse(R\"(\n      [\n        {\"id\": 1, \"meta\": {}},\n        {\"id\": 2, \"meta\": {\"retry_of\": 1}}\n      ]\n    )\");\n\n    const auto records = batch.root();\n    const json_pointer retry_of(\"/meta/retry_of\");\n    for (std::size_t i = 0; i < records.size(); ++i)\n    {\n        const auto record = records[i];\n        if (record.contains(retry_of))\n        {\n            std::cout << \"record \" << i << \" is a retry of \" << record[retry_of].get<int>() << '\\n';\n        }\n        else\n        {\n            std::cout << \"record \" << i << \" is original\\n\";\n        }\n    }\n\n    // contains() with a JSON pointer never throws -- not even for a\n    // pointer that indexes into a primitive (\"/0/id/x\") or uses a\n    // malformed array index (\"/01\"), either of which would need a\n    // try/catch with json::contains(ptr)\n    std::cout << std::boolalpha << records.contains(json_pointer(\"/0/id/x\")) << '\\n';\n    std::cout << std::boolalpha << records.contains(json_pointer(\"/01\")) << '\\n';\n}\n

    Output:

    record 0 is original\nrecord 1 is a retry of 1\nfalse\nfalse\n
    "},{"location":"api/basic_json_view/contains/#see-also","title":"See also","text":"
    • find - find a value in an object
    • count - returns the number of occurrences of a key
    • at, operator[] - resolve a JSON pointer and throw, or return a discarded view
    • BasicJsonType::contains - the corresponding function of basic_json
    "},{"location":"api/basic_json_view/contains/#version-history","title":"Version history","text":"
    • Added in version 3.13.0 unreleased.
    "},{"location":"api/basic_json_view/count/","title":"nlohmann::basic_json_view::count","text":"
    size_type count(string_view_t key) const;\nsize_type count(const char* key) const;\nsize_type count(const string_t& key) const;\n

    Returns the number of members with key key if the value is an object, 0 otherwise. Members with a repeated key are all counted.

    "},{"location":"api/basic_json_view/count/#parameters","title":"Parameters","text":"key (in) key value of the element to count"},{"location":"api/basic_json_view/count/#return-value","title":"Return value","text":"

    the number of members of the object with key key (duplicates included), or 0 if the value is not an object or has no such member.

    "},{"location":"api/basic_json_view/count/#exception-safety","title":"Exception safety","text":"

    No-throw guarantee: this function never throws exceptions.

    "},{"location":"api/basic_json_view/count/#complexity","title":"Complexity","text":"

    Linear in the number of members: unlike the lookup functions, count() does not stop at the first match, because it has to count every member with the key. Members are compared one after another, in document order. Each comparison first checks the key's length \u2014 already known from the index, without reading the key bytes \u2014 before comparing its content. The hash index of the keys of objects with 128 or more members does not help here, since every member is visited.

    "},{"location":"api/basic_json_view/count/#notes","title":"Notes","text":"

    This method always returns 0 when the value is not an object \u2014 including a discarded view.

    If the source text repeats a key, count() returns more than 1 for it, even though the materialized value (like the result of parse()) would have only one member with that key. Hence count(key) > 1 detects duplicate keys. This is unlike the lookup functions (operator[], at, find, contains), which resolve to the first member; see the Notes on duplicate keys of operator[].

    "},{"location":"api/basic_json_view/count/#examples","title":"Examples","text":"Example

    The example below validates that every transaction of a batch carries exactly one amount field, using count() before deciding whether to materialize a transaction at all. It reports a transaction with no amount field and one with a duplicated amount field.

    #include <iostream>\n#include <nlohmann/json_view.hpp>\n\nusing nlohmann::json_document;\n\nint main()\n{\n    // validate that every transaction of a batch carries exactly one\n    // \"amount\" field before materializing any of them into a nlohmann::json\n    // value -- count() counts every member with the key\n    json_document batch = json_document::parse(R\"(\n      [\n        {\"id\": 1, \"amount\": 9.99},\n        {\"id\": 2},\n        {\"id\": 3, \"amount\": 5.00, \"amount\": 500.00}\n      ]\n    )\");\n\n    const auto transactions = batch.root();\n    for (std::size_t i = 0; i < transactions.size(); ++i)\n    {\n        const auto transaction = transactions[i];\n        const auto amounts = transaction.count(\"amount\");\n        if (amounts != 1)\n        {\n            std::cout << \"transaction \" << i << \" has \" << amounts << \" \\\"amount\\\" fields\\n\";\n            continue;\n        }\n        std::cout << \"transaction \" << i << \": \" << transaction[\"amount\"].materialize().dump() << '\\n';\n    }\n}\n

    Output:

    transaction 0: 9.99\ntransaction 1 has 0 \"amount\" fields\ntransaction 2 has 2 \"amount\" fields\n
    "},{"location":"api/basic_json_view/count/#see-also","title":"See also","text":"
    • find - find a value in an object
    • contains - checks whether a key exists
    • BasicJsonType::count - the corresponding function of basic_json
    "},{"location":"api/basic_json_view/count/#version-history","title":"Version history","text":"
    • Added in version 3.13.0 unreleased.
    "},{"location":"api/basic_json_view/dump/","title":"nlohmann::basic_json_view::dump","text":"
    string_t dump(const int indent = -1,\n              const char indent_char = ' ',\n              const bool ensure_ascii = false,\n              const number_format numbers = number_format::shortest) const;\n

    Serializes this value (and its subtree) directly from the flat index, without ever building a BasicJsonType value first. With the default numbers == number_format::shortest, the result is the same string BasicJsonType::dump would produce for the value BasicJsonType::parse() builds from the same source text, called with the same indent, indent_char, and ensure_ascii \u2014 except that members of an object appear in document order rather than sorted by key, and every occurrence of a repeated key is written rather than only the last one (see Notes on duplicate keys). For a json_view (whose BasicJsonType is not ordered), this means dump() can print an object's members in a different order than materialize().dump() of the same subtree.

    "},{"location":"api/basic_json_view/dump/#parameters","title":"Parameters","text":"indent (in) If indent is nonnegative, array elements and object members are pretty-printed with that indent level. An indent level of 0 only inserts newlines. -1 (the default) selects the most compact representation. indent_char (in) The character used for indentation if indent is greater than 0. The default is (space). ensure_ascii (in) If ensure_ascii is true, all non-ASCII characters in the output are escaped with \\uXXXX sequences, and the result consists of ASCII characters only. numbers (in) how to write numbers, see number_format: shortest (the default) writes them the way BasicJsonType::dump would; source copies every number exactly as it appears in the source text."},{"location":"api/basic_json_view/dump/#return-value","title":"Return value","text":"

    string containing the serialization of this value, or \"<discarded>\" if the view is discarded.

    "},{"location":"api/basic_json_view/dump/#exception-safety","title":"Exception safety","text":"

    Strong exception safety: if an exception is thrown, there are no changes to the view or the document it refers to.

    "},{"location":"api/basic_json_view/dump/#exceptions","title":"Exceptions","text":"

    May throw std::bad_alloc if allocating the output string fails. Unlike BasicJsonType::dump, there is no error_handler parameter and no type_error.316: the view only ever holds text the parser already validated as UTF-8, so there is nothing to replace or ignore.

    "},{"location":"api/basic_json_view/dump/#complexity","title":"Complexity","text":"

    Linear in the size of the output text.

    "},{"location":"api/basic_json_view/dump/#notes","title":"Notes","text":"

    The walk over the subtree is iterative, so the nesting depth it can write is limited by available memory only, not by the call stack \u2014 as for materialize().

    Strings are escaped by the same rules as BasicJsonType::dump.

    With numbers == number_format::shortest, floats are written with the library's shortest round-trip conversion, exactly as BasicJsonType::dump would (e.g. 1.5, 100.0, 1e+100), and integers are copied from the source text \u2014 already canonical in JSON, so this matches their shortest form too \u2014 except that -0 is written as 0, the way BasicJsonType::parse() reads it.

    number_format::source copies every number exactly as written in the source text instead, with no exception for -0 \u2014 1.50, 1E2, -0.0, -0, or all digits of an integer literal with more digits than any number type holds (such a literal is itself classified as a float, see What is different) \u2014 something BasicJsonType cannot do, since parsing already reduces every number to its parsed value.

    "},{"location":"api/basic_json_view/dump/#examples","title":"Examples","text":"Example

    The example below forwards a single record out of a larger batch, and re-serializes a configuration file, both without ever building a BasicJsonType value for the surrounding array or for the parts of it that were not needed. It also shows that materialize().dump() of the configuration sorts its keys, where dump() on the view keeps the order they appear in the source text.

    #include <iostream>\n#include <nlohmann/json_view.hpp>\n\nusing nlohmann::json_document;\nusing nlohmann::json_view;\n\nint main()\n{\n    // a large batch of sensor readings -- forward just the one that changed,\n    // without ever building a basic_json value for the batch or for the\n    // readings that are not needed\n    const json_document batch = json_document::parse(R\"(\n      [{\"id\": 1, \"temp\": 21.5}, {\"id\": 2, \"temp\": 87.3}, {\"id\": 3, \"temp\": 21.7}]\n    )\");\n    const json_view readings = batch.root();\n    std::cout << readings[1].dump() << '\\n';\n\n    // a configuration file -- dump() on the view keeps the member order of\n    // the source text; a json value's object_t is std::map, so\n    // materialize().dump() of the very same view sorts the keys instead\n    const json_document config = json_document::parse(\n                                     R\"({\"name\": \"cache\", \"host\": \"db1\", \"port\": 6379, \"timeout\": 30})\");\n    std::cout << config.root().dump(2) << \"\\n\\n\";\n    std::cout << config.root().materialize().dump(2) << '\\n';\n}\n

    Output:

    {\"id\":2,\"temp\":87.3}\n{\n  \"name\": \"cache\",\n  \"host\": \"db1\",\n  \"port\": 6379,\n  \"timeout\": 30\n}\n\n{\n  \"host\": \"db1\",\n  \"name\": \"cache\",\n  \"port\": 6379,\n  \"timeout\": 30\n}\n
    "},{"location":"api/basic_json_view/dump/#see-also","title":"See also","text":"
    • number_format - how dump() writes numbers
    • operator<< - serialize this value to a stream
    • materialize - build a BasicJsonType value, e.g. to use BasicJsonType::dump's error_handler
    • BasicJsonType::dump - the corresponding function of basic_json
    • Zero-copy JSON views - writing a view back without building a tree
    "},{"location":"api/basic_json_view/dump/#version-history","title":"Version history","text":"
    • Added in version 3.13.0 unreleased.
    "},{"location":"api/basic_json_view/empty/","title":"nlohmann::basic_json_view::empty","text":"
    bool empty() const noexcept;\n

    Checks whether size() is 0, as BasicJsonType::empty() would for the same value.

    "},{"location":"api/basic_json_view/empty/#return-value","title":"Return value","text":"

    The return value depends on the type and is defined as follows:

    Value type return value null true discarded true boolean false string false number false object object_t::empty() array array_t::empty()"},{"location":"api/basic_json_view/empty/#exception-safety","title":"Exception safety","text":"

    No-throw guarantee: this function never throws exceptions.

    "},{"location":"api/basic_json_view/empty/#complexity","title":"Complexity","text":"

    Constant.

    "},{"location":"api/basic_json_view/empty/#notes","title":"Notes","text":"

    As for BasicJsonType::empty(), this does not return whether a string value is empty \u2014 it is false for any string, regardless of its length.

    "},{"location":"api/basic_json_view/empty/#examples","title":"Examples","text":"Example

    The example below uses size() and empty() to decide whether a parsed message is worth acting on, without materializing it into a BasicJsonType value.

    #include <iostream>\n#include <nlohmann/json_view.hpp>\n\nusing nlohmann::json_document;\n\nint main()\n{\n    std::cout << std::boolalpha;\n\n    // decide whether a batch is worth processing before building any\n    // nlohmann::json value for it\n    json_document batch = json_document::parse(R\"([1, 2, 3, 4, 5])\");\n    json_document empty_batch = json_document::parse(\"[]\");\n\n    std::cout << batch.root().empty() << ' ' << batch.root().size() << '\\n';\n    std::cout << empty_batch.root().empty() << ' ' << empty_batch.root().size() << '\\n';\n\n    // as for basic_json: null has size 0, every other scalar has size 1\n    json_document n = json_document::parse(\"null\");\n    json_document s = json_document::parse(R\"(\"hi\")\");\n    std::cout << n.root().size() << ' ' << s.root().size() << '\\n';\n}\n

    Output:

    false 5\ntrue 0\n0 1\n
    "},{"location":"api/basic_json_view/empty/#see-also","title":"See also","text":"
    • size - return the number of elements
    • BasicJsonType::empty - the corresponding function of basic_json
    "},{"location":"api/basic_json_view/empty/#version-history","title":"Version history","text":"
    • Added in version 3.13.0 unreleased.
    "},{"location":"api/basic_json_view/end/","title":"nlohmann::basic_json_view::end","text":"
    iterator end() const noexcept;\n

    Returns an iterator to one past the last element of an array, one past the last member value of an object, in document order \u2014 see begin(). A primitive value iterates as a range of one element (itself), and a null value or a discarded view iterates as an empty range (begin() == end()).

    "},{"location":"api/basic_json_view/end/#return-value","title":"Return value","text":"

    Iterator one past the last element.

    "},{"location":"api/basic_json_view/end/#exception-safety","title":"Exception safety","text":"

    No-throw guarantee: this function never throws exceptions.

    "},{"location":"api/basic_json_view/end/#complexity","title":"Complexity","text":"

    Constant.

    "},{"location":"api/basic_json_view/end/#notes","title":"Notes","text":"

    iterator is a forward iterator: unlike BasicJsonType::iterator, it cannot be decremented, so there is no way to reach the last element by stepping back from end(). Use back() instead.

    "},{"location":"api/basic_json_view/end/#examples","title":"Examples","text":"Example

    The example below scans a (possibly large) array of readings for the first one over a threshold, stopping the loop at end() as soon as one is found. Only the matching reading, if any, is ever materialized.

    #include <iostream>\n#include <nlohmann/json_view.hpp>\n\nusing nlohmann::json_document;\n\nint main()\n{\n    // scan a (possibly large) array of readings for the first one over a\n    // threshold; the loop stops at end() as soon as one is found, and only\n    // the matching reading is ever materialized\n    json_document readings = json_document::parse(\"[12, 18, 25, 31, 9]\");\n    const auto values = readings.root();\n\n    auto it = values.begin();\n    for (; it != values.end(); ++it)\n    {\n        if (it->materialize().get<int>() > 20)\n        {\n            break;\n        }\n    }\n\n    if (it != values.end())\n    {\n        std::cout << \"first reading over 20: \" << it->materialize().dump() << '\\n';\n    }\n}\n

    Output:

    first reading over 20: 25\n
    "},{"location":"api/basic_json_view/end/#see-also","title":"See also","text":"
    • begin - returns an iterator to the first element
    • cend - returns a const iterator to one past the last element
    • BasicJsonType::end - the corresponding function of basic_json
    "},{"location":"api/basic_json_view/end/#version-history","title":"Version history","text":"
    • Added in version 3.13.0 unreleased.
    "},{"location":"api/basic_json_view/find/","title":"nlohmann::basic_json_view::find","text":"
    iterator find(string_view_t key) const;\niterator find(const char* key) const;\niterator find(const string_t& key) const;\n

    Finds a member with key key \u2014 the first one, should the key occur more than once (see Notes on duplicate keys). If the value is not an object, or no member has this key, end() is returned.

    "},{"location":"api/basic_json_view/find/#parameters","title":"Parameters","text":"key (in) key value of the element to search for"},{"location":"api/basic_json_view/find/#return-value","title":"Return value","text":"

    An iterator to the member with key key, or end() if there is none or the value is not an object.

    "},{"location":"api/basic_json_view/find/#exception-safety","title":"Exception safety","text":"

    No-throw guarantee: this function never throws exceptions.

    "},{"location":"api/basic_json_view/find/#complexity","title":"Complexity","text":"

    Linear in the number of members: as for ordered_json, members are compared one after another, in document order, stopping at the first match. Each comparison first checks the key's length \u2014 already known from the index, without reading the key bytes \u2014 before comparing its content. Objects with 128 or more members get a hash index of their keys while parsing, so that a lookup in them takes constant time on average.

    "},{"location":"api/basic_json_view/find/#notes","title":"Notes","text":"

    Duplicate keys: the first member wins

    If the source text repeats a key, this resolves to the first member with it, not to the last one that materialize() and parse() keep. See the Notes on duplicate keys of operator[] and Duplicate keys for the reasons and for how to get the last value.

    Unlike BasicJsonType::find, which always returns end() for a non-object type, this also does so for a discarded view \u2014 there is no separate \"invalid\" iterator to return.

    "},{"location":"api/basic_json_view/find/#examples","title":"Examples","text":"Example

    The example below scans a batch of events for those that carry an optional user_id field, using find() instead of operator[] (which would throw for the events that are not objects at all) or contains() followed by a second lookup. Events without a match are never materialized.

    #include <iostream>\n#include <nlohmann/json_view.hpp>\n\nusing nlohmann::json_document;\n\nint main()\n{\n    // a batch of incoming events; only some carry a \"user_id\" -- find()\n    // locates it without throwing for the events that turn out to not be\n    // objects, and without materializing an event that does not match\n    json_document batch = json_document::parse(R\"(\n      [\n        {\"type\": \"click\", \"user_id\": 42},\n        {\"type\": \"ping\"},\n        {\"type\": \"click\", \"user_id\": 7}\n      ]\n    )\");\n\n    const auto events = batch.root();\n    for (std::size_t i = 0; i < events.size(); ++i)\n    {\n        const auto event = events[i];\n        const auto it = event.find(\"user_id\");\n        if (it != event.end())\n        {\n            std::cout << \"user \" << it->materialize().dump() << '\\n';\n        }\n    }\n}\n

    Output:

    user 42\nuser 7\n
    "},{"location":"api/basic_json_view/find/#see-also","title":"See also","text":"
    • count - returns the number of occurrences of a key
    • contains - checks whether a key exists
    • BasicJsonType::find - the corresponding function of basic_json
    "},{"location":"api/basic_json_view/find/#version-history","title":"Version history","text":"
    • Added in version 3.13.0 unreleased.
    "},{"location":"api/basic_json_view/front/","title":"nlohmann::basic_json_view::front","text":"
    basic_json_view front() const;\n

    Returns the first element of an array, the first member value of an object, or the value itself if it is primitive (as for BasicJsonType::front(), a primitive value is a range of one element).

    "},{"location":"api/basic_json_view/front/#return-value","title":"Return value","text":"

    The first element or member value. For a primitive value (number, string, boolean), the value itself.

    "},{"location":"api/basic_json_view/front/#exception-safety","title":"Exception safety","text":"

    Strong guarantee: there are no changes to the view or the document it refers to.

    "},{"location":"api/basic_json_view/front/#exceptions","title":"Exceptions","text":"

    Throws invalid_iterator.214 if the view is null or discarded, or if it is an empty array or object.

    This exception does not carry a JSON_DIAGNOSTICS path: the view has no BasicJsonType value to point at, so the exception is created without one, even if BasicJsonType was built with JSON_DIAGNOSTICS enabled.

    "},{"location":"api/basic_json_view/front/#complexity","title":"Complexity","text":"

    Constant.

    "},{"location":"api/basic_json_view/front/#notes","title":"Notes","text":"

    Unlike BasicJsonType::front(), which has undefined behavior for an empty array or object, front() throws invalid_iterator.214 for an empty array, an empty object, a null value, or a discarded view.

    "},{"location":"api/basic_json_view/front/#examples","title":"Examples","text":"Example

    The example below reads only the earliest entry of a build log with front(), without materializing the rest of the (possibly long) log.

    #include <iostream>\n#include <nlohmann/json_view.hpp>\n\nusing nlohmann::json_document;\n\nint main()\n{\n    // the build log of a running job; front() reads just the earliest event\n    // without materializing the (possibly long) rest of the log\n    json_document log = json_document::parse(R\"([\"queued\", \"started\", \"compiling\", \"linking\", \"done\"])\");\n    std::cout << log.root().front().materialize().dump() << '\\n';\n\n    // an empty log -- front() throws instead of the undefined behavior\n    // basic_json::front() has for an empty array\n    json_document empty_log = json_document::parse(\"[]\");\n    try\n    {\n        static_cast<void>(empty_log.root().front());\n    }\n    catch (const nlohmann::json::invalid_iterator& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n}\n

    Output:

    \"queued\"\n[json.exception.invalid_iterator.214] cannot get value\n
    "},{"location":"api/basic_json_view/front/#see-also","title":"See also","text":"
    • back - access the last element
    • BasicJsonType::front - the corresponding function of basic_json
    "},{"location":"api/basic_json_view/front/#version-history","title":"Version history","text":"
    • Added in version 3.13.0 unreleased.
    "},{"location":"api/basic_json_view/get/","title":"nlohmann::basic_json_view::get","text":"
    template<typename T>\nT get() const;\n

    Converts the value to T.

    For the types below, the conversion works directly on the flat index \u2014 no BasicJsonType value is built for it:

    • bool
    • arithmetic types other than bool (for a boolean, 0/1, exactly as for BasicJsonType::get<T>())
    • std::nullptr_t
    • std::basic_string<char, Traits, Alloc> (including string_t) \u2014 a copy of the string
    • string_view_t \u2014 no copy: the returned view points into the document's source() text, or, for a string that contains escape sequences, into the document's own buffer of decoded strings (see get_string())
    • BasicJsonType \u2014 equivalent to materialize()
    • basic_json_view \u2014 returns *this
    • std::vector<U, A> of the types above \u2014 from an array, element by element, each converted with get<U>(); std::vector<basic_json_view> keeps a view of every element instead of a value
    • std::map<K, basic_json_view, C, A> and std::unordered_map<K, basic_json_view, H, E, A>, if K is constructible from a (const char*, std::size_t) pair \u2014 views of the members of an object; with a repeated key, the view of the last member is kept, as BasicJsonType::parse() keeps its value

    A default-constructible T whose from_json() accepts views reads the view directly as well, without building a BasicJsonType value. This covers the library's own conversions of the standard library types \u2014 all other std::vectors, std::map/std::unordered_map (also with other key types), std::list, std::deque, std::set, std::forward_list, std::valarray, std::array, C arrays, std::pair, std::tuple, std::optional, enumerations, std::filesystem::path, ... -- which give the same values as materialize().get<T>() (from an object, a repeated key keeps the last value, as BasicJsonType::parse() does), as well as the types of the NLOHMANN_DEFINE_TYPE_* and NLOHMANN_DEFINE_DERIVED_TYPE_* macros and the enumerations of NLOHMANN_JSON_SERIALIZE_ENUM, and any from_json() constrained to accept views, e.g. with is_json_view. A from_json() that also accepts types that are no JSON values at all, such as the unconstrained template<typename BasicJsonType> void from_json(const BasicJsonType&,T&) of arbitrary type conversions, is not called with a view: it may use BasicJsonType functions a view does not have. See Writing generic code.

    Duplicate keys

    Such a from_json() looks members up in the view, where a repeated key finds the first member, while materialize().get<T>() sees the last one, as BasicJsonType::parse() keeps it: for {\"x\":1,\"x\":2}, get<point>() reads x == 1. See Duplicate keys.

    Every other T \u2014 user types whose from_json() is written for BasicJsonType only, types without a default constructor, std::tuples holding references, ... \u2014 is converted by materialize().get<T>(): the subtree is built into a real BasicJsonType value first (as BasicJsonType::parse() would), and converted from there exactly as BasicJsonType::get<T>() would convert it.

    "},{"location":"api/basic_json_view/get/#template-parameters","title":"Template parameters","text":"T the type to convert the value to"},{"location":"api/basic_json_view/get/#return-value","title":"Return value","text":"

    the value, converted to T

    "},{"location":"api/basic_json_view/get/#exception-safety","title":"Exception safety","text":"

    Strong guarantee: there are no changes to the view or the document it refers to.

    "},{"location":"api/basic_json_view/get/#exceptions","title":"Exceptions","text":"
    • For the directly-converted types listed above (other than BasicJsonType and basic_json_view, which never throw): throws type_error.302 if the value's type does not match T \u2014 the same exception, with the same message, that BasicJsonType::get<T>() throws for the same JSON type and T.
    • For std::vector<U, A>: throws type_error.302 if the value is not an array; otherwise, whatever converting an element to U throws.
    • For std::map/std::unordered_map of views: throws type_error.302 if the value is not an object.
    • For a T whose from_json() reads the view: whatever that from_json() throws; for the library's conversions and the macros, the same exceptions with the same messages as BasicJsonType::get<T>() of the same value.
    • For every other T: whatever materialize().get<T>() throws \u2014 typically type_error.302, or whatever a user-provided from_json() throws.

    None of the exceptions thrown directly by this function or by a from_json() that reads the view (the first four bullets above) carry a JSON_DIAGNOSTICS path: the view has no BasicJsonType value to point at. An exception thrown while converting through materialize() (the last bullet) is different: it is thrown by a real BasicJsonType value, so it does carry a JSON_DIAGNOSTICS path if BasicJsonType was built with it enabled. That path is relative to the root of the view's subtree, because materialize() builds only the subtree (with parent pointers): it is empty if the failing value is the subtree's root itself, and it never is the path within the whole document.

    "},{"location":"api/basic_json_view/get/#complexity","title":"Complexity","text":"
    • bool, arithmetic types, std::nullptr_t, string_view_t, basic_json_view: constant.
    • std::basic_string<char, Traits, Alloc>: constant, plus one allocation and a copy of the string's bytes.
    • BasicJsonType: linear in the size of the subtree, see materialize().
    • std::vector<U, A>: linear in the number of elements, times the complexity of converting one element to U.
    • std::map/std::unordered_map: linear in the number of members for walking them, plus the container's own insertion cost per member (logarithmic for std::map, amortized constant for std::unordered_map), times the complexity of converting one member to the mapped type.
    • a T whose from_json() reads the view: the cost of that from_json(); for the macros, linear in the number of members times the cost of a lookup, plus the cost of converting the members.
    • every other T: the cost of materialize() and of destroying the BasicJsonType value afterwards, plus that of BasicJsonType::get<T>().
    "},{"location":"api/basic_json_view/get/#notes","title":"Notes","text":"

    Floating-point values

    A floating-point T is converted from the same digits the lexer would see during BasicJsonType::parse(), using the same conversion, so the result is bit-for-bit identical to BasicJsonType::parse(text).get<T>() for the same source text.

    Duplicate keys

    std::map/std::unordered_map conversions keep the last value of a repeated key, like materialize() and BasicJsonType::parse() do. This is the opposite of operator[]/at/find/contains, which resolve to the first occurrence (see the Notes on duplicate keys).

    No pointers, references, or implicit conversion

    Unlike BasicJsonType, basic_json_view has no stored value anywhere to hand out a pointer or a reference to, so it provides neither get_ptr(), get_ref(), nor operator ValueType(). get_string() (equivalently, get<string_view_t>()) is the zero-copy alternative for strings.

    "},{"location":"api/basic_json_view/get/#examples","title":"Examples","text":"Example

    The example below reads typed fields straight into C++ variables, collects a view of every array element with get<std::vector<basic_json_view>>() instead of a value, and converts a nested object into a user type through its from_json() \u2014 which runs on a BasicJsonType value materialize() builds for just that one member.

    #include <iostream>\n#include <nlohmann/json_view.hpp>\n#include <string>\n#include <vector>\n\nusing nlohmann::json_document;\nusing nlohmann::json_view;\n\n// address has no direct conversion in get<T>(), so get<address>() falls back\n// to materialize().get<address>() -- a real nlohmann::json value is built\n// for just this one member, and its own from_json() runs on that\nstruct address\n{\n    std::string city;\n    int zip = 0;\n};\n\nvoid from_json(const nlohmann::json& j, address& a)\n{\n    j.at(\"city\").get_to(a.city);\n    j.at(\"zip\").get_to(a.zip);\n}\n\nint main()\n{\n    json_document doc = json_document::parse(R\"(\n      {\n        \"name\": \"Alice\",\n        \"active\": true,\n        \"orders\": [1, 2, 3],\n        \"address\": {\"city\": \"Berlin\", \"zip\": 10115}\n      }\n    )\");\n    const json_view customer = doc.root();\n\n    // read typed fields straight into C++ variables -- none of these build\n    // a nlohmann::json value\n    const std::string name = customer[\"name\"].get<std::string>();\n    const bool active = customer[\"active\"].get<bool>();\n    std::cout << name << (active ? \" (active)\" : \" (inactive)\") << '\\n';\n\n    // std::vector<json_view> keeps views of the array elements instead of\n    // copies of their values\n    bool first = true;\n    for (const json_view order : customer[\"orders\"].get<std::vector<json_view>>())\n    {\n        std::cout << (first ? \"\" : \" \") << order.get<int>();\n        first = false;\n    }\n    std::cout << '\\n';\n\n    // everything else goes through materialize()\n    const address a = customer[\"address\"].get<address>();\n    std::cout << a.city << ' ' << a.zip << '\\n';\n}\n

    Output:

    Alice (active)\n1 2 3\nBerlin 10115\n
    "},{"location":"api/basic_json_view/get/#see-also","title":"See also","text":"
    • get_to - convert and write into a passed value
    • get_string - the string, without a copy
    • number_token - a number's token text, without a copy
    • materialize - build the BasicJsonType value of this subtree
    • BasicJsonType::get - the corresponding function of basic_json
    • Zero-copy JSON views - which conversions avoid building a basic_json value
    "},{"location":"api/basic_json_view/get/#version-history","title":"Version history","text":"
    • Added in version 3.13.0 unreleased.
    "},{"location":"api/basic_json_view/get_string/","title":"nlohmann::basic_json_view::get_string","text":"
    string_view_t get_string() const;\n

    Returns the string value as a string_view_t, without copying it.

    "},{"location":"api/basic_json_view/get_string/#return-value","title":"Return value","text":"

    The string, as a string_view_t that points either into the document's source() text (a string with no escape sequences), or into the document's own buffer of decoded strings (a string that contains escape sequences, such as \"\\n\" or \"\\u00e9\", which had to be decoded once when the document was parsed).

    "},{"location":"api/basic_json_view/get_string/#exception-safety","title":"Exception safety","text":"

    Strong guarantee: there are no changes to the view or the document it refers to.

    "},{"location":"api/basic_json_view/get_string/#exceptions","title":"Exceptions","text":"

    Throws type_error.302 if the value is not a string; example: \"type must be string, but is array\".

    This exception does not carry a JSON_DIAGNOSTICS path: the view has no BasicJsonType value to point at, so the exception is created without one, even if BasicJsonType was built with JSON_DIAGNOSTICS enabled.

    "},{"location":"api/basic_json_view/get_string/#complexity","title":"Complexity","text":"

    Constant.

    "},{"location":"api/basic_json_view/get_string/#notes","title":"Notes","text":"

    basic_json_view has no BasicJsonType value stored anywhere, so unlike BasicJsonType, it has no get_ref() to hand out a reference to a stored string_t. get_string() (equivalently, get<string_view_t>()) is the zero-copy alternative: BasicJsonType::get_ref<const string_t&>() is its closest counterpart, except that it returns a view instead of a reference to a value that must already exist.

    get_string() borrows the string: nothing is copied, whereas get<std::string>() copies it. For a borrowed document, the returned string_view_t is valid as long as the caller's buffer; for an owned one, as long as the document.

    The returned string_view_t is valid exactly as long as the view that produced it \u2014 see the validity rules of basic_json_view \u2014 and, for a string with no escapes, for as long as the document's source text, which for a borrowed document must remain valid and unmodified for as long as the document exists, since floating-point values and unescaped strings are read from the source lazily.

    "},{"location":"api/basic_json_view/get_string/#examples","title":"Examples","text":"Example

    The example below pulls one field out of a JSON text that stands in for a large API response, and shows that no std::string was allocated for it: the returned view still points inside the original buffer. A field that contains an escape sequence cannot point into the original text \u2014 it was decoded once into the document's own buffer instead \u2014 but still avoids a per-field allocation.

    #include <iostream>\n#include <nlohmann/json_view.hpp>\n#include <string>\n\nusing nlohmann::json_document;\nusing nlohmann::json_view;\n\nint main()\n{\n    // a \"large response\" stand-in: only the \"id\" field is ever read out of it\n    const std::string text =\n        R\"({\"id\": \"8f14e45f-ceea-467e-bb92-963f5e3c7a08\", \"note\": \"created via API\\n\", \"payload\": \"...\"})\";\n    const json_document doc = json_document::parse(text);\n    const json_view response = doc.root();\n\n    const json_view::string_view_t id = response[\"id\"].get_string();\n    std::cout << id << '\\n';\n\n    // no std::string was allocated for \"id\": its bytes still live inside\n    // the original buffer, so id's data lies inside [text.data(),\n    // text.data() + text.size())\n    const bool id_in_source = id.data() >= text.data() && id.data() + id.size() <= text.data() + text.size();\n    std::cout << std::boolalpha << id_in_source << '\\n';\n\n    // \"note\" contains an escape sequence ('\\n'), so it was decoded once\n    // into the document's own buffer -- get_string() still avoids a copy\n    // into a new std::string, but the bytes no longer live inside \"text\"\n    const json_view::string_view_t note = response[\"note\"].get_string();\n    const bool note_in_source = note.data() >= text.data() && note.data() + note.size() <= text.data() + text.size();\n    std::cout << std::boolalpha << note_in_source << '\\n';\n}\n

    Output:

    8f14e45f-ceea-467e-bb92-963f5e3c7a08\ntrue\nfalse\n
    "},{"location":"api/basic_json_view/get_string/#see-also","title":"See also","text":"
    • get - convert the value to a given type (get<string_view_t>() is equivalent to this function)
    • number_token - a number's token text, without a copy
    • BasicJsonType::get_ref - the closest counterpart of basic_json
    • Zero-copy JSON views - borrowing strings instead of copying them
    "},{"location":"api/basic_json_view/get_string/#version-history","title":"Version history","text":"
    • Added in version 3.13.0 unreleased.
    "},{"location":"api/basic_json_view/get_to/","title":"nlohmann::basic_json_view::get_to","text":"
    template<typename T>\nT& get_to(T& v) const;\n

    Converts the value to T and stores it in v, in one of three ways:

    • For the types that get<T>() converts directly \u2014 arithmetic types, bool, std::nullptr_t, string_view_t, std::basic_string, BasicJsonType, basic_json_view, vectors of these, and maps of views \u2014 v is assigned: v = get<T>().
    • For a type whose from_json() accepts views (see get<T>()), that from_json() is called with the view and the existing v, without building a BasicJsonType value.
    • For every other type, the subtree is built into a BasicJsonType value and materialize().get_to(v) is called, i.e. from_json() is invoked with the existing v, exactly as BasicJsonType::get_to() does.
    "},{"location":"api/basic_json_view/get_to/#template-parameters","title":"Template parameters","text":"T the type to convert the value to"},{"location":"api/basic_json_view/get_to/#parameters","title":"Parameters","text":"v (out) the variable to store the converted value in"},{"location":"api/basic_json_view/get_to/#return-value","title":"Return value","text":"

    v, allowing calls to chain

    "},{"location":"api/basic_json_view/get_to/#exception-safety","title":"Exception safety","text":"
    • For the directly converted types: strong exception safety. If an exception is thrown, v is not modified.
    • For every other type: as for BasicJsonType::get_to(). materialize() throws before v is touched, but a from_json() that throws may leave v partly modified.
    "},{"location":"api/basic_json_view/get_to/#exceptions","title":"Exceptions","text":"
    • For the directly converted types: whatever get<T>() throws for the same value and T.
    • For every other type: whatever materialize() and BasicJsonType::get_to() throw.
    "},{"location":"api/basic_json_view/get_to/#complexity","title":"Complexity","text":"
    • For the directly converted types: whatever get<T>() has for the same T.
    • For every other type: that of materialize(), plus that of BasicJsonType::get_to().
    "},{"location":"api/basic_json_view/get_to/#notes","title":"Notes","text":"

    The difference between the two ways matters for a from_json() that sets only the fields present in the JSON: since it runs on the existing v, the other fields of v keep their values, whereas assigning get<T>() would replace them with those of a default-constructed T.

    "},{"location":"api/basic_json_view/get_to/#examples","title":"Examples","text":"Example

    The example below reads several fields of a service configuration directly into existing variables, then uses the returned reference to fold the host/port pair into a single string in the same expression.

    #include <iostream>\n#include <nlohmann/json_view.hpp>\n#include <string>\n\nusing nlohmann::json_document;\nusing nlohmann::json_view;\n\nint main()\n{\n    json_document doc = json_document::parse(R\"({\"host\": \"db.example.com\", \"port\": 5432, \"ssl\": true})\");\n    const json_view config = doc.root();\n\n    // get_to() writes directly into existing variables -- handy for filling\n    // in the members of a struct one field at a time, without an\n    // intermediate value from get<T>() for each one\n    std::string host;\n    int port = 0;\n    bool ssl = false;\n    config[\"host\"].get_to(host);\n    config[\"port\"].get_to(port);\n    config[\"ssl\"].get_to(ssl);\n    std::cout << host << ':' << port << (ssl ? \" (tls)\" : \"\") << '\\n';\n\n    // the return value is a reference to the argument, so a call can be\n    // used directly in a larger expression\n    std::string other_host;\n    std::cout << config[\"host\"].get_to(other_host).size() << '\\n';\n}\n

    Output:

    db.example.com:5432 (tls)\n14\n
    "},{"location":"api/basic_json_view/get_to/#see-also","title":"See also","text":"
    • get - convert the value to a given type
    • BasicJsonType::get_to - the corresponding function of basic_json
    • Zero-copy JSON views - which conversions avoid building a basic_json value
    "},{"location":"api/basic_json_view/get_to/#version-history","title":"Version history","text":"
    • Added in version 3.13.0 unreleased.
    "},{"location":"api/basic_json_view/is_array/","title":"nlohmann::basic_json_view::is_array","text":"
    bool is_array() const noexcept;\n

    This function returns true if and only if the value is an array.

    "},{"location":"api/basic_json_view/is_array/#return-value","title":"Return value","text":"

    true if the type is an array, false otherwise.

    "},{"location":"api/basic_json_view/is_array/#exception-safety","title":"Exception safety","text":"

    No-throw guarantee: this function never throws exceptions.

    "},{"location":"api/basic_json_view/is_array/#complexity","title":"Complexity","text":"

    Constant.

    "},{"location":"api/basic_json_view/is_array/#examples","title":"Examples","text":"Example

    The example below classifies several parsed documents by the type of their root value, without materializing any of them into a BasicJsonType value.

    #include <iostream>\n#include <nlohmann/json_view.hpp>\n\nusing nlohmann::json_document;\n\nint main()\n{\n    std::cout << std::boolalpha;\n\n    // several incoming messages, one json_document per message. type() and\n    // is_*() only look at the flat index built by parse(); no nlohmann::json\n    // tree exists yet, and none is built unless materialize() is called\n    json_document d_null = json_document::parse(\"null\");\n    json_document d_bool = json_document::parse(\"true\");\n    json_document d_int = json_document::parse(\"-42\");\n    json_document d_unsigned = json_document::parse(\"42\");\n    json_document d_float = json_document::parse(\"4.2\");\n    json_document d_string = json_document::parse(R\"(\"hi\")\");\n    json_document d_array = json_document::parse(\"[1, 2, 3]\");\n    json_document d_object = json_document::parse(R\"({\"a\": 1})\");\n\n    std::cout << d_null.root().is_null() << '\\n';\n    std::cout << d_bool.root().is_boolean() << '\\n';\n    std::cout << d_int.root().is_number() << ' ' << d_int.root().is_number_integer() << '\\n';\n    std::cout << d_unsigned.root().is_number_unsigned() << '\\n';\n    std::cout << d_float.root().is_number_float() << '\\n';\n    std::cout << d_string.root().is_string() << '\\n';\n    std::cout << d_array.root().is_array() << ' ' << d_array.root().is_structured() << '\\n';\n    std::cout << d_object.root().is_object() << ' ' << d_object.root().is_primitive() << '\\n';\n\n    // JSON text can never produce a binary value: is_binary() is always false\n    std::cout << d_array.root().is_binary() << '\\n';\n\n    // a default-constructed view, and the root of a document that failed to\n    // parse without exceptions, are both discarded\n    nlohmann::json_view invalid;\n    json_document failed = json_document::parse(\"not json\", /* allow_exceptions */ false);\n    std::cout << invalid.is_discarded() << '\\n';\n    std::cout << failed.root().is_discarded() << '\\n';\n\n    // type() returns the same value_t enumeration as basic_json::type()\n    std::cout << (d_object.root().type() == nlohmann::json::value_t::object) << '\\n';\n}\n

    Output:

    true\ntrue\ntrue true\ntrue\ntrue\ntrue\ntrue true\ntrue false\nfalse\ntrue\ntrue\ntrue\n
    "},{"location":"api/basic_json_view/is_array/#see-also","title":"See also","text":"
    • is_structured - return whether the type is structured
    • size - the number of elements
    • empty - whether there are no elements
    • BasicJsonType::is_array - the corresponding function of basic_json
    "},{"location":"api/basic_json_view/is_array/#version-history","title":"Version history","text":"
    • Added in version 3.13.0 unreleased.
    "},{"location":"api/basic_json_view/is_binary/","title":"nlohmann::basic_json_view::is_binary","text":"
    bool is_binary() const noexcept;\n

    This function always returns false: a document is only ever parsed from JSON text, never from CBOR or the other binary formats, and a JSON text has no binary values, so a view can never refer to one. The function exists for interface parity with BasicJsonType::is_binary.

    "},{"location":"api/basic_json_view/is_binary/#return-value","title":"Return value","text":"

    false, always.

    "},{"location":"api/basic_json_view/is_binary/#exception-safety","title":"Exception safety","text":"

    No-throw guarantee: this function never throws exceptions.

    "},{"location":"api/basic_json_view/is_binary/#complexity","title":"Complexity","text":"

    Constant.

    "},{"location":"api/basic_json_view/is_binary/#examples","title":"Examples","text":"Example

    The example below classifies several parsed documents by the type of their root value, without materializing any of them into a BasicJsonType value.

    #include <iostream>\n#include <nlohmann/json_view.hpp>\n\nusing nlohmann::json_document;\n\nint main()\n{\n    std::cout << std::boolalpha;\n\n    // several incoming messages, one json_document per message. type() and\n    // is_*() only look at the flat index built by parse(); no nlohmann::json\n    // tree exists yet, and none is built unless materialize() is called\n    json_document d_null = json_document::parse(\"null\");\n    json_document d_bool = json_document::parse(\"true\");\n    json_document d_int = json_document::parse(\"-42\");\n    json_document d_unsigned = json_document::parse(\"42\");\n    json_document d_float = json_document::parse(\"4.2\");\n    json_document d_string = json_document::parse(R\"(\"hi\")\");\n    json_document d_array = json_document::parse(\"[1, 2, 3]\");\n    json_document d_object = json_document::parse(R\"({\"a\": 1})\");\n\n    std::cout << d_null.root().is_null() << '\\n';\n    std::cout << d_bool.root().is_boolean() << '\\n';\n    std::cout << d_int.root().is_number() << ' ' << d_int.root().is_number_integer() << '\\n';\n    std::cout << d_unsigned.root().is_number_unsigned() << '\\n';\n    std::cout << d_float.root().is_number_float() << '\\n';\n    std::cout << d_string.root().is_string() << '\\n';\n    std::cout << d_array.root().is_array() << ' ' << d_array.root().is_structured() << '\\n';\n    std::cout << d_object.root().is_object() << ' ' << d_object.root().is_primitive() << '\\n';\n\n    // JSON text can never produce a binary value: is_binary() is always false\n    std::cout << d_array.root().is_binary() << '\\n';\n\n    // a default-constructed view, and the root of a document that failed to\n    // parse without exceptions, are both discarded\n    nlohmann::json_view invalid;\n    json_document failed = json_document::parse(\"not json\", /* allow_exceptions */ false);\n    std::cout << invalid.is_discarded() << '\\n';\n    std::cout << failed.root().is_discarded() << '\\n';\n\n    // type() returns the same value_t enumeration as basic_json::type()\n    std::cout << (d_object.root().type() == nlohmann::json::value_t::object) << '\\n';\n}\n

    Output:

    true\ntrue\ntrue true\ntrue\ntrue\ntrue\ntrue true\ntrue false\nfalse\ntrue\ntrue\ntrue\n
    "},{"location":"api/basic_json_view/is_binary/#see-also","title":"See also","text":"
    • type - return the type of the value
    • BasicJsonType::is_binary - the corresponding function of basic_json
    "},{"location":"api/basic_json_view/is_binary/#version-history","title":"Version history","text":"
    • Added in version 3.13.0 unreleased.
    "},{"location":"api/basic_json_view/is_boolean/","title":"nlohmann::basic_json_view::is_boolean","text":"
    bool is_boolean() const noexcept;\n

    This function returns true if and only if the value is a boolean.

    "},{"location":"api/basic_json_view/is_boolean/#return-value","title":"Return value","text":"

    true if the type is a boolean, false otherwise.

    "},{"location":"api/basic_json_view/is_boolean/#exception-safety","title":"Exception safety","text":"

    No-throw guarantee: this function never throws exceptions.

    "},{"location":"api/basic_json_view/is_boolean/#complexity","title":"Complexity","text":"

    Constant.

    "},{"location":"api/basic_json_view/is_boolean/#examples","title":"Examples","text":"Example

    The example below classifies several parsed documents by the type of their root value, without materializing any of them into a BasicJsonType value.

    #include <iostream>\n#include <nlohmann/json_view.hpp>\n\nusing nlohmann::json_document;\n\nint main()\n{\n    std::cout << std::boolalpha;\n\n    // several incoming messages, one json_document per message. type() and\n    // is_*() only look at the flat index built by parse(); no nlohmann::json\n    // tree exists yet, and none is built unless materialize() is called\n    json_document d_null = json_document::parse(\"null\");\n    json_document d_bool = json_document::parse(\"true\");\n    json_document d_int = json_document::parse(\"-42\");\n    json_document d_unsigned = json_document::parse(\"42\");\n    json_document d_float = json_document::parse(\"4.2\");\n    json_document d_string = json_document::parse(R\"(\"hi\")\");\n    json_document d_array = json_document::parse(\"[1, 2, 3]\");\n    json_document d_object = json_document::parse(R\"({\"a\": 1})\");\n\n    std::cout << d_null.root().is_null() << '\\n';\n    std::cout << d_bool.root().is_boolean() << '\\n';\n    std::cout << d_int.root().is_number() << ' ' << d_int.root().is_number_integer() << '\\n';\n    std::cout << d_unsigned.root().is_number_unsigned() << '\\n';\n    std::cout << d_float.root().is_number_float() << '\\n';\n    std::cout << d_string.root().is_string() << '\\n';\n    std::cout << d_array.root().is_array() << ' ' << d_array.root().is_structured() << '\\n';\n    std::cout << d_object.root().is_object() << ' ' << d_object.root().is_primitive() << '\\n';\n\n    // JSON text can never produce a binary value: is_binary() is always false\n    std::cout << d_array.root().is_binary() << '\\n';\n\n    // a default-constructed view, and the root of a document that failed to\n    // parse without exceptions, are both discarded\n    nlohmann::json_view invalid;\n    json_document failed = json_document::parse(\"not json\", /* allow_exceptions */ false);\n    std::cout << invalid.is_discarded() << '\\n';\n    std::cout << failed.root().is_discarded() << '\\n';\n\n    // type() returns the same value_t enumeration as basic_json::type()\n    std::cout << (d_object.root().type() == nlohmann::json::value_t::object) << '\\n';\n}\n

    Output:

    true\ntrue\ntrue true\ntrue\ntrue\ntrue\ntrue true\ntrue false\nfalse\ntrue\ntrue\ntrue\n
    "},{"location":"api/basic_json_view/is_boolean/#see-also","title":"See also","text":"
    • type - return the type of the value
    • BasicJsonType::is_boolean - the corresponding function of basic_json
    "},{"location":"api/basic_json_view/is_boolean/#version-history","title":"Version history","text":"
    • Added in version 3.13.0 unreleased.
    "},{"location":"api/basic_json_view/is_discarded/","title":"nlohmann::basic_json_view::is_discarded","text":"
    bool is_discarded() const noexcept;\n

    Returns whether this view is invalid, i.e. does not refer to a value. This is the case for a default-constructed view (see (constructor)), and for root() of a document that is itself discarded \u2014 in particular, the root of a failed parse() with allow_exceptions set to false.

    A discarded view is also what operator[] returns for a missing key, an index out of range, or a JSON pointer that cannot be resolved, and for any access on a view that is itself discarded (so a chain such as v[\"a\"][\"b\"] is safe). at throws instead.

    "},{"location":"api/basic_json_view/is_discarded/#return-value","title":"Return value","text":"

    true if the view or its document is discarded, false otherwise.

    "},{"location":"api/basic_json_view/is_discarded/#exception-safety","title":"Exception safety","text":"

    No-throw guarantee: this function never throws exceptions.

    "},{"location":"api/basic_json_view/is_discarded/#complexity","title":"Complexity","text":"

    Constant.

    "},{"location":"api/basic_json_view/is_discarded/#notes","title":"Notes","text":"

    A basic_json_view is not convertible to bool: such a conversion would mean \"refers to a value\", whereas basic_json converts to the bool it holds, so the same code would silently behave differently. Test !v.is_discarded() explicitly.

    "},{"location":"api/basic_json_view/is_discarded/#examples","title":"Examples","text":"Example

    The example below classifies several parsed documents by the type of their root value, without materializing any of them into a BasicJsonType value.

    #include <iostream>\n#include <nlohmann/json_view.hpp>\n\nusing nlohmann::json_document;\n\nint main()\n{\n    std::cout << std::boolalpha;\n\n    // several incoming messages, one json_document per message. type() and\n    // is_*() only look at the flat index built by parse(); no nlohmann::json\n    // tree exists yet, and none is built unless materialize() is called\n    json_document d_null = json_document::parse(\"null\");\n    json_document d_bool = json_document::parse(\"true\");\n    json_document d_int = json_document::parse(\"-42\");\n    json_document d_unsigned = json_document::parse(\"42\");\n    json_document d_float = json_document::parse(\"4.2\");\n    json_document d_string = json_document::parse(R\"(\"hi\")\");\n    json_document d_array = json_document::parse(\"[1, 2, 3]\");\n    json_document d_object = json_document::parse(R\"({\"a\": 1})\");\n\n    std::cout << d_null.root().is_null() << '\\n';\n    std::cout << d_bool.root().is_boolean() << '\\n';\n    std::cout << d_int.root().is_number() << ' ' << d_int.root().is_number_integer() << '\\n';\n    std::cout << d_unsigned.root().is_number_unsigned() << '\\n';\n    std::cout << d_float.root().is_number_float() << '\\n';\n    std::cout << d_string.root().is_string() << '\\n';\n    std::cout << d_array.root().is_array() << ' ' << d_array.root().is_structured() << '\\n';\n    std::cout << d_object.root().is_object() << ' ' << d_object.root().is_primitive() << '\\n';\n\n    // JSON text can never produce a binary value: is_binary() is always false\n    std::cout << d_array.root().is_binary() << '\\n';\n\n    // a default-constructed view, and the root of a document that failed to\n    // parse without exceptions, are both discarded\n    nlohmann::json_view invalid;\n    json_document failed = json_document::parse(\"not json\", /* allow_exceptions */ false);\n    std::cout << invalid.is_discarded() << '\\n';\n    std::cout << failed.root().is_discarded() << '\\n';\n\n    // type() returns the same value_t enumeration as basic_json::type()\n    std::cout << (d_object.root().type() == nlohmann::json::value_t::object) << '\\n';\n}\n

    Output:

    true\ntrue\ntrue true\ntrue\ntrue\ntrue\ntrue true\ntrue false\nfalse\ntrue\ntrue\ntrue\n
    "},{"location":"api/basic_json_view/is_discarded/#see-also","title":"See also","text":"
    • operator[] - access specified element; yields a discarded view where an element is missing
    • (constructor) - the default constructor creates a discarded view
    • basic_json_document::is_discarded - return whether the last parse failed
    • BasicJsonType::is_discarded - the corresponding function of basic_json
    • Zero-copy JSON views - how views differ from basic_json
    "},{"location":"api/basic_json_view/is_discarded/#version-history","title":"Version history","text":"
    • Added in version 3.13.0 unreleased.
    "},{"location":"api/basic_json_view/is_null/","title":"nlohmann::basic_json_view::is_null","text":"
    bool is_null() const noexcept;\n

    This function returns true if and only if the value is null.

    "},{"location":"api/basic_json_view/is_null/#return-value","title":"Return value","text":"

    true if the type is null, false otherwise.

    "},{"location":"api/basic_json_view/is_null/#exception-safety","title":"Exception safety","text":"

    No-throw guarantee: this function never throws exceptions.

    "},{"location":"api/basic_json_view/is_null/#complexity","title":"Complexity","text":"

    Constant.

    "},{"location":"api/basic_json_view/is_null/#examples","title":"Examples","text":"Example

    The example below classifies several parsed documents by the type of their root value, without materializing any of them into a BasicJsonType value.

    #include <iostream>\n#include <nlohmann/json_view.hpp>\n\nusing nlohmann::json_document;\n\nint main()\n{\n    std::cout << std::boolalpha;\n\n    // several incoming messages, one json_document per message. type() and\n    // is_*() only look at the flat index built by parse(); no nlohmann::json\n    // tree exists yet, and none is built unless materialize() is called\n    json_document d_null = json_document::parse(\"null\");\n    json_document d_bool = json_document::parse(\"true\");\n    json_document d_int = json_document::parse(\"-42\");\n    json_document d_unsigned = json_document::parse(\"42\");\n    json_document d_float = json_document::parse(\"4.2\");\n    json_document d_string = json_document::parse(R\"(\"hi\")\");\n    json_document d_array = json_document::parse(\"[1, 2, 3]\");\n    json_document d_object = json_document::parse(R\"({\"a\": 1})\");\n\n    std::cout << d_null.root().is_null() << '\\n';\n    std::cout << d_bool.root().is_boolean() << '\\n';\n    std::cout << d_int.root().is_number() << ' ' << d_int.root().is_number_integer() << '\\n';\n    std::cout << d_unsigned.root().is_number_unsigned() << '\\n';\n    std::cout << d_float.root().is_number_float() << '\\n';\n    std::cout << d_string.root().is_string() << '\\n';\n    std::cout << d_array.root().is_array() << ' ' << d_array.root().is_structured() << '\\n';\n    std::cout << d_object.root().is_object() << ' ' << d_object.root().is_primitive() << '\\n';\n\n    // JSON text can never produce a binary value: is_binary() is always false\n    std::cout << d_array.root().is_binary() << '\\n';\n\n    // a default-constructed view, and the root of a document that failed to\n    // parse without exceptions, are both discarded\n    nlohmann::json_view invalid;\n    json_document failed = json_document::parse(\"not json\", /* allow_exceptions */ false);\n    std::cout << invalid.is_discarded() << '\\n';\n    std::cout << failed.root().is_discarded() << '\\n';\n\n    // type() returns the same value_t enumeration as basic_json::type()\n    std::cout << (d_object.root().type() == nlohmann::json::value_t::object) << '\\n';\n}\n

    Output:

    true\ntrue\ntrue true\ntrue\ntrue\ntrue\ntrue true\ntrue false\nfalse\ntrue\ntrue\ntrue\n
    "},{"location":"api/basic_json_view/is_null/#see-also","title":"See also","text":"
    • type - return the type of the value
    • BasicJsonType::is_null - the corresponding function of basic_json
    "},{"location":"api/basic_json_view/is_null/#version-history","title":"Version history","text":"
    • Added in version 3.13.0 unreleased.
    "},{"location":"api/basic_json_view/is_number/","title":"nlohmann::basic_json_view::is_number","text":"
    bool is_number() const noexcept;\n

    This function returns true if and only if the value is a number, i.e. an integer, unsigned integer, or floating-point value. It is defined as is_number_integer() || is_number_float().

    "},{"location":"api/basic_json_view/is_number/#return-value","title":"Return value","text":"

    true if the type is a number, false otherwise.

    "},{"location":"api/basic_json_view/is_number/#exception-safety","title":"Exception safety","text":"

    No-throw guarantee: this function never throws exceptions.

    "},{"location":"api/basic_json_view/is_number/#complexity","title":"Complexity","text":"

    Constant.

    "},{"location":"api/basic_json_view/is_number/#examples","title":"Examples","text":"Example

    The example below classifies several parsed documents by the type of their root value, without materializing any of them into a BasicJsonType value.

    #include <iostream>\n#include <nlohmann/json_view.hpp>\n\nusing nlohmann::json_document;\n\nint main()\n{\n    std::cout << std::boolalpha;\n\n    // several incoming messages, one json_document per message. type() and\n    // is_*() only look at the flat index built by parse(); no nlohmann::json\n    // tree exists yet, and none is built unless materialize() is called\n    json_document d_null = json_document::parse(\"null\");\n    json_document d_bool = json_document::parse(\"true\");\n    json_document d_int = json_document::parse(\"-42\");\n    json_document d_unsigned = json_document::parse(\"42\");\n    json_document d_float = json_document::parse(\"4.2\");\n    json_document d_string = json_document::parse(R\"(\"hi\")\");\n    json_document d_array = json_document::parse(\"[1, 2, 3]\");\n    json_document d_object = json_document::parse(R\"({\"a\": 1})\");\n\n    std::cout << d_null.root().is_null() << '\\n';\n    std::cout << d_bool.root().is_boolean() << '\\n';\n    std::cout << d_int.root().is_number() << ' ' << d_int.root().is_number_integer() << '\\n';\n    std::cout << d_unsigned.root().is_number_unsigned() << '\\n';\n    std::cout << d_float.root().is_number_float() << '\\n';\n    std::cout << d_string.root().is_string() << '\\n';\n    std::cout << d_array.root().is_array() << ' ' << d_array.root().is_structured() << '\\n';\n    std::cout << d_object.root().is_object() << ' ' << d_object.root().is_primitive() << '\\n';\n\n    // JSON text can never produce a binary value: is_binary() is always false\n    std::cout << d_array.root().is_binary() << '\\n';\n\n    // a default-constructed view, and the root of a document that failed to\n    // parse without exceptions, are both discarded\n    nlohmann::json_view invalid;\n    json_document failed = json_document::parse(\"not json\", /* allow_exceptions */ false);\n    std::cout << invalid.is_discarded() << '\\n';\n    std::cout << failed.root().is_discarded() << '\\n';\n\n    // type() returns the same value_t enumeration as basic_json::type()\n    std::cout << (d_object.root().type() == nlohmann::json::value_t::object) << '\\n';\n}\n

    Output:

    true\ntrue\ntrue true\ntrue\ntrue\ntrue\ntrue true\ntrue false\nfalse\ntrue\ntrue\ntrue\n
    "},{"location":"api/basic_json_view/is_number/#see-also","title":"See also","text":"
    • is_number_integer - return whether the value is an integer or unsigned integer number
    • is_number_unsigned - return whether the value is an unsigned integer number
    • is_number_float - return whether the value is a floating-point number
    • BasicJsonType::is_number - the corresponding function of basic_json
    "},{"location":"api/basic_json_view/is_number/#version-history","title":"Version history","text":"
    • Added in version 3.13.0 unreleased.
    "},{"location":"api/basic_json_view/is_number_float/","title":"nlohmann::basic_json_view::is_number_float","text":"
    bool is_number_float() const noexcept;\n

    This function returns true if and only if the value is a floating-point number.

    "},{"location":"api/basic_json_view/is_number_float/#return-value","title":"Return value","text":"

    true if the type is value_t::number_float, false otherwise.

    "},{"location":"api/basic_json_view/is_number_float/#exception-safety","title":"Exception safety","text":"

    No-throw guarantee: this function never throws exceptions.

    "},{"location":"api/basic_json_view/is_number_float/#complexity","title":"Complexity","text":"

    Constant.

    "},{"location":"api/basic_json_view/is_number_float/#notes","title":"Notes","text":"

    As for BasicJsonType::parse, an integer literal that does not fit into the 64-bit integer type is classified as a floating-point number, so is_number_float() can be true even for an integer-looking token in the source text.

    "},{"location":"api/basic_json_view/is_number_float/#examples","title":"Examples","text":"Example

    The example below classifies several parsed documents by the type of their root value, without materializing any of them into a BasicJsonType value.

    #include <iostream>\n#include <nlohmann/json_view.hpp>\n\nusing nlohmann::json_document;\n\nint main()\n{\n    std::cout << std::boolalpha;\n\n    // several incoming messages, one json_document per message. type() and\n    // is_*() only look at the flat index built by parse(); no nlohmann::json\n    // tree exists yet, and none is built unless materialize() is called\n    json_document d_null = json_document::parse(\"null\");\n    json_document d_bool = json_document::parse(\"true\");\n    json_document d_int = json_document::parse(\"-42\");\n    json_document d_unsigned = json_document::parse(\"42\");\n    json_document d_float = json_document::parse(\"4.2\");\n    json_document d_string = json_document::parse(R\"(\"hi\")\");\n    json_document d_array = json_document::parse(\"[1, 2, 3]\");\n    json_document d_object = json_document::parse(R\"({\"a\": 1})\");\n\n    std::cout << d_null.root().is_null() << '\\n';\n    std::cout << d_bool.root().is_boolean() << '\\n';\n    std::cout << d_int.root().is_number() << ' ' << d_int.root().is_number_integer() << '\\n';\n    std::cout << d_unsigned.root().is_number_unsigned() << '\\n';\n    std::cout << d_float.root().is_number_float() << '\\n';\n    std::cout << d_string.root().is_string() << '\\n';\n    std::cout << d_array.root().is_array() << ' ' << d_array.root().is_structured() << '\\n';\n    std::cout << d_object.root().is_object() << ' ' << d_object.root().is_primitive() << '\\n';\n\n    // JSON text can never produce a binary value: is_binary() is always false\n    std::cout << d_array.root().is_binary() << '\\n';\n\n    // a default-constructed view, and the root of a document that failed to\n    // parse without exceptions, are both discarded\n    nlohmann::json_view invalid;\n    json_document failed = json_document::parse(\"not json\", /* allow_exceptions */ false);\n    std::cout << invalid.is_discarded() << '\\n';\n    std::cout << failed.root().is_discarded() << '\\n';\n\n    // type() returns the same value_t enumeration as basic_json::type()\n    std::cout << (d_object.root().type() == nlohmann::json::value_t::object) << '\\n';\n}\n

    Output:

    true\ntrue\ntrue true\ntrue\ntrue\ntrue\ntrue true\ntrue false\nfalse\ntrue\ntrue\ntrue\n
    "},{"location":"api/basic_json_view/is_number_float/#see-also","title":"See also","text":"
    • is_number - return whether the value is a number
    • BasicJsonType::is_number_float - the corresponding function of basic_json
    "},{"location":"api/basic_json_view/is_number_float/#version-history","title":"Version history","text":"
    • Added in version 3.13.0 unreleased.
    "},{"location":"api/basic_json_view/is_number_integer/","title":"nlohmann::basic_json_view::is_number_integer","text":"
    bool is_number_integer() const noexcept;\n

    This function returns true if and only if the value is an integer or unsigned integer number.

    "},{"location":"api/basic_json_view/is_number_integer/#return-value","title":"Return value","text":"

    true if the type is value_t::number_integer or value_t::number_unsigned, false otherwise.

    "},{"location":"api/basic_json_view/is_number_integer/#exception-safety","title":"Exception safety","text":"

    No-throw guarantee: this function never throws exceptions.

    "},{"location":"api/basic_json_view/is_number_integer/#complexity","title":"Complexity","text":"

    Constant.

    "},{"location":"api/basic_json_view/is_number_integer/#notes","title":"Notes","text":"

    As for BasicJsonType::is_number_integer, this includes unsigned integer values; use is_number_unsigned to test for those specifically.

    "},{"location":"api/basic_json_view/is_number_integer/#examples","title":"Examples","text":"Example

    The example below classifies several parsed documents by the type of their root value, without materializing any of them into a BasicJsonType value.

    #include <iostream>\n#include <nlohmann/json_view.hpp>\n\nusing nlohmann::json_document;\n\nint main()\n{\n    std::cout << std::boolalpha;\n\n    // several incoming messages, one json_document per message. type() and\n    // is_*() only look at the flat index built by parse(); no nlohmann::json\n    // tree exists yet, and none is built unless materialize() is called\n    json_document d_null = json_document::parse(\"null\");\n    json_document d_bool = json_document::parse(\"true\");\n    json_document d_int = json_document::parse(\"-42\");\n    json_document d_unsigned = json_document::parse(\"42\");\n    json_document d_float = json_document::parse(\"4.2\");\n    json_document d_string = json_document::parse(R\"(\"hi\")\");\n    json_document d_array = json_document::parse(\"[1, 2, 3]\");\n    json_document d_object = json_document::parse(R\"({\"a\": 1})\");\n\n    std::cout << d_null.root().is_null() << '\\n';\n    std::cout << d_bool.root().is_boolean() << '\\n';\n    std::cout << d_int.root().is_number() << ' ' << d_int.root().is_number_integer() << '\\n';\n    std::cout << d_unsigned.root().is_number_unsigned() << '\\n';\n    std::cout << d_float.root().is_number_float() << '\\n';\n    std::cout << d_string.root().is_string() << '\\n';\n    std::cout << d_array.root().is_array() << ' ' << d_array.root().is_structured() << '\\n';\n    std::cout << d_object.root().is_object() << ' ' << d_object.root().is_primitive() << '\\n';\n\n    // JSON text can never produce a binary value: is_binary() is always false\n    std::cout << d_array.root().is_binary() << '\\n';\n\n    // a default-constructed view, and the root of a document that failed to\n    // parse without exceptions, are both discarded\n    nlohmann::json_view invalid;\n    json_document failed = json_document::parse(\"not json\", /* allow_exceptions */ false);\n    std::cout << invalid.is_discarded() << '\\n';\n    std::cout << failed.root().is_discarded() << '\\n';\n\n    // type() returns the same value_t enumeration as basic_json::type()\n    std::cout << (d_object.root().type() == nlohmann::json::value_t::object) << '\\n';\n}\n

    Output:

    true\ntrue\ntrue true\ntrue\ntrue\ntrue\ntrue true\ntrue false\nfalse\ntrue\ntrue\ntrue\n
    "},{"location":"api/basic_json_view/is_number_integer/#see-also","title":"See also","text":"
    • is_number - return whether the value is a number
    • is_number_unsigned - return whether the value is an unsigned integer number
    • BasicJsonType::is_number_integer - the corresponding function of basic_json
    "},{"location":"api/basic_json_view/is_number_integer/#version-history","title":"Version history","text":"
    • Added in version 3.13.0 unreleased.
    "},{"location":"api/basic_json_view/is_number_unsigned/","title":"nlohmann::basic_json_view::is_number_unsigned","text":"
    bool is_number_unsigned() const noexcept;\n

    This function returns true if and only if the value is an unsigned integer number.

    "},{"location":"api/basic_json_view/is_number_unsigned/#return-value","title":"Return value","text":"

    true if the type is value_t::number_unsigned, false otherwise.

    "},{"location":"api/basic_json_view/is_number_unsigned/#exception-safety","title":"Exception safety","text":"

    No-throw guarantee: this function never throws exceptions.

    "},{"location":"api/basic_json_view/is_number_unsigned/#complexity","title":"Complexity","text":"

    Constant.

    "},{"location":"api/basic_json_view/is_number_unsigned/#examples","title":"Examples","text":"Example

    The example below classifies several parsed documents by the type of their root value, without materializing any of them into a BasicJsonType value.

    #include <iostream>\n#include <nlohmann/json_view.hpp>\n\nusing nlohmann::json_document;\n\nint main()\n{\n    std::cout << std::boolalpha;\n\n    // several incoming messages, one json_document per message. type() and\n    // is_*() only look at the flat index built by parse(); no nlohmann::json\n    // tree exists yet, and none is built unless materialize() is called\n    json_document d_null = json_document::parse(\"null\");\n    json_document d_bool = json_document::parse(\"true\");\n    json_document d_int = json_document::parse(\"-42\");\n    json_document d_unsigned = json_document::parse(\"42\");\n    json_document d_float = json_document::parse(\"4.2\");\n    json_document d_string = json_document::parse(R\"(\"hi\")\");\n    json_document d_array = json_document::parse(\"[1, 2, 3]\");\n    json_document d_object = json_document::parse(R\"({\"a\": 1})\");\n\n    std::cout << d_null.root().is_null() << '\\n';\n    std::cout << d_bool.root().is_boolean() << '\\n';\n    std::cout << d_int.root().is_number() << ' ' << d_int.root().is_number_integer() << '\\n';\n    std::cout << d_unsigned.root().is_number_unsigned() << '\\n';\n    std::cout << d_float.root().is_number_float() << '\\n';\n    std::cout << d_string.root().is_string() << '\\n';\n    std::cout << d_array.root().is_array() << ' ' << d_array.root().is_structured() << '\\n';\n    std::cout << d_object.root().is_object() << ' ' << d_object.root().is_primitive() << '\\n';\n\n    // JSON text can never produce a binary value: is_binary() is always false\n    std::cout << d_array.root().is_binary() << '\\n';\n\n    // a default-constructed view, and the root of a document that failed to\n    // parse without exceptions, are both discarded\n    nlohmann::json_view invalid;\n    json_document failed = json_document::parse(\"not json\", /* allow_exceptions */ false);\n    std::cout << invalid.is_discarded() << '\\n';\n    std::cout << failed.root().is_discarded() << '\\n';\n\n    // type() returns the same value_t enumeration as basic_json::type()\n    std::cout << (d_object.root().type() == nlohmann::json::value_t::object) << '\\n';\n}\n

    Output:

    true\ntrue\ntrue true\ntrue\ntrue\ntrue\ntrue true\ntrue false\nfalse\ntrue\ntrue\ntrue\n
    "},{"location":"api/basic_json_view/is_number_unsigned/#see-also","title":"See also","text":"
    • is_number_integer - return whether the value is an integer or unsigned integer number
    • BasicJsonType::is_number_unsigned - the corresponding function of basic_json
    "},{"location":"api/basic_json_view/is_number_unsigned/#version-history","title":"Version history","text":"
    • Added in version 3.13.0 unreleased.
    "},{"location":"api/basic_json_view/is_object/","title":"nlohmann::basic_json_view::is_object","text":"
    bool is_object() const noexcept;\n

    This function returns true if and only if the value is an object.

    "},{"location":"api/basic_json_view/is_object/#return-value","title":"Return value","text":"

    true if the type is an object, false otherwise.

    "},{"location":"api/basic_json_view/is_object/#exception-safety","title":"Exception safety","text":"

    No-throw guarantee: this function never throws exceptions.

    "},{"location":"api/basic_json_view/is_object/#complexity","title":"Complexity","text":"

    Constant.

    "},{"location":"api/basic_json_view/is_object/#examples","title":"Examples","text":"Example

    The example below classifies several parsed documents by the type of their root value, without materializing any of them into a BasicJsonType value.

    #include <iostream>\n#include <nlohmann/json_view.hpp>\n\nusing nlohmann::json_document;\n\nint main()\n{\n    std::cout << std::boolalpha;\n\n    // several incoming messages, one json_document per message. type() and\n    // is_*() only look at the flat index built by parse(); no nlohmann::json\n    // tree exists yet, and none is built unless materialize() is called\n    json_document d_null = json_document::parse(\"null\");\n    json_document d_bool = json_document::parse(\"true\");\n    json_document d_int = json_document::parse(\"-42\");\n    json_document d_unsigned = json_document::parse(\"42\");\n    json_document d_float = json_document::parse(\"4.2\");\n    json_document d_string = json_document::parse(R\"(\"hi\")\");\n    json_document d_array = json_document::parse(\"[1, 2, 3]\");\n    json_document d_object = json_document::parse(R\"({\"a\": 1})\");\n\n    std::cout << d_null.root().is_null() << '\\n';\n    std::cout << d_bool.root().is_boolean() << '\\n';\n    std::cout << d_int.root().is_number() << ' ' << d_int.root().is_number_integer() << '\\n';\n    std::cout << d_unsigned.root().is_number_unsigned() << '\\n';\n    std::cout << d_float.root().is_number_float() << '\\n';\n    std::cout << d_string.root().is_string() << '\\n';\n    std::cout << d_array.root().is_array() << ' ' << d_array.root().is_structured() << '\\n';\n    std::cout << d_object.root().is_object() << ' ' << d_object.root().is_primitive() << '\\n';\n\n    // JSON text can never produce a binary value: is_binary() is always false\n    std::cout << d_array.root().is_binary() << '\\n';\n\n    // a default-constructed view, and the root of a document that failed to\n    // parse without exceptions, are both discarded\n    nlohmann::json_view invalid;\n    json_document failed = json_document::parse(\"not json\", /* allow_exceptions */ false);\n    std::cout << invalid.is_discarded() << '\\n';\n    std::cout << failed.root().is_discarded() << '\\n';\n\n    // type() returns the same value_t enumeration as basic_json::type()\n    std::cout << (d_object.root().type() == nlohmann::json::value_t::object) << '\\n';\n}\n

    Output:

    true\ntrue\ntrue true\ntrue\ntrue\ntrue\ntrue true\ntrue false\nfalse\ntrue\ntrue\ntrue\n
    "},{"location":"api/basic_json_view/is_object/#see-also","title":"See also","text":"
    • is_structured - return whether the type is structured
    • size - the number of elements
    • empty - whether there are no elements
    • BasicJsonType::is_object - the corresponding function of basic_json
    "},{"location":"api/basic_json_view/is_object/#version-history","title":"Version history","text":"
    • Added in version 3.13.0 unreleased.
    "},{"location":"api/basic_json_view/is_primitive/","title":"nlohmann::basic_json_view::is_primitive","text":"
    bool is_primitive() const noexcept;\n

    This function returns true if and only if the value is primitive, i.e. null, a boolean, a number, or a string. It is defined as is_null() || is_string() || is_boolean() || is_number().

    "},{"location":"api/basic_json_view/is_primitive/#return-value","title":"Return value","text":"

    true if the type is primitive, false otherwise.

    "},{"location":"api/basic_json_view/is_primitive/#exception-safety","title":"Exception safety","text":"

    No-throw guarantee: this function never throws exceptions.

    "},{"location":"api/basic_json_view/is_primitive/#complexity","title":"Complexity","text":"

    Constant.

    "},{"location":"api/basic_json_view/is_primitive/#examples","title":"Examples","text":"Example

    The example below classifies several parsed documents by the type of their root value, without materializing any of them into a BasicJsonType value.

    #include <iostream>\n#include <nlohmann/json_view.hpp>\n\nusing nlohmann::json_document;\n\nint main()\n{\n    std::cout << std::boolalpha;\n\n    // several incoming messages, one json_document per message. type() and\n    // is_*() only look at the flat index built by parse(); no nlohmann::json\n    // tree exists yet, and none is built unless materialize() is called\n    json_document d_null = json_document::parse(\"null\");\n    json_document d_bool = json_document::parse(\"true\");\n    json_document d_int = json_document::parse(\"-42\");\n    json_document d_unsigned = json_document::parse(\"42\");\n    json_document d_float = json_document::parse(\"4.2\");\n    json_document d_string = json_document::parse(R\"(\"hi\")\");\n    json_document d_array = json_document::parse(\"[1, 2, 3]\");\n    json_document d_object = json_document::parse(R\"({\"a\": 1})\");\n\n    std::cout << d_null.root().is_null() << '\\n';\n    std::cout << d_bool.root().is_boolean() << '\\n';\n    std::cout << d_int.root().is_number() << ' ' << d_int.root().is_number_integer() << '\\n';\n    std::cout << d_unsigned.root().is_number_unsigned() << '\\n';\n    std::cout << d_float.root().is_number_float() << '\\n';\n    std::cout << d_string.root().is_string() << '\\n';\n    std::cout << d_array.root().is_array() << ' ' << d_array.root().is_structured() << '\\n';\n    std::cout << d_object.root().is_object() << ' ' << d_object.root().is_primitive() << '\\n';\n\n    // JSON text can never produce a binary value: is_binary() is always false\n    std::cout << d_array.root().is_binary() << '\\n';\n\n    // a default-constructed view, and the root of a document that failed to\n    // parse without exceptions, are both discarded\n    nlohmann::json_view invalid;\n    json_document failed = json_document::parse(\"not json\", /* allow_exceptions */ false);\n    std::cout << invalid.is_discarded() << '\\n';\n    std::cout << failed.root().is_discarded() << '\\n';\n\n    // type() returns the same value_t enumeration as basic_json::type()\n    std::cout << (d_object.root().type() == nlohmann::json::value_t::object) << '\\n';\n}\n

    Output:

    true\ntrue\ntrue true\ntrue\ntrue\ntrue\ntrue true\ntrue false\nfalse\ntrue\ntrue\ntrue\n
    "},{"location":"api/basic_json_view/is_primitive/#see-also","title":"See also","text":"
    • is_structured - return whether the type is structured (the complement of this function, for a non-discarded view)
    • BasicJsonType::is_primitive - the corresponding function of basic_json
    "},{"location":"api/basic_json_view/is_primitive/#version-history","title":"Version history","text":"
    • Added in version 3.13.0 unreleased.
    "},{"location":"api/basic_json_view/is_string/","title":"nlohmann::basic_json_view::is_string","text":"
    bool is_string() const noexcept;\n

    This function returns true if and only if the value is a string.

    "},{"location":"api/basic_json_view/is_string/#return-value","title":"Return value","text":"

    true if the type is a string, false otherwise.

    "},{"location":"api/basic_json_view/is_string/#exception-safety","title":"Exception safety","text":"

    No-throw guarantee: this function never throws exceptions.

    "},{"location":"api/basic_json_view/is_string/#complexity","title":"Complexity","text":"

    Constant.

    "},{"location":"api/basic_json_view/is_string/#examples","title":"Examples","text":"Example

    The example below classifies several parsed documents by the type of their root value, without materializing any of them into a BasicJsonType value.

    #include <iostream>\n#include <nlohmann/json_view.hpp>\n\nusing nlohmann::json_document;\n\nint main()\n{\n    std::cout << std::boolalpha;\n\n    // several incoming messages, one json_document per message. type() and\n    // is_*() only look at the flat index built by parse(); no nlohmann::json\n    // tree exists yet, and none is built unless materialize() is called\n    json_document d_null = json_document::parse(\"null\");\n    json_document d_bool = json_document::parse(\"true\");\n    json_document d_int = json_document::parse(\"-42\");\n    json_document d_unsigned = json_document::parse(\"42\");\n    json_document d_float = json_document::parse(\"4.2\");\n    json_document d_string = json_document::parse(R\"(\"hi\")\");\n    json_document d_array = json_document::parse(\"[1, 2, 3]\");\n    json_document d_object = json_document::parse(R\"({\"a\": 1})\");\n\n    std::cout << d_null.root().is_null() << '\\n';\n    std::cout << d_bool.root().is_boolean() << '\\n';\n    std::cout << d_int.root().is_number() << ' ' << d_int.root().is_number_integer() << '\\n';\n    std::cout << d_unsigned.root().is_number_unsigned() << '\\n';\n    std::cout << d_float.root().is_number_float() << '\\n';\n    std::cout << d_string.root().is_string() << '\\n';\n    std::cout << d_array.root().is_array() << ' ' << d_array.root().is_structured() << '\\n';\n    std::cout << d_object.root().is_object() << ' ' << d_object.root().is_primitive() << '\\n';\n\n    // JSON text can never produce a binary value: is_binary() is always false\n    std::cout << d_array.root().is_binary() << '\\n';\n\n    // a default-constructed view, and the root of a document that failed to\n    // parse without exceptions, are both discarded\n    nlohmann::json_view invalid;\n    json_document failed = json_document::parse(\"not json\", /* allow_exceptions */ false);\n    std::cout << invalid.is_discarded() << '\\n';\n    std::cout << failed.root().is_discarded() << '\\n';\n\n    // type() returns the same value_t enumeration as basic_json::type()\n    std::cout << (d_object.root().type() == nlohmann::json::value_t::object) << '\\n';\n}\n

    Output:

    true\ntrue\ntrue true\ntrue\ntrue\ntrue\ntrue true\ntrue false\nfalse\ntrue\ntrue\ntrue\n
    "},{"location":"api/basic_json_view/is_string/#see-also","title":"See also","text":"
    • source_offset - byte offset of this value in the source text, which differs for strings: an escaped string has none
    • BasicJsonType::is_string - the corresponding function of basic_json
    "},{"location":"api/basic_json_view/is_string/#version-history","title":"Version history","text":"
    • Added in version 3.13.0 unreleased.
    "},{"location":"api/basic_json_view/is_structured/","title":"nlohmann::basic_json_view::is_structured","text":"
    bool is_structured() const noexcept;\n

    This function returns true if and only if the value is structured, i.e. an array or an object. It is defined as is_array() || is_object().

    "},{"location":"api/basic_json_view/is_structured/#return-value","title":"Return value","text":"

    true if the type is structured, false otherwise.

    "},{"location":"api/basic_json_view/is_structured/#exception-safety","title":"Exception safety","text":"

    No-throw guarantee: this function never throws exceptions.

    "},{"location":"api/basic_json_view/is_structured/#complexity","title":"Complexity","text":"

    Constant.

    "},{"location":"api/basic_json_view/is_structured/#examples","title":"Examples","text":"Example

    The example below classifies several parsed documents by the type of their root value, without materializing any of them into a BasicJsonType value.

    #include <iostream>\n#include <nlohmann/json_view.hpp>\n\nusing nlohmann::json_document;\n\nint main()\n{\n    std::cout << std::boolalpha;\n\n    // several incoming messages, one json_document per message. type() and\n    // is_*() only look at the flat index built by parse(); no nlohmann::json\n    // tree exists yet, and none is built unless materialize() is called\n    json_document d_null = json_document::parse(\"null\");\n    json_document d_bool = json_document::parse(\"true\");\n    json_document d_int = json_document::parse(\"-42\");\n    json_document d_unsigned = json_document::parse(\"42\");\n    json_document d_float = json_document::parse(\"4.2\");\n    json_document d_string = json_document::parse(R\"(\"hi\")\");\n    json_document d_array = json_document::parse(\"[1, 2, 3]\");\n    json_document d_object = json_document::parse(R\"({\"a\": 1})\");\n\n    std::cout << d_null.root().is_null() << '\\n';\n    std::cout << d_bool.root().is_boolean() << '\\n';\n    std::cout << d_int.root().is_number() << ' ' << d_int.root().is_number_integer() << '\\n';\n    std::cout << d_unsigned.root().is_number_unsigned() << '\\n';\n    std::cout << d_float.root().is_number_float() << '\\n';\n    std::cout << d_string.root().is_string() << '\\n';\n    std::cout << d_array.root().is_array() << ' ' << d_array.root().is_structured() << '\\n';\n    std::cout << d_object.root().is_object() << ' ' << d_object.root().is_primitive() << '\\n';\n\n    // JSON text can never produce a binary value: is_binary() is always false\n    std::cout << d_array.root().is_binary() << '\\n';\n\n    // a default-constructed view, and the root of a document that failed to\n    // parse without exceptions, are both discarded\n    nlohmann::json_view invalid;\n    json_document failed = json_document::parse(\"not json\", /* allow_exceptions */ false);\n    std::cout << invalid.is_discarded() << '\\n';\n    std::cout << failed.root().is_discarded() << '\\n';\n\n    // type() returns the same value_t enumeration as basic_json::type()\n    std::cout << (d_object.root().type() == nlohmann::json::value_t::object) << '\\n';\n}\n

    Output:

    true\ntrue\ntrue true\ntrue\ntrue\ntrue\ntrue true\ntrue false\nfalse\ntrue\ntrue\ntrue\n
    "},{"location":"api/basic_json_view/is_structured/#see-also","title":"See also","text":"
    • is_primitive - return whether the type is primitive
    • size, empty - the number of elements, and whether there are none
    • BasicJsonType::is_structured - the corresponding function of basic_json
    "},{"location":"api/basic_json_view/is_structured/#version-history","title":"Version history","text":"
    • Added in version 3.13.0 unreleased.
    "},{"location":"api/basic_json_view/items/","title":"nlohmann::basic_json_view::items","text":"
    /* unspecified */ items() const noexcept;\n

    Returns a range of items \u2014 (key, value) pairs \u2014 for use in range-based for loops. An item's key() is a string_view_t (for an array element, its index converted to a string, as for BasicJsonType::items()), and its value() is a basic_json_view of the element.

    The returned type is not part of the public API and may change between versions; use a range-based for loop (see the example), or decltype(v.items()) if you need to name it.

    for (const auto& item : v.items())\n{\n    std::cout << \"key: \" << item.key() << \", value: \" << item.value() << '\\n';\n}\n

    On C++17, item also supports structured bindings:

    for (const auto [key, value] : v.items())\n{\n    std::cout << \"key: \" << key << \", value: \" << value << '\\n';\n}\n

    Note the const auto (by value), not const auto&: unlike BasicJsonType::items(), whose elements are references into an existing object, a view's item is produced on the fly for each step of the iteration, so there is nothing for a reference to bind to.

    "},{"location":"api/basic_json_view/items/#return-value","title":"Return value","text":"

    A range whose iterators dereference to an item (with key() and value(), see above) and whose begin()/end() are equivalent to basic_json_view::begin()/end(), in document order.

    "},{"location":"api/basic_json_view/items/#exception-safety","title":"Exception safety","text":"

    No-throw guarantee: this function never throws exceptions.

    "},{"location":"api/basic_json_view/items/#complexity","title":"Complexity","text":"

    Constant.

    "},{"location":"api/basic_json_view/items/#notes","title":"Notes","text":"

    As for begin()/end(), items() visits every member of an object, including all occurrences of a duplicate key \u2014 unlike operator[], at, find, and contains, which resolve to the first member with a given key. See the Notes on duplicate keys of operator[].

    Lifetime issues

    Unlike BasicJsonType::items() (see #2040), calling items() on a temporary view is safe, for instance for (auto item : v[\"a\"].items()): the returned range holds a copy of the view. What must outlive the loop is the document and, for a borrowed document, the source buffer.

    "},{"location":"api/basic_json_view/items/#examples","title":"Examples","text":"Example

    The example below shows a settings object whose source text records every update to a key as a duplicate member, in the order they happened. items() walks all of them, so the update history is visible, while operator[] only ever sees the first one and materialize() \u2014 like BasicJsonType::parse() \u2014 keeps only the last.

    #include <iostream>\n#include <nlohmann/json_view.hpp>\n\nusing nlohmann::json_document;\n\nint main()\n{\n    // a settings object whose source text records every update to a key as\n    // a duplicate member. items() visits all of them, in document order, so\n    // the update history is visible; operator[] only ever sees the first\n    // one, and materialize() -- like basic_json::parse() -- keeps the last\n    json_document updates = json_document::parse(R\"({\"retries\": 1, \"timeout\": 30, \"retries\": 5})\");\n    const auto settings = updates.root();\n\n    for (const auto& item : settings.items())\n    {\n        std::cout << item.key() << '=' << item.value().materialize().dump() << '\\n';\n    }\n\n    std::cout << \"first \\\"retries\\\" seen by operator[]: \" << settings[\"retries\"].materialize().dump() << '\\n';\n    std::cout << \"last \\\"retries\\\" kept by materialize(): \" << settings.materialize()[\"retries\"].dump() << '\\n';\n}\n

    Output:

    retries=1\ntimeout=30\nretries=5\nfirst \"retries\" seen by operator[]: 1\nlast \"retries\" kept by materialize(): 5\n
    "},{"location":"api/basic_json_view/items/#see-also","title":"See also","text":"
    • begin, end - the iterators items() is built on
    • BasicJsonType::items - the corresponding function of basic_json
    "},{"location":"api/basic_json_view/items/#version-history","title":"Version history","text":"
    • Added in version 3.13.0 unreleased.
    "},{"location":"api/basic_json_view/materialize/","title":"nlohmann::basic_json_view::materialize","text":"
    BasicJsonType materialize() const;\n

    Builds the BasicJsonType value of this subtree: the value BasicJsonType::parse() would have produced for the same source text, allocated for the first time by this call.

    "},{"location":"api/basic_json_view/materialize/#return-value","title":"Return value","text":"

    The BasicJsonType value of this subtree, or a discarded BasicJsonType value (BasicJsonType(value_t::discarded)) if the view is discarded.

    "},{"location":"api/basic_json_view/materialize/#exception-safety","title":"Exception safety","text":"

    Strong guarantee: there are no changes to the view or the document it refers to (nothing about either is mutated by this function).

    "},{"location":"api/basic_json_view/materialize/#exceptions","title":"Exceptions","text":"

    May throw std::bad_alloc (via BasicJsonType's allocator) if constructing the result fails.

    "},{"location":"api/basic_json_view/materialize/#complexity","title":"Complexity","text":"

    Linear in the size of the subtree.

    "},{"location":"api/basic_json_view/materialize/#notes","title":"Notes","text":"

    materialize() replays the subtree through the same SAX builder BasicJsonType::parse() uses, so the result matches it exactly \u2014 including, for an object, that a repeated key keeps only its last value. The replay is iterative, so it is not limited by the call stack the way a naive recursive conversion would be; the JSON nesting depth is limited only by available memory, as for BasicJsonType::parse() itself.

    With JSON_DIAGNOSTIC_POSITIONS enabled, the values get the source positions BasicJsonType::parse() would give them, also for the subtree of a view (the positions are those in the document's whole source text), and exceptions about them name the same bytes. For values of an editable document, positions are all-or-nothing, and start_pos() and end_pos() return std::string::npos for

    • a value written by an edit (a copy of an array or object of the document is also new; copies of its scalars keep their positions),
    • an array or object whose elements were changed (its elements keep theirs), and
    • an array or object whose last element has no positions (its end is found from that element).

    This differs from a basic_json value, whose positions are not updated when it is changed: they stay as they were parsed, even if they no longer match the value (see start_pos()).

    Documents loaded from an image have the positions of the saved document. Its strings with escapes have positions only if the document was parsed with JSON_DIAGNOSTIC_POSITIONS: the position of their opening quote is recorded while parsing, and save() and load() keep it whether or not they are compiled with the macro.

    Calling materialize() on the same view repeatedly builds a new, independent BasicJsonType value each time; it never caches the result.

    "},{"location":"api/basic_json_view/materialize/#examples","title":"Examples","text":"Example

    The example below skips messages that are not useful \u2014 a discarded value, or an empty array \u2014 using only is_array() and empty(), and calls materialize() only for the messages that are actually used, so no BasicJsonType value (and none of its per-element allocations) is ever built for the skipped ones.

    #include <array>\n#include <iostream>\n#include <nlohmann/json_view.hpp>\n\nusing nlohmann::json_document;\n\nint main()\n{\n    // three incoming messages; skip the ones that are not useful without ever\n    // building a nlohmann::json value for them\n    json_document heartbeat = json_document::parse(\"null\");\n    json_document empty_batch = json_document::parse(\"[]\");\n    json_document batch = json_document::parse(R\"([{\"id\": 1}, {\"id\": 2}, {\"id\": 3}])\");\n    std::array<const json_document*, 3> messages = {{&heartbeat, &empty_batch, &batch}};\n\n    for (const json_document* d : messages)\n    {\n        // is_array()/empty() only look at the flat index: a discarded\n        // heartbeat or an empty batch is never turned into a nlohmann::json\n        // value, so no per-element allocation happens for them\n        if (!d->root().is_array() || d->root().empty())\n        {\n            std::cout << \"skipped\\n\";\n            continue;\n        }\n\n        // materialize() replays the subtree through the same SAX builder\n        // basic_json::parse() uses, so the result is exactly what\n        // basic_json::parse() would have produced for the same text\n        nlohmann::json value = d->root().materialize();\n        std::cout << value.dump() << '\\n';\n    }\n}\n

    Output:

    skipped\nskipped\n[{\"id\":1},{\"id\":2},{\"id\":3}]\n
    "},{"location":"api/basic_json_view/materialize/#see-also","title":"See also","text":"
    • root - the view of a document's root value
    • BasicJsonType::parse - build a BasicJsonType value directly from a JSON text
    • JSON_DIAGNOSTIC_POSITIONS - source positions on parsed values
    • Zero-copy JSON views - when to build a basic_json value from a view
    "},{"location":"api/basic_json_view/materialize/#version-history","title":"Version history","text":"
    • Added in version 3.13.0 unreleased.
    "},{"location":"api/basic_json_view/number_format/","title":"nlohmann::basic_json_view::number_format","text":"
    enum class number_format {\n    shortest,\n    source\n};\n

    This enumeration is used in dump to choose how numbers are written. Two values are differentiated:

    shortest integers are copied from the source text \u2014 already canonical in JSON \u2014 except that -0 becomes 0, the way BasicJsonType::parse() reads it; floats are written with the library's shortest round-trip conversion, exactly as BasicJsonType::dump() would (e.g. 1.5, 100.0, 1e+100) source every number is copied exactly as it appears in the source text \u2014 1.50, 1E2, -0, all digits of an integer literal with more digits than any number type holds \u2014 something BasicJsonType cannot do, since parsing already reduces every number to its parsed value"},{"location":"api/basic_json_view/number_format/#examples","title":"Examples","text":"Example

    The example below writes back a price list received from a supplier: with number_format::shortest (the default), a trailing zero and scientific notation are normalized away and a long account number that overflows every number type is rounded, the same way materialize().dump() (or basic_json::dump()) would; number_format::source keeps every number exactly as it was written in the source text instead.

    #include <iostream>\n#include <nlohmann/json_view.hpp>\n\nusing nlohmann::json_document;\nusing nlohmann::json_view;\n\nint main()\n{\n    // a price list received from a supplier feed -- prices and account\n    // numbers must be forwarded exactly, e.g. into an invoice\n    const json_document doc = json_document::parse(R\"(\n      [{\"sku\": \"A1\", \"price\": 19.90, \"account_id\": 12345678901234567890123456},\n       {\"sku\": \"A2\", \"price\": 1E2, \"account_id\": 98765432109876543210987654}]\n    )\");\n    const json_view list = doc.root();\n\n    // number_format::shortest (the default) writes numbers the way\n    // basic_json::dump() would: \"19.90\" becomes \"19.9\", \"1E2\" becomes\n    // \"100.0\", and each account number -- far beyond any 64-bit integer --\n    // is rounded to the nearest double, exactly as materialize().dump()\n    // (or a plain nlohmann::json) would round it\n    std::cout << list.dump() << '\\n';\n\n    // number_format::source copies every number exactly as it was written\n    // in the source text instead -- something basic_json cannot do at all,\n    // since parsing already reduces every number to its parsed value\n    std::cout << list.dump(-1, ' ', false, json_view::number_format::source) << '\\n';\n}\n

    Output:

    [{\"sku\":\"A1\",\"price\":19.9,\"account_id\":1.2345678901234568e+25},{\"sku\":\"A2\",\"price\":100.0,\"account_id\":9.876543210987655e+25}]\n[{\"sku\":\"A1\",\"price\":19.90,\"account_id\":12345678901234567890123456},{\"sku\":\"A2\",\"price\":1E2,\"account_id\":98765432109876543210987654}]\n
    "},{"location":"api/basic_json_view/number_format/#see-also","title":"See also","text":"
    • dump - serialize to a JSON-formatted string
    • number_token - get a single number's token text without dumping the whole value
    • BasicJsonType::error_handler_t - the analogous enumeration for BasicJsonType::dump's decoding-error behavior
    • Zero-copy JSON views - writing numbers as they appeared in the source
    "},{"location":"api/basic_json_view/number_format/#version-history","title":"Version history","text":"
    • Added in version 3.13.0 unreleased.
    "},{"location":"api/basic_json_view/number_token/","title":"nlohmann::basic_json_view::number_token","text":"
    string_view_t number_token() const;\n

    Returns the number exactly as it appears in the source text, without parsing or rounding it.

    "},{"location":"api/basic_json_view/number_token/#return-value","title":"Return value","text":"

    The number's token text, as a string_view_t into the document's source() text \u2014 for example \"1.50\", \"1E2\", \"-0\", or an integer literal with more digits than any number type holds (such as a 30-digit integer, which get<T>() and materialize() can only represent approximately, as a number_float_t).

    "},{"location":"api/basic_json_view/number_token/#exception-safety","title":"Exception safety","text":"

    Strong guarantee: there are no changes to the view or the document it refers to.

    "},{"location":"api/basic_json_view/number_token/#exceptions","title":"Exceptions","text":"

    Throws type_error.302 if the value is not a number; example: \"type must be number, but is string\".

    This exception does not carry a JSON_DIAGNOSTICS path: the view has no BasicJsonType value to point at, so the exception is created without one, even if BasicJsonType was built with JSON_DIAGNOSTICS enabled.

    "},{"location":"api/basic_json_view/number_token/#complexity","title":"Complexity","text":"

    Constant.

    "},{"location":"api/basic_json_view/number_token/#notes","title":"Notes","text":"

    BasicJsonType has no counterpart to this function: once a number is parsed into number_integer_t, number_unsigned_t, or number_float_t, its original textual form (leading zeros aside, which are already rejected by the grammar; trailing zeros in the fraction; the case and sign of the exponent; ...) is gone. number_token() is useful precisely where that form must survive \u2014 a price or an identifier that must be reproduced exactly, or a number too large for any of BasicJsonType's number types to hold without loss.

    The returned string_view_t always points into the document's source() text \u2014 numbers are never decoded into the document's separate string buffer \u2014 and is valid exactly as long as that text is, see the validity rules of basic_json_view.

    "},{"location":"api/basic_json_view/number_token/#examples","title":"Examples","text":"Example

    The example below keeps a price and an order ID exactly as they were written in an incoming order, where converting them with get<T>() would lose information: the price picks up floating-point rounding, and the order ID \u2014 more digits than a 64-bit integer holds \u2014 can only be approximated as a double once materialize()d.

    #include <iostream>\n#include <nlohmann/json_view.hpp>\n\nusing nlohmann::json_document;\nusing nlohmann::json_view;\n\nint main()\n{\n    // a price and an order id from an incoming order -- both need to be\n    // reproduced exactly, e.g. for an invoice or an audit log\n    json_document doc = json_document::parse(R\"(\n      {\"price\": 19.90, \"order_id\": 1234567890123456789012345, \"quantity\": 3}\n    )\");\n    const json_view order = doc.root();\n\n    // number_token() returns the number exactly as written in the source\n    std::cout << order[\"price\"].number_token() << '\\n';\n    std::cout << order[\"order_id\"].number_token() << '\\n';\n\n    // get<double>() converts it instead -- the exact source text is gone:\n    // \"19.90\" becomes the double closest to 19.9, printed without the\n    // trailing zero, and the 25-digit order id -- far beyond any 64-bit\n    // integer -- can only be approximated as a double\n    std::cout << order[\"price\"].get<double>() << '\\n';\n    std::cout << order.materialize()[\"order_id\"].dump() << '\\n';\n\n    // an ordinary quantity has nothing to lose either way\n    std::cout << order[\"quantity\"].number_token() << \" == \" << order[\"quantity\"].get<int>() << '\\n';\n}\n

    Output:

    19.90\n1234567890123456789012345\n19.9\n1.2345678901234568e+24\n3 == 3\n
    "},{"location":"api/basic_json_view/number_token/#see-also","title":"See also","text":"
    • get - convert the value to a given type
    • get_string - the string, without a copy
    • BasicJsonType::number_integer_t, number_unsigned_t, number_float_t - the number types get<T>() and materialize() convert into
    • Zero-copy JSON views - reading a number exactly as written
    "},{"location":"api/basic_json_view/number_token/#version-history","title":"Version history","text":"
    • Added in version 3.13.0 unreleased.
    "},{"location":"api/basic_json_view/operator%5B%5D/","title":"nlohmann::basic_json_view::operator[]","text":"
    // (1)\nbasic_json_view operator[](string_view_t key) const;\nbasic_json_view operator[](const char* key) const;\nbasic_json_view operator[](const string_t& key) const;\n\n// (2)\nbasic_json_view operator[](size_type idx) const;\ntemplate<typename IntegerType>\nbasic_json_view operator[](IntegerType idx) const;\n\n// (3)\nbasic_json_view operator[](const json_pointer& ptr) const;\n
    1. Returns the value of the object member with key key \u2014 the first one, should the key occur more than once (see the Notes below) \u2014 or a discarded view if there is no such member.
    2. Returns the array element at index idx, or a discarded view if idx is out of range. The template accepts every integer type except bool and std::size_t (int, unsigned, long, std::int64_t, ...) and forwards to the size_type overload, so that an integer argument is not ambiguous between that overload and 1; a negative idx is out of range.
    3. Returns the value a JSON pointer ptr refers to, starting at this value, or a discarded view wherever resolving it further is not possible without inserting into or extending the document (see Return value and Exceptions below).
    "},{"location":"api/basic_json_view/operator%5B%5D/#parameters","title":"Parameters","text":"key (in) object key of the element to access idx (in) index of the element to access ptr (in) JSON pointer to the element to access"},{"location":"api/basic_json_view/operator%5B%5D/#return-value","title":"Return value","text":"
    1. the value of the first member with key key, or a discarded view if no member has this key (or if this view is discarded)
    2. the element at index idx, or a discarded view if idx >= size() or idx is negative (or if this view is discarded)
    3. the value ptr resolves to, starting at this value, or a discarded view (also if this view is discarded) for exactly the reference tokens where the const overload of BasicJsonType::operator[] invokes undefined behavior for the same pointer and the same document: an object member that does not exist, or an array index that is out of range
    "},{"location":"api/basic_json_view/operator%5B%5D/#exception-safety","title":"Exception safety","text":"

    Strong guarantee: there are no changes to the view or the document it refers to.

    "},{"location":"api/basic_json_view/operator%5B%5D/#exceptions","title":"Exceptions","text":"
    1. Throws type_error.305 if the value is not an object and not discarded \u2014 the same exception, with the same message, that the const overload of BasicJsonType::operator[] throws for a string argument on a non-object value.
    2. Throws type_error.305 if the value is not an array and not discarded \u2014 the same exception, with the same message, that the const overload of BasicJsonType::operator[] throws for a numeric argument on a non-array value.
    3. Throws the same exceptions, with the same messages, that the const overload of BasicJsonType::operator[] throws for the same pointer and the same document:
      • out_of_range.402 if a reference token is \"-\" at an array.
      • out_of_range.404 if a reference token cannot be resolved because it is used on a primitive value.
      • parse_error.106 if an array index in ptr begins with '0'.
      • parse_error.109 if an array index in ptr is not a number.

    None of these exceptions carry a JSON_DIAGNOSTICS path: the view has no BasicJsonType value to point at, so the exception is created without one, even if BasicJsonType was built with JSON_DIAGNOSTICS enabled.

    "},{"location":"api/basic_json_view/operator%5B%5D/#complexity","title":"Complexity","text":"
    1. Linear in the number of members: as for ordered_json, members are compared one after another, in document order, stopping at the first match. Each comparison first checks the key's length \u2014 already known from the index, without reading the key bytes \u2014 before comparing its content, so a key of a different length than key is rejected without touching the source text. Objects with 128 or more members get a hash index of their keys while parsing, so that a lookup in them takes constant time on average.
    2. Linear in idx: elements are skipped one at a time from the first one, since they are not a fixed size in the index (unlike BasicJsonType's array, which is random-access). Constant if no element of the array is an array or object, since the elements are then adjacent in the index.
    3. Linear in the number of reference tokens of ptr and, for each token, in the number of members of the object at that level (as 1.) or the index into the array (as 2.).
    "},{"location":"api/basic_json_view/operator%5B%5D/#notes","title":"Notes","text":"

    Unlike BasicJsonType::operator[], which is undefined behavior (guarded by a runtime assertion) for a missing key on a const value, this operator returns a safe, testable result for a missing key or an index out of range: a discarded view, which is tested with is_discarded. There is also no non-const overload that inserts a missing key or extends an array \u2014 a view never modifies the document.

    Chained access

    operator[] on a discarded view returns a discarded view and does not throw, so a chain like v[\"a\"][\"b\"][0] is safe even if \"a\" or \"b\" is missing: the first missing step makes the whole result discarded, which is tested once at the end. Type errors on values that are not discarded still throw: a key on an array or a primitive, or an index on an object or a primitive, is type_error.305 as for BasicJsonType. at still throws for a discarded view, as it does for a missing key.

    Duplicate keys: the first member wins

    If the source text has an object with a duplicate key, operator[] (and at, find, contains, value, and JSON pointer resolution) all resolve to the first member with that key, because a lookup can stop as soon as it finds a match. This is different from materialize() (and BasicJsonType::parse()), which replay every member in order and so keep the last value for a repeated key, so v[\"a\"] and v.materialize()[\"a\"] can differ. To get the value parse() would give, use materialize() or iterate the members with items() and keep the last match. The key hash index of a larger object (128 members or more) leads to the first member of a key as well. begin()/end() and items() iterate over all members, including duplicates, in document order. See Duplicate keys and size().

    JSON pointer resolution

    Overload 3 walks ptr one reference token at a time, starting at this value, the same way at and contains do. It only ever returns a discarded view where the const overload of BasicJsonType::operator[] would be undefined behavior for the same pointer \u2014 a missing object member or an out-of-range array index \u2014 and still throws for every other way ptr can fail to resolve. See at for the checked version, which throws in every case instead, and contains for a version that never throws.

    "},{"location":"api/basic_json_view/operator%5B%5D/#examples","title":"Examples","text":"Example: (1)/(2) access specified element

    The example below reads a couple of fields out of a batch of user records without ever materializing a full BasicJsonType value for the batch. operator[] is used both to look up an optional object member and to index into an array \u2014 in both cases, a missing value comes back as a discarded view that can be tested with a plain if, instead of relying on undefined behavior.

    #include <iostream>\n#include <nlohmann/json_view.hpp>\n\nusing nlohmann::json_document;\n\nint main()\n{\n    // two user records from a large API response; only the fields that are\n    // actually read are ever touched, and no nlohmann::json tree is built\n    // for the batch\n    json_document batch = json_document::parse(R\"(\n      [\n        {\"name\": \"Alice\", \"email\": \"alice@example.com\", \"tags\": [\"admin\", \"ops\"]},\n        {\"name\": \"Bob\", \"tags\": []}\n      ]\n    )\");\n\n    const auto users = batch.root();\n    for (std::size_t i = 0; i < users.size(); ++i)\n    {\n        const auto user = users[i];\n        std::cout << user[\"name\"].materialize().dump();\n\n        // operator[] on a missing object key gives a discarded view -- test\n        // it with is_discarded(). The const overload of json::operator[]\n        // would instead be undefined behavior (guarded by an assertion) for\n        // a missing key\n        const auto email = user[\"email\"];\n        if (!email.is_discarded())\n        {\n            std::cout << \" <\" << email.materialize().dump() << \">\";\n        }\n\n        // the same holds for an array index past the end: a discarded view,\n        // not undefined behavior\n        const auto first_tag = user[\"tags\"][0];\n        if (!first_tag.is_discarded())\n        {\n            std::cout << \" #\" << first_tag.materialize().dump();\n        }\n\n        std::cout << '\\n';\n    }\n}\n

    Output:

    \"Alice\" <\"alice@example.com\"> #\"admin\"\n\"Bob\"\n
    Example: (3) access specified element via JSON pointer

    The example below reaches straight into one deeply nested field of a large document with a single JSON pointer, without ever building a tree for the rest of it, and shows the discarded-view and throwing outcomes of a pointer that cannot be fully resolved.

    #include <iostream>\n#include <nlohmann/json_view.hpp>\n\nusing nlohmann::json_document;\nusing json_pointer = nlohmann::json::json_pointer;\n\nint main()\n{\n    // a larger document; operator[] with a JSON pointer reaches straight to\n    // one deeply nested field, without ever building a tree for the rest\n    json_document doc = json_document::parse(R\"(\n      {\n        \"region\": {\n          \"servers\": [\n            {\"name\": \"eu-1\", \"metrics\": {\"cpu\": 0.42}},\n            {\"name\": \"eu-2\", \"metrics\": {\"cpu\": 0.71}}\n          ]\n        }\n      }\n    )\");\n\n    const auto root = doc.root();\n    std::cout << root[json_pointer(\"/region/servers/1/metrics/cpu\")].materialize().dump() << '\\n';\n\n    // a missing key or an out-of-range index along the path gives a\n    // discarded view, exactly where const json::operator[] would be\n    // undefined behavior for the same pointer\n    const auto missing = root[json_pointer(\"/region/servers/5/metrics/cpu\")];\n    if (!missing.is_discarded())\n    {\n        std::cout << missing.materialize().dump() << '\\n';\n    }\n    else\n    {\n        std::cout << \"no such server\\n\";\n    }\n\n    // indexing into a primitive still throws, as basic_json::operator[]\n    // does for the same pointer\n    try\n    {\n        static_cast<void>(root[json_pointer(\"/region/servers/0/name/x\")]);\n    }\n    catch (const nlohmann::json::out_of_range& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n}\n

    Output:

    0.71\nno such server\n[json.exception.out_of_range.404] unresolved reference token 'x'\n
    "},{"location":"api/basic_json_view/operator%5B%5D/#see-also","title":"See also","text":"
    • at - access specified element with bounds checking (throws instead of returning a discarded view)
    • front, back - access the first or last element
    • find, contains - look up a member without throwing
    • BasicJsonType::operator[] - the corresponding function of basic_json
    • json_pointer - JSON pointer type used by overload 3
    "},{"location":"api/basic_json_view/operator%5B%5D/#version-history","title":"Version history","text":"
    • Added in version 3.13.0 unreleased.
    "},{"location":"api/basic_json_view/operator_eq/","title":"nlohmann::basic_json_view::operator==","text":"
    // (1)\nbool operator==(const basic_json_view& lhs, const basic_json_view& rhs);\n\n// (2)\nbool operator==(const basic_json_view& lhs, const BasicJsonType& rhs);\nbool operator==(const BasicJsonType& lhs, const basic_json_view& rhs);\n
    1. Compares two views for equality: whether the values BasicJsonType::parse() would produce for lhs and rhs are equal, according to BasicJsonType's operator==.
    2. Compares a view and a BasicJsonType value for equality, in either order: whether the value parse() would produce for the view and the other operand are equal, according to BasicJsonType's operator==.

    Neither overload builds a BasicJsonType value for a view to do the comparison (see Notes below). Numbers compare by value across their types (1 == 1.0), and an object compares by its members, with duplicate keys resolved exactly as parse() resolves them \u2014 the last value, at the position of the first occurrence of the key. This is not what operator[] and the other lookups return for a duplicate key: they find the first member (see Duplicate keys).

    "},{"location":"api/basic_json_view/operator_eq/#parameters","title":"Parameters","text":"lhs (in) first value to consider rhs (in) second value to consider"},{"location":"api/basic_json_view/operator_eq/#return-value","title":"Return value","text":"

    whether the values lhs and rhs are equal

    "},{"location":"api/basic_json_view/operator_eq/#exception-safety","title":"Exception safety","text":"

    Strong exception safety: if an exception is thrown, there are no changes to either operand, or to the document(s) a view refers to.

    "},{"location":"api/basic_json_view/operator_eq/#exceptions","title":"Exceptions","text":"

    May throw std::bad_alloc. Unlike the other comparison and most other basic_json_view functions, operator== is not noexcept: resolving an object's members needs a temporary array to sort them by key (see Complexity below), and that allocation can fail.

    "},{"location":"api/basic_json_view/operator_eq/#complexity","title":"Complexity","text":"

    Linear in the size of the compared values: every number, string, array element, and object member is visited at most once, and the walk is iterative, so the nesting depth it can compare is limited by available memory only, not by the call stack (as for materialize()). Resolving an object's members takes an additional O(n log n) in the number of members at that level, since they are sorted by key to detect and resolve duplicates before being compared. Two arrays of different size() are rejected without visiting either one's elements.

    "},{"location":"api/basic_json_view/operator_eq/#notes","title":"Notes","text":"

    Only a single number, boolean, or null value is ever materialized into a BasicJsonType, to reuse its operator== \u2014 for numbers, so that values written differently in the source text but equal in value (e.g. an integer and a floating-point literal) still compare equal, following the same rules BasicJsonType does for special values such as NaN. Constructing one of these scalars never allocates. Strings are compared directly, without allocating, either from the source text on both sides or, for overload 2, against BasicJsonType's own string. Arrays and objects are never materialized at all; only their elements or members are visited, one pair at a time.

    How objects are compared

    For a json_view (BasicJsonType::object_t is std::map), members are compared by key, regardless of the order they appear in the source text. For an ordered_json_view (object_t is ordered_map), they are compared in the order they occur, so the very same two objects with their members reordered can compare equal as json_views but not as ordered_json_views. This is exactly how json and ordered_json compare, see \"Comparing different basic_json specializations\".

    Discarded views

    A discarded view compares the same way a discarded BasicJsonType value does, which is governed by JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON: by default, a discarded view is never equal to anything, not even another discarded view.

    No ordering comparison (operator<) is provided for basic_json_view; materialize() is the way to get a BasicJsonType value that supports it.

    "},{"location":"api/basic_json_view/operator_eq/#examples","title":"Examples","text":"Example

    The example below checks whether a newly received configuration differs from the previous one, and whether a received document matches what a test expects \u2014 directly on views, without ever materializing a BasicJsonType value for either side.

    #include <iostream>\n#include <nlohmann/json_view.hpp>\n\nusing nlohmann::json_document;\nusing nlohmann::json;\n\nint main()\n{\n    // two snapshots of a polled configuration endpoint -- compare them\n    // directly as views, without ever building a nlohmann::json value for\n    // either one\n    const json_document previous = json_document::parse(\n                                       R\"({\"name\": \"cache\", \"port\": 6379, \"timeout\": 30})\");\n    const json_document current = json_document::parse(\n                                      R\"({\"port\": 6379.0, \"timeout\": 30, \"name\": \"cache\"})\");\n\n    // same members, reordered, and 6379 written as a float -- operator==\n    // treats them the same way BasicJsonType::operator== would\n    std::cout << std::boolalpha << (previous.root() == current.root()) << '\\n';\n\n    // an actually changed value is detected the same way\n    const json_document changed = json_document::parse(\n                                      R\"({\"name\": \"cache\", \"port\": 6380, \"timeout\": 30})\");\n    std::cout << (previous.root() == changed.root()) << '\\n';\n\n    // comparing a view directly against an expected json value -- handy in a\n    // test, without materializing the received document at all\n    const json expected = {{\"name\", \"cache\"}, {\"port\", 6379}, {\"timeout\", 30}};\n    std::cout << (previous.root() == expected) << '\\n';\n}\n

    Output:

    true\nfalse\ntrue\n
    "},{"location":"api/basic_json_view/operator_eq/#see-also","title":"See also","text":"
    • operator!= - compare for inequality
    • materialize - build a BasicJsonType value, e.g. to keep comparing after the document is gone
    • BasicJsonType::operator== - the corresponding function of basic_json
    "},{"location":"api/basic_json_view/operator_eq/#version-history","title":"Version history","text":"
    • Added in version 3.13.0 unreleased.
    "},{"location":"api/basic_json_view/operator_ltlt/","title":"nlohmann::basic_json_view::operator<<","text":"
    std::ostream& operator<<(std::ostream& o, const basic_json_view& v);\n

    Not available when JSON_NO_IO is defined.

    Serializes the given view v to the output stream o, using dump \u2014 exactly as operator<<(std::ostream&, const basic_json&) does for a basic_json value.

    • The indentation of the output can be controlled with the member variable width of the output stream o. For instance, using the manipulator std::setw(4) on o sets the indentation level to 4, and the serialization result is the same as calling v.dump(4). A width of 0 or less (the default) selects the most compact representation, as v.dump(-1) does.
    • The indentation character can be controlled with the member variable fill of the output stream o. For instance, the manipulator std::setfill('\\t') sets indentation to use a tab character rather than the default space character.
    • As for basic_json, o's width is reset to 0 after this call, whether or not it was greater than 0 before.

    Numbers are always written as v.dump() writes them by default, i.e. as with number_format::shortest; there is no way to select number_format::source through the stream.

    "},{"location":"api/basic_json_view/operator_ltlt/#parameters","title":"Parameters","text":"o (in, out) stream to write to v (in) view to serialize"},{"location":"api/basic_json_view/operator_ltlt/#return-value","title":"Return value","text":"

    the stream o

    "},{"location":"api/basic_json_view/operator_ltlt/#exceptions","title":"Exceptions","text":"

    May throw std::bad_alloc, propagated from dump. Unlike operator<<(std::ostream&, const basic_json&), there is no UTF-8 decoding step that could throw type_error.316, and no error_handler to choose between \u2014 see the Exceptions of dump.

    "},{"location":"api/basic_json_view/operator_ltlt/#complexity","title":"Complexity","text":"

    Linear, as dump.

    "},{"location":"api/basic_json_view/operator_ltlt/#examples","title":"Examples","text":"Example

    The example below writes one record out of a larger batch straight to a log stream \u2014 compact for a one-line entry, and pretty-printed with std::setw/std::setfill for a readable dump \u2014 without ever building a BasicJsonType value for the record, or for the rest of the batch.

    #include <iostream>\n#include <iomanip>\n#include <nlohmann/json_view.hpp>\n\nusing nlohmann::json_document;\nusing nlohmann::json_view;\n\nint main()\n{\n    // one order out of a large incoming batch -- write it straight to a log\n    // stream without ever building a basic_json value for it, or for the\n    // rest of the batch\n    const json_document doc = json_document::parse(R\"(\n      [{\"id\": 1, \"item\": \"cable\"}, {\"id\": 2, \"item\": \"adapter\"}]\n    )\");\n    const json_view orders = doc.root();\n\n    // compact, for a one-line log entry\n    std::cout << orders[1] << '\\n';\n\n    // std::setw sets the indentation level, exactly as for basic_json\n    std::cout << std::setw(2) << orders[1] << \"\\n\\n\";\n\n    // std::setfill changes the indentation character\n    std::cout << std::setw(1) << std::setfill('\\t') << orders[1] << '\\n';\n}\n

    Output:

    {\"id\":2,\"item\":\"adapter\"}\n{\n  \"id\": 2,\n  \"item\": \"adapter\"\n}\n\n{\n    \"id\": 2,\n    \"item\": \"adapter\"\n}\n
    "},{"location":"api/basic_json_view/operator_ltlt/#see-also","title":"See also","text":"
    • dump - serialize to a JSON-formatted string
    • operator<<(std::ostream&) - the corresponding operator for basic_json
    • JSON_NO_IO - switch off functions relying on certain C++ I/O headers
    • Zero-copy JSON views - writing a view back without building a tree
    "},{"location":"api/basic_json_view/operator_ltlt/#version-history","title":"Version history","text":"
    • Added in version 3.13.0 unreleased.
    "},{"location":"api/basic_json_view/operator_ne/","title":"nlohmann::basic_json_view::operator!=","text":"
    // (1)\nbool operator!=(const basic_json_view& lhs, const basic_json_view& rhs);\n\n// (2)\nbool operator!=(const basic_json_view& lhs, const BasicJsonType& rhs);\nbool operator!=(const BasicJsonType& lhs, const basic_json_view& rhs);\n
    1. Compares two views for inequality. Returns !(lhs == rhs), see operator==.
    2. Compares a view and a BasicJsonType value for inequality, in either order. Returns !(lhs == rhs) (or, for the reversed order, !(rhs == lhs)), see operator==.

    Since operator!= is defined as the negation of operator==, it follows the same rules for special cases: for instance, since a discarded view is never equal to anything by default (see operator=='s Notes), it is never unequal to anything either \u2014 discarded != discarded is also false, exactly as for a discarded BasicJsonType value.

    "},{"location":"api/basic_json_view/operator_ne/#parameters","title":"Parameters","text":"lhs (in) first value to consider rhs (in) second value to consider"},{"location":"api/basic_json_view/operator_ne/#return-value","title":"Return value","text":"

    whether the values lhs and rhs are not equal

    "},{"location":"api/basic_json_view/operator_ne/#exception-safety","title":"Exception safety","text":"

    Strong exception safety: if an exception is thrown, there are no changes to either operand, or to the document(s) a view refers to.

    "},{"location":"api/basic_json_view/operator_ne/#exceptions","title":"Exceptions","text":"

    May throw std::bad_alloc, propagated from operator==. Unlike most other basic_json_view functions, operator!= is not noexcept.

    "},{"location":"api/basic_json_view/operator_ne/#complexity","title":"Complexity","text":"

    Linear, as operator==.

    "},{"location":"api/basic_json_view/operator_ne/#notes","title":"Notes","text":"

    See the Notes of operator== \u2014 in particular for how an object's members are compared (order matters for ordered_json_view but not for json_view) and for how discarded views compare.

    No ordering comparison (operator<) is provided for basic_json_view; materialize() is the way to get a BasicJsonType value that supports it.

    "},{"location":"api/basic_json_view/operator_ne/#examples","title":"Examples","text":"Example

    The example below asserts, as a test would, that a received document differs from an unwanted value, and shows that \u2014 as for json/ordered_json \u2014 reordering an object's members is detected as a difference for an ordered_json_view but not for a json_view.

    #include <iostream>\n#include <nlohmann/json_view.hpp>\n\nusing nlohmann::json_document;\nusing nlohmann::ordered_json_document;\nusing nlohmann::json;\n\nint main()\n{\n    // assert, as a test would, that a received document differs from an\n    // unwanted shape -- without ever materializing it into a json value just\n    // to compare\n    const json_document received = json_document::parse(\n                                       R\"({\"status\": \"ok\", \"code\": 200})\");\n    const json unwanted = {{\"status\", \"error\"}, {\"code\", 500}};\n    std::cout << std::boolalpha << (received.root() != unwanted) << '\\n';\n\n    // json (std::map) compares object members regardless of order ...\n    const json_document a = json_document::parse(R\"({\"a\": 1, \"b\": 2})\");\n    const json_document b = json_document::parse(R\"({\"b\": 2, \"a\": 1})\");\n    std::cout << (a.root() != b.root()) << '\\n';\n\n    // ... but ordered_json (ordered_map) compares them in the order they\n    // appear, so the very same reordering is detected as a difference\n    const ordered_json_document oa = ordered_json_document::parse(R\"({\"a\": 1, \"b\": 2})\");\n    const ordered_json_document ob = ordered_json_document::parse(R\"({\"b\": 2, \"a\": 1})\");\n    std::cout << (oa.root() != ob.root()) << '\\n';\n}\n

    Output:

    true\nfalse\ntrue\n
    "},{"location":"api/basic_json_view/operator_ne/#see-also","title":"See also","text":"
    • operator== - compare for equality
    • materialize - build a BasicJsonType value, e.g. to keep comparing after the document is gone
    • BasicJsonType::operator!= - the corresponding function of basic_json
    "},{"location":"api/basic_json_view/operator_ne/#version-history","title":"Version history","text":"
    • Added in version 3.13.0 unreleased.
    "},{"location":"api/basic_json_view/size/","title":"nlohmann::basic_json_view::size","text":"
    size_type size() const noexcept;\n

    Returns the number of elements, as BasicJsonType::size() would for the same value.

    "},{"location":"api/basic_json_view/size/#return-value","title":"Return value","text":"

    The return value depends on the type and is defined as follows:

    Value type return value null 0 discarded 0 boolean 1 string 1 number 1 object number of key/value pairs array number of elements"},{"location":"api/basic_json_view/size/#exception-safety","title":"Exception safety","text":"

    No-throw guarantee: this function never throws exceptions.

    "},{"location":"api/basic_json_view/size/#complexity","title":"Complexity","text":"

    Constant: for an object or array, the element count is stored in the index, not counted on demand.

    "},{"location":"api/basic_json_view/size/#notes","title":"Notes","text":"

    As for BasicJsonType::size(), this does not return the length of a string value \u2014 it is 1 for a string, regardless of its length.

    If the source text has an object with a duplicate key, every occurrence counts towards its size() \u2014 unlike materialize() (and BasicJsonType::parse()), which keeps only the last value for a repeated key. This means v.size() can be larger than v.materialize().size(). See the Notes on duplicate keys of operator[] for why lookups and iteration disagree on how many members there are.

    "},{"location":"api/basic_json_view/size/#examples","title":"Examples","text":"Example

    The example below uses size() and empty() to decide whether a parsed message is worth acting on, without materializing it into a BasicJsonType value.

    #include <iostream>\n#include <nlohmann/json_view.hpp>\n\nusing nlohmann::json_document;\n\nint main()\n{\n    std::cout << std::boolalpha;\n\n    // decide whether a batch is worth processing before building any\n    // nlohmann::json value for it\n    json_document batch = json_document::parse(R\"([1, 2, 3, 4, 5])\");\n    json_document empty_batch = json_document::parse(\"[]\");\n\n    std::cout << batch.root().empty() << ' ' << batch.root().size() << '\\n';\n    std::cout << empty_batch.root().empty() << ' ' << empty_batch.root().size() << '\\n';\n\n    // as for basic_json: null has size 0, every other scalar has size 1\n    json_document n = json_document::parse(\"null\");\n    json_document s = json_document::parse(R\"(\"hi\")\");\n    std::cout << n.root().size() << ' ' << s.root().size() << '\\n';\n}\n

    Output:

    false 5\ntrue 0\n0 1\n
    "},{"location":"api/basic_json_view/size/#see-also","title":"See also","text":"
    • empty - return whether the value has no elements
    • BasicJsonType::size - the corresponding function of basic_json
    "},{"location":"api/basic_json_view/size/#version-history","title":"Version history","text":"
    • Added in version 3.13.0 unreleased.
    "},{"location":"api/basic_json_view/source_offset/","title":"nlohmann::basic_json_view::source_offset","text":"
    std::size_t source_offset() const noexcept;\n

    Returns the byte offset of this value in the document's source() text, without materializing anything.

    "},{"location":"api/basic_json_view/source_offset/#return-value","title":"Return value","text":"
    • For a string with no escapes, a number, true/false/null, an array, or an object: the byte offset of the first byte of the value's token (for a string: the first byte after the opening quote) in source().
    • static_cast<std::size_t>(-1) for a discarded view, and for a string that contains escapes \u2014 such a string was decoded once into the document's own buffer, so there is no single byte range in source() left to point at.
    "},{"location":"api/basic_json_view/source_offset/#exception-safety","title":"Exception safety","text":"

    No-throw guarantee: this function never throws exceptions.

    "},{"location":"api/basic_json_view/source_offset/#complexity","title":"Complexity","text":"

    Constant.

    "},{"location":"api/basic_json_view/source_offset/#notes","title":"Notes","text":"

    This is a raw offset, not a length: the API does not (yet) expose how many bytes the token occupies in the source text, so source_offset() alone is enough to report where a value came from (for an error message, for syntax highlighting, ...) but not to slice its exact text back out of source() for a string, whose token length is not the same as its decoded size().

    "},{"location":"api/basic_json_view/source_offset/#examples","title":"Examples","text":"Example
    #include <iostream>\n#include <string>\n#include <nlohmann/json_view.hpp>\n\nusing nlohmann::json_document;\n\nint main()\n{\n    std::cout << std::boolalpha;\n\n    // source_offset() points into source(): useful to report *where* in the\n    // original text a value came from (error messages, syntax highlighting,\n    // forwarding a sub-range verbatim, ...) without materializing it\n    json_document doc = json_document::parse(R\"(  123)\");\n    auto v = doc.root();\n    std::cout << v.source_offset() << ' '\n              << std::string(doc.source().data() + v.source_offset(), 3) << '\\n';\n\n    // a string without escapes also stays in the source text\n    json_document plain = json_document::parse(R\"(\"ab\")\");\n    std::cout << plain.source()[plain.root().source_offset()] << '\\n';\n\n    // a string with escapes is decoded once into the document's own buffer, so\n    // there is no single byte range in source() to point at: source_offset()\n    // returns the \"not applicable\" sentinel\n    json_document escaped = json_document::parse(R\"(\"a\\nb\")\");\n    std::cout << (escaped.root().source_offset() == static_cast<std::size_t>(-1)) << '\\n';\n\n    // a discarded view -- default-constructed, or the root of a failed parse\n    // with allow_exceptions == false -- has no offset either\n    json_document failed = json_document::parse(\"not json\", false);\n    std::cout << (failed.root().source_offset() == static_cast<std::size_t>(-1)) << '\\n';\n}\n

    Output:

    2 123\na\ntrue\ntrue\n
    "},{"location":"api/basic_json_view/source_offset/#see-also","title":"See also","text":"
    • source - the parsed text
    • is_string - return whether the value is a string
    • Zero-copy JSON views - images and the source text
    "},{"location":"api/basic_json_view/source_offset/#version-history","title":"Version history","text":"
    • Added in version 3.13.0 unreleased.
    "},{"location":"api/basic_json_view/type/","title":"nlohmann::basic_json_view::type","text":"
    value_t type() const noexcept;\n

    Returns the type of the value this view refers to, as a value from the value_t enumeration \u2014 the same enumeration BasicJsonType::type() uses.

    "},{"location":"api/basic_json_view/type/#return-value","title":"Return value","text":"

    The type of the value; value_t::discarded for a discarded view.

    "},{"location":"api/basic_json_view/type/#exception-safety","title":"Exception safety","text":"

    No-throw guarantee: this function never throws exceptions.

    "},{"location":"api/basic_json_view/type/#complexity","title":"Complexity","text":"

    Constant.

    "},{"location":"api/basic_json_view/type/#notes","title":"Notes","text":"

    Unlike BasicJsonType::type(), this function can never return value_t::binary: a JSON text has no binary values, so type() only distinguishes the eight ordinary JSON value types (plus discarded).

    "},{"location":"api/basic_json_view/type/#examples","title":"Examples","text":"Example

    The example below classifies several parsed documents by the type of their root value, without materializing any of them into a BasicJsonType value.

    #include <iostream>\n#include <nlohmann/json_view.hpp>\n\nusing nlohmann::json_document;\n\nint main()\n{\n    std::cout << std::boolalpha;\n\n    // several incoming messages, one json_document per message. type() and\n    // is_*() only look at the flat index built by parse(); no nlohmann::json\n    // tree exists yet, and none is built unless materialize() is called\n    json_document d_null = json_document::parse(\"null\");\n    json_document d_bool = json_document::parse(\"true\");\n    json_document d_int = json_document::parse(\"-42\");\n    json_document d_unsigned = json_document::parse(\"42\");\n    json_document d_float = json_document::parse(\"4.2\");\n    json_document d_string = json_document::parse(R\"(\"hi\")\");\n    json_document d_array = json_document::parse(\"[1, 2, 3]\");\n    json_document d_object = json_document::parse(R\"({\"a\": 1})\");\n\n    std::cout << d_null.root().is_null() << '\\n';\n    std::cout << d_bool.root().is_boolean() << '\\n';\n    std::cout << d_int.root().is_number() << ' ' << d_int.root().is_number_integer() << '\\n';\n    std::cout << d_unsigned.root().is_number_unsigned() << '\\n';\n    std::cout << d_float.root().is_number_float() << '\\n';\n    std::cout << d_string.root().is_string() << '\\n';\n    std::cout << d_array.root().is_array() << ' ' << d_array.root().is_structured() << '\\n';\n    std::cout << d_object.root().is_object() << ' ' << d_object.root().is_primitive() << '\\n';\n\n    // JSON text can never produce a binary value: is_binary() is always false\n    std::cout << d_array.root().is_binary() << '\\n';\n\n    // a default-constructed view, and the root of a document that failed to\n    // parse without exceptions, are both discarded\n    nlohmann::json_view invalid;\n    json_document failed = json_document::parse(\"not json\", /* allow_exceptions */ false);\n    std::cout << invalid.is_discarded() << '\\n';\n    std::cout << failed.root().is_discarded() << '\\n';\n\n    // type() returns the same value_t enumeration as basic_json::type()\n    std::cout << (d_object.root().type() == nlohmann::json::value_t::object) << '\\n';\n}\n

    Output:

    true\ntrue\ntrue true\ntrue\ntrue\ntrue\ntrue true\ntrue false\nfalse\ntrue\ntrue\ntrue\n
    "},{"location":"api/basic_json_view/type/#see-also","title":"See also","text":"
    • is_null, is_boolean, is_number, is_string, is_array, is_object - type-specific predicates built on type()
    • BasicJsonType::type - the corresponding function of basic_json
    "},{"location":"api/basic_json_view/type/#version-history","title":"Version history","text":"
    • Added in version 3.13.0 unreleased.
    "},{"location":"api/basic_json_view/type_name/","title":"nlohmann::basic_json_view::type_name","text":"
    const char* type_name() const noexcept;\n

    Returns the type name as string to be used in error messages \u2014 usually to indicate that a function was called on a wrong JSON type. Identical to BasicJsonType::type_name(), including the extra \"discarded\" return value for a discarded view (BasicJsonType::type_name() produces the same string for a discarded BasicJsonType value).

    "},{"location":"api/basic_json_view/type_name/#return-value","title":"Return value","text":"

    a string representation of the type (value_t):

    Value type return value null \"null\" boolean \"boolean\" string \"string\" number (integer, unsigned integer, floating-point) \"number\" object \"object\" array \"array\" discarded \"discarded\"

    type_name() never returns \"binary\", since a JSON text has no binary values (see is_binary()); it also never returns \"invalid\", since a view's kind always comes from a value the parser actually produced.

    "},{"location":"api/basic_json_view/type_name/#exception-safety","title":"Exception safety","text":"

    No-throw guarantee: this function never throws exceptions.

    "},{"location":"api/basic_json_view/type_name/#complexity","title":"Complexity","text":"

    Constant.

    "},{"location":"api/basic_json_view/type_name/#examples","title":"Examples","text":"Example

    The example below reports why some parsed messages were rejected, using only type_name() \u2014 no BasicJsonType value is ever built for the ones that are wrong, and the message text matches what BasicJsonType::type_name() would produce for the same value.

    #include <iostream>\n#include <nlohmann/json_view.hpp>\n\nusing nlohmann::json_document;\nusing nlohmann::json_view;\n\nint main()\n{\n    // report why some parsed messages were rejected, using only\n    // type_name() -- no nlohmann::json value is built for the ones that\n    // are wrong\n    json_document good = json_document::parse(R\"({\"id\": 1})\");\n    json_document bad = json_document::parse(\"[1, 2, 3]\");\n    json_document failed = json_document::parse(\"not json\", /* allow_exceptions */ false);\n\n    for (const json_view v :\n            {\n                good.root(), bad.root(), failed.root()\n            })\n    {\n        if (v.is_object())\n        {\n            std::cout << \"ok\\n\";\n        }\n        else\n        {\n            std::cout << \"expected an object, got \" << v.type_name() << '\\n';\n        }\n    }\n}\n

    Output:

    ok\nexpected an object, got array\nexpected an object, got discarded\n
    "},{"location":"api/basic_json_view/type_name/#see-also","title":"See also","text":"
    • type - return the type of the value
    • BasicJsonType::type_name - the corresponding function of basic_json
    "},{"location":"api/basic_json_view/type_name/#version-history","title":"Version history","text":"
    • Added in version 3.13.0 unreleased.
    "},{"location":"api/basic_json_view/value/","title":"nlohmann::basic_json_view::value","text":"
    // (1)\ntemplate<typename T>\nT value(string_view_t key, const T& default_value) const;\nstring_t value(string_view_t key, const char* default_value) const;\n\n// (2)\ntemplate<typename T>\nT value(const json_pointer& ptr, const T& default_value) const;\nstring_t value(const json_pointer& ptr, const char* default_value) const;\n
    1. Returns the value of the object member with key key \u2014 the first one, should the key occur more than once (see Notes on duplicate keys) \u2014 converted to T, or default_value if there is no such member.
    2. Returns the value a JSON pointer ptr refers to, starting at this value, converted to T, or default_value if ptr cannot be resolved.

    Both overloads have a dedicated const char* overload, so v.value(key, \"default\") (and the JSON pointer equivalent) deduce string_t, not const char*, for their return type and for the comparison used to pick between key and default_value.

    "},{"location":"api/basic_json_view/value/#template-parameters","title":"Template parameters","text":"T the type to convert the found value to; also the type of default_value"},{"location":"api/basic_json_view/value/#parameters","title":"Parameters","text":"key (in) object key of the element to access ptr (in) JSON pointer to the element to access default_value (in) the value to return if key/ptr resolves to no value"},{"location":"api/basic_json_view/value/#return-value","title":"Return value","text":"
    1. the first member with key key, converted to T, or default_value
    2. the value ptr resolves to, converted to T, or default_value
    "},{"location":"api/basic_json_view/value/#exception-safety","title":"Exception safety","text":"

    Strong guarantee: there are no changes to the view or the document it refers to.

    "},{"location":"api/basic_json_view/value/#exceptions","title":"Exceptions","text":"
    1. Throws type_error.306 if the value is not an object \u2014 the same exception, with the same message, that BasicJsonType::value throws for the same call. If a member with key key is found, throws whatever converting it to T throws (typically type_error.302, with the same message BasicJsonType::value throws for the same mismatch); a missing member never throws.
    2. Throws type_error.306 if this value \u2014 not the value ptr resolves to \u2014 is neither an object nor an array. Throws parse_error.106 or parse_error.109 if ptr contains a malformed array index. If ptr resolves to a value, throws whatever converting it to T throws. Every other way ptr can fail to resolve \u2014 a missing key, an out-of-range or \"-\" array index, an unresolvable token on a primitive \u2014 yields default_value instead of throwing, exactly as BasicJsonType::value catches out_of_range and returns default_value.

    None of these exceptions carry a JSON_DIAGNOSTICS path: the view has no BasicJsonType value to point at, so the exception is created without one, even if BasicJsonType was built with JSON_DIAGNOSTICS enabled.

    "},{"location":"api/basic_json_view/value/#complexity","title":"Complexity","text":"
    1. Linear in the number of members: as for operator[], members are compared one after another, in document order, stopping at the first match. Plus the complexity of converting the found member to T (see get). Objects with 128 or more members get a hash index of their keys while parsing, so that a lookup in them takes constant time on average.
    2. Linear in the number of reference tokens of ptr and, for each token, in the number of members of the object at that level or the index into the array \u2014 as for the operator[] and at overloads that take a JSON pointer. Plus the complexity of converting the resolved value to T.
    "},{"location":"api/basic_json_view/value/#notes","title":"Notes","text":"

    Duplicate keys: the first member wins

    If the source text repeats a key, this resolves to the first member with it, not to the last one that materialize() and parse() keep. See the Notes on duplicate keys of operator[] and Duplicate keys for the reasons and for how to get the last value.

    Differences to at and operator[]

    Unlike at, this function does not throw if key/ptr resolves to no value. Unlike operator[], it never returns a discarded view \u2014 it always returns a T \u2014 and it is available on any view, since it never needs to insert a missing element the way the non-const BasicJsonType::operator[] would.

    Which values can be asked

    As for BasicJsonType::value, the key overload (1) requires an object, and the JSON pointer overload (2) an object or an array.

    "},{"location":"api/basic_json_view/value/#examples","title":"Examples","text":"Example: (1) access specified object element with default value

    The example below reads a couple of optional configuration fields with a default, so that a missing key never needs a try/catch of its own.

    #include <iostream>\n#include <nlohmann/json_view.hpp>\n#include <string>\n\nusing nlohmann::json_document;\nusing nlohmann::json_view;\n\nint main()\n{\n    json_document doc = json_document::parse(R\"({\"server\": {\"host\": \"localhost\"}})\");\n    const json_view server = doc.root()[\"server\"];\n\n    // \"port\" is missing -- value() returns the default instead of\n    // throwing, so optional configuration fields never need their own\n    // try/catch\n    std::cout << server.value(\"host\", std::string(\"0.0.0.0\")) << '\\n';\n    std::cout << server.value(\"port\", 8080) << '\\n';\n\n    // a present but wrong-typed default still throws -- value() only\n    // replaces \"not found\", not \"wrong type\", exactly as basic_json::value\n    try\n    {\n        static_cast<void>(server.value(\"host\", 0));\n    }\n    catch (const nlohmann::json::type_error& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n}\n

    Output:

    localhost\n8080\n[json.exception.type_error.302] type must be number, but is string\n
    Example: (2) access specified element via JSON pointer with default value

    The example below reads an optional, nested configuration value with a default, given as a JSON pointer.

    #include <iostream>\n#include <nlohmann/json_view.hpp>\n\nusing nlohmann::json_document;\nusing nlohmann::json_view;\nusing json_pointer = nlohmann::json::json_pointer;\n\nint main()\n{\n    json_document doc = json_document::parse(R\"({\"server\": {\"host\": \"localhost\", \"limits\": {\"connections\": 100}}})\");\n    const json_view config = doc.root();\n\n    // a nested, optional setting read with a default -- no exception, even\n    // though \"timeout\" is missing several levels down\n    std::cout << config.value(json_pointer(\"/server/limits/connections\"), 10) << '\\n';\n    std::cout << config.value(json_pointer(\"/server/limits/timeout\"), 30) << '\\n';\n\n    // an out-of-range array index also falls back to the default\n    json_document list_doc = json_document::parse(R\"({\"servers\": [\"a\", \"b\"]})\");\n    std::cout << list_doc.root().value(json_pointer(\"/servers/5\"), std::string(\"none\")) << '\\n';\n}\n

    Output:

    100\n30\nnone\n
    "},{"location":"api/basic_json_view/value/#see-also","title":"See also","text":"
    • at - access specified element with bounds checking (throws instead of returning a default value)
    • operator[] - access specified element (returns a discarded view instead of a default value)
    • BasicJsonType::value - the corresponding function of basic_json
    "},{"location":"api/basic_json_view/value/#version-history","title":"Version history","text":"
    • Added in version 3.13.0 unreleased.
    "},{"location":"api/byte_container_with_subtype/","title":"nlohmann::byte_container_with_subtype","text":"
    template<typename BinaryType>\nclass byte_container_with_subtype : public BinaryType;\n

    This type extends the template parameter BinaryType provided to basic_json with a subtype used by BSON, CBOR, and MessagePack. This type exists so that the user does not have to specify a type themselves with a specific naming scheme in order to override the binary type.

    "},{"location":"api/byte_container_with_subtype/#template-parameters","title":"Template parameters","text":"BinaryType container to store bytes (std::vector<std::uint8_t> by default)"},{"location":"api/byte_container_with_subtype/#member-types","title":"Member types","text":"
    • container_type - the type of the underlying container (BinaryType)
    • subtype_type - the type of the subtype (std::uint64_t)
    "},{"location":"api/byte_container_with_subtype/#member-functions","title":"Member functions","text":"
    • (constructor)
    • operator== - comparison: equal
    • operator!= - comparison: not equal
    • set_subtype - sets the binary subtype
    • subtype - return the binary subtype
    • has_subtype - return whether the value has a subtype
    • clear_subtype - clears the binary subtype
    "},{"location":"api/byte_container_with_subtype/#see-also","title":"See also","text":"
    • Binary values - how binary values and subtypes are handled
    • binary - create a binary array value
    • get_binary - get a reference to the stored binary value
    • binary_t - type for binary arrays
    • Binary formats - formats that can store binary values
    "},{"location":"api/byte_container_with_subtype/#version-history","title":"Version history","text":"
    • Added in version 3.8.0.
    • Changed the type of subtypes to std::uint64_t in 3.10.0.
    "},{"location":"api/byte_container_with_subtype/byte_container_with_subtype/","title":"nlohmann::byte_container_with_subtype::byte_container_with_subtype","text":"
    // (1)\nbyte_container_with_subtype();\n\n// (2)\nbyte_container_with_subtype(const container_type& container);\nbyte_container_with_subtype(container_type&& container);\n\n// (3)\nbyte_container_with_subtype(const container_type& container, subtype_type subtype);\nbyte_container_with_subtype(container_type&& container, subtype_type subtype);\n
    1. Create an empty binary container without a subtype.
    2. Create a binary container without a subtype.
    3. Create a binary container with a subtype.
    "},{"location":"api/byte_container_with_subtype/byte_container_with_subtype/#parameters","title":"Parameters","text":"container (in) binary container subtype (in) subtype"},{"location":"api/byte_container_with_subtype/byte_container_with_subtype/#examples","title":"Examples","text":"Example

    The example below demonstrates how byte containers can be created.

    #include <iostream>\n#include <nlohmann/json.hpp>\n\n// define a byte container based on std::vector\nusing byte_container_with_subtype = nlohmann::byte_container_with_subtype<std::vector<std::uint8_t>>;\n\nusing nlohmann::json;\n\nint main()\n{\n    // (1) create empty container\n    auto c1 = byte_container_with_subtype();\n\n    std::vector<std::uint8_t> bytes = {{0xca, 0xfe, 0xba, 0xbe}};\n\n    // (2) create container\n    auto c2 = byte_container_with_subtype(bytes);\n\n    // (3) create container with subtype\n    auto c3 = byte_container_with_subtype(bytes, 42);\n\n    std::cout << json(c1) << \"\\n\" << json(c2) << \"\\n\" << json(c3) << '\\n';\n}\n

    Output:

    {\"bytes\":[],\"subtype\":null}\n{\"bytes\":[202,254,186,190],\"subtype\":null}\n{\"bytes\":[202,254,186,190],\"subtype\":42}\n
    "},{"location":"api/byte_container_with_subtype/byte_container_with_subtype/#see-also","title":"See also","text":"
    • set_subtype - sets the binary subtype
    • subtype - return the binary subtype
    • has_subtype - return whether the value has a subtype
    • binary - create a binary JSON value
    • Binary Values - the article on binary values
    "},{"location":"api/byte_container_with_subtype/byte_container_with_subtype/#version-history","title":"Version history","text":"

    Added in version 3.8.0.

    "},{"location":"api/byte_container_with_subtype/clear_subtype/","title":"nlohmann::byte_container_with_subtype::clear_subtype","text":"
    void clear_subtype() noexcept;\n

    Clears the binary subtype and flags the value as not having a subtype, which has implications for serialization; for instance, MessagePack will prefer the bin family over the ext family.

    "},{"location":"api/byte_container_with_subtype/clear_subtype/#exception-safety","title":"Exception safety","text":"

    No-throw guarantee: this function never throws exceptions.

    "},{"location":"api/byte_container_with_subtype/clear_subtype/#complexity","title":"Complexity","text":"

    Constant.

    "},{"location":"api/byte_container_with_subtype/clear_subtype/#examples","title":"Examples","text":"Example

    The example below demonstrates how clear_subtype can remove subtypes.

    #include <iostream>\n#include <nlohmann/json.hpp>\n\n// define a byte container based on std::vector\nusing byte_container_with_subtype = nlohmann::byte_container_with_subtype<std::vector<std::uint8_t>>;\n\nusing nlohmann::json;\n\nint main()\n{\n    std::vector<std::uint8_t> bytes = {{0xca, 0xfe, 0xba, 0xbe}};\n\n    // create container with subtype\n    auto c1 = byte_container_with_subtype(bytes, 42);\n\n    std::cout << \"before calling clear_subtype(): \" << json(c1) << '\\n';\n\n    c1.clear_subtype();\n\n    std::cout << \"after calling clear_subtype(): \" << json(c1) << '\\n';\n}\n

    Output:

    before calling clear_subtype(): {\"bytes\":[202,254,186,190],\"subtype\":42}\nafter calling clear_subtype(): {\"bytes\":[202,254,186,190],\"subtype\":null}\n
    "},{"location":"api/byte_container_with_subtype/clear_subtype/#see-also","title":"See also","text":"
    • Binary values - how binary values and subtypes are handled
    • set_subtype - sets the binary subtype
    • has_subtype - return whether the value has a subtype
    • subtype - return the binary subtype
    "},{"location":"api/byte_container_with_subtype/clear_subtype/#version-history","title":"Version history","text":"

    Added in version 3.8.0.

    "},{"location":"api/byte_container_with_subtype/has_subtype/","title":"nlohmann::byte_container_with_subtype::has_subtype","text":"
    constexpr bool has_subtype() const noexcept;\n

    Returns whether the value has a subtype.

    "},{"location":"api/byte_container_with_subtype/has_subtype/#return-value","title":"Return value","text":"

    whether the value has a subtype

    "},{"location":"api/byte_container_with_subtype/has_subtype/#exception-safety","title":"Exception safety","text":"

    No-throw guarantee: this function never throws exceptions.

    "},{"location":"api/byte_container_with_subtype/has_subtype/#complexity","title":"Complexity","text":"

    Constant.

    "},{"location":"api/byte_container_with_subtype/has_subtype/#examples","title":"Examples","text":"Example

    The example below demonstrates how has_subtype can check whether a subtype was set.

    #include <iostream>\n#include <nlohmann/json.hpp>\n\n// define a byte container based on std::vector\nusing byte_container_with_subtype = nlohmann::byte_container_with_subtype<std::vector<std::uint8_t>>;\n\nint main()\n{\n    std::vector<std::uint8_t> bytes = {{0xca, 0xfe, 0xba, 0xbe}};\n\n    // create container\n    auto c1 = byte_container_with_subtype(bytes);\n\n    // create container with subtype\n    auto c2 = byte_container_with_subtype(bytes, 42);\n\n    std::cout << std::boolalpha << \"c1.has_subtype() = \" << c1.has_subtype()\n              << \"\\nc2.has_subtype() = \" << c2.has_subtype() << '\\n';\n}\n

    Output:

    c1.has_subtype() = false\nc2.has_subtype() = true\n
    "},{"location":"api/byte_container_with_subtype/has_subtype/#see-also","title":"See also","text":"
    • Binary values - how binary values and subtypes are handled
    • set_subtype - sets the binary subtype
    • clear_subtype - clears the binary subtype
    • subtype - return the binary subtype
    "},{"location":"api/byte_container_with_subtype/has_subtype/#version-history","title":"Version history","text":"

    Added in version 3.8.0.

    "},{"location":"api/byte_container_with_subtype/operator_eq/","title":"nlohmann::byte_container_with_subtype::operator==","text":"
    bool operator==(const byte_container_with_subtype& rhs) const;\n

    Compares two byte containers for equality by comparing (1) the underlying binary data (the BinaryType base, compared with BinaryType's own operator==) and (2) the subtype information \u2014 both containers must either have no subtype, or have a subtype and the same subtype value.

    "},{"location":"api/byte_container_with_subtype/operator_eq/#parameters","title":"Parameters","text":"rhs (in) byte container to compare *this with"},{"location":"api/byte_container_with_subtype/operator_eq/#return-value","title":"Return value","text":"

    whether *this and rhs are equal

    "},{"location":"api/byte_container_with_subtype/operator_eq/#complexity","title":"Complexity","text":"

    Linear in the size of the compared containers.

    "},{"location":"api/byte_container_with_subtype/operator_eq/#examples","title":"Examples","text":"Example

    The example below demonstrates comparing byte containers with and without subtypes.

    #include <iostream>\n#include <nlohmann/json.hpp>\n\n// define a byte container based on std::vector\nusing byte_container_with_subtype = nlohmann::byte_container_with_subtype<std::vector<std::uint8_t>>;\n\nint main()\n{\n    std::vector<std::uint8_t> bytes = {{0xca, 0xfe, 0xba, 0xbe}};\n\n    // create containers without and with a subtype\n    auto c1 = byte_container_with_subtype(bytes);\n    auto c2 = byte_container_with_subtype(bytes);\n    auto c3 = byte_container_with_subtype(bytes, 42);\n    auto c4 = byte_container_with_subtype(bytes, 42);\n    auto c5 = byte_container_with_subtype(bytes, 23);\n\n    std::cout << std::boolalpha\n              << \"c1 == c2: \" << (c1 == c2) << '\\n'\n              << \"c1 == c3: \" << (c1 == c3) << '\\n'\n              << \"c3 == c4: \" << (c3 == c4) << '\\n'\n              << \"c3 == c5: \" << (c3 == c5) << '\\n';\n}\n

    Output:

    c1 == c2: true\nc1 == c3: false\nc3 == c4: true\nc3 == c5: false\n
    "},{"location":"api/byte_container_with_subtype/operator_eq/#see-also","title":"See also","text":"
    • Binary values - how binary values and subtypes are handled
    • operator!= - comparison: not equal
    • has_subtype - return whether the value has a subtype
    • subtype - return the binary subtype
    "},{"location":"api/byte_container_with_subtype/operator_eq/#version-history","title":"Version history","text":"
    • Added in version 3.8.0.
    "},{"location":"api/byte_container_with_subtype/operator_ne/","title":"nlohmann::byte_container_with_subtype::operator!=","text":"
    bool operator!=(const byte_container_with_subtype& rhs) const;\n

    Compares two byte containers for inequality. Returns !(rhs == *this); see operator== for the equality semantics.

    "},{"location":"api/byte_container_with_subtype/operator_ne/#parameters","title":"Parameters","text":"rhs (in) byte container to compare *this with"},{"location":"api/byte_container_with_subtype/operator_ne/#return-value","title":"Return value","text":"

    whether *this and rhs are not equal

    "},{"location":"api/byte_container_with_subtype/operator_ne/#complexity","title":"Complexity","text":"

    Linear in the size of the compared containers.

    "},{"location":"api/byte_container_with_subtype/operator_ne/#examples","title":"Examples","text":"Example

    The example below demonstrates comparing byte containers with and without subtypes.

    #include <iostream>\n#include <nlohmann/json.hpp>\n\n// define a byte container based on std::vector\nusing byte_container_with_subtype = nlohmann::byte_container_with_subtype<std::vector<std::uint8_t>>;\n\nint main()\n{\n    std::vector<std::uint8_t> bytes = {{0xca, 0xfe, 0xba, 0xbe}};\n\n    // create containers without and with a subtype\n    auto c1 = byte_container_with_subtype(bytes);\n    auto c2 = byte_container_with_subtype(bytes);\n    auto c3 = byte_container_with_subtype(bytes, 42);\n    auto c4 = byte_container_with_subtype(bytes, 42);\n    auto c5 = byte_container_with_subtype(bytes, 23);\n\n    std::cout << std::boolalpha\n              << \"c1 != c2: \" << (c1 != c2) << '\\n'\n              << \"c1 != c3: \" << (c1 != c3) << '\\n'\n              << \"c3 != c4: \" << (c3 != c4) << '\\n'\n              << \"c3 != c5: \" << (c3 != c5) << '\\n';\n}\n

    Output:

    c1 != c2: false\nc1 != c3: true\nc3 != c4: false\nc3 != c5: true\n
    "},{"location":"api/byte_container_with_subtype/operator_ne/#see-also","title":"See also","text":"
    • Binary values - how binary values and subtypes are handled
    • operator== - comparison: equal
    • has_subtype - return whether the value has a subtype
    • subtype - return the binary subtype
    "},{"location":"api/byte_container_with_subtype/operator_ne/#version-history","title":"Version history","text":"
    • Added in version 3.8.0.
    "},{"location":"api/byte_container_with_subtype/set_subtype/","title":"nlohmann::byte_container_with_subtype::set_subtype","text":"
    void set_subtype(subtype_type subtype) noexcept;\n

    Sets the binary subtype of the value, also flags a binary JSON value as having a subtype, which has implications for serialization.

    "},{"location":"api/byte_container_with_subtype/set_subtype/#parameters","title":"Parameters","text":"subtype (in) subtype to set"},{"location":"api/byte_container_with_subtype/set_subtype/#exception-safety","title":"Exception safety","text":"

    No-throw guarantee: this function never throws exceptions.

    "},{"location":"api/byte_container_with_subtype/set_subtype/#complexity","title":"Complexity","text":"

    Constant.

    "},{"location":"api/byte_container_with_subtype/set_subtype/#examples","title":"Examples","text":"Example

    The example below demonstrates how a subtype can be set with set_subtype.

    #include <iostream>\n#include <nlohmann/json.hpp>\n\n// define a byte container based on std::vector\nusing byte_container_with_subtype = nlohmann::byte_container_with_subtype<std::vector<std::uint8_t>>;\n\nusing nlohmann::json;\n\nint main()\n{\n    std::vector<std::uint8_t> bytes = {{0xca, 0xfe, 0xba, 0xbe}};\n\n    // create container without subtype\n    auto c = byte_container_with_subtype(bytes);\n\n    std::cout << \"before calling set_subtype(42): \" << json(c) << '\\n';\n\n    // set the subtype\n    c.set_subtype(42);\n\n    std::cout << \"after calling set_subtype(42): \" << json(c) << '\\n';\n}\n

    Output:

    before calling set_subtype(42): {\"bytes\":[202,254,186,190],\"subtype\":null}\nafter calling set_subtype(42): {\"bytes\":[202,254,186,190],\"subtype\":42}\n
    "},{"location":"api/byte_container_with_subtype/set_subtype/#see-also","title":"See also","text":"
    • Binary values - how binary values and subtypes are handled
    • subtype - return the binary subtype
    • has_subtype - return whether the value has a subtype
    • clear_subtype - clears the binary subtype
    "},{"location":"api/byte_container_with_subtype/set_subtype/#version-history","title":"Version history","text":"

    Added in version 3.8.0.

    "},{"location":"api/byte_container_with_subtype/subtype/","title":"nlohmann::byte_container_with_subtype::subtype","text":"
    constexpr subtype_type subtype() const noexcept;\n

    Returns the numerical subtype of the value if it has a subtype. If it does not have a subtype, this function will return subtype_type(-1) as a sentinel value.

    "},{"location":"api/byte_container_with_subtype/subtype/#return-value","title":"Return value","text":"

    the numerical subtype of the binary value, or subtype_type(-1) if no subtype is set

    "},{"location":"api/byte_container_with_subtype/subtype/#exception-safety","title":"Exception safety","text":"

    No-throw guarantee: this function never throws exceptions.

    "},{"location":"api/byte_container_with_subtype/subtype/#complexity","title":"Complexity","text":"

    Constant.

    "},{"location":"api/byte_container_with_subtype/subtype/#examples","title":"Examples","text":"Example

    The example below demonstrates how the subtype can be retrieved with subtype. Note how subtype_type(-1) is returned for container c1.

    #include <iostream>\n#include <nlohmann/json.hpp>\n\n// define a byte container based on std::vector\nusing byte_container_with_subtype = nlohmann::byte_container_with_subtype<std::vector<std::uint8_t>>;\n\nint main()\n{\n    std::vector<std::uint8_t> bytes = {{0xca, 0xfe, 0xba, 0xbe}};\n\n    // create container\n    auto c1 = byte_container_with_subtype(bytes);\n\n    // create container with subtype\n    auto c2 = byte_container_with_subtype(bytes, 42);\n\n    std::cout << \"c1.subtype() = \" << c1.subtype()\n              << \"\\nc2.subtype() = \" << c2.subtype() << '\\n';\n\n    // in case no subtype is set, return special value\n    assert(c1.subtype() == static_cast<byte_container_with_subtype::subtype_type>(-1));\n}\n

    Output:

    c1.subtype() = 18446744073709551615\nc2.subtype() = 42\n
    "},{"location":"api/byte_container_with_subtype/subtype/#see-also","title":"See also","text":"
    • Binary values - how binary values and subtypes are handled
    • set_subtype - sets the binary subtype
    • has_subtype - return whether the value has a subtype
    • clear_subtype - clears the binary subtype
    "},{"location":"api/byte_container_with_subtype/subtype/#version-history","title":"Version history","text":"
    • Added in version 3.8.0
    • Fixed return value to properly return subtype_type(-1) as documented in version 3.10.0.
    "},{"location":"api/json_pointer/","title":"nlohmann::json_pointer","text":"
    template<typename RefStringType>\nclass json_pointer;\n

    A JSON pointer defines a string syntax for identifying a specific value within a JSON document. It can be used with functions at and operator[]. Furthermore, JSON pointers are the base for JSON patches.

    "},{"location":"api/json_pointer/#template-parameters","title":"Template parameters","text":"RefStringType the string type used for the reference tokens making up the JSON pointer

    Deprecation

    For backwards compatibility RefStringType may also be a specialization of basic_json in which case string_t will be deduced as basic_json::string_t. This feature is deprecated and may be removed in a future major version.

    See the migration guide for how to update existing code.

    A JSON pointer is internally a sequence of reference tokens. front, pop_front, and push_front act on the first reference token, whereas back, pop_back, and push_back act on the last one. parent_pointer returns a new JSON pointer with the last reference token removed (like a non-mutating pop_back):

    flowchart LR\n    A[\"a\"] --> B[\"b\"] --> C[\"c\"]\n\n    front[\"front() / pop_front() / push_front()\"] -.-> A\n    back[\"back() / pop_back() / push_back()\"] -.-> C\n    parent[\"parent_pointer() returns /a/b\"] -.-> B

    Boxes are the reference tokens in order; dotted arrows show which token each member function reads, removes, or adds to.

    The diagram shows the reference tokens of the JSON pointer /a/b/c.

    "},{"location":"api/json_pointer/#member-types","title":"Member types","text":"
    • string_t - the string type used for the reference tokens
    "},{"location":"api/json_pointer/#member-functions","title":"Member functions","text":"
    • (constructor)
    • to_string - return a string representation of the JSON pointer
    • operator string_t - return a string representation of the JSON pointer (deprecated)
    • operator== - compare: equal
    • operator!= - compare: not equal
    • operator<=> - compare: 3-way (C++20)
    • operator/= - append to the end of the JSON pointer
    • operator/ - create JSON Pointer by appending
    • parent_pointer - returns the parent of this JSON pointer
    • pop_back - remove the last reference token
    • back - return last reference token
    • push_back - append an unescaped token at the end of the pointer
    • pop_front - remove the first reference token
    • front - return first reference token
    • push_front - append an unescaped token at the start of the pointer
    • empty - return whether the pointer points to the root document
    "},{"location":"api/json_pointer/#literals","title":"Literals","text":"
    • operator\"\"_json_pointer - user-defined string literal for JSON pointers
    "},{"location":"api/json_pointer/#see-also","title":"See also","text":"
    • RFC 6901 - specification of JSON Pointer
    • JSON Pointer - the article on JSON Pointer support
    • JSON Patch and Diff - patch paths are JSON pointers
    "},{"location":"api/json_pointer/#version-history","title":"Version history","text":"
    • Added in version 2.0.0.
    • Changed template parameter from basic_json to string type in version 3.11.0.
    "},{"location":"api/json_pointer/back/","title":"nlohmann::json_pointer::back","text":"
    const string_t& back() const;\n

    Return the last reference token.

    "},{"location":"api/json_pointer/back/#return-value","title":"Return value","text":"

    Last reference token.

    "},{"location":"api/json_pointer/back/#exception-safety","title":"Exception safety","text":"

    Strong exception safety: if an exception occurs, the original value stays intact.

    "},{"location":"api/json_pointer/back/#exceptions","title":"Exceptions","text":"

    Throws out_of_range.405 if the JSON pointer has no parent.

    "},{"location":"api/json_pointer/back/#complexity","title":"Complexity","text":"

    Constant.

    "},{"location":"api/json_pointer/back/#examples","title":"Examples","text":"Example

    The example shows the usage of back.

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // different JSON Pointers\n    json::json_pointer ptr1(\"/foo\");\n    json::json_pointer ptr2(\"/foo/0\");\n\n    // call empty()\n    std::cout << \"last reference token of \\\"\" << ptr1 << \"\\\" is \\\"\" << ptr1.back() << \"\\\"\\n\"\n              << \"last reference token of \\\"\" << ptr2 << \"\\\" is \\\"\" << ptr2.back() << \"\\\"\" << '\\n';\n}\n

    Output:

    last reference token of \"/foo\" is \"foo\"\nlast reference token of \"/foo/0\" is \"0\"\n
    "},{"location":"api/json_pointer/back/#see-also","title":"See also","text":"
    • front - return first reference token
    • pop_back - remove the last reference token
    • push_back - append an unescaped token at the end of the pointer
    • parent_pointer - returns the parent of this JSON pointer
    "},{"location":"api/json_pointer/back/#version-history","title":"Version history","text":"
    • Added in version 3.6.0.
    • Changed return type to string_t in version 3.11.0.
    "},{"location":"api/json_pointer/empty/","title":"nlohmann::json_pointer::empty","text":"
    bool empty() const noexcept;\n

    Return whether the pointer points to the root document.

    "},{"location":"api/json_pointer/empty/#return-value","title":"Return value","text":"

    true iff the JSON pointer points to the root document.

    "},{"location":"api/json_pointer/empty/#exception-safety","title":"Exception safety","text":"

    No-throw guarantee: this function never throws exceptions.

    "},{"location":"api/json_pointer/empty/#complexity","title":"Complexity","text":"

    Constant.

    "},{"location":"api/json_pointer/empty/#examples","title":"Examples","text":"Example

    The example shows the result of empty for different JSON Pointers.

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // different JSON Pointers\n    json::json_pointer ptr0;\n    json::json_pointer ptr1(\"\");\n    json::json_pointer ptr2(\"/foo\");\n    json::json_pointer ptr3(\"/foo/0\");\n\n    // call empty()\n    std::cout << std::boolalpha\n              << \"\\\"\" << ptr0 << \"\\\": \" << ptr0.empty() << '\\n'\n              << \"\\\"\" << ptr1 << \"\\\": \" << ptr1.empty() << '\\n'\n              << \"\\\"\" << ptr2 << \"\\\": \" << ptr2.empty() << '\\n'\n              << \"\\\"\" << ptr3 << \"\\\": \" << ptr3.empty() << '\\n';\n}\n

    Output:

    \"\": true\n\"\": true\n\"/foo\": false\n\"/foo/0\": false\n
    "},{"location":"api/json_pointer/empty/#see-also","title":"See also","text":"
    • front - return first reference token
    • back - return last reference token
    • to_string - return a string representation of the JSON pointer
    "},{"location":"api/json_pointer/empty/#version-history","title":"Version history","text":"

    Added in version 3.6.0.

    "},{"location":"api/json_pointer/front/","title":"nlohmann::json_pointer::front","text":"
    const string_t& front() const;\n

    Return the first reference token.

    "},{"location":"api/json_pointer/front/#return-value","title":"Return value","text":"

    First reference token.

    "},{"location":"api/json_pointer/front/#exception-safety","title":"Exception safety","text":"

    Strong exception safety: if an exception occurs, the original value stays intact.

    "},{"location":"api/json_pointer/front/#exceptions","title":"Exceptions","text":"

    Throws out_of_range.405 if the JSON pointer has no parent.

    "},{"location":"api/json_pointer/front/#complexity","title":"Complexity","text":"

    Constant.

    "},{"location":"api/json_pointer/front/#examples","title":"Examples","text":"Example

    The example shows the usage of front.

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // different JSON Pointers\n    json::json_pointer ptr1(\"/foo\");\n    json::json_pointer ptr2(\"/foo/0\");\n\n    // call empty()\n    std::cout << \"first reference token of \\\"\" << ptr1 << \"\\\" is \\\"\" << ptr1.front() << \"\\\"\\n\"\n              << \"first reference token of \\\"\" << ptr2 << \"\\\" is \\\"\" << ptr2.front() << \"\\\"\" << '\\n';\n}\n

    Output:

    first reference token of \"/foo\" is \"foo\"\nfirst reference token of \"/foo/0\" is \"foo\"\n
    "},{"location":"api/json_pointer/front/#see-also","title":"See also","text":"
    • back - return last reference token
    • pop_front - remove the first reference token
    • push_front - append an unescaped token at the start of the pointer
    "},{"location":"api/json_pointer/front/#version-history","title":"Version history","text":"
    • Added in version 3.13.0 unreleased.
    "},{"location":"api/json_pointer/json_pointer/","title":"nlohmann::json_pointer::json_pointer","text":"
    explicit json_pointer(const string_t& s = \"\");\n

    Create a JSON pointer according to the syntax described in Section 3 of RFC6901.

    "},{"location":"api/json_pointer/json_pointer/#parameters","title":"Parameters","text":"s (in) string representing the JSON pointer; if omitted, the empty string is assumed which references the whole JSON value"},{"location":"api/json_pointer/json_pointer/#exception-safety","title":"Exception safety","text":"

    Strong guarantee: if an exception is thrown, there are no changes to any JSON pointer.

    "},{"location":"api/json_pointer/json_pointer/#exceptions","title":"Exceptions","text":"
    • Throws parse_error.107 if the given JSON pointer s is nonempty and does not begin with a slash (/); see example below.
    • Throws parse_error.108 if a tilde (~) in the given JSON pointer s is not followed by 0 (representing ~) or 1 (representing /); see example below.
    "},{"location":"api/json_pointer/json_pointer/#complexity","title":"Complexity","text":"

    Linear in the length of s.

    "},{"location":"api/json_pointer/json_pointer/#examples","title":"Examples","text":"Example

    The example shows the construction several valid JSON pointers as well as the exceptional behavior.

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // correct JSON pointers\n    json::json_pointer p1;\n    json::json_pointer p2(\"\");\n    json::json_pointer p3(\"/\");\n    json::json_pointer p4(\"//\");\n    json::json_pointer p5(\"/foo/bar\");\n    json::json_pointer p6(\"/foo/bar/-\");\n    json::json_pointer p7(\"/foo/~0\");\n    json::json_pointer p8(\"/foo/~1\");\n\n    // error: JSON pointer does not begin with a slash\n    try\n    {\n        json::json_pointer p9(\"foo\");\n    }\n    catch (const json::parse_error& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n\n    // error: JSON pointer uses escape symbol ~ not followed by 0 or 1\n    try\n    {\n        json::json_pointer p10(\"/foo/~\");\n    }\n    catch (const json::parse_error& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n\n    // error: JSON pointer uses escape symbol ~ not followed by 0 or 1\n    try\n    {\n        json::json_pointer p11(\"/foo/~3\");\n    }\n    catch (const json::parse_error& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n}\n

    Output:

    [json.exception.parse_error.107] parse error at byte 1: JSON pointer must be empty or begin with '/' - was: 'foo'\n[json.exception.parse_error.108] parse error: escape character '~' must be followed with '0' or '1'\n[json.exception.parse_error.108] parse error: escape character '~' must be followed with '0' or '1'\n
    "},{"location":"api/json_pointer/json_pointer/#see-also","title":"See also","text":"
    • JSON Pointer - the article on JSON Pointer support
    • operator\"\"_json_pointer - user-defined string literal for JSON pointers
    "},{"location":"api/json_pointer/json_pointer/#version-history","title":"Version history","text":"
    • Added in version 2.0.0.
    • Changed type of s to string_t in version 3.11.0.
    "},{"location":"api/json_pointer/operator_eq/","title":"nlohmann::json_pointer::operator==","text":"
    // until C++20\ntemplate<typename RefStringTypeLhs, typename RefStringTypeRhs>\nbool operator==(\n    const json_pointer<RefStringTypeLhs>& lhs,\n    const json_pointer<RefStringTypeRhs>& rhs) noexcept;            // (1)\n\ntemplate<typename RefStringTypeLhs, typename StringType>\nbool operator==(\n    const json_pointer<RefStringTypeLhs>& lhs,\n    const StringType& rhs);                                         // (2)\n\ntemplate<typename RefStringTypeRhs, typename StringType>\nbool operator==(\n    const StringType& lhs,\n    const json_pointer<RefStringTypeRhs>& rhs);                     // (2)\n\n// since C++20\ntemplate<typename RefStringTypeRhs>\nbool operator==(\n    const json_pointer<RefStringTypeRhs>& rhs) const noexcept;      // (1)\n\nbool operator==(const string_t& rhs) const;                         // (2)\n
    1. Compares two JSON pointers for equality by comparing their reference tokens.

    2. Compares a JSON pointer and a string or a string and a JSON pointer for equality by converting the string to a JSON pointer and comparing the JSON pointers according to 1.

    "},{"location":"api/json_pointer/operator_eq/#template-parameters","title":"Template parameters","text":"RefStringTypeLhs, RefStringTypeRhs the string type of the left-hand side or right-hand side JSON pointer, respectively StringType the string type derived from the json_pointer operand (json_pointer::string_t)"},{"location":"api/json_pointer/operator_eq/#parameters","title":"Parameters","text":"lhs (in) first value to consider rhs (in) second value to consider"},{"location":"api/json_pointer/operator_eq/#return-value","title":"Return value","text":"

    whether the values lhs/*this and rhs are equal

    "},{"location":"api/json_pointer/operator_eq/#exception-safety","title":"Exception safety","text":"
    1. No-throw guarantee: this function never throws exceptions.
    2. Strong exception safety: if an exception occurs, the original value stays intact.
    "},{"location":"api/json_pointer/operator_eq/#exceptions","title":"Exceptions","text":"
    1. (none)
    2. The function can throw the following exceptions:
    3. Throws parse_error.107 if the given JSON pointer s is nonempty and does not begin with a slash (/); see example below.
    4. Throws parse_error.108 if a tilde (~) in the given JSON pointer s is not followed by 0 (representing ~) or 1 (representing /); see example below.
    "},{"location":"api/json_pointer/operator_eq/#complexity","title":"Complexity","text":"

    Constant if lhs and rhs differ in the number of reference tokens, otherwise linear in the number of reference tokens.

    "},{"location":"api/json_pointer/operator_eq/#notes","title":"Notes","text":"

    Deprecation

    Overload 2 is deprecated and will be removed in a future major version release.

    See the migration guide for how to update existing code.

    "},{"location":"api/json_pointer/operator_eq/#examples","title":"Examples","text":"Example: (1) Comparing JSON pointers

    The example demonstrates comparing JSON pointers.

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // different JSON pointers\n    json::json_pointer ptr0;\n    json::json_pointer ptr1(\"\");\n    json::json_pointer ptr2(\"/foo\");\n\n    // compare JSON pointers\n    std::cout << std::boolalpha\n              << \"\\\"\" << ptr0 << \"\\\" == \\\"\" << ptr0 << \"\\\": \" << (ptr0 == ptr0) << '\\n'\n              << \"\\\"\" << ptr0 << \"\\\" == \\\"\" << ptr1 << \"\\\": \" << (ptr0 == ptr1) << '\\n'\n              << \"\\\"\" << ptr1 << \"\\\" == \\\"\" << ptr2 << \"\\\": \" << (ptr1 == ptr2) << '\\n'\n              << \"\\\"\" << ptr2 << \"\\\" == \\\"\" << ptr2 << \"\\\": \" << (ptr2 == ptr2) << '\\n';\n}\n

    Output:

    \"\" == \"\": true\n\"\" == \"\": true\n\"\" == \"/foo\": false\n\"/foo\" == \"/foo\": true\n
    Example: (2) Comparing JSON pointers and strings

    The example demonstrates comparing JSON pointers and strings, and when doing so may raise an exception.

    #include <exception>\n#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // different JSON pointers\n    json::json_pointer ptr0;\n    json::json_pointer ptr1(\"\");\n    json::json_pointer ptr2(\"/foo\");\n\n    // different strings\n    std::string str0(\"\");\n    std::string str1(\"/foo\");\n    std::string str2(\"bar\");\n\n    // compare JSON pointers and strings\n    std::cout << std::boolalpha\n              << \"\\\"\" << ptr0 << \"\\\" == \\\"\" << str0 << \"\\\": \" << (ptr0 == str0) << '\\n'\n              << \"\\\"\" << str0 << \"\\\" == \\\"\" << ptr1 << \"\\\": \" << (str0 == ptr1) << '\\n'\n              << \"\\\"\" << ptr2 << \"\\\" == \\\"\" << str1 << \"\\\": \" << (ptr2 == str1) << '\\n';\n\n    try\n    {\n        std::cout << \"\\\"\" << str2 << \"\\\" == \\\"\" << ptr2 << \"\\\": \" << (str2 == ptr2) << '\\n';\n    }\n    catch (const json::parse_error& ex)\n    {\n        std::cout << ex.what() << '\\n';\n    }\n}\n

    Output:

    \"\" == \"\": true\n\"\" == \"\": true\n\"/foo\" == \"/foo\": true\n\"bar\" == \"/foo\": [json.exception.parse_error.107] parse error at byte 1: JSON pointer must be empty or begin with '/' - was: 'bar'\n
    "},{"location":"api/json_pointer/operator_eq/#see-also","title":"See also","text":"
    • operator!= - compare for inequality
    • operator<=> - comparison: 3-way (C++20)
    "},{"location":"api/json_pointer/operator_eq/#version-history","title":"Version history","text":"
    1. Added in version 2.1.0. Added C++20 member functions in version 3.11.2.
    2. Added for backward compatibility and deprecated in version 3.11.2.
    "},{"location":"api/json_pointer/operator_ne/","title":"nlohmann::json_pointer::operator!=","text":"
    // until C++20\ntemplate<typename RefStringTypeLhs, typename RefStringTypeRhs>\nbool operator!=(\n    const json_pointer<RefStringTypeLhs>& lhs,\n    const json_pointer<RefStringTypeRhs>& rhs) noexcept;  // (1)\n\ntemplate<typename RefStringTypeLhs, typename StringType>\nbool operator!=(\n    const json_pointer<RefStringTypeLhs>& lhs,\n    const StringType& rhs);                               // (2)\n\ntemplate<typename RefStringTypeRhs, typename StringType>\nbool operator!=(\n    const StringType& lhs,\n    const json_pointer<RefStringTypeRhs>& rhs);           // (2)\n
    1. Compares two JSON pointers for inequality by comparing their reference tokens.

    2. Compares a JSON pointer and a string or a string and a JSON pointer for inequality by converting the string to a JSON pointer and comparing the JSON pointers according to 1.

    "},{"location":"api/json_pointer/operator_ne/#template-parameters","title":"Template parameters","text":"RefStringTypeLhs, RefStringTypeRhs the string type of the left-hand side or right-hand side JSON pointer, respectively StringType the string type derived from the json_pointer operand (json_pointer::string_t)"},{"location":"api/json_pointer/operator_ne/#parameters","title":"Parameters","text":"lhs (in) first value to consider rhs (in) second value to consider"},{"location":"api/json_pointer/operator_ne/#return-value","title":"Return value","text":"

    whether the values lhs/*this and rhs are not equal

    "},{"location":"api/json_pointer/operator_ne/#exception-safety","title":"Exception safety","text":"
    1. No-throw guarantee: this function never throws exceptions.
    2. Strong exception safety: if an exception occurs, the original value stays intact.
    "},{"location":"api/json_pointer/operator_ne/#exceptions","title":"Exceptions","text":"
    1. (none)
    2. The function can throw the following exceptions:
    3. Throws parse_error.107 if the given JSON pointer s is nonempty and does not begin with a slash (/); see example below.
    4. Throws parse_error.108 if a tilde (~) in the given JSON pointer s is not followed by 0 (representing ~) or 1 (representing /); see example below.
    "},{"location":"api/json_pointer/operator_ne/#complexity","title":"Complexity","text":"

    Constant if lhs and rhs differ in the number of reference tokens, otherwise linear in the number of reference tokens.

    "},{"location":"api/json_pointer/operator_ne/#notes","title":"Notes","text":"

    Operator overload resolution

    Since C++20 overload resolution will consider the rewritten candidate generated from operator==.

    Deprecation

    Overload 2 is deprecated and will be removed in a future major version release.

    See the migration guide for how to update existing code.

    "},{"location":"api/json_pointer/operator_ne/#examples","title":"Examples","text":"Example: (1) Comparing JSON pointers

    The example demonstrates comparing JSON pointers.

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // different JSON pointers\n    json::json_pointer ptr0;\n    json::json_pointer ptr1(\"\");\n    json::json_pointer ptr2(\"/foo\");\n\n    // compare JSON pointers\n    std::cout << std::boolalpha\n              << \"\\\"\" << ptr0 << \"\\\" != \\\"\" << ptr0 << \"\\\": \" << (ptr0 != ptr0) << '\\n'\n              << \"\\\"\" << ptr0 << \"\\\" != \\\"\" << ptr1 << \"\\\": \" << (ptr0 != ptr1) << '\\n'\n              << \"\\\"\" << ptr1 << \"\\\" != \\\"\" << ptr2 << \"\\\": \" << (ptr1 != ptr2) << '\\n'\n              << \"\\\"\" << ptr2 << \"\\\" != \\\"\" << ptr2 << \"\\\": \" << (ptr2 != ptr2) << '\\n';\n}\n

    Output:

    \"\" != \"\": false\n\"\" != \"\": false\n\"\" != \"/foo\": true\n\"/foo\" != \"/foo\": false\n
    Example: (2) Comparing JSON pointers and strings

    The example demonstrates comparing JSON pointers and strings, and when doing so may raise an exception.

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // different JSON pointers\n    json::json_pointer ptr0;\n    json::json_pointer ptr1(\"\");\n    json::json_pointer ptr2(\"/foo\");\n\n    // different strings\n    std::string str0(\"\");\n    std::string str1(\"/foo\");\n    std::string str2(\"bar\");\n\n    // compare JSON pointers and strings\n    std::cout << std::boolalpha\n              << \"\\\"\" << ptr0 << \"\\\" != \\\"\" << str0 << \"\\\": \" << (ptr0 != str0) << '\\n'\n              << \"\\\"\" << str0 << \"\\\" != \\\"\" << ptr1 << \"\\\": \" << (str0 != ptr1) << '\\n'\n              << \"\\\"\" << ptr2 << \"\\\" != \\\"\" << str1 << \"\\\": \" << (ptr2 != str1) << '\\n';\n\n    try\n    {\n        std::cout << \"\\\"\" << str2 << \"\\\" != \\\"\" << ptr2 << \"\\\": \" << (str2 != ptr2) << '\\n';\n    }\n    catch (const json::parse_error& ex)\n    {\n        std::cout << ex.what() << '\\n';\n    }\n}\n

    Output:

    \"\" != \"\": false\n\"\" != \"\": false\n\"/foo\" != \"/foo\": false\n\"bar\" != \"/foo\": [json.exception.parse_error.107] parse error at byte 1: JSON pointer must be empty or begin with '/' - was: 'bar'\n
    "},{"location":"api/json_pointer/operator_ne/#see-also","title":"See also","text":"
    • operator== - compare for equality
    • operator<=> - comparison: 3-way (C++20)
    "},{"location":"api/json_pointer/operator_ne/#version-history","title":"Version history","text":"
    1. Added in version 2.1.0.
    2. Added for backward compatibility and deprecated in version 3.11.2.
    "},{"location":"api/json_pointer/operator_slash/","title":"nlohmann::json_pointer::operator/","text":"
    // (1)\njson_pointer operator/(const json_pointer& lhs, const json_pointer& rhs);\n\n// (2)\njson_pointer operator/(const json_pointer& lhs, string_t token);\n\n// (3)\njson_pointer operator/(const json_pointer& lhs, std::size_t array_idx);\n
    1. create a new JSON pointer by appending the right JSON pointer at the end of the left JSON pointer
    2. create a new JSON pointer by appending the unescaped token at the end of the JSON pointer
    3. create a new JSON pointer by appending the array-index-token at the end of the JSON pointer
    "},{"location":"api/json_pointer/operator_slash/#parameters","title":"Parameters","text":"lhs (in) JSON pointer rhs (in) JSON pointer to append token (in) reference token to append array_idx (in) array index to append"},{"location":"api/json_pointer/operator_slash/#return-value","title":"Return value","text":"
    1. a new JSON pointer with rhs appended to lhs
    2. a new JSON pointer with unescaped token appended to lhs
    3. a new JSON pointer with array_idx appended to lhs
    "},{"location":"api/json_pointer/operator_slash/#exception-safety","title":"Exception safety","text":"

    Strong guarantee: if an exception is thrown, there are no changes to any JSON pointer. The operands are not modified; a new JSON pointer is built from a copy of lhs.

    "},{"location":"api/json_pointer/operator_slash/#complexity","title":"Complexity","text":"
    1. Linear in the length of lhs and rhs.
    2. Linear in the length of lhs.
    3. Linear in the length of lhs.
    "},{"location":"api/json_pointer/operator_slash/#examples","title":"Examples","text":"Example

    The example shows the usage of operator/.

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create a JSON pointer\n    json::json_pointer ptr(\"/foo\");\n\n    // append a JSON Pointer\n    std::cout << \"\\\"\" << ptr / json::json_pointer(\"/bar/baz\") << \"\\\"\\n\";\n\n    // append a string\n    std::cout << \"\\\"\" << ptr / \"fob\" << \"\\\"\\n\";\n\n    // append an array index\n    std::cout << \"\\\"\" << ptr / 42 << \"\\\"\" << '\\n';\n}\n

    Output:

    \"/foo/bar/baz\"\n\"/foo/fob\"\n\"/foo/42\"\n
    "},{"location":"api/json_pointer/operator_slash/#see-also","title":"See also","text":"
    • operator/= - append to the end of the JSON pointer
    • push_back - append an unescaped token at the end of the pointer
    • JSON Pointer - the article on JSON Pointer support
    "},{"location":"api/json_pointer/operator_slash/#version-history","title":"Version history","text":"
    1. Added in version 3.6.0.
    2. Added in version 3.6.0. Changed type of token to string_t in version 3.11.0.
    3. Added in version 3.6.0.
    "},{"location":"api/json_pointer/operator_slasheq/","title":"nlohmann::json_pointer::operator/=","text":"
    // (1)\njson_pointer& operator/=(const json_pointer& ptr);\n\n// (2)\njson_pointer& operator/=(string_t token);\n\n// (3)\njson_pointer& operator/=(std::size_t array_idx)\n
    1. append another JSON pointer at the end of this JSON pointer
    2. append an unescaped reference token at the end of this JSON pointer
    3. append an array index at the end of this JSON pointer
    "},{"location":"api/json_pointer/operator_slasheq/#parameters","title":"Parameters","text":"ptr (in) JSON pointer to append; may be the JSON pointer itself (p /= p), which then appends a copy of its reference tokens token (in) reference token to append array_idx (in) array index to append"},{"location":"api/json_pointer/operator_slasheq/#return-value","title":"Return value","text":"
    1. JSON pointer with ptr appended
    2. JSON pointer with token appended without escaping token
    3. JSON pointer with array_idx appended
    "},{"location":"api/json_pointer/operator_slasheq/#exception-safety","title":"Exception safety","text":"
    1. Basic guarantee: if an exception is thrown (for instance, if copying a reference token fails), the JSON pointer is left in a valid state, but it may contain some of the reference tokens of ptr.
    2. Strong guarantee: if an exception is thrown, there are no changes to the JSON pointer.
    3. Strong guarantee: if an exception is thrown, there are no changes to the JSON pointer.
    "},{"location":"api/json_pointer/operator_slasheq/#complexity","title":"Complexity","text":"
    1. Linear in the length of ptr.
    2. Amortized constant.
    3. Amortized constant.
    "},{"location":"api/json_pointer/operator_slasheq/#examples","title":"Examples","text":"Example

    The example shows the usage of operator/=.

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create a JSON pointer\n    json::json_pointer ptr(\"/foo\");\n    std::cout << \"\\\"\" << ptr << \"\\\"\\n\";\n\n    // append a JSON Pointer\n    ptr /= json::json_pointer(\"/bar/baz\");\n    std::cout << \"\\\"\" << ptr << \"\\\"\\n\";\n\n    // append a string\n    ptr /= \"fob\";\n    std::cout << \"\\\"\" << ptr << \"\\\"\\n\";\n\n    // append an array index\n    ptr /= 42;\n    std::cout << \"\\\"\" << ptr << \"\\\"\" << '\\n';\n}\n

    Output:

    \"/foo\"\n\"/foo/bar/baz\"\n\"/foo/bar/baz/fob\"\n\"/foo/bar/baz/fob/42\"\n
    "},{"location":"api/json_pointer/operator_slasheq/#see-also","title":"See also","text":"
    • operator/ - create JSON Pointer by appending
    • push_back - append an unescaped token at the end of the pointer
    • JSON Pointer - the article on JSON Pointer support
    "},{"location":"api/json_pointer/operator_slasheq/#version-history","title":"Version history","text":"
    1. Added in version 3.6.0. Appending a JSON pointer to itself no longer results in undefined behavior in version 3.13.0.
    2. Added in version 3.6.0. Changed type of token to string_t in version 3.11.0.
    3. Added in version 3.6.0.
    "},{"location":"api/json_pointer/operator_spaceship/","title":"nlohmann::json_pointer::operator<=>","text":"
    // since C++20\ntemplate<typename RefStringTypeRhs>\nstd::strong_ordering operator<=>(const json_pointer<RefStringTypeRhs>& rhs) const noexcept; // *NOPAD*\n

    3-way compares two JSON pointers by lexicographically comparing their sequences of reference tokens: corresponding reference tokens are compared with string_t's own operator<=>, and the first pair of tokens that differs determines the result. If all corresponding reference tokens compare equal, the JSON pointer with fewer reference tokens is ordered first.

    "},{"location":"api/json_pointer/operator_spaceship/#template-parameters","title":"Template parameters","text":"RefStringTypeRhs the string type of the right-hand side JSON pointer"},{"location":"api/json_pointer/operator_spaceship/#parameters","title":"Parameters","text":"rhs (in) JSON pointer to compare *this with"},{"location":"api/json_pointer/operator_spaceship/#return-value","title":"Return value","text":"

    the std::strong_ordering of the 3-way comparison of *this and rhs

    "},{"location":"api/json_pointer/operator_spaceship/#exception-safety","title":"Exception safety","text":"

    No-throw guarantee: this function never throws exceptions.

    "},{"location":"api/json_pointer/operator_spaceship/#complexity","title":"Complexity","text":"

    Linear in the number of reference tokens.

    "},{"location":"api/json_pointer/operator_spaceship/#notes","title":"Notes","text":"

    Ordering enables use as an associative container key

    Together with operator==, operator<=> makes json_pointer a LessThanComparable type, so it can be used as the key type of ordered associative containers such as std::map or std::set.

    Before C++20

    Without C++20's three-way comparison, json_pointer provides a non-member operator< instead, which orders JSON pointers the same way. JSON pointers can therefore be used as keys of ordered associative containers with any supported C++ standard.

    "},{"location":"api/json_pointer/operator_spaceship/#examples","title":"Examples","text":"Example

    The example demonstrates 3-way comparing JSON pointers.

    #include <compare>\n#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nconst char* to_string(const std::strong_ordering& so)\n{\n    if (std::is_lt(so))\n    {\n        return \"less\";\n    }\n    else if (std::is_gt(so))\n    {\n        return \"greater\";\n    }\n    return \"equal\";\n}\n\nint main()\n{\n    // different JSON pointers\n    json::json_pointer ptr1(\"/a/b\");\n    json::json_pointer ptr2(\"/a/c\");\n    json::json_pointer ptr3(\"/a/b/c\");\n    json::json_pointer ptr4(\"/a/b\");\n\n    // 3-way compare JSON pointers\n    std::cout << \"\\\"\" << ptr1 << \"\\\" <=> \\\"\" << ptr2 << \"\\\": \" << to_string(ptr1 <=> ptr2) << '\\n' // *NOPAD*\n              << \"\\\"\" << ptr1 << \"\\\" <=> \\\"\" << ptr3 << \"\\\": \" << to_string(ptr1 <=> ptr3) << '\\n' // *NOPAD*\n              << \"\\\"\" << ptr1 << \"\\\" <=> \\\"\" << ptr4 << \"\\\": \" << to_string(ptr1 <=> ptr4) << std::endl; // *NOPAD*\n}\n

    Output:

    \"/a/b\" <=> \"/a/c\": less\n\"/a/b\" <=> \"/a/b/c\": less\n\"/a/b\" <=> \"/a/b\": equal\n
    "},{"location":"api/json_pointer/operator_spaceship/#see-also","title":"See also","text":"
    • operator== - compare: equal
    • operator!= - compare: not equal
    "},{"location":"api/json_pointer/operator_spaceship/#version-history","title":"Version history","text":"
    • Added in version 3.11.2.
    "},{"location":"api/json_pointer/operator_string_t/","title":"nlohmann::json_pointer::operator string_t","text":"
    operator string_t() const\n

    Return a string representation of the JSON pointer.

    "},{"location":"api/json_pointer/operator_string_t/#return-value","title":"Return value","text":"

    A string representation of the JSON pointer

    "},{"location":"api/json_pointer/operator_string_t/#possible-implementation","title":"Possible implementation","text":"
    operator string_t() const\n{\n    return to_string();\n}\n
    "},{"location":"api/json_pointer/operator_string_t/#notes","title":"Notes","text":"

    Deprecation

    This function is deprecated in favor of to_string and will be removed in a future major version release.

    See the migration guide for how to update existing code.

    "},{"location":"api/json_pointer/operator_string_t/#examples","title":"Examples","text":"Example

    The example shows how JSON Pointers can be implicitly converted to strings.

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // different JSON Pointers\n    json::json_pointer ptr1(\"/foo/0\");\n    json::json_pointer ptr2(\"/a~1b\");\n\n    // implicit conversion to string\n    std::string s;\n    s += ptr1;\n    s += \"\\n\";\n    s += ptr2;\n\n    std::cout << s << '\\n';\n}\n

    Output:

    /foo/0\n/a~1b\n
    "},{"location":"api/json_pointer/operator_string_t/#see-also","title":"See also","text":"
    • to_string - return a string representation of the JSON pointer
    • string_t - type for strings
    "},{"location":"api/json_pointer/operator_string_t/#version-history","title":"Version history","text":"
    • Added in version 2.0.0.
    • Changed type to string_t and deprecated in version 3.11.0.
    "},{"location":"api/json_pointer/parent_pointer/","title":"nlohmann::json_pointer::parent_pointer","text":"
    json_pointer parent_pointer() const;\n

    Returns the parent of this JSON pointer.

    "},{"location":"api/json_pointer/parent_pointer/#return-value","title":"Return value","text":"

    Parent of this JSON pointer; in case this JSON pointer is the root, the root itself is returned.

    "},{"location":"api/json_pointer/parent_pointer/#exception-safety","title":"Exception safety","text":"

    Strong exception safety: if an exception occurs, the original value stays intact. The function is not noexcept and allocates a new JSON pointer, so it can throw std::bad_alloc; it throws no library exceptions.

    "},{"location":"api/json_pointer/parent_pointer/#complexity","title":"Complexity","text":"

    Linear in the length of the JSON pointer.

    "},{"location":"api/json_pointer/parent_pointer/#examples","title":"Examples","text":"Example

    The example shows the result of parent_pointer for different JSON Pointers.

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // different JSON Pointers\n    json::json_pointer ptr1(\"\");\n    json::json_pointer ptr2(\"/foo\");\n    json::json_pointer ptr3(\"/foo/0\");\n\n    // call parent_pointer()\n    std::cout << std::boolalpha\n              << \"parent of \\\"\" << ptr1 << \"\\\" is \\\"\" << ptr1.parent_pointer() << \"\\\"\\n\"\n              << \"parent of \\\"\" << ptr2 << \"\\\" is \\\"\" << ptr2.parent_pointer() << \"\\\"\\n\"\n              << \"parent of \\\"\" << ptr3 << \"\\\" is \\\"\" << ptr3.parent_pointer() << \"\\\"\" << '\\n';\n}\n

    Output:

    parent of \"\" is \"\"\nparent of \"/foo\" is \"\"\nparent of \"/foo/0\" is \"/foo\"\n
    "},{"location":"api/json_pointer/parent_pointer/#see-also","title":"See also","text":"
    • pop_back - remove the last reference token
    • back - return the last reference token
    "},{"location":"api/json_pointer/parent_pointer/#version-history","title":"Version history","text":"

    Added in version 3.6.0.

    "},{"location":"api/json_pointer/pop_back/","title":"nlohmann::json_pointer::pop_back","text":"
    void pop_back();\n

    Remove the last reference token.

    "},{"location":"api/json_pointer/pop_back/#exception-safety","title":"Exception safety","text":"

    Strong exception safety: if an exception occurs, the original value stays intact.

    "},{"location":"api/json_pointer/pop_back/#exceptions","title":"Exceptions","text":"

    Throws out_of_range.405 if the JSON pointer has no parent.

    "},{"location":"api/json_pointer/pop_back/#complexity","title":"Complexity","text":"

    Constant.

    "},{"location":"api/json_pointer/pop_back/#examples","title":"Examples","text":"Example

    The example shows the usage of pop_back.

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create empty JSON Pointer\n    json::json_pointer ptr(\"/foo/bar/baz\");\n    std::cout << \"\\\"\" << ptr << \"\\\"\\n\";\n\n    // call pop_back()\n    ptr.pop_back();\n    std::cout << \"\\\"\" << ptr << \"\\\"\\n\";\n\n    ptr.pop_back();\n    std::cout << \"\\\"\" << ptr << \"\\\"\\n\";\n\n    ptr.pop_back();\n    std::cout << \"\\\"\" << ptr << \"\\\"\\n\";\n}\n

    Output:

    \"/foo/bar/baz\"\n\"/foo/bar\"\n\"/foo\"\n\"\"\n
    "},{"location":"api/json_pointer/pop_back/#see-also","title":"See also","text":"
    • back - return last reference token
    • push_back - append an unescaped token at the end of the pointer
    • parent_pointer - returns the parent of this JSON pointer
    "},{"location":"api/json_pointer/pop_back/#version-history","title":"Version history","text":"

    Added in version 3.6.0.

    "},{"location":"api/json_pointer/pop_front/","title":"nlohmann::json_pointer::pop_front","text":"
    void pop_front();\n

    Remove the first reference token.

    "},{"location":"api/json_pointer/pop_front/#exception-safety","title":"Exception safety","text":"

    Strong exception safety: if an exception occurs, the original value stays intact.

    "},{"location":"api/json_pointer/pop_front/#exceptions","title":"Exceptions","text":"

    Throws out_of_range.405 if the JSON pointer has no parent.

    "},{"location":"api/json_pointer/pop_front/#complexity","title":"Complexity","text":"

    Linear in the number of reference tokens in the json_pointer.

    "},{"location":"api/json_pointer/pop_front/#examples","title":"Examples","text":"Example

    The example shows the usage of pop_front.

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create empty JSON Pointer\n    json::json_pointer ptr(\"/foo/bar/baz\");\n    std::cout << \"\\\"\" << ptr << \"\\\"\\n\";\n\n    // call pop_front()\n    ptr.pop_front();\n    std::cout << \"\\\"\" << ptr << \"\\\"\\n\";\n\n    ptr.pop_front();\n    std::cout << \"\\\"\" << ptr << \"\\\"\\n\";\n\n    ptr.pop_front();\n    std::cout << \"\\\"\" << ptr << \"\\\"\\n\";\n}\n

    Output:

    \"/foo/bar/baz\"\n\"/bar/baz\"\n\"/baz\"\n\"\"\n
    "},{"location":"api/json_pointer/pop_front/#see-also","title":"See also","text":"
    • front - return first reference token
    • push_front - append an unescaped token at the start of the pointer
    "},{"location":"api/json_pointer/pop_front/#version-history","title":"Version history","text":"
    • Added in version 3.13.0 unreleased.
    "},{"location":"api/json_pointer/push_back/","title":"nlohmann::json_pointer::push_back","text":"
    void push_back(const string_t& token);\n\nvoid push_back(string_t&& token);\n

    Append an unescaped token at the end of the reference pointer.

    "},{"location":"api/json_pointer/push_back/#parameters","title":"Parameters","text":"token (in) token to add"},{"location":"api/json_pointer/push_back/#exception-safety","title":"Exception safety","text":"

    Strong exception safety: if an exception occurs, the original value stays intact.

    "},{"location":"api/json_pointer/push_back/#complexity","title":"Complexity","text":"

    Amortized constant.

    "},{"location":"api/json_pointer/push_back/#examples","title":"Examples","text":"Example

    The example shows the result of push_back for different JSON Pointers.

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create empty JSON Pointer\n    json::json_pointer ptr;\n    std::cout << \"\\\"\" << ptr << \"\\\"\\n\";\n\n    // call push_back()\n    ptr.push_back(\"foo\");\n    std::cout << \"\\\"\" << ptr << \"\\\"\\n\";\n\n    ptr.push_back(\"0\");\n    std::cout << \"\\\"\" << ptr << \"\\\"\\n\";\n\n    ptr.push_back(\"bar\");\n    std::cout << \"\\\"\" << ptr << \"\\\"\\n\";\n}\n

    Output:

    \"\"\n\"/foo\"\n\"/foo/0\"\n\"/foo/0/bar\"\n
    "},{"location":"api/json_pointer/push_back/#see-also","title":"See also","text":"
    • back - return last reference token
    • pop_back - remove the last reference token
    • operator/= - append to the end of the JSON pointer
    • operator/ - create JSON Pointer by appending
    "},{"location":"api/json_pointer/push_back/#version-history","title":"Version history","text":"
    • Added in version 3.6.0.
    • Changed type of token to string_t in version 3.11.0.
    "},{"location":"api/json_pointer/push_front/","title":"nlohmann::json_pointer::push_front","text":"
    void push_front(const string_t& token);\n\nvoid push_front(string_t&& token);\n

    Append an unescaped token at the start of the reference pointer.

    "},{"location":"api/json_pointer/push_front/#parameters","title":"Parameters","text":"token (in) token to add"},{"location":"api/json_pointer/push_front/#exception-safety","title":"Exception safety","text":"

    Basic guarantee: if an exception is thrown (for instance, if copying the reference token fails), the JSON pointer is left in a valid state, but its reference tokens may have changed.

    "},{"location":"api/json_pointer/push_front/#complexity","title":"Complexity","text":"

    Linear in the number of reference tokens in the json_pointer.

    "},{"location":"api/json_pointer/push_front/#examples","title":"Examples","text":"Example

    The example shows the result of push_front for different JSON Pointers.

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create empty JSON Pointer\n    json::json_pointer ptr;\n    std::cout << \"\\\"\" << ptr << \"\\\"\\n\";\n\n    // call push_front()\n    ptr.push_front(\"foo\");\n    std::cout << \"\\\"\" << ptr << \"\\\"\\n\";\n\n    ptr.push_front(\"0\");\n    std::cout << \"\\\"\" << ptr << \"\\\"\\n\";\n\n    ptr.push_front(\"bar\");\n    std::cout << \"\\\"\" << ptr << \"\\\"\\n\";\n}\n

    Output:

    \"\"\n\"/foo\"\n\"/0/foo\"\n\"/bar/0/foo\"\n
    "},{"location":"api/json_pointer/push_front/#see-also","title":"See also","text":"
    • front - return first reference token
    • pop_front - remove the first reference token
    "},{"location":"api/json_pointer/push_front/#version-history","title":"Version history","text":"
    • Added in version 3.13.0 unreleased.
    "},{"location":"api/json_pointer/string_t/","title":"nlohmann::json_pointer::string_t","text":"
    using string_t = RefStringType;\n

    The string type used for the reference tokens making up the JSON pointer.

    See basic_json::string_t for more information.

    "},{"location":"api/json_pointer/string_t/#examples","title":"Examples","text":"Example

    The example shows the type string_t and its relation to basic_json::string_t.

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    json::json_pointer::string_t s = \"This is a string.\";\n\n    std::cout << s << '\\n';\n\n    std::cout << std::boolalpha << std::is_same<json::json_pointer::string_t, json::string_t>::value << '\\n';\n}\n

    Output:

    This is a string.\ntrue\n
    "},{"location":"api/json_pointer/string_t/#see-also","title":"See also","text":"
    • basic_json::string_t - type used to store JSON strings
    • to_string - return a string representation of the JSON pointer
    "},{"location":"api/json_pointer/string_t/#version-history","title":"Version history","text":"
    • Added in version 3.11.0.
    "},{"location":"api/json_pointer/to_string/","title":"nlohmann::json_pointer::to_string","text":"
    string_t to_string() const;\n

    Return a string representation of the JSON pointer.

    "},{"location":"api/json_pointer/to_string/#return-value","title":"Return value","text":"

    A string representation of the JSON pointer

    "},{"location":"api/json_pointer/to_string/#exception-safety","title":"Exception safety","text":"

    Strong exception safety: if an exception occurs, the original value stays intact.

    "},{"location":"api/json_pointer/to_string/#complexity","title":"Complexity","text":"

    Linear in the total length of the reference tokens.

    "},{"location":"api/json_pointer/to_string/#notes","title":"Notes","text":"

    For each JSON pointer ptr, it holds:

    ptr == json_pointer(ptr.to_string());\n
    "},{"location":"api/json_pointer/to_string/#examples","title":"Examples","text":"Example

    The example shows the result of to_string.

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // different JSON Pointers\n    json::json_pointer ptr1(\"\");\n    json::json_pointer ptr2(\"/foo\");\n    json::json_pointer ptr3(\"/foo/0\");\n    json::json_pointer ptr4(\"/\");\n    json::json_pointer ptr5(\"/a~1b\");\n    json::json_pointer ptr6(\"/c%d\");\n    json::json_pointer ptr7(\"/e^f\");\n    json::json_pointer ptr8(\"/g|h\");\n    json::json_pointer ptr9(\"/i\\\\j\");\n    json::json_pointer ptr10(\"/k\\\"l\");\n    json::json_pointer ptr11(\"/ \");\n    json::json_pointer ptr12(\"/m~0n\");\n\n    std::cout << \"\\\"\" << ptr1.to_string() << \"\\\"\\n\"\n              << \"\\\"\" << ptr2.to_string() << \"\\\"\\n\"\n              << \"\\\"\" << ptr3.to_string() << \"\\\"\\n\"\n              << \"\\\"\" << ptr4.to_string() << \"\\\"\\n\"\n              << \"\\\"\" << ptr5.to_string() << \"\\\"\\n\"\n              << \"\\\"\" << ptr6.to_string() << \"\\\"\\n\"\n              << \"\\\"\" << ptr7.to_string() << \"\\\"\\n\"\n              << \"\\\"\" << ptr8.to_string() << \"\\\"\\n\"\n              << \"\\\"\" << ptr9.to_string() << \"\\\"\\n\"\n              << \"\\\"\" << ptr10.to_string() << \"\\\"\\n\"\n              << \"\\\"\" << ptr11.to_string() << \"\\\"\\n\"\n              << \"\\\"\" << ptr12.to_string() << \"\\\"\" << '\\n';\n}\n

    Output:

    \"\"\n\"/foo\"\n\"/foo/0\"\n\"/\"\n\"/a~1b\"\n\"/c%d\"\n\"/e^f\"\n\"/g|h\"\n\"/i\\j\"\n\"/k\"l\"\n\"/ \"\n\"/m~0n\"\n
    "},{"location":"api/json_pointer/to_string/#see-also","title":"See also","text":"
    • operator string_t - return a string representation of the JSON pointer (deprecated)
    • operator<< - write a JSON pointer to a stream
    "},{"location":"api/json_pointer/to_string/#version-history","title":"Version history","text":"
    • Added in version 2.0.0.
    • Changed return type to string_t in version 3.11.0.
    "},{"location":"api/json_sax/","title":"nlohmann::json_sax","text":"
    template<typename BasicJsonType>\nstruct json_sax;\n

    This class describes the SAX interface used by sax_parse. Each function is called in different situations while the input is parsed. The boolean return value informs the parser whether to continue processing the input.

    For instance, parsing the JSON text {\"a\": [1, true]} triggers the following callbacks, in order:

    sequenceDiagram\n    participant P as Parser\n    participant H as SAX handler\n\n    P->>H: start_object(elements)\n    P->>H: key(\"a\")\n    P->>H: start_array(elements)\n    P->>H: number_unsigned(1)\n    P->>H: boolean(true)\n    P->>H: end_array()\n    P->>H: end_object()

    Each arrow is one call from the parser to the SAX handler, from top to bottom in the order the calls happen.

    Note elements is passed as std::numeric_limits<std::size_t>::max() (i.e., \"unknown\") for JSON text input; only binary formats such as CBOR or MessagePack may report the actual number of elements in start_object/ start_array. Also note that 1 is reported via number_unsigned rather than number_integer because it has no leading - sign.

    "},{"location":"api/json_sax/#template-parameters","title":"Template parameters","text":"BasicJsonType a specialization of basic_json"},{"location":"api/json_sax/#member-types","title":"Member types","text":"
    • number_integer_t - BasicJsonType's type for numbers (integer)
    • number_unsigned_t - BasicJsonType's type for numbers (unsigned)
    • number_float_t - BasicJsonType's type for numbers (floating-point)
    • string_t - BasicJsonType's type for strings
    • binary_t - BasicJsonType's type for binary arrays
    "},{"location":"api/json_sax/#member-functions","title":"Member functions","text":"
    • binary (virtual) - a binary value was read
    • boolean (virtual) - a boolean value was read
    • end_array (virtual) - the end of an array was read
    • end_object (virtual) - the end of an object was read
    • key (virtual) - an object key was read
    • null (virtual) - a null value was read
    • number_float (virtual) - a floating-point number was read
    • number_integer (virtual) - an integer number was read
    • number_unsigned (virtual) - an unsigned integer number was read
    • parse_error (virtual) - a parse error occurred
    • start_array (virtual) - the beginning of an array was read
    • start_object (virtual) - the beginning of an object was read
    • string (virtual) - a string value was read
    "},{"location":"api/json_sax/#see-also","title":"See also","text":"
    • SAX interface - guide to event-based parsing
    • sax_parse - generate SAX events from an input
    • parse - DOM parsing, with optional parser callbacks
    • Parse exceptions - how parse errors are reported
    "},{"location":"api/json_sax/#version-history","title":"Version history","text":"
    • Added in version 3.2.0.
    • Support for binary values (binary_t, binary) added in version 3.8.0.
    "},{"location":"api/json_sax/binary/","title":"nlohmann::json_sax::binary","text":"
    virtual bool binary(binary_t& val) = 0;\n

    A binary value was read.

    "},{"location":"api/json_sax/binary/#parameters","title":"Parameters","text":"val (in) binary value"},{"location":"api/json_sax/binary/#return-value","title":"Return value","text":"

    Whether parsing should proceed.

    "},{"location":"api/json_sax/binary/#notes","title":"Notes","text":"

    It is safe to move the passed binary value.

    "},{"location":"api/json_sax/binary/#examples","title":"Examples","text":"Example

    The example below shows how the SAX interface is used.

    #include <iostream>\n#include <iomanip>\n#include <sstream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\n// a simple event consumer that collects string representations of the passed\n// values; note inheriting from json::json_sax_t is not required, but can\n// help not to forget a required function\nclass sax_event_consumer : public json::json_sax_t\n{\n  public:\n    std::vector<std::string> events;\n\n    bool null() override\n    {\n        events.push_back(\"null()\");\n        return true;\n    }\n\n    bool boolean(bool val) override\n    {\n        events.push_back(\"boolean(val=\" + std::string(val ? \"true\" : \"false\") + \")\");\n        return true;\n    }\n\n    bool number_integer(number_integer_t val) override\n    {\n        events.push_back(\"number_integer(val=\" + std::to_string(val) + \")\");\n        return true;\n    }\n\n    bool number_unsigned(number_unsigned_t val) override\n    {\n        events.push_back(\"number_unsigned(val=\" + std::to_string(val) + \")\");\n        return true;\n    }\n\n    bool number_float(number_float_t val, const string_t& s) override\n    {\n        events.push_back(\"number_float(val=\" + std::to_string(val) + \", s=\" + s + \")\");\n        return true;\n    }\n\n    bool string(string_t& val) override\n    {\n        events.push_back(\"string(val=\" + val + \")\");\n        return true;\n    }\n\n    bool start_object(std::size_t elements) override\n    {\n        events.push_back(\"start_object(elements=\" + std::to_string(elements) + \")\");\n        return true;\n    }\n\n    bool end_object() override\n    {\n        events.push_back(\"end_object()\");\n        return true;\n    }\n\n    bool start_array(std::size_t elements) override\n    {\n        events.push_back(\"start_array(elements=\" + std::to_string(elements) + \")\");\n        return true;\n    }\n\n    bool end_array() override\n    {\n        events.push_back(\"end_array()\");\n        return true;\n    }\n\n    bool key(string_t& val) override\n    {\n        events.push_back(\"key(val=\" + val + \")\");\n        return true;\n    }\n\n    bool binary(json::binary_t& val) override\n    {\n        events.push_back(\"binary(val=[...])\");\n        return true;\n    }\n\n    bool parse_error(std::size_t position, const std::string& last_token, const json::exception& ex) override\n    {\n        events.push_back(\"parse_error(position=\" + std::to_string(position) + \", last_token=\" + last_token + \",\\n            ex=\" + std::string(ex.what()) + \")\");\n        return false;\n    }\n};\n\nint main()\n{\n    // CBOR byte string\n    std::vector<std::uint8_t> vec = {{0x44, 0xcA, 0xfe, 0xba, 0xbe}};\n\n    // create a SAX event consumer object\n    sax_event_consumer sec;\n\n    // parse CBOR\n    bool result = json::sax_parse(vec, &sec, json::input_format_t::cbor);\n\n    // output the recorded events\n    for (auto& event : sec.events)\n    {\n        std::cout << event << \"\\n\";\n    }\n\n    // output the result of sax_parse\n    std::cout << \"\\nresult: \" << std::boolalpha << result << '\\n';\n}\n

    Output:

    binary(val=[...])\n\nresult: true\n
    "},{"location":"api/json_sax/binary/#see-also","title":"See also","text":"
    • sax_parse - SAX parser
    • SAX Interface - the SAX interface article
    • Binary Values - the article on binary values
    "},{"location":"api/json_sax/binary/#version-history","title":"Version history","text":"
    • Added in version 3.8.0.
    "},{"location":"api/json_sax/boolean/","title":"nlohmann::json_sax::boolean","text":"
    virtual bool boolean(bool val) = 0;\n

    A boolean value was read.

    "},{"location":"api/json_sax/boolean/#parameters","title":"Parameters","text":"val (in) boolean value"},{"location":"api/json_sax/boolean/#return-value","title":"Return value","text":"

    Whether parsing should proceed.

    "},{"location":"api/json_sax/boolean/#examples","title":"Examples","text":"Example

    The example below shows how the SAX interface is used.

    #include <iostream>\n#include <iomanip>\n#include <sstream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\n// a simple event consumer that collects string representations of the passed\n// values; note inheriting from json::json_sax_t is not required, but can\n// help not to forget a required function\nclass sax_event_consumer : public json::json_sax_t\n{\n  public:\n    std::vector<std::string> events;\n\n    bool null() override\n    {\n        events.push_back(\"null()\");\n        return true;\n    }\n\n    bool boolean(bool val) override\n    {\n        events.push_back(\"boolean(val=\" + std::string(val ? \"true\" : \"false\") + \")\");\n        return true;\n    }\n\n    bool number_integer(number_integer_t val) override\n    {\n        events.push_back(\"number_integer(val=\" + std::to_string(val) + \")\");\n        return true;\n    }\n\n    bool number_unsigned(number_unsigned_t val) override\n    {\n        events.push_back(\"number_unsigned(val=\" + std::to_string(val) + \")\");\n        return true;\n    }\n\n    bool number_float(number_float_t val, const string_t& s) override\n    {\n        events.push_back(\"number_float(val=\" + std::to_string(val) + \", s=\" + s + \")\");\n        return true;\n    }\n\n    bool string(string_t& val) override\n    {\n        events.push_back(\"string(val=\" + val + \")\");\n        return true;\n    }\n\n    bool start_object(std::size_t elements) override\n    {\n        events.push_back(\"start_object(elements=\" + std::to_string(elements) + \")\");\n        return true;\n    }\n\n    bool end_object() override\n    {\n        events.push_back(\"end_object()\");\n        return true;\n    }\n\n    bool start_array(std::size_t elements) override\n    {\n        events.push_back(\"start_array(elements=\" + std::to_string(elements) + \")\");\n        return true;\n    }\n\n    bool end_array() override\n    {\n        events.push_back(\"end_array()\");\n        return true;\n    }\n\n    bool key(string_t& val) override\n    {\n        events.push_back(\"key(val=\" + val + \")\");\n        return true;\n    }\n\n    bool binary(json::binary_t& val) override\n    {\n        events.push_back(\"binary(val=[...])\");\n        return true;\n    }\n\n    bool parse_error(std::size_t position, const std::string& last_token, const json::exception& ex) override\n    {\n        events.push_back(\"parse_error(position=\" + std::to_string(position) + \", last_token=\" + last_token + \",\\n            ex=\" + std::string(ex.what()) + \")\");\n        return false;\n    }\n};\n\nint main()\n{\n    // a JSON text\n    const auto* text = R\"(\n    {\n        \"Image\": {\n            \"Width\":  800,\n            \"Height\": 600,\n            \"Title\":  \"View from 15th Floor\",\n            \"Thumbnail\": {\n                \"Url\":    \"http://www.example.com/image/481989943\",\n                \"Height\": 125,\n                \"Width\":  100\n            },\n            \"Animated\" : false,\n            \"IDs\": [116, 943, 234, -38793],\n            \"DeletionDate\": null,\n            \"Distance\": 12.723374634\n        }\n    }]\n    )\";\n\n    // create a SAX event consumer object\n    sax_event_consumer sec;\n\n    // parse JSON\n    bool result = json::sax_parse(text, &sec);\n\n    // output the recorded events\n    for (auto& event : sec.events)\n    {\n        std::cout << event << \"\\n\";\n    }\n\n    // output the result of sax_parse\n    std::cout << \"\\nresult: \" << std::boolalpha << result << '\\n';\n}\n

    Output:

    start_object(elements=18446744073709551615)\nkey(val=Image)\nstart_object(elements=18446744073709551615)\nkey(val=Width)\nnumber_unsigned(val=800)\nkey(val=Height)\nnumber_unsigned(val=600)\nkey(val=Title)\nstring(val=View from 15th Floor)\nkey(val=Thumbnail)\nstart_object(elements=18446744073709551615)\nkey(val=Url)\nstring(val=http://www.example.com/image/481989943)\nkey(val=Height)\nnumber_unsigned(val=125)\nkey(val=Width)\nnumber_unsigned(val=100)\nend_object()\nkey(val=Animated)\nboolean(val=false)\nkey(val=IDs)\nstart_array(elements=18446744073709551615)\nnumber_unsigned(val=116)\nnumber_unsigned(val=943)\nnumber_unsigned(val=234)\nnumber_integer(val=-38793)\nend_array()\nkey(val=DeletionDate)\nnull()\nkey(val=Distance)\nnumber_float(val=12.723375, s=12.723374634)\nend_object()\nend_object()\nparse_error(position=460, last_token=12.723374634<U+000A>        }<U+000A>    }],\n            ex=[json.exception.parse_error.101] parse error at line 17, column 6: syntax error while parsing value - unexpected ']'; expected end of input)\n\nresult: false\n
    "},{"location":"api/json_sax/boolean/#see-also","title":"See also","text":"
    • sax_parse - SAX parser
    • SAX Interface - the SAX interface article
    "},{"location":"api/json_sax/boolean/#version-history","title":"Version history","text":"
    • Added in version 3.2.0.
    "},{"location":"api/json_sax/end_array/","title":"nlohmann::json_sax::end_array","text":"
    virtual bool end_array() = 0;\n

    The end of an array was read.

    "},{"location":"api/json_sax/end_array/#return-value","title":"Return value","text":"

    Whether parsing should proceed.

    "},{"location":"api/json_sax/end_array/#examples","title":"Examples","text":"Example

    The example below shows how the SAX interface is used.

    #include <iostream>\n#include <iomanip>\n#include <sstream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\n// a simple event consumer that collects string representations of the passed\n// values; note inheriting from json::json_sax_t is not required, but can\n// help not to forget a required function\nclass sax_event_consumer : public json::json_sax_t\n{\n  public:\n    std::vector<std::string> events;\n\n    bool null() override\n    {\n        events.push_back(\"null()\");\n        return true;\n    }\n\n    bool boolean(bool val) override\n    {\n        events.push_back(\"boolean(val=\" + std::string(val ? \"true\" : \"false\") + \")\");\n        return true;\n    }\n\n    bool number_integer(number_integer_t val) override\n    {\n        events.push_back(\"number_integer(val=\" + std::to_string(val) + \")\");\n        return true;\n    }\n\n    bool number_unsigned(number_unsigned_t val) override\n    {\n        events.push_back(\"number_unsigned(val=\" + std::to_string(val) + \")\");\n        return true;\n    }\n\n    bool number_float(number_float_t val, const string_t& s) override\n    {\n        events.push_back(\"number_float(val=\" + std::to_string(val) + \", s=\" + s + \")\");\n        return true;\n    }\n\n    bool string(string_t& val) override\n    {\n        events.push_back(\"string(val=\" + val + \")\");\n        return true;\n    }\n\n    bool start_object(std::size_t elements) override\n    {\n        events.push_back(\"start_object(elements=\" + std::to_string(elements) + \")\");\n        return true;\n    }\n\n    bool end_object() override\n    {\n        events.push_back(\"end_object()\");\n        return true;\n    }\n\n    bool start_array(std::size_t elements) override\n    {\n        events.push_back(\"start_array(elements=\" + std::to_string(elements) + \")\");\n        return true;\n    }\n\n    bool end_array() override\n    {\n        events.push_back(\"end_array()\");\n        return true;\n    }\n\n    bool key(string_t& val) override\n    {\n        events.push_back(\"key(val=\" + val + \")\");\n        return true;\n    }\n\n    bool binary(json::binary_t& val) override\n    {\n        events.push_back(\"binary(val=[...])\");\n        return true;\n    }\n\n    bool parse_error(std::size_t position, const std::string& last_token, const json::exception& ex) override\n    {\n        events.push_back(\"parse_error(position=\" + std::to_string(position) + \", last_token=\" + last_token + \",\\n            ex=\" + std::string(ex.what()) + \")\");\n        return false;\n    }\n};\n\nint main()\n{\n    // a JSON text\n    const auto* text = R\"(\n    {\n        \"Image\": {\n            \"Width\":  800,\n            \"Height\": 600,\n            \"Title\":  \"View from 15th Floor\",\n            \"Thumbnail\": {\n                \"Url\":    \"http://www.example.com/image/481989943\",\n                \"Height\": 125,\n                \"Width\":  100\n            },\n            \"Animated\" : false,\n            \"IDs\": [116, 943, 234, -38793],\n            \"DeletionDate\": null,\n            \"Distance\": 12.723374634\n        }\n    }]\n    )\";\n\n    // create a SAX event consumer object\n    sax_event_consumer sec;\n\n    // parse JSON\n    bool result = json::sax_parse(text, &sec);\n\n    // output the recorded events\n    for (auto& event : sec.events)\n    {\n        std::cout << event << \"\\n\";\n    }\n\n    // output the result of sax_parse\n    std::cout << \"\\nresult: \" << std::boolalpha << result << '\\n';\n}\n

    Output:

    start_object(elements=18446744073709551615)\nkey(val=Image)\nstart_object(elements=18446744073709551615)\nkey(val=Width)\nnumber_unsigned(val=800)\nkey(val=Height)\nnumber_unsigned(val=600)\nkey(val=Title)\nstring(val=View from 15th Floor)\nkey(val=Thumbnail)\nstart_object(elements=18446744073709551615)\nkey(val=Url)\nstring(val=http://www.example.com/image/481989943)\nkey(val=Height)\nnumber_unsigned(val=125)\nkey(val=Width)\nnumber_unsigned(val=100)\nend_object()\nkey(val=Animated)\nboolean(val=false)\nkey(val=IDs)\nstart_array(elements=18446744073709551615)\nnumber_unsigned(val=116)\nnumber_unsigned(val=943)\nnumber_unsigned(val=234)\nnumber_integer(val=-38793)\nend_array()\nkey(val=DeletionDate)\nnull()\nkey(val=Distance)\nnumber_float(val=12.723375, s=12.723374634)\nend_object()\nend_object()\nparse_error(position=460, last_token=12.723374634<U+000A>        }<U+000A>    }],\n            ex=[json.exception.parse_error.101] parse error at line 17, column 6: syntax error while parsing value - unexpected ']'; expected end of input)\n\nresult: false\n
    "},{"location":"api/json_sax/end_array/#see-also","title":"See also","text":"
    • start_array - the beginning of an array was read
    • sax_parse - SAX parser
    • SAX Interface - guide to event-based parsing
    "},{"location":"api/json_sax/end_array/#version-history","title":"Version history","text":"
    • Added in version 3.2.0.
    "},{"location":"api/json_sax/end_object/","title":"nlohmann::json_sax::end_object","text":"
    virtual bool end_object() = 0;\n

    The end of an object was read.

    "},{"location":"api/json_sax/end_object/#return-value","title":"Return value","text":"

    Whether parsing should proceed.

    "},{"location":"api/json_sax/end_object/#examples","title":"Examples","text":"Example

    The example below shows how the SAX interface is used.

    #include <iostream>\n#include <iomanip>\n#include <sstream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\n// a simple event consumer that collects string representations of the passed\n// values; note inheriting from json::json_sax_t is not required, but can\n// help not to forget a required function\nclass sax_event_consumer : public json::json_sax_t\n{\n  public:\n    std::vector<std::string> events;\n\n    bool null() override\n    {\n        events.push_back(\"null()\");\n        return true;\n    }\n\n    bool boolean(bool val) override\n    {\n        events.push_back(\"boolean(val=\" + std::string(val ? \"true\" : \"false\") + \")\");\n        return true;\n    }\n\n    bool number_integer(number_integer_t val) override\n    {\n        events.push_back(\"number_integer(val=\" + std::to_string(val) + \")\");\n        return true;\n    }\n\n    bool number_unsigned(number_unsigned_t val) override\n    {\n        events.push_back(\"number_unsigned(val=\" + std::to_string(val) + \")\");\n        return true;\n    }\n\n    bool number_float(number_float_t val, const string_t& s) override\n    {\n        events.push_back(\"number_float(val=\" + std::to_string(val) + \", s=\" + s + \")\");\n        return true;\n    }\n\n    bool string(string_t& val) override\n    {\n        events.push_back(\"string(val=\" + val + \")\");\n        return true;\n    }\n\n    bool start_object(std::size_t elements) override\n    {\n        events.push_back(\"start_object(elements=\" + std::to_string(elements) + \")\");\n        return true;\n    }\n\n    bool end_object() override\n    {\n        events.push_back(\"end_object()\");\n        return true;\n    }\n\n    bool start_array(std::size_t elements) override\n    {\n        events.push_back(\"start_array(elements=\" + std::to_string(elements) + \")\");\n        return true;\n    }\n\n    bool end_array() override\n    {\n        events.push_back(\"end_array()\");\n        return true;\n    }\n\n    bool key(string_t& val) override\n    {\n        events.push_back(\"key(val=\" + val + \")\");\n        return true;\n    }\n\n    bool binary(json::binary_t& val) override\n    {\n        events.push_back(\"binary(val=[...])\");\n        return true;\n    }\n\n    bool parse_error(std::size_t position, const std::string& last_token, const json::exception& ex) override\n    {\n        events.push_back(\"parse_error(position=\" + std::to_string(position) + \", last_token=\" + last_token + \",\\n            ex=\" + std::string(ex.what()) + \")\");\n        return false;\n    }\n};\n\nint main()\n{\n    // a JSON text\n    const auto* text = R\"(\n    {\n        \"Image\": {\n            \"Width\":  800,\n            \"Height\": 600,\n            \"Title\":  \"View from 15th Floor\",\n            \"Thumbnail\": {\n                \"Url\":    \"http://www.example.com/image/481989943\",\n                \"Height\": 125,\n                \"Width\":  100\n            },\n            \"Animated\" : false,\n            \"IDs\": [116, 943, 234, -38793],\n            \"DeletionDate\": null,\n            \"Distance\": 12.723374634\n        }\n    }]\n    )\";\n\n    // create a SAX event consumer object\n    sax_event_consumer sec;\n\n    // parse JSON\n    bool result = json::sax_parse(text, &sec);\n\n    // output the recorded events\n    for (auto& event : sec.events)\n    {\n        std::cout << event << \"\\n\";\n    }\n\n    // output the result of sax_parse\n    std::cout << \"\\nresult: \" << std::boolalpha << result << '\\n';\n}\n

    Output:

    start_object(elements=18446744073709551615)\nkey(val=Image)\nstart_object(elements=18446744073709551615)\nkey(val=Width)\nnumber_unsigned(val=800)\nkey(val=Height)\nnumber_unsigned(val=600)\nkey(val=Title)\nstring(val=View from 15th Floor)\nkey(val=Thumbnail)\nstart_object(elements=18446744073709551615)\nkey(val=Url)\nstring(val=http://www.example.com/image/481989943)\nkey(val=Height)\nnumber_unsigned(val=125)\nkey(val=Width)\nnumber_unsigned(val=100)\nend_object()\nkey(val=Animated)\nboolean(val=false)\nkey(val=IDs)\nstart_array(elements=18446744073709551615)\nnumber_unsigned(val=116)\nnumber_unsigned(val=943)\nnumber_unsigned(val=234)\nnumber_integer(val=-38793)\nend_array()\nkey(val=DeletionDate)\nnull()\nkey(val=Distance)\nnumber_float(val=12.723375, s=12.723374634)\nend_object()\nend_object()\nparse_error(position=460, last_token=12.723374634<U+000A>        }<U+000A>    }],\n            ex=[json.exception.parse_error.101] parse error at line 17, column 6: syntax error while parsing value - unexpected ']'; expected end of input)\n\nresult: false\n
    "},{"location":"api/json_sax/end_object/#see-also","title":"See also","text":"
    • start_object - the beginning of an object was read
    • key - an object key was read
    • sax_parse - SAX parser
    • SAX Interface - guide to event-based parsing
    "},{"location":"api/json_sax/end_object/#version-history","title":"Version history","text":"
    • Added in version 3.2.0.
    "},{"location":"api/json_sax/key/","title":"nlohmann::json_sax::key","text":"
    virtual bool key(string_t& val) = 0;\n

    An object key was read.

    "},{"location":"api/json_sax/key/#parameters","title":"Parameters","text":"val (in) object key"},{"location":"api/json_sax/key/#return-value","title":"Return value","text":"

    Whether parsing should proceed.

    "},{"location":"api/json_sax/key/#notes","title":"Notes","text":"

    It is safe to move the passed object key value.

    "},{"location":"api/json_sax/key/#examples","title":"Examples","text":"Example

    The example below shows how the SAX interface is used.

    #include <iostream>\n#include <iomanip>\n#include <sstream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\n// a simple event consumer that collects string representations of the passed\n// values; note inheriting from json::json_sax_t is not required, but can\n// help not to forget a required function\nclass sax_event_consumer : public json::json_sax_t\n{\n  public:\n    std::vector<std::string> events;\n\n    bool null() override\n    {\n        events.push_back(\"null()\");\n        return true;\n    }\n\n    bool boolean(bool val) override\n    {\n        events.push_back(\"boolean(val=\" + std::string(val ? \"true\" : \"false\") + \")\");\n        return true;\n    }\n\n    bool number_integer(number_integer_t val) override\n    {\n        events.push_back(\"number_integer(val=\" + std::to_string(val) + \")\");\n        return true;\n    }\n\n    bool number_unsigned(number_unsigned_t val) override\n    {\n        events.push_back(\"number_unsigned(val=\" + std::to_string(val) + \")\");\n        return true;\n    }\n\n    bool number_float(number_float_t val, const string_t& s) override\n    {\n        events.push_back(\"number_float(val=\" + std::to_string(val) + \", s=\" + s + \")\");\n        return true;\n    }\n\n    bool string(string_t& val) override\n    {\n        events.push_back(\"string(val=\" + val + \")\");\n        return true;\n    }\n\n    bool start_object(std::size_t elements) override\n    {\n        events.push_back(\"start_object(elements=\" + std::to_string(elements) + \")\");\n        return true;\n    }\n\n    bool end_object() override\n    {\n        events.push_back(\"end_object()\");\n        return true;\n    }\n\n    bool start_array(std::size_t elements) override\n    {\n        events.push_back(\"start_array(elements=\" + std::to_string(elements) + \")\");\n        return true;\n    }\n\n    bool end_array() override\n    {\n        events.push_back(\"end_array()\");\n        return true;\n    }\n\n    bool key(string_t& val) override\n    {\n        events.push_back(\"key(val=\" + val + \")\");\n        return true;\n    }\n\n    bool binary(json::binary_t& val) override\n    {\n        events.push_back(\"binary(val=[...])\");\n        return true;\n    }\n\n    bool parse_error(std::size_t position, const std::string& last_token, const json::exception& ex) override\n    {\n        events.push_back(\"parse_error(position=\" + std::to_string(position) + \", last_token=\" + last_token + \",\\n            ex=\" + std::string(ex.what()) + \")\");\n        return false;\n    }\n};\n\nint main()\n{\n    // a JSON text\n    const auto* text = R\"(\n    {\n        \"Image\": {\n            \"Width\":  800,\n            \"Height\": 600,\n            \"Title\":  \"View from 15th Floor\",\n            \"Thumbnail\": {\n                \"Url\":    \"http://www.example.com/image/481989943\",\n                \"Height\": 125,\n                \"Width\":  100\n            },\n            \"Animated\" : false,\n            \"IDs\": [116, 943, 234, -38793],\n            \"DeletionDate\": null,\n            \"Distance\": 12.723374634\n        }\n    }]\n    )\";\n\n    // create a SAX event consumer object\n    sax_event_consumer sec;\n\n    // parse JSON\n    bool result = json::sax_parse(text, &sec);\n\n    // output the recorded events\n    for (auto& event : sec.events)\n    {\n        std::cout << event << \"\\n\";\n    }\n\n    // output the result of sax_parse\n    std::cout << \"\\nresult: \" << std::boolalpha << result << '\\n';\n}\n

    Output:

    start_object(elements=18446744073709551615)\nkey(val=Image)\nstart_object(elements=18446744073709551615)\nkey(val=Width)\nnumber_unsigned(val=800)\nkey(val=Height)\nnumber_unsigned(val=600)\nkey(val=Title)\nstring(val=View from 15th Floor)\nkey(val=Thumbnail)\nstart_object(elements=18446744073709551615)\nkey(val=Url)\nstring(val=http://www.example.com/image/481989943)\nkey(val=Height)\nnumber_unsigned(val=125)\nkey(val=Width)\nnumber_unsigned(val=100)\nend_object()\nkey(val=Animated)\nboolean(val=false)\nkey(val=IDs)\nstart_array(elements=18446744073709551615)\nnumber_unsigned(val=116)\nnumber_unsigned(val=943)\nnumber_unsigned(val=234)\nnumber_integer(val=-38793)\nend_array()\nkey(val=DeletionDate)\nnull()\nkey(val=Distance)\nnumber_float(val=12.723375, s=12.723374634)\nend_object()\nend_object()\nparse_error(position=460, last_token=12.723374634<U+000A>        }<U+000A>    }],\n            ex=[json.exception.parse_error.101] parse error at line 17, column 6: syntax error while parsing value - unexpected ']'; expected end of input)\n\nresult: false\n
    "},{"location":"api/json_sax/key/#see-also","title":"See also","text":"
    • start_object - the beginning of an object was read
    • end_object - the end of an object was read
    • sax_parse - SAX parser
    • SAX Interface - guide to event-based parsing
    "},{"location":"api/json_sax/key/#version-history","title":"Version history","text":"
    • Added in version 3.2.0.
    "},{"location":"api/json_sax/null/","title":"nlohmann::json_sax::null","text":"
    virtual bool null() = 0;\n

    A null value was read.

    "},{"location":"api/json_sax/null/#return-value","title":"Return value","text":"

    Whether parsing should proceed.

    "},{"location":"api/json_sax/null/#examples","title":"Examples","text":"Example

    The example below shows how the SAX interface is used.

    #include <iostream>\n#include <iomanip>\n#include <sstream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\n// a simple event consumer that collects string representations of the passed\n// values; note inheriting from json::json_sax_t is not required, but can\n// help not to forget a required function\nclass sax_event_consumer : public json::json_sax_t\n{\n  public:\n    std::vector<std::string> events;\n\n    bool null() override\n    {\n        events.push_back(\"null()\");\n        return true;\n    }\n\n    bool boolean(bool val) override\n    {\n        events.push_back(\"boolean(val=\" + std::string(val ? \"true\" : \"false\") + \")\");\n        return true;\n    }\n\n    bool number_integer(number_integer_t val) override\n    {\n        events.push_back(\"number_integer(val=\" + std::to_string(val) + \")\");\n        return true;\n    }\n\n    bool number_unsigned(number_unsigned_t val) override\n    {\n        events.push_back(\"number_unsigned(val=\" + std::to_string(val) + \")\");\n        return true;\n    }\n\n    bool number_float(number_float_t val, const string_t& s) override\n    {\n        events.push_back(\"number_float(val=\" + std::to_string(val) + \", s=\" + s + \")\");\n        return true;\n    }\n\n    bool string(string_t& val) override\n    {\n        events.push_back(\"string(val=\" + val + \")\");\n        return true;\n    }\n\n    bool start_object(std::size_t elements) override\n    {\n        events.push_back(\"start_object(elements=\" + std::to_string(elements) + \")\");\n        return true;\n    }\n\n    bool end_object() override\n    {\n        events.push_back(\"end_object()\");\n        return true;\n    }\n\n    bool start_array(std::size_t elements) override\n    {\n        events.push_back(\"start_array(elements=\" + std::to_string(elements) + \")\");\n        return true;\n    }\n\n    bool end_array() override\n    {\n        events.push_back(\"end_array()\");\n        return true;\n    }\n\n    bool key(string_t& val) override\n    {\n        events.push_back(\"key(val=\" + val + \")\");\n        return true;\n    }\n\n    bool binary(json::binary_t& val) override\n    {\n        events.push_back(\"binary(val=[...])\");\n        return true;\n    }\n\n    bool parse_error(std::size_t position, const std::string& last_token, const json::exception& ex) override\n    {\n        events.push_back(\"parse_error(position=\" + std::to_string(position) + \", last_token=\" + last_token + \",\\n            ex=\" + std::string(ex.what()) + \")\");\n        return false;\n    }\n};\n\nint main()\n{\n    // a JSON text\n    const auto* text = R\"(\n    {\n        \"Image\": {\n            \"Width\":  800,\n            \"Height\": 600,\n            \"Title\":  \"View from 15th Floor\",\n            \"Thumbnail\": {\n                \"Url\":    \"http://www.example.com/image/481989943\",\n                \"Height\": 125,\n                \"Width\":  100\n            },\n            \"Animated\" : false,\n            \"IDs\": [116, 943, 234, -38793],\n            \"DeletionDate\": null,\n            \"Distance\": 12.723374634\n        }\n    }]\n    )\";\n\n    // create a SAX event consumer object\n    sax_event_consumer sec;\n\n    // parse JSON\n    bool result = json::sax_parse(text, &sec);\n\n    // output the recorded events\n    for (auto& event : sec.events)\n    {\n        std::cout << event << \"\\n\";\n    }\n\n    // output the result of sax_parse\n    std::cout << \"\\nresult: \" << std::boolalpha << result << '\\n';\n}\n

    Output:

    start_object(elements=18446744073709551615)\nkey(val=Image)\nstart_object(elements=18446744073709551615)\nkey(val=Width)\nnumber_unsigned(val=800)\nkey(val=Height)\nnumber_unsigned(val=600)\nkey(val=Title)\nstring(val=View from 15th Floor)\nkey(val=Thumbnail)\nstart_object(elements=18446744073709551615)\nkey(val=Url)\nstring(val=http://www.example.com/image/481989943)\nkey(val=Height)\nnumber_unsigned(val=125)\nkey(val=Width)\nnumber_unsigned(val=100)\nend_object()\nkey(val=Animated)\nboolean(val=false)\nkey(val=IDs)\nstart_array(elements=18446744073709551615)\nnumber_unsigned(val=116)\nnumber_unsigned(val=943)\nnumber_unsigned(val=234)\nnumber_integer(val=-38793)\nend_array()\nkey(val=DeletionDate)\nnull()\nkey(val=Distance)\nnumber_float(val=12.723375, s=12.723374634)\nend_object()\nend_object()\nparse_error(position=460, last_token=12.723374634<U+000A>        }<U+000A>    }],\n            ex=[json.exception.parse_error.101] parse error at line 17, column 6: syntax error while parsing value - unexpected ']'; expected end of input)\n\nresult: false\n
    "},{"location":"api/json_sax/null/#see-also","title":"See also","text":"
    • sax_parse - SAX parser
    • SAX Interface - the SAX interface article
    "},{"location":"api/json_sax/null/#version-history","title":"Version history","text":"
    • Added in version 3.2.0.
    "},{"location":"api/json_sax/number_float/","title":"nlohmann::json_sax::number_float","text":"
    virtual bool number_float(number_float_t val, const string_t& s) = 0;\n

    A floating-point number was read.

    "},{"location":"api/json_sax/number_float/#parameters","title":"Parameters","text":"val (in) floating-point value s (in) string representation of the original input"},{"location":"api/json_sax/number_float/#return-value","title":"Return value","text":"

    Whether parsing should proceed.

    "},{"location":"api/json_sax/number_float/#examples","title":"Examples","text":"Example

    The example below shows how the SAX interface is used.

    #include <iostream>\n#include <iomanip>\n#include <sstream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\n// a simple event consumer that collects string representations of the passed\n// values; note inheriting from json::json_sax_t is not required, but can\n// help not to forget a required function\nclass sax_event_consumer : public json::json_sax_t\n{\n  public:\n    std::vector<std::string> events;\n\n    bool null() override\n    {\n        events.push_back(\"null()\");\n        return true;\n    }\n\n    bool boolean(bool val) override\n    {\n        events.push_back(\"boolean(val=\" + std::string(val ? \"true\" : \"false\") + \")\");\n        return true;\n    }\n\n    bool number_integer(number_integer_t val) override\n    {\n        events.push_back(\"number_integer(val=\" + std::to_string(val) + \")\");\n        return true;\n    }\n\n    bool number_unsigned(number_unsigned_t val) override\n    {\n        events.push_back(\"number_unsigned(val=\" + std::to_string(val) + \")\");\n        return true;\n    }\n\n    bool number_float(number_float_t val, const string_t& s) override\n    {\n        events.push_back(\"number_float(val=\" + std::to_string(val) + \", s=\" + s + \")\");\n        return true;\n    }\n\n    bool string(string_t& val) override\n    {\n        events.push_back(\"string(val=\" + val + \")\");\n        return true;\n    }\n\n    bool start_object(std::size_t elements) override\n    {\n        events.push_back(\"start_object(elements=\" + std::to_string(elements) + \")\");\n        return true;\n    }\n\n    bool end_object() override\n    {\n        events.push_back(\"end_object()\");\n        return true;\n    }\n\n    bool start_array(std::size_t elements) override\n    {\n        events.push_back(\"start_array(elements=\" + std::to_string(elements) + \")\");\n        return true;\n    }\n\n    bool end_array() override\n    {\n        events.push_back(\"end_array()\");\n        return true;\n    }\n\n    bool key(string_t& val) override\n    {\n        events.push_back(\"key(val=\" + val + \")\");\n        return true;\n    }\n\n    bool binary(json::binary_t& val) override\n    {\n        events.push_back(\"binary(val=[...])\");\n        return true;\n    }\n\n    bool parse_error(std::size_t position, const std::string& last_token, const json::exception& ex) override\n    {\n        events.push_back(\"parse_error(position=\" + std::to_string(position) + \", last_token=\" + last_token + \",\\n            ex=\" + std::string(ex.what()) + \")\");\n        return false;\n    }\n};\n\nint main()\n{\n    // a JSON text\n    const auto* text = R\"(\n    {\n        \"Image\": {\n            \"Width\":  800,\n            \"Height\": 600,\n            \"Title\":  \"View from 15th Floor\",\n            \"Thumbnail\": {\n                \"Url\":    \"http://www.example.com/image/481989943\",\n                \"Height\": 125,\n                \"Width\":  100\n            },\n            \"Animated\" : false,\n            \"IDs\": [116, 943, 234, -38793],\n            \"DeletionDate\": null,\n            \"Distance\": 12.723374634\n        }\n    }]\n    )\";\n\n    // create a SAX event consumer object\n    sax_event_consumer sec;\n\n    // parse JSON\n    bool result = json::sax_parse(text, &sec);\n\n    // output the recorded events\n    for (auto& event : sec.events)\n    {\n        std::cout << event << \"\\n\";\n    }\n\n    // output the result of sax_parse\n    std::cout << \"\\nresult: \" << std::boolalpha << result << '\\n';\n}\n

    Output:

    start_object(elements=18446744073709551615)\nkey(val=Image)\nstart_object(elements=18446744073709551615)\nkey(val=Width)\nnumber_unsigned(val=800)\nkey(val=Height)\nnumber_unsigned(val=600)\nkey(val=Title)\nstring(val=View from 15th Floor)\nkey(val=Thumbnail)\nstart_object(elements=18446744073709551615)\nkey(val=Url)\nstring(val=http://www.example.com/image/481989943)\nkey(val=Height)\nnumber_unsigned(val=125)\nkey(val=Width)\nnumber_unsigned(val=100)\nend_object()\nkey(val=Animated)\nboolean(val=false)\nkey(val=IDs)\nstart_array(elements=18446744073709551615)\nnumber_unsigned(val=116)\nnumber_unsigned(val=943)\nnumber_unsigned(val=234)\nnumber_integer(val=-38793)\nend_array()\nkey(val=DeletionDate)\nnull()\nkey(val=Distance)\nnumber_float(val=12.723375, s=12.723374634)\nend_object()\nend_object()\nparse_error(position=460, last_token=12.723374634<U+000A>        }<U+000A>    }],\n            ex=[json.exception.parse_error.101] parse error at line 17, column 6: syntax error while parsing value - unexpected ']'; expected end of input)\n\nresult: false\n
    "},{"location":"api/json_sax/number_float/#see-also","title":"See also","text":"
    • number_integer - an integer number was read
    • number_unsigned - an unsigned integer number was read
    • sax_parse - SAX parser
    • SAX Interface - guide to event-based parsing
    "},{"location":"api/json_sax/number_float/#version-history","title":"Version history","text":"
    • Added in version 3.2.0.
    "},{"location":"api/json_sax/number_integer/","title":"nlohmann::json_sax::number_integer","text":"
    virtual bool number_integer(number_integer_t val) = 0;\n

    An integer number was read.

    "},{"location":"api/json_sax/number_integer/#parameters","title":"Parameters","text":"val (in) integer value"},{"location":"api/json_sax/number_integer/#return-value","title":"Return value","text":"

    Whether parsing should proceed.

    "},{"location":"api/json_sax/number_integer/#examples","title":"Examples","text":"Example

    The example below shows how the SAX interface is used.

    #include <iostream>\n#include <iomanip>\n#include <sstream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\n// a simple event consumer that collects string representations of the passed\n// values; note inheriting from json::json_sax_t is not required, but can\n// help not to forget a required function\nclass sax_event_consumer : public json::json_sax_t\n{\n  public:\n    std::vector<std::string> events;\n\n    bool null() override\n    {\n        events.push_back(\"null()\");\n        return true;\n    }\n\n    bool boolean(bool val) override\n    {\n        events.push_back(\"boolean(val=\" + std::string(val ? \"true\" : \"false\") + \")\");\n        return true;\n    }\n\n    bool number_integer(number_integer_t val) override\n    {\n        events.push_back(\"number_integer(val=\" + std::to_string(val) + \")\");\n        return true;\n    }\n\n    bool number_unsigned(number_unsigned_t val) override\n    {\n        events.push_back(\"number_unsigned(val=\" + std::to_string(val) + \")\");\n        return true;\n    }\n\n    bool number_float(number_float_t val, const string_t& s) override\n    {\n        events.push_back(\"number_float(val=\" + std::to_string(val) + \", s=\" + s + \")\");\n        return true;\n    }\n\n    bool string(string_t& val) override\n    {\n        events.push_back(\"string(val=\" + val + \")\");\n        return true;\n    }\n\n    bool start_object(std::size_t elements) override\n    {\n        events.push_back(\"start_object(elements=\" + std::to_string(elements) + \")\");\n        return true;\n    }\n\n    bool end_object() override\n    {\n        events.push_back(\"end_object()\");\n        return true;\n    }\n\n    bool start_array(std::size_t elements) override\n    {\n        events.push_back(\"start_array(elements=\" + std::to_string(elements) + \")\");\n        return true;\n    }\n\n    bool end_array() override\n    {\n        events.push_back(\"end_array()\");\n        return true;\n    }\n\n    bool key(string_t& val) override\n    {\n        events.push_back(\"key(val=\" + val + \")\");\n        return true;\n    }\n\n    bool binary(json::binary_t& val) override\n    {\n        events.push_back(\"binary(val=[...])\");\n        return true;\n    }\n\n    bool parse_error(std::size_t position, const std::string& last_token, const json::exception& ex) override\n    {\n        events.push_back(\"parse_error(position=\" + std::to_string(position) + \", last_token=\" + last_token + \",\\n            ex=\" + std::string(ex.what()) + \")\");\n        return false;\n    }\n};\n\nint main()\n{\n    // a JSON text\n    const auto* text = R\"(\n    {\n        \"Image\": {\n            \"Width\":  800,\n            \"Height\": 600,\n            \"Title\":  \"View from 15th Floor\",\n            \"Thumbnail\": {\n                \"Url\":    \"http://www.example.com/image/481989943\",\n                \"Height\": 125,\n                \"Width\":  100\n            },\n            \"Animated\" : false,\n            \"IDs\": [116, 943, 234, -38793],\n            \"DeletionDate\": null,\n            \"Distance\": 12.723374634\n        }\n    }]\n    )\";\n\n    // create a SAX event consumer object\n    sax_event_consumer sec;\n\n    // parse JSON\n    bool result = json::sax_parse(text, &sec);\n\n    // output the recorded events\n    for (auto& event : sec.events)\n    {\n        std::cout << event << \"\\n\";\n    }\n\n    // output the result of sax_parse\n    std::cout << \"\\nresult: \" << std::boolalpha << result << '\\n';\n}\n

    Output:

    start_object(elements=18446744073709551615)\nkey(val=Image)\nstart_object(elements=18446744073709551615)\nkey(val=Width)\nnumber_unsigned(val=800)\nkey(val=Height)\nnumber_unsigned(val=600)\nkey(val=Title)\nstring(val=View from 15th Floor)\nkey(val=Thumbnail)\nstart_object(elements=18446744073709551615)\nkey(val=Url)\nstring(val=http://www.example.com/image/481989943)\nkey(val=Height)\nnumber_unsigned(val=125)\nkey(val=Width)\nnumber_unsigned(val=100)\nend_object()\nkey(val=Animated)\nboolean(val=false)\nkey(val=IDs)\nstart_array(elements=18446744073709551615)\nnumber_unsigned(val=116)\nnumber_unsigned(val=943)\nnumber_unsigned(val=234)\nnumber_integer(val=-38793)\nend_array()\nkey(val=DeletionDate)\nnull()\nkey(val=Distance)\nnumber_float(val=12.723375, s=12.723374634)\nend_object()\nend_object()\nparse_error(position=460, last_token=12.723374634<U+000A>        }<U+000A>    }],\n            ex=[json.exception.parse_error.101] parse error at line 17, column 6: syntax error while parsing value - unexpected ']'; expected end of input)\n\nresult: false\n
    "},{"location":"api/json_sax/number_integer/#see-also","title":"See also","text":"
    • number_unsigned - an unsigned integer number was read
    • number_float - a floating-point number was read
    • sax_parse - SAX parser
    • SAX Interface - guide to event-based parsing
    "},{"location":"api/json_sax/number_integer/#version-history","title":"Version history","text":"
    • Added in version 3.2.0.
    "},{"location":"api/json_sax/number_unsigned/","title":"nlohmann::json_sax::number_unsigned","text":"
    virtual bool number_unsigned(number_unsigned_t val) = 0;\n

    An unsigned integer number was read.

    "},{"location":"api/json_sax/number_unsigned/#parameters","title":"Parameters","text":"val (in) unsigned integer value"},{"location":"api/json_sax/number_unsigned/#return-value","title":"Return value","text":"

    Whether parsing should proceed.

    "},{"location":"api/json_sax/number_unsigned/#examples","title":"Examples","text":"Example

    The example below shows how the SAX interface is used.

    #include <iostream>\n#include <iomanip>\n#include <sstream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\n// a simple event consumer that collects string representations of the passed\n// values; note inheriting from json::json_sax_t is not required, but can\n// help not to forget a required function\nclass sax_event_consumer : public json::json_sax_t\n{\n  public:\n    std::vector<std::string> events;\n\n    bool null() override\n    {\n        events.push_back(\"null()\");\n        return true;\n    }\n\n    bool boolean(bool val) override\n    {\n        events.push_back(\"boolean(val=\" + std::string(val ? \"true\" : \"false\") + \")\");\n        return true;\n    }\n\n    bool number_integer(number_integer_t val) override\n    {\n        events.push_back(\"number_integer(val=\" + std::to_string(val) + \")\");\n        return true;\n    }\n\n    bool number_unsigned(number_unsigned_t val) override\n    {\n        events.push_back(\"number_unsigned(val=\" + std::to_string(val) + \")\");\n        return true;\n    }\n\n    bool number_float(number_float_t val, const string_t& s) override\n    {\n        events.push_back(\"number_float(val=\" + std::to_string(val) + \", s=\" + s + \")\");\n        return true;\n    }\n\n    bool string(string_t& val) override\n    {\n        events.push_back(\"string(val=\" + val + \")\");\n        return true;\n    }\n\n    bool start_object(std::size_t elements) override\n    {\n        events.push_back(\"start_object(elements=\" + std::to_string(elements) + \")\");\n        return true;\n    }\n\n    bool end_object() override\n    {\n        events.push_back(\"end_object()\");\n        return true;\n    }\n\n    bool start_array(std::size_t elements) override\n    {\n        events.push_back(\"start_array(elements=\" + std::to_string(elements) + \")\");\n        return true;\n    }\n\n    bool end_array() override\n    {\n        events.push_back(\"end_array()\");\n        return true;\n    }\n\n    bool key(string_t& val) override\n    {\n        events.push_back(\"key(val=\" + val + \")\");\n        return true;\n    }\n\n    bool binary(json::binary_t& val) override\n    {\n        events.push_back(\"binary(val=[...])\");\n        return true;\n    }\n\n    bool parse_error(std::size_t position, const std::string& last_token, const json::exception& ex) override\n    {\n        events.push_back(\"parse_error(position=\" + std::to_string(position) + \", last_token=\" + last_token + \",\\n            ex=\" + std::string(ex.what()) + \")\");\n        return false;\n    }\n};\n\nint main()\n{\n    // a JSON text\n    const auto* text = R\"(\n    {\n        \"Image\": {\n            \"Width\":  800,\n            \"Height\": 600,\n            \"Title\":  \"View from 15th Floor\",\n            \"Thumbnail\": {\n                \"Url\":    \"http://www.example.com/image/481989943\",\n                \"Height\": 125,\n                \"Width\":  100\n            },\n            \"Animated\" : false,\n            \"IDs\": [116, 943, 234, -38793],\n            \"DeletionDate\": null,\n            \"Distance\": 12.723374634\n        }\n    }]\n    )\";\n\n    // create a SAX event consumer object\n    sax_event_consumer sec;\n\n    // parse JSON\n    bool result = json::sax_parse(text, &sec);\n\n    // output the recorded events\n    for (auto& event : sec.events)\n    {\n        std::cout << event << \"\\n\";\n    }\n\n    // output the result of sax_parse\n    std::cout << \"\\nresult: \" << std::boolalpha << result << '\\n';\n}\n

    Output:

    start_object(elements=18446744073709551615)\nkey(val=Image)\nstart_object(elements=18446744073709551615)\nkey(val=Width)\nnumber_unsigned(val=800)\nkey(val=Height)\nnumber_unsigned(val=600)\nkey(val=Title)\nstring(val=View from 15th Floor)\nkey(val=Thumbnail)\nstart_object(elements=18446744073709551615)\nkey(val=Url)\nstring(val=http://www.example.com/image/481989943)\nkey(val=Height)\nnumber_unsigned(val=125)\nkey(val=Width)\nnumber_unsigned(val=100)\nend_object()\nkey(val=Animated)\nboolean(val=false)\nkey(val=IDs)\nstart_array(elements=18446744073709551615)\nnumber_unsigned(val=116)\nnumber_unsigned(val=943)\nnumber_unsigned(val=234)\nnumber_integer(val=-38793)\nend_array()\nkey(val=DeletionDate)\nnull()\nkey(val=Distance)\nnumber_float(val=12.723375, s=12.723374634)\nend_object()\nend_object()\nparse_error(position=460, last_token=12.723374634<U+000A>        }<U+000A>    }],\n            ex=[json.exception.parse_error.101] parse error at line 17, column 6: syntax error while parsing value - unexpected ']'; expected end of input)\n\nresult: false\n
    "},{"location":"api/json_sax/number_unsigned/#see-also","title":"See also","text":"
    • number_integer - an integer number was read
    • number_float - a floating-point number was read
    • sax_parse - SAX parser
    • SAX Interface - guide to event-based parsing
    "},{"location":"api/json_sax/number_unsigned/#version-history","title":"Version history","text":"
    • Added in version 3.2.0.
    "},{"location":"api/json_sax/parse_error/","title":"nlohmann::json_sax::parse_error","text":"
    virtual bool parse_error(std::size_t position,\n                         const std::string& last_token,\n                         const detail::exception& ex) = 0;\n

    A parse error occurred.

    "},{"location":"api/json_sax/parse_error/#parameters","title":"Parameters","text":"position (in) the position in the input where the error occurs last_token (in) the last read token ex (in) an exception object describing the error"},{"location":"api/json_sax/parse_error/#return-value","title":"Return value","text":"

    Whether parsing should proceed (must return false).

    "},{"location":"api/json_sax/parse_error/#examples","title":"Examples","text":"Example

    The example below shows how the SAX interface is used.

    #include <iostream>\n#include <iomanip>\n#include <sstream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\n// a simple event consumer that collects string representations of the passed\n// values; note inheriting from json::json_sax_t is not required, but can\n// help not to forget a required function\nclass sax_event_consumer : public json::json_sax_t\n{\n  public:\n    std::vector<std::string> events;\n\n    bool null() override\n    {\n        events.push_back(\"null()\");\n        return true;\n    }\n\n    bool boolean(bool val) override\n    {\n        events.push_back(\"boolean(val=\" + std::string(val ? \"true\" : \"false\") + \")\");\n        return true;\n    }\n\n    bool number_integer(number_integer_t val) override\n    {\n        events.push_back(\"number_integer(val=\" + std::to_string(val) + \")\");\n        return true;\n    }\n\n    bool number_unsigned(number_unsigned_t val) override\n    {\n        events.push_back(\"number_unsigned(val=\" + std::to_string(val) + \")\");\n        return true;\n    }\n\n    bool number_float(number_float_t val, const string_t& s) override\n    {\n        events.push_back(\"number_float(val=\" + std::to_string(val) + \", s=\" + s + \")\");\n        return true;\n    }\n\n    bool string(string_t& val) override\n    {\n        events.push_back(\"string(val=\" + val + \")\");\n        return true;\n    }\n\n    bool start_object(std::size_t elements) override\n    {\n        events.push_back(\"start_object(elements=\" + std::to_string(elements) + \")\");\n        return true;\n    }\n\n    bool end_object() override\n    {\n        events.push_back(\"end_object()\");\n        return true;\n    }\n\n    bool start_array(std::size_t elements) override\n    {\n        events.push_back(\"start_array(elements=\" + std::to_string(elements) + \")\");\n        return true;\n    }\n\n    bool end_array() override\n    {\n        events.push_back(\"end_array()\");\n        return true;\n    }\n\n    bool key(string_t& val) override\n    {\n        events.push_back(\"key(val=\" + val + \")\");\n        return true;\n    }\n\n    bool binary(json::binary_t& val) override\n    {\n        events.push_back(\"binary(val=[...])\");\n        return true;\n    }\n\n    bool parse_error(std::size_t position, const std::string& last_token, const json::exception& ex) override\n    {\n        events.push_back(\"parse_error(position=\" + std::to_string(position) + \", last_token=\" + last_token + \",\\n            ex=\" + std::string(ex.what()) + \")\");\n        return false;\n    }\n};\n\nint main()\n{\n    // a JSON text\n    const auto* text = R\"(\n    {\n        \"Image\": {\n            \"Width\":  800,\n            \"Height\": 600,\n            \"Title\":  \"View from 15th Floor\",\n            \"Thumbnail\": {\n                \"Url\":    \"http://www.example.com/image/481989943\",\n                \"Height\": 125,\n                \"Width\":  100\n            },\n            \"Animated\" : false,\n            \"IDs\": [116, 943, 234, -38793],\n            \"DeletionDate\": null,\n            \"Distance\": 12.723374634\n        }\n    }]\n    )\";\n\n    // create a SAX event consumer object\n    sax_event_consumer sec;\n\n    // parse JSON\n    bool result = json::sax_parse(text, &sec);\n\n    // output the recorded events\n    for (auto& event : sec.events)\n    {\n        std::cout << event << \"\\n\";\n    }\n\n    // output the result of sax_parse\n    std::cout << \"\\nresult: \" << std::boolalpha << result << '\\n';\n}\n

    Output:

    start_object(elements=18446744073709551615)\nkey(val=Image)\nstart_object(elements=18446744073709551615)\nkey(val=Width)\nnumber_unsigned(val=800)\nkey(val=Height)\nnumber_unsigned(val=600)\nkey(val=Title)\nstring(val=View from 15th Floor)\nkey(val=Thumbnail)\nstart_object(elements=18446744073709551615)\nkey(val=Url)\nstring(val=http://www.example.com/image/481989943)\nkey(val=Height)\nnumber_unsigned(val=125)\nkey(val=Width)\nnumber_unsigned(val=100)\nend_object()\nkey(val=Animated)\nboolean(val=false)\nkey(val=IDs)\nstart_array(elements=18446744073709551615)\nnumber_unsigned(val=116)\nnumber_unsigned(val=943)\nnumber_unsigned(val=234)\nnumber_integer(val=-38793)\nend_array()\nkey(val=DeletionDate)\nnull()\nkey(val=Distance)\nnumber_float(val=12.723375, s=12.723374634)\nend_object()\nend_object()\nparse_error(position=460, last_token=12.723374634<U+000A>        }<U+000A>    }],\n            ex=[json.exception.parse_error.101] parse error at line 17, column 6: syntax error while parsing value - unexpected ']'; expected end of input)\n\nresult: false\n
    "},{"location":"api/json_sax/parse_error/#see-also","title":"See also","text":"
    • sax_parse - SAX parser
    • Parsing and Exceptions - the article on handling parse errors without exceptions
    • SAX Interface - guide to event-based parsing
    "},{"location":"api/json_sax/parse_error/#version-history","title":"Version history","text":"
    • Added in version 3.2.0.
    "},{"location":"api/json_sax/start_array/","title":"nlohmann::json_sax::start_array","text":"
    virtual bool start_array(std::size_t elements) = 0;\n

    The beginning of an array was read.

    "},{"location":"api/json_sax/start_array/#parameters","title":"Parameters","text":"elements (in) number of array elements, or std::numeric_limits<std::size_t>::max() if unknown"},{"location":"api/json_sax/start_array/#return-value","title":"Return value","text":"

    Whether parsing should proceed.

    "},{"location":"api/json_sax/start_array/#notes","title":"Notes","text":"

    Binary formats may report the number of elements.

    "},{"location":"api/json_sax/start_array/#examples","title":"Examples","text":"Example

    The example below shows how the SAX interface is used.

    #include <iostream>\n#include <iomanip>\n#include <sstream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\n// a simple event consumer that collects string representations of the passed\n// values; note inheriting from json::json_sax_t is not required, but can\n// help not to forget a required function\nclass sax_event_consumer : public json::json_sax_t\n{\n  public:\n    std::vector<std::string> events;\n\n    bool null() override\n    {\n        events.push_back(\"null()\");\n        return true;\n    }\n\n    bool boolean(bool val) override\n    {\n        events.push_back(\"boolean(val=\" + std::string(val ? \"true\" : \"false\") + \")\");\n        return true;\n    }\n\n    bool number_integer(number_integer_t val) override\n    {\n        events.push_back(\"number_integer(val=\" + std::to_string(val) + \")\");\n        return true;\n    }\n\n    bool number_unsigned(number_unsigned_t val) override\n    {\n        events.push_back(\"number_unsigned(val=\" + std::to_string(val) + \")\");\n        return true;\n    }\n\n    bool number_float(number_float_t val, const string_t& s) override\n    {\n        events.push_back(\"number_float(val=\" + std::to_string(val) + \", s=\" + s + \")\");\n        return true;\n    }\n\n    bool string(string_t& val) override\n    {\n        events.push_back(\"string(val=\" + val + \")\");\n        return true;\n    }\n\n    bool start_object(std::size_t elements) override\n    {\n        events.push_back(\"start_object(elements=\" + std::to_string(elements) + \")\");\n        return true;\n    }\n\n    bool end_object() override\n    {\n        events.push_back(\"end_object()\");\n        return true;\n    }\n\n    bool start_array(std::size_t elements) override\n    {\n        events.push_back(\"start_array(elements=\" + std::to_string(elements) + \")\");\n        return true;\n    }\n\n    bool end_array() override\n    {\n        events.push_back(\"end_array()\");\n        return true;\n    }\n\n    bool key(string_t& val) override\n    {\n        events.push_back(\"key(val=\" + val + \")\");\n        return true;\n    }\n\n    bool binary(json::binary_t& val) override\n    {\n        events.push_back(\"binary(val=[...])\");\n        return true;\n    }\n\n    bool parse_error(std::size_t position, const std::string& last_token, const json::exception& ex) override\n    {\n        events.push_back(\"parse_error(position=\" + std::to_string(position) + \", last_token=\" + last_token + \",\\n            ex=\" + std::string(ex.what()) + \")\");\n        return false;\n    }\n};\n\nint main()\n{\n    // a JSON text\n    const auto* text = R\"(\n    {\n        \"Image\": {\n            \"Width\":  800,\n            \"Height\": 600,\n            \"Title\":  \"View from 15th Floor\",\n            \"Thumbnail\": {\n                \"Url\":    \"http://www.example.com/image/481989943\",\n                \"Height\": 125,\n                \"Width\":  100\n            },\n            \"Animated\" : false,\n            \"IDs\": [116, 943, 234, -38793],\n            \"DeletionDate\": null,\n            \"Distance\": 12.723374634\n        }\n    }]\n    )\";\n\n    // create a SAX event consumer object\n    sax_event_consumer sec;\n\n    // parse JSON\n    bool result = json::sax_parse(text, &sec);\n\n    // output the recorded events\n    for (auto& event : sec.events)\n    {\n        std::cout << event << \"\\n\";\n    }\n\n    // output the result of sax_parse\n    std::cout << \"\\nresult: \" << std::boolalpha << result << '\\n';\n}\n

    Output:

    start_object(elements=18446744073709551615)\nkey(val=Image)\nstart_object(elements=18446744073709551615)\nkey(val=Width)\nnumber_unsigned(val=800)\nkey(val=Height)\nnumber_unsigned(val=600)\nkey(val=Title)\nstring(val=View from 15th Floor)\nkey(val=Thumbnail)\nstart_object(elements=18446744073709551615)\nkey(val=Url)\nstring(val=http://www.example.com/image/481989943)\nkey(val=Height)\nnumber_unsigned(val=125)\nkey(val=Width)\nnumber_unsigned(val=100)\nend_object()\nkey(val=Animated)\nboolean(val=false)\nkey(val=IDs)\nstart_array(elements=18446744073709551615)\nnumber_unsigned(val=116)\nnumber_unsigned(val=943)\nnumber_unsigned(val=234)\nnumber_integer(val=-38793)\nend_array()\nkey(val=DeletionDate)\nnull()\nkey(val=Distance)\nnumber_float(val=12.723375, s=12.723374634)\nend_object()\nend_object()\nparse_error(position=460, last_token=12.723374634<U+000A>        }<U+000A>    }],\n            ex=[json.exception.parse_error.101] parse error at line 17, column 6: syntax error while parsing value - unexpected ']'; expected end of input)\n\nresult: false\n
    "},{"location":"api/json_sax/start_array/#see-also","title":"See also","text":"
    • end_array - the end of an array was read
    • sax_parse - SAX parser
    • SAX Interface - guide to event-based parsing
    "},{"location":"api/json_sax/start_array/#version-history","title":"Version history","text":"
    • Added in version 3.2.0.
    "},{"location":"api/json_sax/start_object/","title":"nlohmann::json_sax::start_object","text":"
    virtual bool start_object(std::size_t elements) = 0;\n

    The beginning of an object was read.

    "},{"location":"api/json_sax/start_object/#parameters","title":"Parameters","text":"elements (in) number of object elements, or std::numeric_limits<std::size_t>::max() if unknown"},{"location":"api/json_sax/start_object/#return-value","title":"Return value","text":"

    Whether parsing should proceed.

    "},{"location":"api/json_sax/start_object/#notes","title":"Notes","text":"

    Binary formats may report the number of elements.

    "},{"location":"api/json_sax/start_object/#examples","title":"Examples","text":"Example

    The example below shows how the SAX interface is used.

    #include <iostream>\n#include <iomanip>\n#include <sstream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\n// a simple event consumer that collects string representations of the passed\n// values; note inheriting from json::json_sax_t is not required, but can\n// help not to forget a required function\nclass sax_event_consumer : public json::json_sax_t\n{\n  public:\n    std::vector<std::string> events;\n\n    bool null() override\n    {\n        events.push_back(\"null()\");\n        return true;\n    }\n\n    bool boolean(bool val) override\n    {\n        events.push_back(\"boolean(val=\" + std::string(val ? \"true\" : \"false\") + \")\");\n        return true;\n    }\n\n    bool number_integer(number_integer_t val) override\n    {\n        events.push_back(\"number_integer(val=\" + std::to_string(val) + \")\");\n        return true;\n    }\n\n    bool number_unsigned(number_unsigned_t val) override\n    {\n        events.push_back(\"number_unsigned(val=\" + std::to_string(val) + \")\");\n        return true;\n    }\n\n    bool number_float(number_float_t val, const string_t& s) override\n    {\n        events.push_back(\"number_float(val=\" + std::to_string(val) + \", s=\" + s + \")\");\n        return true;\n    }\n\n    bool string(string_t& val) override\n    {\n        events.push_back(\"string(val=\" + val + \")\");\n        return true;\n    }\n\n    bool start_object(std::size_t elements) override\n    {\n        events.push_back(\"start_object(elements=\" + std::to_string(elements) + \")\");\n        return true;\n    }\n\n    bool end_object() override\n    {\n        events.push_back(\"end_object()\");\n        return true;\n    }\n\n    bool start_array(std::size_t elements) override\n    {\n        events.push_back(\"start_array(elements=\" + std::to_string(elements) + \")\");\n        return true;\n    }\n\n    bool end_array() override\n    {\n        events.push_back(\"end_array()\");\n        return true;\n    }\n\n    bool key(string_t& val) override\n    {\n        events.push_back(\"key(val=\" + val + \")\");\n        return true;\n    }\n\n    bool binary(json::binary_t& val) override\n    {\n        events.push_back(\"binary(val=[...])\");\n        return true;\n    }\n\n    bool parse_error(std::size_t position, const std::string& last_token, const json::exception& ex) override\n    {\n        events.push_back(\"parse_error(position=\" + std::to_string(position) + \", last_token=\" + last_token + \",\\n            ex=\" + std::string(ex.what()) + \")\");\n        return false;\n    }\n};\n\nint main()\n{\n    // a JSON text\n    const auto* text = R\"(\n    {\n        \"Image\": {\n            \"Width\":  800,\n            \"Height\": 600,\n            \"Title\":  \"View from 15th Floor\",\n            \"Thumbnail\": {\n                \"Url\":    \"http://www.example.com/image/481989943\",\n                \"Height\": 125,\n                \"Width\":  100\n            },\n            \"Animated\" : false,\n            \"IDs\": [116, 943, 234, -38793],\n            \"DeletionDate\": null,\n            \"Distance\": 12.723374634\n        }\n    }]\n    )\";\n\n    // create a SAX event consumer object\n    sax_event_consumer sec;\n\n    // parse JSON\n    bool result = json::sax_parse(text, &sec);\n\n    // output the recorded events\n    for (auto& event : sec.events)\n    {\n        std::cout << event << \"\\n\";\n    }\n\n    // output the result of sax_parse\n    std::cout << \"\\nresult: \" << std::boolalpha << result << '\\n';\n}\n

    Output:

    start_object(elements=18446744073709551615)\nkey(val=Image)\nstart_object(elements=18446744073709551615)\nkey(val=Width)\nnumber_unsigned(val=800)\nkey(val=Height)\nnumber_unsigned(val=600)\nkey(val=Title)\nstring(val=View from 15th Floor)\nkey(val=Thumbnail)\nstart_object(elements=18446744073709551615)\nkey(val=Url)\nstring(val=http://www.example.com/image/481989943)\nkey(val=Height)\nnumber_unsigned(val=125)\nkey(val=Width)\nnumber_unsigned(val=100)\nend_object()\nkey(val=Animated)\nboolean(val=false)\nkey(val=IDs)\nstart_array(elements=18446744073709551615)\nnumber_unsigned(val=116)\nnumber_unsigned(val=943)\nnumber_unsigned(val=234)\nnumber_integer(val=-38793)\nend_array()\nkey(val=DeletionDate)\nnull()\nkey(val=Distance)\nnumber_float(val=12.723375, s=12.723374634)\nend_object()\nend_object()\nparse_error(position=460, last_token=12.723374634<U+000A>        }<U+000A>    }],\n            ex=[json.exception.parse_error.101] parse error at line 17, column 6: syntax error while parsing value - unexpected ']'; expected end of input)\n\nresult: false\n
    "},{"location":"api/json_sax/start_object/#see-also","title":"See also","text":"
    • end_object - the end of an object was read
    • key - an object key was read
    • sax_parse - SAX parser
    • SAX Interface - guide to event-based parsing
    "},{"location":"api/json_sax/start_object/#version-history","title":"Version history","text":"
    • Added in version 3.2.0.
    "},{"location":"api/json_sax/string/","title":"nlohmann::json_sax::string","text":"
    virtual bool string(string_t& val) = 0;\n

    A string value was read.

    "},{"location":"api/json_sax/string/#parameters","title":"Parameters","text":"val (in) string value"},{"location":"api/json_sax/string/#return-value","title":"Return value","text":"

    Whether parsing should proceed.

    "},{"location":"api/json_sax/string/#notes","title":"Notes","text":"

    It is safe to move the passed string value.

    "},{"location":"api/json_sax/string/#examples","title":"Examples","text":"Example

    The example below shows how the SAX interface is used.

    #include <iostream>\n#include <iomanip>\n#include <sstream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\n// a simple event consumer that collects string representations of the passed\n// values; note inheriting from json::json_sax_t is not required, but can\n// help not to forget a required function\nclass sax_event_consumer : public json::json_sax_t\n{\n  public:\n    std::vector<std::string> events;\n\n    bool null() override\n    {\n        events.push_back(\"null()\");\n        return true;\n    }\n\n    bool boolean(bool val) override\n    {\n        events.push_back(\"boolean(val=\" + std::string(val ? \"true\" : \"false\") + \")\");\n        return true;\n    }\n\n    bool number_integer(number_integer_t val) override\n    {\n        events.push_back(\"number_integer(val=\" + std::to_string(val) + \")\");\n        return true;\n    }\n\n    bool number_unsigned(number_unsigned_t val) override\n    {\n        events.push_back(\"number_unsigned(val=\" + std::to_string(val) + \")\");\n        return true;\n    }\n\n    bool number_float(number_float_t val, const string_t& s) override\n    {\n        events.push_back(\"number_float(val=\" + std::to_string(val) + \", s=\" + s + \")\");\n        return true;\n    }\n\n    bool string(string_t& val) override\n    {\n        events.push_back(\"string(val=\" + val + \")\");\n        return true;\n    }\n\n    bool start_object(std::size_t elements) override\n    {\n        events.push_back(\"start_object(elements=\" + std::to_string(elements) + \")\");\n        return true;\n    }\n\n    bool end_object() override\n    {\n        events.push_back(\"end_object()\");\n        return true;\n    }\n\n    bool start_array(std::size_t elements) override\n    {\n        events.push_back(\"start_array(elements=\" + std::to_string(elements) + \")\");\n        return true;\n    }\n\n    bool end_array() override\n    {\n        events.push_back(\"end_array()\");\n        return true;\n    }\n\n    bool key(string_t& val) override\n    {\n        events.push_back(\"key(val=\" + val + \")\");\n        return true;\n    }\n\n    bool binary(json::binary_t& val) override\n    {\n        events.push_back(\"binary(val=[...])\");\n        return true;\n    }\n\n    bool parse_error(std::size_t position, const std::string& last_token, const json::exception& ex) override\n    {\n        events.push_back(\"parse_error(position=\" + std::to_string(position) + \", last_token=\" + last_token + \",\\n            ex=\" + std::string(ex.what()) + \")\");\n        return false;\n    }\n};\n\nint main()\n{\n    // a JSON text\n    const auto* text = R\"(\n    {\n        \"Image\": {\n            \"Width\":  800,\n            \"Height\": 600,\n            \"Title\":  \"View from 15th Floor\",\n            \"Thumbnail\": {\n                \"Url\":    \"http://www.example.com/image/481989943\",\n                \"Height\": 125,\n                \"Width\":  100\n            },\n            \"Animated\" : false,\n            \"IDs\": [116, 943, 234, -38793],\n            \"DeletionDate\": null,\n            \"Distance\": 12.723374634\n        }\n    }]\n    )\";\n\n    // create a SAX event consumer object\n    sax_event_consumer sec;\n\n    // parse JSON\n    bool result = json::sax_parse(text, &sec);\n\n    // output the recorded events\n    for (auto& event : sec.events)\n    {\n        std::cout << event << \"\\n\";\n    }\n\n    // output the result of sax_parse\n    std::cout << \"\\nresult: \" << std::boolalpha << result << '\\n';\n}\n

    Output:

    start_object(elements=18446744073709551615)\nkey(val=Image)\nstart_object(elements=18446744073709551615)\nkey(val=Width)\nnumber_unsigned(val=800)\nkey(val=Height)\nnumber_unsigned(val=600)\nkey(val=Title)\nstring(val=View from 15th Floor)\nkey(val=Thumbnail)\nstart_object(elements=18446744073709551615)\nkey(val=Url)\nstring(val=http://www.example.com/image/481989943)\nkey(val=Height)\nnumber_unsigned(val=125)\nkey(val=Width)\nnumber_unsigned(val=100)\nend_object()\nkey(val=Animated)\nboolean(val=false)\nkey(val=IDs)\nstart_array(elements=18446744073709551615)\nnumber_unsigned(val=116)\nnumber_unsigned(val=943)\nnumber_unsigned(val=234)\nnumber_integer(val=-38793)\nend_array()\nkey(val=DeletionDate)\nnull()\nkey(val=Distance)\nnumber_float(val=12.723375, s=12.723374634)\nend_object()\nend_object()\nparse_error(position=460, last_token=12.723374634<U+000A>        }<U+000A>    }],\n            ex=[json.exception.parse_error.101] parse error at line 17, column 6: syntax error while parsing value - unexpected ']'; expected end of input)\n\nresult: false\n
    "},{"location":"api/json_sax/string/#see-also","title":"See also","text":"
    • sax_parse - SAX parser
    • SAX Interface - the SAX interface article
    "},{"location":"api/json_sax/string/#version-history","title":"Version history","text":"
    • Added in version 3.2.0.
    "},{"location":"api/macros/","title":"Macros","text":"

    Some aspects of the library can be configured by defining preprocessor macros before including the json.hpp header. See also the macro overview page.

    "},{"location":"api/macros/#runtime-assertions","title":"Runtime assertions","text":"
    • JSON_ASSERT(x) - control behavior of runtime assertions
    "},{"location":"api/macros/#exceptions","title":"Exceptions","text":"
    • JSON_CATCH_USER(exception)JSON_THROW_USER(exception)JSON_TRY_USER - control exceptions
    • JSON_DIAGNOSTICS - control extended diagnostics
    • JSON_DIAGNOSTIC_POSITIONS - access positions of elements
    • JSON_NOEXCEPTION - switch off exceptions
    "},{"location":"api/macros/#parsing","title":"Parsing","text":"
    • JSON_DISABLE_STREAM_BULK_SCAN - read a std::istream one character at a time instead of scanning its stream buffer in bulk
    • JSON_DISABLE_UNLOCKED_FILE_IO - read a FILE* with std::fgetc instead of locking it once and using the unlocked stdio functions
    • JSON_PRECISE_STREAM_POSITION - opt in to leaving an input stream positioned right after a parsed number
    • JSON_STRICT_BINARY_UTF8 - opt in to checking strings for valid UTF-8 in the CBOR, UBJSON, BJData, and BSON writers
    • JSON_STRICT_NUL_HANDLING - opt in to rejecting a NUL byte in the input instead of treating it as end of input
    "},{"location":"api/macros/#language-support","title":"Language support","text":"
    • JSON_HAS_CPP_11JSON_HAS_CPP_14JSON_HAS_CPP_17JSON_HAS_CPP_20 - set supported C++ standard
    • JSON_HAS_FILESYSTEMJSON_HAS_EXPERIMENTAL_FILESYSTEM - control std::filesystem support
    • JSON_HAS_RANGE_VIEW_CONVERSION - control construction from std::ranges views
    • JSON_HAS_RANGES - control std::ranges support
    • JSON_HAS_STATIC_RTTI - control RTTI (run time type information) support
    • JSON_HAS_STD_FORMAT - control std::format/std::formatter support
    • JSON_HAS_THREE_WAY_COMPARISON - control 3-way comparison support
    • JSON_NO_AUTOMATIC_UDLS - do not include the user-defined string literals (UDLs) automatically
    • JSON_NO_IO - switch off functions relying on certain C++ I/O headers
    • JSON_NO_SIMD - use only portable code instead of vector instructions (SSE2, SSSE3, NEON)
    • JSON_NO_THREAD_LOCAL - switch off the use of thread_local storage
    • JSON_SKIP_UNSUPPORTED_COMPILER_CHECK - do not warn about unsupported compilers
    • JSON_USE_GLOBAL_UDLS - place user-defined string literals (UDLs) into the global namespace
    • JSON_USE_SIMDUTF - use the simdutf library to accelerate UTF-8 validation
    "},{"location":"api/macros/#library-version","title":"Library version","text":"
    • JSON_SKIP_LIBRARY_VERSION_CHECK - skip library version check
    • NLOHMANN_JSON_VERSION_MAJORNLOHMANN_JSON_VERSION_MINORNLOHMANN_JSON_VERSION_PATCH - library version information
    "},{"location":"api/macros/#library-namespace","title":"Library namespace","text":"
    • NLOHMANN_JSON_NAMESPACE - full name of the nlohmann namespace
    • NLOHMANN_JSON_NAMESPACE_BEGINNLOHMANN_JSON_NAMESPACE_END - open and close the library namespace
    • NLOHMANN_JSON_NAMESPACE_NO_VERSION - disable the version component of the inline namespace
    "},{"location":"api/macros/#type-conversions","title":"Type conversions","text":"
    • JSON_BRACE_INIT_COPY_SEMANTICS - opt in to copy/move semantics for single-element brace initialization
    • JSON_DISABLE_ENUM_SERIALIZATION - switch off default serialization/deserialization functions for enums
    • JSON_DISABLE_TUPLE_REFERENCE_CONVERSION - switch off conversion from a one-element tuple of a JSON reference
    • JSON_USE_IMPLICIT_CONVERSIONS - control implicit conversions
    • JSON_USE_OBJECTS_FOR_ENUM_KEYED_MAPS - opt in to storing maps with enum keys as objects
    "},{"location":"api/macros/#deprecated-functions","title":"Deprecated functions","text":"
    • JSON_DELETE_DEPRECATED_FUNCTIONS - opt in to deleting the deprecated functions ahead of their removal in version 4.0.0
    "},{"location":"api/macros/#comparison-behavior","title":"Comparison behavior","text":"
    • JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON - control comparison of discarded values
    "},{"location":"api/macros/#serializationdeserialization-macros","title":"Serialization/deserialization macros","text":""},{"location":"api/macros/#enums","title":"Enums","text":"
    • NLOHMANN_JSON_SERIALIZE_ENUM - serialize/deserialize an enum
    • NLOHMANN_JSON_SERIALIZE_ENUM_STRICT - serialize/deserialize an enum with exceptions
    "},{"location":"api/macros/#classes-and-structs","title":"Classes and structs","text":"
    • NLOHMANN_DEFINE_TYPE_INTRUSIVE - serialize/deserialize a non-derived class with private members
    • NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT - serialize/deserialize a non-derived class with private members; uses default values
    • NLOHMANN_DEFINE_TYPE_INTRUSIVE_ONLY_SERIALIZE - serialize a non-derived class with private members
    • NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE - serialize/deserialize a non-derived class
    • NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT - serialize/deserialize a non-derived class; uses default values
    • NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE - serialize a non-derived class

    • NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE - serialize/deserialize a derived class with private members

    • NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_WITH_DEFAULT - serialize/deserialize a derived class with private members; uses default values
    • NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_ONLY_SERIALIZE - serialize a derived class with private members
    • NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE - serialize/deserialize a derived class
    • NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_WITH_DEFAULT - serialize/deserialize a derived class; uses default values
    • NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE - serialize a derived class
    • NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_NAMES - serialize/deserialize a non-derived class with private members; uses custom names
    • NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT_WITH_NAMES - serialize/deserialize a non-derived class with private members; uses default values; uses custom names
    • NLOHMANN_DEFINE_TYPE_INTRUSIVE_ONLY_SERIALIZE_WITH_NAMES - serialize a non-derived class with private members; uses custom names
    • NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_NAMES - serialize/deserialize a non-derived class; uses custom names
    • NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT_WITH_NAMES - serialize/deserialize a non-derived class; uses default values; uses custom names
    • NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE_WITH_NAMES - serialize a non-derived class; uses custom names

    • NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_WITH_NAMES - serialize/deserialize a derived class with private members; uses custom names

    • NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_WITH_DEFAULT_WITH_NAMES - serialize/deserialize a derived class with private members; uses default values; uses custom names
    • NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_ONLY_SERIALIZE_WITH_NAMES - serialize a derived class with private members; uses custom names
    • NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_WITH_NAMES - serialize/deserialize a derived class; uses custom names
    • NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_WITH_DEFAULT_WITH_NAMES - serialize/deserialize a derived class; uses default values; uses custom names
    • NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE_WITH_NAMES - serialize a derived class; uses custom names
    "},{"location":"api/macros/#see-also","title":"See also","text":"
    • Macros - guide to the supported macros
    • Runtime assertions - assertions guarding against undefined behavior
    • Arbitrary type conversions - using the NLOHMANN_DEFINE_TYPE_* macros
    • Enum conversion - using NLOHMANN_JSON_SERIALIZE_ENUM
    • The nlohmann namespace - how the library's namespace is defined and versioned
    • CMake integration - setting macros from the build system
    • Integration - integrate the library and set macros
    • Modules - macros and C++20 modules
    • Working Without Exceptions - using the library without exceptions
    • Architecture - how the library is put together
    "},{"location":"api/macros/json_assert/","title":"JSON_ASSERT","text":"
    #define JSON_ASSERT(x) /* value */\n

    This macro controls which code is executed for runtime assertions of the library.

    "},{"location":"api/macros/json_assert/#parameters","title":"Parameters","text":"x (in) expression of a scalar type"},{"location":"api/macros/json_assert/#default-definition","title":"Default definition","text":"

    The default value is assert(x).

    #define JSON_ASSERT(x) assert(x)\n

    Therefore, assertions can be switched off by defining NDEBUG.

    "},{"location":"api/macros/json_assert/#notes","title":"Notes","text":"
    • The library uses numerous assertions to guarantee invariants and to abort in case of otherwise undefined behavior (e.g., when calling operator[] with a missing object key on a const object). See page runtime assertions for more information.
    • Defining the macro to code that does not call std::abort may leave the library in an undefined state.
    • The macro is undefined outside the library.
    "},{"location":"api/macros/json_assert/#examples","title":"Examples","text":"Example: default behavior

    The following code will trigger an assertion at runtime:

    #include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    const json j = {{\"key\", \"value\"}};\n    auto v = j[\"missing\"];\n}\n

    Output:

    Assertion failed: (m_value.object->find(key) != m_value.object->end()), function operator[], file json.hpp, line 2144.\n
    Example: user-defined behavior

    The assertion reporting can be changed by defining JSON_ASSERT(x) differently.

    #include <cstdio>\n#include <cstdlib>\n#define JSON_ASSERT(x) if(!(x)){fprintf(stderr, \"assertion error in %s\\n\", __FUNCTION__); std::abort();}\n\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    const json j = {{\"key\", \"value\"}};\n    auto v = j[\"missing\"];\n}\n

    Output:

    assertion error in operator[]\n
    "},{"location":"api/macros/json_assert/#see-also","title":"See also","text":"
    • Runtime Assertions - overview documentation
    • Supported Macros - guide to all supported macros
    "},{"location":"api/macros/json_assert/#version-history","title":"Version history","text":"
    • Added in version 3.9.0.
    "},{"location":"api/macros/json_brace_init_copy_semantics/","title":"JSON_BRACE_INIT_COPY_SEMANTICS","text":"
    #define JSON_BRACE_INIT_COPY_SEMANTICS /* value */\n

    When defined to 1, single-element brace initialization of a basic_json value is treated as a copy/move of the element rather than wrapping it in a single-element array.

    "},{"location":"api/macros/json_brace_init_copy_semantics/#default-definition","title":"Default definition","text":"

    The default value is 0 (disabled \u2014 existing behavior is preserved).

    #define JSON_BRACE_INIT_COPY_SEMANTICS 0\n
    "},{"location":"api/macros/json_brace_init_copy_semantics/#notes","title":"Notes","text":"

    Background

    C++ always prefers the initializer_list constructor over the copy/move constructor for brace initialization. This means that code like

    json obj = {{\"key\", \"value\"}};\njson j{obj};\n

    creates a single-element array [{\"key\":\"value\"}] instead of a copy of obj. This behavior is compiler-dependent for older compilers (GCC wrapped, Clang did not), but starting from Clang 20, both compilers behave the same way.

    Enabling this macro opts into copy/move semantics for this case (see #5074).

    Opt-in only

    This macro must be defined before including <nlohmann/json.hpp>. Defining it after the include has no effect.

    Applies to every single-element list

    The macro does not only affect a single JSON value in braces. Any single-element braced list is treated as its element, so it no longer creates a one-element array:

    json j1 = {1};       // 1, not [1]\njson j2 = {\"text\"};  // \"text\", not [\"text\"]\njson j3 = {{1, 2}};  // [1,2], not [[1,2]]\n

    Code that relies on these producing arrays must use json::array() instead (see below). Lists with more than one element, and a single [string, value] pair written as a braced list, such as {{\"key\", \"value\"}}, which still creates an object, are not affected. This exception is based on how the pair is written, not on the shape of its value: an existing JSON value that happens to be a two-element array with a string as its first element, such as json arr = {\"key\", 42};, is still copied by json j{arr}; rather than turned into an object. The library's own conversions are not affected either: for example, std::tuple<int>{5} still becomes [5].

    ABI compatibility

    The value of this macro is encoded in the namespace (tag _bics), resulting in distinct symbol names. Translation units compiled with and without it can therefore be linked into the same program without One Definition Rule (ODR) violations, but they cannot exchange instances of library types.

    Workaround without the macro

    To explicitly create a single-element array without enabling this macro, use json::array():

    json j = json::array({obj});  // always creates [obj]\n
    "},{"location":"api/macros/json_brace_init_copy_semantics/#examples","title":"Examples","text":"Example: default behavior (macro not defined)

    Without the macro, single-element brace initialization wraps the value in an array:

    #include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    json obj = {{\"key\", \"value\"}};\n\n    json j{obj};\n    // j is [{\"key\":\"value\"}]  -- single-element array, NOT a copy of obj\n}\n
    Example: opt-in copy semantics (macro defined to 1)

    With the macro, single-element brace initialization copies/moves the value:

    #define JSON_BRACE_INIT_COPY_SEMANTICS 1\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    json obj = {{\"key\", \"value\"}};\n\n    json j{obj};\n    // j is {\"key\":\"value\"}  -- copy of obj\n}\n
    "},{"location":"api/macros/json_brace_init_copy_semantics/#see-also","title":"See also","text":"
    • FAQ: Brace initialization yields arrays - why brace initialization may create arrays
    • basic_json(initializer_list_t) - the affected constructor
    • Creating JSON values - initializer lists and braces
    "},{"location":"api/macros/json_brace_init_copy_semantics/#version-history","title":"Version history","text":"
    • Added in version 3.13.0 unreleased.
    • Planned to become the default (with the macro removed) in version 4.0.0.
    "},{"location":"api/macros/json_delete_deprecated_functions/","title":"JSON_DELETE_DEPRECATED_FUNCTIONS","text":"
    #define JSON_DELETE_DEPRECATED_FUNCTIONS /* value */\n

    When defined to 1, all deprecated functions of the library are declared as deleted (= delete) instead of only being marked as deprecated. Code that still calls one of them no longer compiles. This way, you can find all calls that need to be replaced before version 4.0.0 unreleased removes these functions; the migration guide describes how.

    A deleted function, unlike a removed one, still takes part in overload resolution. A call that would select it therefore fails to compile instead of silently selecting another overload. This matters for the deprecated from_*(ptr, len) overloads of from_cbor, from_msgpack, from_ubjson, from_bjdata, from_bon8, and from_bson: without them, a call like from_cbor(ptr, len) would compile, read ptr as a NUL-terminated string, and convert len to the strict parameter.

    The macro does not affect the deprecated legacy comparison of discarded values, which is controlled by JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON.

    "},{"location":"api/macros/json_delete_deprecated_functions/#default-definition","title":"Default definition","text":"

    The default value is 0 (disabled, the deprecated functions can still be called, and the compiler warns about it).

    #define JSON_DELETE_DEPRECATED_FUNCTIONS 0\n
    "},{"location":"api/macros/json_delete_deprecated_functions/#notes","title":"Notes","text":"

    CMake option

    The macro can also be set with the CMake option JSON_DeleteDeprecatedFunctions (OFF by default).

    Opt-in only

    This macro must be defined before including <nlohmann/json.hpp>. Defining it after the include has no effect. Define it for the whole project to avoid different declarations of the same class in different translation units.

    ABI compatibility

    The macro only turns calls that compile into calls that do not; it does not change the layout or the behavior of any type. Its value is therefore not encoded in the namespace.

    "},{"location":"api/macros/json_delete_deprecated_functions/#examples","title":"Examples","text":"Example: default behavior (macro not defined)

    Without the macro, the deprecated overload is called, and the compiler warns about it:

    #include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    const std::vector<std::uint8_t> v = {0x82, 0x01, 0x02};\n    auto j = json::from_cbor(v.data(), v.size());\n    // warning: 'from_cbor' is deprecated: Since 3.8.0; use from_cbor(ptr, ptr + len)\n}\n
    Example: deleted deprecated functions (macro defined to 1)

    With the macro, the call does not compile:

    #define JSON_DELETE_DEPRECATED_FUNCTIONS 1\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    const std::vector<std::uint8_t> v = {0x82, 0x01, 0x02};\n    auto j = json::from_cbor(v.data(), v.size());\n    // error: call to deleted function 'from_cbor'\n}\n
    "},{"location":"api/macros/json_delete_deprecated_functions/#see-also","title":"See also","text":"
    • Roadmap: removal of deprecated functions - the deprecated functions and the version they were deprecated in
    • Migration guide: replace deprecated functions - how to replace each deprecated function
    • Supported Macros - guide to all supported macros
    • CMake - the corresponding CMake option
    "},{"location":"api/macros/json_delete_deprecated_functions/#version-history","title":"Version history","text":"
    • Added in version 3.13.0 unreleased.
    • Planned to be removed in version 4.0.0, which removes the deprecated functions. The deprecated from_*(ptr, len) overloads stay deleted in version 4.0.0 unreleased.
    "},{"location":"api/macros/json_diagnostic_positions/","title":"JSON_DIAGNOSTIC_POSITIONS","text":"
    #define JSON_DIAGNOSTIC_POSITIONS /* value */\n

    This macro enables position diagnostics for generated JSON objects.

    When enabled, two new member functions start_pos() and end_pos() are added to basic_json values. If the value was created by calling theparse function, then these functions allow querying the byte positions of the value in the input it was parsed from. In case the value was constructed by other means, std::string::npos is returned.

    start_pos() returns the position of the first character of a given value in the original JSON string, while end_pos() returns the position of the character following the last character. For objects and arrays, the first and last characters correspond to the opening or closing braces/brackets, respectively. For primitive values, the first and last character represents the opening and closing quotes (strings) or the first and last character of the field's numerical or predefined value (true, false, null), respectively.

    JSON type return value start_pos() return value end_pos() object position of the opening { position after the closing } array position of the opening [ position after the closing ] string position of the opening \" position after the closing \" number position of the first character position after the last character boolean position of t for true and f for false position after e null position of n position after l

    Given the above, end_pos()-start_pos() for a JSON value provides the length of the parsed JSON string for that value, including the opening or closing braces, brackets, or quotes.

    Note that enabling this macro increases the size of every JSON value by two std::size_t fields and adds slight runtime overhead to parsing, copying JSON value objects, and the generation of error messages for exceptions. It also causes these values to be reported in those error messages.

    "},{"location":"api/macros/json_diagnostic_positions/#default-definition","title":"Default definition","text":"

    The default value is 0 (position diagnostics are switched off).

    #define JSON_DIAGNOSTIC_POSITIONS 0\n

    When the macro is not defined, the library will define it to its default value.

    "},{"location":"api/macros/json_diagnostic_positions/#notes","title":"Notes","text":"

    CMake option

    Diagnostic positions can also be controlled with the CMake option JSON_Diagnostic_Positions (OFF by default) which defines JSON_DIAGNOSTIC_POSITIONS accordingly.

    Availability

    Diagnostic positions are only available if the value was created by the parse function. The sax_parse function or all other means to create a JSON value do not set the diagnostic positions and start_pos() and end_pos() will only return std::string::npos for these values.

    Invalidation

    The returned positions are only valid as long as the JSON value is not changed. The positions are not updated when the JSON value is changed.

    "},{"location":"api/macros/json_diagnostic_positions/#examples","title":"Examples","text":"Example: retrieving positions
    #include <iostream>\n\n#define JSON_DIAGNOSTIC_POSITIONS 1\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    std::string json_string = R\"(\n    {\n        \"address\": {\n            \"street\": \"Fake Street\",\n            \"housenumber\": 1\n        }\n    }\n    )\";\n    json j = json::parse(json_string);\n\n    std::cout << \"Root diagnostic positions: \\n\";\n    std::cout << \"\\tstart_pos: \" << j.start_pos() << '\\n';\n    std::cout << \"\\tend_pos:\" << j.end_pos() << \"\\n\";\n    std::cout << \"Original string: \\n\";\n    std::cout << \"{\\n        \\\"address\\\": {\\n            \\\"street\\\": \\\"Fake Street\\\",\\n            \\\"housenumber\\\": 1\\n        }\\n    }\" << \"\\n\";\n    std::cout << \"Parsed string: \\n\";\n    std::cout << json_string.substr(j.start_pos(), j.end_pos() - j.start_pos()) << \"\\n\\n\";\n\n    std::cout << \"address diagnostic positions: \\n\";\n    std::cout << \"\\tstart_pos:\" << j[\"address\"].start_pos() << '\\n';\n    std::cout << \"\\tend_pos:\" << j[\"address\"].end_pos() << \"\\n\\n\";\n    std::cout << \"Original string: \\n\";\n    std::cout << \"{            \\\"street\\\": \\\"Fake Street\\\",\\n            \\\"housenumber\\\": 1\\n        }\" << \"\\n\";\n    std::cout << \"Parsed string: \\n\";\n    std::cout << json_string.substr(j[\"address\"].start_pos(), j[\"address\"].end_pos() - j[\"address\"].start_pos()) << \"\\n\\n\";\n\n    std::cout << \"street diagnostic positions: \\n\";\n    std::cout << \"\\tstart_pos:\" << j[\"address\"][\"street\"].start_pos() << '\\n';\n    std::cout << \"\\tend_pos:\" << j[\"address\"][\"street\"].end_pos() << \"\\n\\n\";\n    std::cout << \"Original string: \\n\";\n    std::cout << \"\\\"Fake Street\\\"\" << \"\\n\";\n    std::cout << \"Parsed string: \\n\";\n    std::cout << json_string.substr(j[\"address\"][\"street\"].start_pos(), j[\"address\"][\"street\"].end_pos() - j[\"address\"][\"street\"].start_pos()) << \"\\n\\n\";\n\n    std::cout << \"housenumber diagnostic positions: \\n\";\n    std::cout << \"\\tstart_pos:\" << j[\"address\"][\"housenumber\"].start_pos() << '\\n';\n    std::cout << \"\\tend_pos:\" << j[\"address\"][\"housenumber\"].end_pos() << \"\\n\\n\";\n    std::cout << \"Original string: \\n\";\n    std::cout << \"1\" << \"\\n\";\n    std::cout << \"Parsed string: \\n\";\n    std::cout << json_string.substr(j[\"address\"][\"housenumber\"].start_pos(), j[\"address\"][\"housenumber\"].end_pos() - j[\"address\"][\"housenumber\"].start_pos()) << \"\\n\\n\";\n}\n

    Output:

    Root diagnostic positions: \n    start_pos: 5\n    end_pos:109\nOriginal string: \n{\n        \"address\": {\n            \"street\": \"Fake Street\",\n            \"housenumber\": 1\n        }\n    }\nParsed string: \n{\n        \"address\": {\n            \"street\": \"Fake Street\",\n            \"housenumber\": 1\n        }\n    }\n\naddress diagnostic positions: \n    start_pos:26\n    end_pos:103\n\nOriginal string: \n{            \"street\": \"Fake Street\",\n            \"housenumber\": 1\n        }\nParsed string: \n{\n            \"street\": \"Fake Street\",\n            \"housenumber\": 1\n        }\n\nstreet diagnostic positions: \n    start_pos:50\n    end_pos:63\n\nOriginal string: \n\"Fake Street\"\nParsed string: \n\"Fake Street\"\n\nhousenumber diagnostic positions: \n    start_pos:92\n    end_pos:93\n\nOriginal string: \n1\nParsed string: \n1\n

    The output shows the start/end positions of all the objects and fields in the JSON string.

    Example: using only diagnostic positions in exceptions
    #include <iostream>\n\n#define JSON_DIAGNOSTIC_POSITIONS 1\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\n/* Demonstration of type error exception with diagnostic positions support enabled */\nint main()\n{\n    //Invalid json string - housenumber type must be int instead of string\n    const std::string json_invalid_string = R\"(\n    {\n        \"address\": {\n            \"street\": \"Fake Street\",\n            \"housenumber\": \"1\"\n        }\n    }\n    )\";\n    json j = json::parse(json_invalid_string);\n    try\n    {\n        int housenumber = j[\"address\"][\"housenumber\"];\n        std::cout << housenumber;\n    }\n    catch (const json::exception& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n}\n

    Output:

    [json.exception.type_error.302] (bytes 92-95) type must be number, but is string\n
    The output shows the exception with start/end positions only.\n
    Example: using extended diagnostics with positions enabled in exceptions
    #include <iostream>\n\n#define JSON_DIAGNOSTICS 1\n#define JSON_DIAGNOSTIC_POSITIONS 1\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\n/* Demonstration of type error exception with diagnostic positions support enabled */\nint main()\n{\n    //Invalid json string - housenumber type must be int instead of string\n    const std::string json_invalid_string = R\"(\n    {\n        \"address\": {\n            \"street\": \"Fake Street\",\n            \"housenumber\": \"1\"\n        }\n    }\n    )\";\n    json j = json::parse(json_invalid_string);\n    try\n    {\n        int housenumber = j[\"address\"][\"housenumber\"];\n        std::cout << housenumber;\n    }\n    catch (const json::exception& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n}\n

    Output:

    [json.exception.type_error.302] (/address/housenumber) (bytes 92-95) type must be number, but is string\n
    The output shows the exception with diagnostic path info and start/end positions.\n
    "},{"location":"api/macros/json_diagnostic_positions/#see-also","title":"See also","text":"
    • JSON_Diagnostic_Positions - CMake option to control the macro
    • JSON_DIAGNOSTICS - macro to control extended diagnostics
    • materialize() - values of a JSON view, with the same positions
    • Parsing and Exceptions - handling parse errors and locating them in the input
    "},{"location":"api/macros/json_diagnostic_positions/#version-history","title":"Version history","text":"
    • Added in version 3.12.0.
    "},{"location":"api/macros/json_diagnostics/","title":"JSON_DIAGNOSTICS","text":"
    #define JSON_DIAGNOSTICS /* value */\n

    This macro enables extended diagnostics for exception messages. Possible values are 1 to enable or 0 to disable (default).

    When enabled, exception messages contain a JSON Pointer to the JSON value that triggered the exception. Note that enabling this macro increases the size of every JSON value by one pointer and adds some runtime overhead.

    "},{"location":"api/macros/json_diagnostics/#default-definition","title":"Default definition","text":"

    The default value is 0 (extended diagnostics are switched off).

    #define JSON_DIAGNOSTICS 0\n

    When the macro is not defined, the library will define it to its default value.

    "},{"location":"api/macros/json_diagnostics/#notes","title":"Notes","text":"

    ABI compatibility

    As of version 3.11.0, this macro is no longer required to be defined consistently throughout a codebase to avoid One Definition Rule (ODR) violations, as the value of this macro is encoded in the namespace, resulting in distinct symbol names.

    This allows different parts of a codebase to use different versions or configurations of this library without causing improper behavior.

    Where possible, it is still recommended that all code define this the same way for maximum interoperability.

    CMake option

    Diagnostic messages can also be controlled with the CMake option JSON_Diagnostics (OFF by default) which defines JSON_DIAGNOSTICS accordingly. Note this only applies when building the library from source \u2014 see the pre-installed-package caveat on that page.

    "},{"location":"api/macros/json_diagnostics/#examples","title":"Examples","text":"Example: default behavior
    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    json j;\n    j[\"address\"][\"street\"] = \"Fake Street\";\n    j[\"address\"][\"housenumber\"] = \"12\";\n\n    try\n    {\n        int housenumber = j[\"address\"][\"housenumber\"];\n    }\n    catch (const json::exception& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n}\n

    Output:

    [json.exception.type_error.302] type must be number, but is string\n

    This exception can be hard to debug if storing the value \"12\" and accessing it is further apart.

    Example: extended diagnostic messages
    #include <iostream>\n\n# define JSON_DIAGNOSTICS 1\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    json j;\n    j[\"address\"][\"street\"] = \"Fake Street\";\n    j[\"address\"][\"housenumber\"] = \"12\";\n\n    try\n    {\n        int housenumber = j[\"address\"][\"housenumber\"];\n    }\n    catch (const json::exception& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n}\n

    Output:

    [json.exception.type_error.302] (/address/housenumber) type must be number, but is string\n

    Now the exception message contains a JSON Pointer /address/housenumber that indicates which value has the wrong type.

    Example: using only diagnostic positions in exceptions
    #include <iostream>\n\n#define JSON_DIAGNOSTIC_POSITIONS 1\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\n/* Demonstration of type error exception with diagnostic positions support enabled */\nint main()\n{\n    //Invalid json string - housenumber type must be int instead of string\n    const std::string json_invalid_string = R\"(\n    {\n        \"address\": {\n            \"street\": \"Fake Street\",\n            \"housenumber\": \"1\"\n        }\n    }\n    )\";\n    json j = json::parse(json_invalid_string);\n    try\n    {\n        int housenumber = j[\"address\"][\"housenumber\"];\n        std::cout << housenumber;\n    }\n    catch (const json::exception& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n}\n

    Output:

    [json.exception.type_error.302] (bytes 92-95) type must be number, but is string\n
    The output shows the exception with start/end positions only.

    "},{"location":"api/macros/json_diagnostics/#see-also","title":"See also","text":"
    • JSON_Diagnostics - CMake option to control the macro
    • JSON_DIAGNOSTIC_POSITIONS - macro to access positions of elements
    • Supported Macros - guide to all supported macros
    • Exceptions: extended diagnostic messages - how extended diagnostics change the messages
    • Debugging - debugging aids
    • exception - base class of all exceptions thrown by the library
    "},{"location":"api/macros/json_diagnostics/#version-history","title":"Version history","text":"
    • Added in version 3.10.0.
    • As of version 3.11.0, the definition is allowed to vary between translation units.
    "},{"location":"api/macros/json_disable_enum_serialization/","title":"JSON_DISABLE_ENUM_SERIALIZATION","text":"
    #define JSON_DISABLE_ENUM_SERIALIZATION /* value */\n

    When defined to 1, default serialization and deserialization functions for enums are excluded and have to be provided by the user, for example, using NLOHMANN_JSON_SERIALIZE_ENUM (see arbitrary type conversions for more details).

    Parsing or serializing an enum will result in a compiler error.

    This works for both unscoped and scoped enums.

    "},{"location":"api/macros/json_disable_enum_serialization/#default-definition","title":"Default definition","text":"

    The default value is 0.

    #define JSON_DISABLE_ENUM_SERIALIZATION 0\n
    "},{"location":"api/macros/json_disable_enum_serialization/#notes","title":"Notes","text":"

    CMake option

    Enum serialization can also be controlled with the CMake option JSON_DisableEnumSerialization (OFF by default) which defines JSON_DISABLE_ENUM_SERIALIZATION accordingly.

    "},{"location":"api/macros/json_disable_enum_serialization/#examples","title":"Examples","text":"Example: Disabled behavior

    The code below forces the library not to create default serialization/deserialization functions from_json and to_json, meaning the code below does not compile.

    #define JSON_DISABLE_ENUM_SERIALIZATION 1\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nenum class Choice\n{\n    first,\n    second,\n};\n\nint main()\n{\n    // normally invokes to_json serialization function but with JSON_DISABLE_ENUM_SERIALIZATION defined, it does not\n    const json j = Choice::first; \n\n    // normally invokes from_json parse function but with JSON_DISABLE_ENUM_SERIALIZATION defined, it does not\n    Choice ch = j.get<Choice>();\n}\n
    Example: Serialize enum macro

    The code below forces the library not to create default serialization/deserialization functions from_json and to_json, but uses NLOHMANN_JSON_SERIALIZE_ENUM to parse and serialize the enum.

    #define JSON_DISABLE_ENUM_SERIALIZATION 1\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nenum class Choice\n{\n    first,\n    second,\n};\n\nNLOHMANN_JSON_SERIALIZE_ENUM(Choice,\n{\n    { Choice::first, \"first\" },\n    { Choice::second, \"second\" },\n})\n\nint main()\n{\n    // uses user-defined to_json function defined by macro\n    const json j = Choice::first; \n\n    // uses user-defined from_json function defined by macro\n    Choice ch = j.get<Choice>();\n}\n
    Example: User-defined serialization/deserialization functions

    The code below forces the library not to create default serialization/deserialization functions from_json and to_json, but uses user-defined functions to parse and serialize the enum.

    #define JSON_DISABLE_ENUM_SERIALIZATION 1\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nenum class Choice\n{\n    first,\n    second,\n};\n\nvoid from_json(const json& j, Choice& ch)\n{\n    auto value = j.get<std::string>();\n    if (value == \"first\")\n    {\n        ch = Choice::first;\n    }\n    else if (value == \"second\")\n    {\n        ch = Choice::second;\n    }\n}\n\nvoid to_json(json& j, const Choice& ch)\n{\n    if (ch == Choice::first)\n    {\n        j = \"first\";\n    }\n    else if (ch == Choice::second)\n    {\n        j = \"second\";\n    }\n}\n\nint main()\n{\n    // uses user-defined to_json function\n    const json j = Choice::first; \n\n    // uses user-defined from_json function\n    Choice ch = j.get<Choice>();\n}\n
    "},{"location":"api/macros/json_disable_enum_serialization/#see-also","title":"See also","text":"
    • JSON_DisableEnumSerialization - CMake option to control the macro
    • NLOHMANN_JSON_SERIALIZE_ENUM - serialize/deserialize an enum
    • Specializing enum conversion - map enums to JSON strings instead of integers
    "},{"location":"api/macros/json_disable_enum_serialization/#version-history","title":"Version history","text":"
    • Added in version 3.11.0.
    "},{"location":"api/macros/json_disable_stream_bulk_scan/","title":"JSON_DISABLE_STREAM_BULK_SCAN","text":"
    #define JSON_DISABLE_STREAM_BULK_SCAN /* value */\n

    When defined to 1, parsing from a std::istream reads the input one character at a time through the stream buffer, as in version 3.12.0 and earlier, instead of scanning the characters that the stream buffer already holds in bulk.

    The macro is an escape hatch for stream buffers that do not follow the usual contract of std::basic_streambuf (see the requirements on the stream buffer in the notes below). It does not change any result: values, exceptions, and the position of the stream after parsing are the same either way. Only the speed differs.

    "},{"location":"api/macros/json_disable_stream_bulk_scan/#default-definition","title":"Default definition","text":"

    The default value is 0: streams are scanned in bulk.

    #define JSON_DISABLE_STREAM_BULK_SCAN 0\n
    "},{"location":"api/macros/json_disable_stream_bulk_scan/#notes","title":"Notes","text":"

    How streams are scanned

    A std::streambuf keeps the part of the input it has read but not yet handed out in its get area, the range from gptr() to egptr(). A std::filebuf, for instance, reads the file in blocks of a few kilobytes into its get area, and a std::stringbuf exposes its whole string as one get area.

    When parsing from a std::istream, the parser scans this get area directly, with the same fast paths that it uses for a std::string: runs of ordinary string characters, numbers, and indentation are recognized several bytes at a time instead of being requested from the stream buffer one character at a time. When the parser reaches the end of the get area, it asks the stream buffer for the next character as before, which makes the stream buffer refill its get area.

    The parser only reads characters that it would also have read one at a time, and it advances the stream buffer exactly over the characters it consumes. Nothing is read ahead, buffered elsewhere, or put back. Therefore, the stream is left exactly where it was left before:

    • operator>> and sax_parse with strict = false can still read several values from one stream, and the stream can still be used with other std::istream functions after a value has been read.
    • With JSON_PRECISE_STREAM_POSITION, the stream is still positioned right after a parsed number.
    • Exception messages, including the line, the column, and the last read token, are unchanged.

    Performance

    Parsing from a std::ifstream or std::istringstream is typically 1.5 to 2 times as fast as before, and reading many small values from one stream with operator>> 1.4 to 4 times as fast. Parsing from a stream is then within about 10 to 20 % of first reading the whole file into a std::string and parsing that.

    A stream buffer without a get area (one that only overrides underflow() and uflow() and hands out every character from there) offers nothing to scan in bulk, so it is read one character at a time as before.

    Requirements on the stream buffer

    The bulk scan relies on the following behavior, which every stream buffer of the standard library and every stream buffer that keeps its input in its get area has:

    • When sgetc() returns a character while gptr() < egptr(), that character is *gptr(); when sbumpc() returns one, it was at gptr() before the call.
    • Characters in the get area are not changed while they are in the get area.
    • underflow() or uflow() either sets up a get area that holds the returned character at gptr() (or at gptr() - 1 after uflow()), or leaves the get area empty.

    A stream buffer that returns characters from uflow() while leaving unrelated characters in its get area, or that changes the characters in its get area in place, does not meet these requirements. Define the macro to 1 for such stream buffers.

    ABI compatibility

    The value of this macro is encoded in the namespace (tag _dsbs), resulting in distinct symbol names. Translation units compiled with and without it can therefore be linked into the same program without One Definition Rule (ODR) violations, but they cannot exchange instances of library types.

    Other inputs

    Strings, string views, vectors, arrays, and pointer or iterator ranges over contiguous memory are scanned in bulk anyway. Reading from a FILE* is not affected by this macro; see JSON_DISABLE_UNLOCKED_FILE_IO for that input.

    "},{"location":"api/macros/json_disable_stream_bulk_scan/#examples","title":"Examples","text":"Example: reading values from a stream (default)

    The stream is scanned in bulk, and the values are read one after the other:

    #include <iostream>\n#include <sstream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    std::istringstream input(R\"({\"id\": 1} {\"id\": 2} 42 rest)\");\n    json j1, j2, j3;\n    input >> j1 >> j2 >> j3;  // {\"id\":1}, {\"id\":2}, 42\n\n    std::string word;\n    input >> word;            // \"rest\"\n}\n
    Example: reading one character at a time (macro defined to 1)

    With the macro, the same program reads the stream one character at a time, with the same results:

    #define JSON_DISABLE_STREAM_BULK_SCAN 1\n#include <iostream>\n#include <sstream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    std::istringstream input(R\"({\"id\": 1} {\"id\": 2} 42 rest)\");\n    json j1, j2, j3;\n    input >> j1 >> j2 >> j3;  // {\"id\":1}, {\"id\":2}, 42\n\n    std::string word;\n    input >> word;            // \"rest\"\n}\n
    "},{"location":"api/macros/json_disable_stream_bulk_scan/#see-also","title":"See also","text":"
    • parse - deserialize from a compatible input
    • operator>> - deserialize from stream
    • sax_parse - generate SAX events
    • JSON_PRECISE_STREAM_POSITION - leave an input stream positioned right after a parsed number
    • JSON_DISABLE_UNLOCKED_FILE_IO - read a FILE* with the locking stdio functions
    • Parsing: input sources and performance - how input sources affect parsing performance
    • Large, Streamed, and Partial Input - chunked, concatenated, and very large input
    "},{"location":"api/macros/json_disable_stream_bulk_scan/#version-history","title":"Version history","text":"
    • Added in version 3.13.0 unreleased.
    "},{"location":"api/macros/json_disable_tuple_reference_conversion/","title":"JSON_DISABLE_TUPLE_REFERENCE_CONVERSION","text":"
    #define JSON_DISABLE_TUPLE_REFERENCE_CONVERSION /* value */\n

    When defined to 1, a basic_json value can no longer be constructed from a one-element std::tuple whose element is a reference to that basic_json type, such as std::tuple<json&>, std::tuple<const json&>, or std::tuple<json&&>. These are the tuples created by std::forward_as_tuple(j).

    "},{"location":"api/macros/json_disable_tuple_reference_conversion/#default-definition","title":"Default definition","text":"

    The default value is 0 (disabled \u2014 existing behavior is preserved).

    #define JSON_DISABLE_TUPLE_REFERENCE_CONVERSION 0\n
    "},{"location":"api/macros/json_disable_tuple_reference_conversion/#notes","title":"Notes","text":"

    Background

    By default, basic_json can be constructed from any std::tuple whose elements can be converted to JSON; the result is an array. This includes std::tuple<json&>, which becomes a one-element array.

    std::tuple only converts another tuple element by element if its element type cannot be constructed from the whole source tuple. Because json can be constructed from std::tuple<json&>, std::tuple instead converts the whole tuple into a single json value. This has two surprising effects:

    json j = true;\n\n// rejected by some standard libraries (e.g., libc++); with others, the\n// reference binds to a temporary that is destroyed right away\nstd::tuple<const json&> t1(std::forward_as_tuple(j));\n\n// compiles, but std::get<0>(t2) is [true], not true\nstd::tuple<json> t2(std::forward_as_tuple(j));\n

    Enabling this macro removes the conversion, so both tuples are converted element by element: std::get<0>(t1) refers to j, and std::get<0>(t2) is a copy of j (see #2226).

    Opt-in only

    This macro must be defined before including <nlohmann/json.hpp>. Defining it after the include has no effect.

    Affected conversions

    Only one-element tuples holding a reference to the same basic_json type are affected. Constructing a JSON value from them no longer compiles:

    json j = true;\njson a = std::forward_as_tuple(j);  // error with the macro enabled\njson b = json::array({j});          // use this instead: [true]\n

    Tuples holding a JSON value (std::make_tuple(j)), tuples with more than one element, and tuples holding references to other types (including other basic_json specializations) are converted to arrays as before.

    CMake option

    This behavior can also be controlled with the CMake option JSON_DisableTupleReferenceConversion (OFF by default) which defines JSON_DISABLE_TUPLE_REFERENCE_CONVERSION accordingly.

    "},{"location":"api/macros/json_disable_tuple_reference_conversion/#examples","title":"Examples","text":"Example: default behavior (macro not defined)
    #include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    json j = true;\n\n    std::tuple<json> t(std::forward_as_tuple(j));\n    // std::get<0>(t) is [true] -- the whole tuple was converted\n}\n
    Example: conversion disabled (macro defined to 1)
    #define JSON_DISABLE_TUPLE_REFERENCE_CONVERSION 1\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    json j = true;\n\n    std::tuple<json> t(std::forward_as_tuple(j));\n    // std::get<0>(t) is true -- a copy of j\n\n    std::tuple<const json&> r(std::forward_as_tuple(j));\n    // std::get<0>(r) refers to j\n}\n
    "},{"location":"api/macros/json_disable_tuple_reference_conversion/#see-also","title":"See also","text":"
    • basic_json(CompatibleType&&) - the affected constructor
    • JSON_DisableTupleReferenceConversion - CMake option to control the macro
    • Converting values - getting values out
    • Arbitrary Type Conversions - converting your own types
    "},{"location":"api/macros/json_disable_tuple_reference_conversion/#version-history","title":"Version history","text":"
    • Added in version 3.13.0 unreleased.
    • Planned to become the default (with the macro removed) in version 4.0.0.
    "},{"location":"api/macros/json_disable_unlocked_file_io/","title":"JSON_DISABLE_UNLOCKED_FILE_IO","text":"
    #define JSON_DISABLE_UNLOCKED_FILE_IO /* value */\n

    When defined to 1, parsing from a FILE* reads every character with std::fgetc, as in version 3.12.0 and earlier, instead of locking the file once and reading it with the unlocked stdio functions.

    It does not change any result: values, exceptions, and the position of the file after parsing are the same either way. Only the speed and the locking of the file differ (see the notes on locking below).

    Builds with MemorySanitizer use std::fgetc automatically, because the inline getc_unlocked of glibc reads the stdio buffer directly, which glibc (not instrumented) filled, and MemorySanitizer would report it as uninitialized.

    "},{"location":"api/macros/json_disable_unlocked_file_io/#default-definition","title":"Default definition","text":"

    The default value is 0: the file is locked once and read with the unlocked stdio functions where they are available.

    #define JSON_DISABLE_UNLOCKED_FILE_IO 0\n
    "},{"location":"api/macros/json_disable_unlocked_file_io/#notes","title":"Notes","text":"

    Background

    The C standard library makes every std::fgetc call thread-safe by locking and unlocking the FILE object. When parsing from a FILE*, the parser reads one character at a time, so this happens for every character of the input.

    Instead, the parser locks the file once when parsing starts and unlocks it when parsing ends - also when an exception is thrown - and reads the characters in between without locking:

    C library functions glibc (Linux), Apple (macOS, iOS), Android, FreeBSD, NetBSD, OpenBSD, DragonFly BSD flockfile, getc_unlocked, funlockfile (POSIX) Microsoft (MSVC, clang-cl) _lock_file, _fgetc_nolock, _unlock_file others (e.g., musl, MinGW, newlib) std::fgetc, as before

    This makes parsing from a FILE* 3 to 4 times as fast with the Apple C library and 1.1 to 1.3 times as fast with glibc, whose locking is cheaper. The binary formats (from_cbor, from_msgpack, ...) read from a FILE* the same way.

    Locking

    While a value is parsed from a FILE*, the parsing thread holds the file's lock. The lock is recursive, so the parsing thread itself - for instance, a SAX handler or a parser callback - can keep using the file with stdio functions such as std::ftell. Other threads that use the same FILE object wait until the parser is done. Before, they could interleave their reads with the parser's, which made the parsed input unpredictable anyway.

    A program in which a SAX handler or parser callback waits for another thread that uses the same FILE object would deadlock. Define the macro to 1 for such programs.

    ABI compatibility

    The value of this macro is encoded in the namespace (tag _dufio), resulting in distinct symbol names. Translation units compiled with and without it can therefore be linked into the same program without One Definition Rule (ODR) violations, but they cannot exchange instances of library types.

    Other inputs

    Reading from a std::istream is not affected by this macro; see JSON_DISABLE_STREAM_BULK_SCAN for that input.

    "},{"location":"api/macros/json_disable_unlocked_file_io/#examples","title":"Examples","text":"Example: parsing from a FILE* (default)

    The file is locked once while it is parsed:

    #include <cstdio>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    std::FILE* f = std::fopen(\"example.json\", \"rb\");\n    json j = json::parse(f);  // f is locked until parse() returns\n    std::fclose(f);\n}\n
    Example: locking for every character (macro defined to 1)

    With the macro, every character is read with std::fgetc, with the same result:

    #define JSON_DISABLE_UNLOCKED_FILE_IO 1\n#include <cstdio>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    std::FILE* f = std::fopen(\"example.json\", \"rb\");\n    json j = json::parse(f);  // std::fgetc for every character\n    std::fclose(f);\n}\n
    "},{"location":"api/macros/json_disable_unlocked_file_io/#see-also","title":"See also","text":"
    • parse - deserialize from a compatible input
    • sax_parse - generate SAX events
    • JSON_DISABLE_STREAM_BULK_SCAN - read a std::istream one character at a time
    • Parsing: input sources and performance - how input sources affect parsing performance
    • Large, Streamed, and Partial Input - chunked, concatenated, and very large input
    "},{"location":"api/macros/json_disable_unlocked_file_io/#version-history","title":"Version history","text":"
    • Added in version 3.13.0 unreleased.
    "},{"location":"api/macros/json_has_cpp_11/","title":"JSON_HAS_CPP_11, JSON_HAS_CPP_14, JSON_HAS_CPP_17, JSON_HAS_CPP_20, JSON_HAS_CPP_23, JSON_HAS_CPP_26","text":"
    #define JSON_HAS_CPP_11\n#define JSON_HAS_CPP_14\n#define JSON_HAS_CPP_17\n#define JSON_HAS_CPP_20\n#define JSON_HAS_CPP_23\n#define JSON_HAS_CPP_26\n

    The library targets C++11, but also supports some features introduced in later C++ versions (e.g., std::string_view support for C++17). For these new features, the library implements some preprocessor checks to determine the C++ standard. By defining any of these symbols, the internal check is overridden and the provided C++ version is unconditionally assumed. This can be helpful for compilers that only implement parts of the standard and would be detected incorrectly.

    "},{"location":"api/macros/json_has_cpp_11/#default-definition","title":"Default definition","text":"

    The default value is detected based on preprocessor macros such as __cplusplus, _HAS_CXX17, or _MSVC_LANG.

    "},{"location":"api/macros/json_has_cpp_11/#notes","title":"Notes","text":"
    • When the C++ standard is detected automatically, JSON_HAS_CPP_11 is always defined. When you override the detection by defining one of these macros manually, the automatic detection is skipped entirely, so you should define all applicable macros (including JSON_HAS_CPP_11) yourself.
    • All macros are undefined outside the library.
    "},{"location":"api/macros/json_has_cpp_11/#examples","title":"Examples","text":"Example

    The code below forces the library to use the C++14 standard:

    #define JSON_HAS_CPP_14 1\n#include <nlohmann/json.hpp>\n\n...\n
    "},{"location":"api/macros/json_has_cpp_11/#see-also","title":"See also","text":"
    • JSON_HAS_FILESYSTEM / JSON_HAS_EXPERIMENTAL_FILESYSTEM - control std::filesystem support
    • JSON_HAS_RANGES - control std::ranges support
    • JSON_HAS_THREE_WAY_COMPARISON - control 3-way comparison support
    • JSON_HAS_STD_FORMAT - control std::format/std::formatter support
    • Supported Macros - guide to all supported macros
    "},{"location":"api/macros/json_has_cpp_11/#version-history","title":"Version history","text":"
    • Added in version 3.10.0.
    • Added JSON_HAS_CPP_23 in version 3.12.0.
    • Added JSON_HAS_CPP_26 in version 3.13.0 unreleased.
    "},{"location":"api/macros/json_has_filesystem/","title":"JSON_HAS_FILESYSTEM / JSON_HAS_EXPERIMENTAL_FILESYSTEM","text":"
    #define JSON_HAS_FILESYSTEM /* value */\n#define JSON_HAS_EXPERIMENTAL_FILESYSTEM /* value */\n

    When compiling with C++17, the library provides conversions from and to std::filesystem::path. As compiler support for filesystem is limited, the library tries to detect whether <filesystem>/std::filesystem (JSON_HAS_FILESYSTEM) or <experimental/filesystem>/std::experimental::filesystem (JSON_HAS_EXPERIMENTAL_FILESYSTEM) should be used. To override the built-in check, define JSON_HAS_FILESYSTEM or JSON_HAS_EXPERIMENTAL_FILESYSTEM to 1.

    "},{"location":"api/macros/json_has_filesystem/#default-definition","title":"Default definition","text":"

    The default value is detected based on the preprocessor macros __cpp_lib_filesystem, __cpp_lib_experimental_filesystem, __has_include(<filesystem>), or __has_include(<experimental/filesystem>).

    Known compiler/stdlib exclusions

    Even when the feature-test macro indicates filesystem support is available, the library disables it on the following broken toolchains:

    • MinGW + GCC 8 \u2014 disabled entirely (broken std::filesystem implementation; MinGW-w64 bug 737)
    • GCC (non-Clang) < 8 \u2014 disabled (no filesystem support)
    • Clang < 7 \u2014 disabled (no filesystem support)
    • MSVC < 19.14 \u2014 disabled (no filesystem support)
    • iOS < 13 \u2014 disabled (no filesystem support)
    • macOS < Catalina (10.15) \u2014 disabled (no filesystem support)

    If JSON_HAS_FILESYSTEM or JSON_HAS_EXPERIMENTAL_FILESYSTEM is 0 despite __cpp_lib_filesystem being defined, one of the exclusions above likely applies to your toolchain.

    "},{"location":"api/macros/json_has_filesystem/#notes","title":"Notes","text":"
    • Note that older compilers or older versions of libstdc++ also require the library stdc++fs to be linked to for filesystem support.
    • Both macros are undefined outside the library.
    "},{"location":"api/macros/json_has_filesystem/#examples","title":"Examples","text":"Example

    The code below forces the library to use the header <experimental/filesystem>.

    #define JSON_HAS_EXPERIMENTAL_FILESYSTEM 1\n#include <nlohmann/json.hpp>\n\n...\n
    "},{"location":"api/macros/json_has_filesystem/#see-also","title":"See also","text":"
    • JSON_HAS_CPP_11 / JSON_HAS_CPP_14 / JSON_HAS_CPP_17 / JSON_HAS_CPP_20 / JSON_HAS_CPP_23 / JSON_HAS_CPP_26 - set supported C++ standard
    • Supported Macros - guide to all supported macros
    • Converting values - conversions of values
    "},{"location":"api/macros/json_has_filesystem/#version-history","title":"Version history","text":"
    • Added in version 3.10.5.
    "},{"location":"api/macros/json_has_range_view_conversion/","title":"JSON_HAS_RANGE_VIEW_CONVERSION","text":"
    #define JSON_HAS_RANGE_VIEW_CONVERSION /* value */\n

    This macro indicates whether a JSON array can be constructed directly from a C++20 range view (std::ranges::view), such as the result of std::views::filter or std::views::transform. Possible values are 1 when supported or 0 when unsupported.

    "},{"location":"api/macros/json_has_range_view_conversion/#default-definition","title":"Default definition","text":"

    The default value is 1 if JSON_HAS_RANGES is 1 and the compiler is not MinGW (that is, __MINGW32__ is not defined), and 0 otherwise.

    When the macro is not defined, the library will define it to its default value.

    Known compiler/stdlib exclusions

    • MinGW \u2014 disabled, because its std::ranges support is incomplete (issue #4916).
    • All toolchains for which JSON_HAS_RANGES is disabled.
    "},{"location":"api/macros/json_has_range_view_conversion/#examples","title":"Examples","text":"Example

    The code below forces the library to disable the conversion from range views:

    #define JSON_HAS_RANGE_VIEW_CONVERSION 0\n#include <nlohmann/json.hpp>\n\n...\n
    "},{"location":"api/macros/json_has_range_view_conversion/#see-also","title":"See also","text":"
    • JSON_HAS_RANGES - control std::ranges support
    • Constructing from a C++20 range view - usage of the feature
    "},{"location":"api/macros/json_has_range_view_conversion/#version-history","title":"Version history","text":"
    • Added in version 3.13.0 unreleased.
    "},{"location":"api/macros/json_has_ranges/","title":"JSON_HAS_RANGES","text":"
    #define JSON_HAS_RANGES /* value */\n

    This macro indicates whether the standard library has any support for ranges. Implies support for concepts. Possible values are 1 when supported or 0 when unsupported.

    "},{"location":"api/macros/json_has_ranges/#default-definition","title":"Default definition","text":"

    The default value is detected based on the preprocessor macro __cpp_lib_ranges.

    When the macro is not defined, the library will define it to its default value.

    Known compiler/stdlib exclusions

    Even when the feature-test macro __cpp_lib_ranges indicates ranges support is available, the library disables it on the following incomplete or broken toolchains:

    • GCC 11.1.0 \u2014 disabled (the shipped <ranges> header has a syntax error; issue #4440)
    • libstdc++ < 11 \u2014 disabled (incomplete C++20 ranges support; issue #4440)
    • Clang < 16 with libstdc++ \u2014 disabled (incomplete ranges support; issue #5161)
    • libc++ < 160000 \u2014 disabled (incomplete C++20 ranges support; issue #4440)
    • nvcc (CUDA) 12.0.x and 12.1.x \u2014 disabled (the enable_borrowed_range variable-template syntax triggers a parse error under these two toolkit versions; fixed in CUDA 12.2; issue #3907)

    If JSON_HAS_RANGES is 0 despite __cpp_lib_ranges being defined, one of the exclusions above likely applies to your toolchain.

    "},{"location":"api/macros/json_has_ranges/#examples","title":"Examples","text":"Example

    The code below forces the library to enable support for ranges:

    #define JSON_HAS_RANGES 1\n#include <nlohmann/json.hpp>\n\n...\n
    "},{"location":"api/macros/json_has_ranges/#see-also","title":"See also","text":"
    • JSON_HAS_CPP_11 / JSON_HAS_CPP_14 / JSON_HAS_CPP_17 / JSON_HAS_CPP_20 / JSON_HAS_CPP_23 / JSON_HAS_CPP_26 - set supported C++ standard
    • JSON_HAS_RANGE_VIEW_CONVERSION - control construction from std::ranges views
    • JSON_HAS_STD_FORMAT - a similar feature-detection macro, for std::format/std::formatter support
    • Supported Macros - guide to all supported macros
    "},{"location":"api/macros/json_has_ranges/#version-history","title":"Version history","text":"
    • Added in version 3.11.0.
    • Added the exclusions for libstdc++ < 11, Clang < 16 with libstdc++, libc++ < 16, and nvcc (CUDA) 12.0.x and 12.1.x in version 3.13.0 unreleased. Before, only GCC 11.1.0 was excluded.
    "},{"location":"api/macros/json_has_static_rtti/","title":"JSON_HAS_STATIC_RTTI","text":"
    #define JSON_HAS_STATIC_RTTI /* value */\n

    This macro indicates whether the standard library has any support for RTTI (run time type information). Possible values are 1 when supported or 0 when unsupported.

    "},{"location":"api/macros/json_has_static_rtti/#default-definition","title":"Default definition","text":"

    The default value is detected based on the preprocessor macro _HAS_STATIC_RTTI.

    When the macro is not defined, the library will define it to its default value.

    "},{"location":"api/macros/json_has_static_rtti/#examples","title":"Examples","text":"Example

    The code below forces the library to enable support for libraries with RTTI dependence:

    #define JSON_HAS_STATIC_RTTI 1\n#include <nlohmann/json.hpp>\n\n...\n
    "},{"location":"api/macros/json_has_static_rtti/#see-also","title":"See also","text":"
    • operator ValueType - get a value (implicit); on C++17, this macro controls whether std::any is excluded from its candidate types
    • Supported Macros - guide to all supported macros
    • Converting values - conversions of values
    "},{"location":"api/macros/json_has_static_rtti/#version-history","title":"Version history","text":"
    • Added in version 3.11.3.
    "},{"location":"api/macros/json_has_std_format/","title":"JSON_HAS_STD_FORMAT","text":"
    #define JSON_HAS_STD_FORMAT /* value */\n

    This macro indicates whether the standard library has support for std::format/std::formatter (that is, the <format> header). Possible values are 1 when supported or 0 when unsupported.

    "},{"location":"api/macros/json_has_std_format/#default-definition","title":"Default definition","text":"

    The default value is detected based on the preprocessor macros JSON_HAS_CPP_20 and __cpp_lib_format.

    When the macro is not defined, the library will define it to its default value.

    "},{"location":"api/macros/json_has_std_format/#notes","title":"Notes","text":"

    Enabled functionality

    When this macro evaluates to 1, the library provides a std::formatter<basic_json> specialization so JSON values can be used directly with std::format.

    "},{"location":"api/macros/json_has_std_format/#examples","title":"Examples","text":"Example

    The code below forces the library to disable support for std::format, even if the standard library would otherwise support it:

    #define JSON_HAS_STD_FORMAT 0\n#include <nlohmann/json.hpp>\n\n...\n
    "},{"location":"api/macros/json_has_std_format/#see-also","title":"See also","text":"
    • std::formatter<basic_json> - format JSON values with std::format
    • Supported Macros - guide to all supported macros
    • Serialization - serialize values to text
    "},{"location":"api/macros/json_has_std_format/#version-history","title":"Version history","text":"
    • Added in version 3.13.0 unreleased.
    "},{"location":"api/macros/json_has_three_way_comparison/","title":"JSON_HAS_THREE_WAY_COMPARISON","text":"
    #define JSON_HAS_THREE_WAY_COMPARISON /* value */\n

    This macro indicates whether the compiler and standard library support 3-way comparison. Possible values are 1 when supported or 0 when unsupported.

    "},{"location":"api/macros/json_has_three_way_comparison/#default-definition","title":"Default definition","text":"

    The default value is detected based on the preprocessor macros __cpp_impl_three_way_comparison and __cpp_lib_three_way_comparison.

    When the macro is not defined, the library will define it to its default value.

    "},{"location":"api/macros/json_has_three_way_comparison/#examples","title":"Examples","text":"Example

    The code below forces the library to use 3-way comparison:

    #define JSON_HAS_THREE_WAY_COMPARISON 1\n#include <nlohmann/json.hpp>\n\n...\n
    "},{"location":"api/macros/json_has_three_way_comparison/#see-also","title":"See also","text":"
    • operator<=> - 3-way compare JSON values
    • operator== - compare JSON pointers for equality
    "},{"location":"api/macros/json_has_three_way_comparison/#version-history","title":"Version history","text":"
    • Added in version 3.11.0.
    "},{"location":"api/macros/json_no_automatic_udls/","title":"JSON_NO_AUTOMATIC_UDLS","text":"
    #define JSON_NO_AUTOMATIC_UDLS\n

    When defined, <nlohmann/json.hpp> does not include <nlohmann/json_literals.hpp>, so the user-defined string literals operator\"\"_json and operator\"\"_json_pointer are not declared. Include <nlohmann/json_literals.hpp> in the files that use them.

    The literals are ordinary inline functions whose bodies call the parser, so every translation unit that includes them instantiates the parser \u2014 even if it never parses anything itself. Defining JSON_NO_AUTOMATIC_UDLS for a whole project avoids this cost in translation units that do not parse (e.g., ones that only define types and conversions or pass json values around) and reduces their compile time.

    "},{"location":"api/macros/json_no_automatic_udls/#default-definition","title":"Default definition","text":"

    By default, JSON_NO_AUTOMATIC_UDLS is not defined, and <nlohmann/json.hpp> includes <nlohmann/json_literals.hpp>.

    #undef JSON_NO_AUTOMATIC_UDLS\n
    "},{"location":"api/macros/json_no_automatic_udls/#notes","title":"Notes","text":"

    Header <nlohmann/json_literals.hpp>

    The header includes <nlohmann/json.hpp> itself and places the literals according to JSON_USE_GLOBAL_UDLS. It is part of the multi-header sources (include/nlohmann) and of the single-header sources (single_include/nlohmann), next to json.hpp.

    C++ modules

    The nlohmann.json module always exports the literals, regardless of this macro.

    "},{"location":"api/macros/json_no_automatic_udls/#examples","title":"Examples","text":"Example

    The code below includes the library without the literals and adds them in a single translation unit.

    // compiled with -DJSON_NO_AUTOMATIC_UDLS for the whole project\n\n// this file uses the literals, so it includes them explicitly\n// (the header includes <nlohmann/json.hpp> itself)\n#include <nlohmann/json_literals.hpp>\n\nint main()\n{\n    auto j = R\"({\"foo\": 42})\"_json;\n    return j.at(\"/foo\"_json_pointer) == 42 ? 0 : 1;\n}\n

    Without the include of <nlohmann/json_literals.hpp>, the code would fail to compile.

    "},{"location":"api/macros/json_no_automatic_udls/#see-also","title":"See also","text":"
    • operator\"\"_json - user-defined string literal for JSON values
    • operator\"\"_json_pointer - user-defined string literal for JSON pointers
    • JSON_USE_GLOBAL_UDLS - place user-defined string literals (UDLs) into the global namespace
    • Compile times - options to reduce compile times
    • Creating JSON values - the article on creating JSON values
    "},{"location":"api/macros/json_no_automatic_udls/#version-history","title":"Version history","text":"
    • Added in version 3.13.0 unreleased.
    "},{"location":"api/macros/json_no_io/","title":"JSON_NO_IO","text":"
    #define JSON_NO_IO\n

    When defined, headers <cstdio>, <ios>, <iosfwd>, <istream>, and <ostream> are not included and parse functions relying on these headers are excluded. This is relevant for environments where these I/O functions are disallowed for security reasons (e.g., Intel Software Guard Extensions (SGX)).

    "},{"location":"api/macros/json_no_io/#default-definition","title":"Default definition","text":"

    By default, JSON_NO_IO is not defined.

    #undef JSON_NO_IO\n
    "},{"location":"api/macros/json_no_io/#examples","title":"Examples","text":"Example

    The code below forces the library not to use the headers <cstdio>, <ios>, <iosfwd>, <istream>, and <ostream>.

    #define JSON_NO_IO 1\n#include <nlohmann/json.hpp>\n\n...\n
    "},{"location":"api/macros/json_no_io/#see-also","title":"See also","text":"
    • operator<< - serialize to stream
    • operator>> - deserialize from stream
    • Serialization - pretty-printing, UTF-8 handling, and number output
    • Parsing - overview of the parsing functions
    "},{"location":"api/macros/json_no_io/#version-history","title":"Version history","text":"
    • Added in version 3.10.0.
    "},{"location":"api/macros/json_no_simd/","title":"JSON_NO_SIMD","text":"
    #define JSON_NO_SIMD\n

    When defined, the library uses only portable C++ code where it would otherwise use vector instructions: when scanning strings during parsing, and when writing floating-point numbers during serialization. This includes the parser of basic_json_document (<nlohmann/json_view.hpp>).

    The macro is an escape hatch, for example for toolchains that cannot compile the vector code, for sanitizers or analyzers that do not understand it, or to compare the speed of both variants. It does not change any result: values, exceptions, and error positions are the same either way. Only the speed differs.

    "},{"location":"api/macros/json_no_simd/#default-definition","title":"Default definition","text":"

    By default, JSON_NO_SIMD is not defined, and vector instructions are used where the target has them.

    #undef JSON_NO_SIMD\n
    "},{"location":"api/macros/json_no_simd/#notes","title":"Notes","text":"

    Which instructions are used

    • x86-64: SSE2, which every x86-64 CPU has, finds the end of runs of plain string characters 16 bytes at a time and writes the digits of floating-point numbers. The UTF-8 check of non-ASCII text needs SSSE3, which is not part of x86-64: it is compiled for SSSE3 with a function attribute and used when the CPU has SSSE3 (every x86-64 CPU since about 2011), else the portable check. Code compiled for SSSE3 anyway (e.g., with -mssse3 or -march=native) skips this check of the CPU. 32-bit x86 uses SSE2 for strings when the compiler targets it.
    • AArch64: NEON, which every 64-bit Arm CPU has, checks UTF-8 text and long runs of plain string characters 16 bytes at a time, and writes the digits of floating-point numbers. With MSVC, only the floating-point digits use NEON.
    • Other targets: portable code only.

    Strings are only scanned this way for contiguous input and for the characters a std::istream holds in its stream buffer (see JSON_DISABLE_STREAM_BULK_SCAN); other inputs are read one character at a time.

    Interaction with JSON_USE_SIMDUTF

    With JSON_USE_SIMDUTF, runs of string characters are first validated by simdutf; the code described here is used for what simdutf does not accept, so that errors are reported at the same position. JSON_NO_SIMD does not affect simdutf.

    ABI compatibility

    The macro selects between two definitions of the library's internal scanning and formatting functions. Whether it is defined is encoded in the namespace (tag _ns), resulting in distinct symbol names. Translation units compiled with and without it can therefore be linked into the same program without One Definition Rule (ODR) violations, but they cannot exchange instances of library types.

    "},{"location":"api/macros/json_no_simd/#examples","title":"Examples","text":"Example: switching off vector instructions

    The program parses and serializes the same values with and without the macro:

    #define JSON_NO_SIMD\n#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    const json j = json::parse(R\"({\"name\": \"\u65e5\u672c\u8a9e text\", \"pi\": 3.141592653589793})\");\n    std::cout << j.dump() << '\\n';  // {\"name\":\"\u65e5\u672c\u8a9e text\",\"pi\":3.141592653589793}\n}\n
    "},{"location":"api/macros/json_no_simd/#see-also","title":"See also","text":"
    • parse - deserialize from a compatible input
    • dump - serialization
    • JSON_USE_SIMDUTF - use the simdutf library to accelerate UTF-8 validation
    • JSON_DISABLE_STREAM_BULK_SCAN - read a std::istream one character at a time
    • Parsing: input sources and performance - how input sources affect parsing performance
    • Serialization - pretty-printing, UTF-8 handling, and number output
    • Zero-copy JSON views - the zero-copy view, whose parser the macro also affects
    "},{"location":"api/macros/json_no_simd/#version-history","title":"Version history","text":"
    • Added in version 3.13.0 unreleased.
    "},{"location":"api/macros/json_no_thread_local/","title":"JSON_NO_THREAD_LOCAL","text":"
    #define JSON_NO_THREAD_LOCAL\n

    When defined, the library does not use thread_local storage. This is relevant for the few environments whose toolchain does not support it.

    Copying a value and comparing two values both descend into the first levels by letting the containers copy or compare themselves, and finish whatever is nested deeper than that without the call stack, so that neither can exhaust the stack however deeply the values are nested. Each counts the levels it has descended into in a thread_local variable, as a counter shared between threads would be raced.

    Without those counters, no descent can be bounded safely, so objects and arrays are copied and compared without the call stack right away. Both keep working exactly as they do otherwise - the same values come out, the same comparisons hold, and deeply nested values are handled just as safely - but both are slower, because the containers no longer copy or compare themselves. Copying the benchmark documents takes 9% (canada.json) to 34% (twitter.json) longer, and comparing two equal ones 10% (citm_catalog.json) to 90% (canada.json) longer.

    "},{"location":"api/macros/json_no_thread_local/#default-definition","title":"Default definition","text":"

    By default, JSON_NO_THREAD_LOCAL is not defined.

    #undef JSON_NO_THREAD_LOCAL\n

    The library defines it by itself for Clang targeting MinGW, which does not survive the thread_local storage: copying a value segfaults there, with both old and current Clang versions, while GCC targeting MinGW is unaffected. Copying and comparing fall back to working without the call stack there, as they do whenever the macro is defined.

    "},{"location":"api/macros/json_no_thread_local/#examples","title":"Examples","text":"Example

    The code below forces the library not to use thread_local storage.

    #define JSON_NO_THREAD_LOCAL 1\n#include <nlohmann/json.hpp>\n\n...\n
    "},{"location":"api/macros/json_no_thread_local/#see-also","title":"See also","text":"
    • FAQ: Thread safety - thread-safety guarantees of the library
    • Supported Macros - guide to all supported macros
    "},{"location":"api/macros/json_no_thread_local/#version-history","title":"Version history","text":"
    • Added in version 3.13.0 unreleased.
    "},{"location":"api/macros/json_noexception/","title":"JSON_NOEXCEPTION","text":"
    #define JSON_NOEXCEPTION\n

    Exceptions can be switched off by defining the symbol JSON_NOEXCEPTION. When defining JSON_NOEXCEPTION, try is replaced by if (true), catch is replaced by if (false), and throw is replaced by std::abort().

    The same effect is achieved by setting the compiler flag -fno-exceptions.

    "},{"location":"api/macros/json_noexception/#default-definition","title":"Default definition","text":"

    By default, the macro is not defined.

    #undef JSON_NOEXCEPTION\n
    "},{"location":"api/macros/json_noexception/#notes","title":"Notes","text":"

    The explanatory what() string of exceptions is not available for MSVC if exceptions are disabled, see #2824.

    "},{"location":"api/macros/json_noexception/#examples","title":"Examples","text":"Example

    The code below switches off exceptions in the library.

    #define JSON_NOEXCEPTION 1\n#include <nlohmann/json.hpp>\n\n...\n
    "},{"location":"api/macros/json_noexception/#see-also","title":"See also","text":"
    • Switch off exceptions - more information how to switch off exceptions
    • Supported Macros - guide to all supported macros
    • Working Without Exceptions - using the library without exceptions
    • Exceptions - all exceptions and their error codes
    • exception - base class of all exceptions thrown by the library
    "},{"location":"api/macros/json_noexception/#version-history","title":"Version history","text":"

    Added in version 2.1.0.

    "},{"location":"api/macros/json_precise_stream_position/","title":"JSON_PRECISE_STREAM_POSITION","text":"
    #define JSON_PRECISE_STREAM_POSITION /* value */\n

    When defined to 1, operator>> and sax_parse with strict = false leave a std::istream positioned right after the parsed value for every value type. By default, the character that terminates a number is consumed as well.

    The macro only affects reading from a std::istream when the rest of the stream is not required to be consumed. parse, accept, and all other inputs (strings, iterators, containers, FILE*) are never affected.

    "},{"location":"api/macros/json_precise_stream_position/#default-definition","title":"Default definition","text":"

    The default value is 0 (disabled \u2014 existing behavior is preserved).

    #define JSON_PRECISE_STREAM_POSITION 0\n
    "},{"location":"api/macros/json_precise_stream_position/#notes","title":"Notes","text":"

    Background

    A number is the only JSON value whose end can be detected solely by reading the character that follows it. By default, that character is consumed and not put back, so the stream is left one byte too far after a number, and only after a number:

    std::istringstream input(\"1true\");\njson j;\ninput >> j;  // j == 1, but the stream now starts at \"rue\"\n

    With this macro, the character is only looked at and left in the stream, so the stream starts at true. This does not require the stream buffer to support putting a character back.

    This was not changed unconditionally, because code can depend on the consumed character, even unknowingly (see #5340). Both of the following work by default only because the character after each number is swallowed, and behave differently with this macro:

    std::istringstream input(\"1,2,3\");\njson j1, j2, j3;\ninput >> j1 >> j2 >> j3;  // default: 1, 2, 3\n                          // with the macro: throws parse_error.101 at the ','\n
    std::istringstream input(\"42\\nfoo\");\njson j;\nstd::string line;\ninput >> j;\nstd::getline(input, line);  // default: \"foo\"\n                            // with the macro: \"\" (like after reading an int with >>)\n

    In both cases, the behavior with the macro is what you already get today when the value is not a number: \"a\",\"b\" fails at the ,, and std::getline after {} returns an empty string. This macro offers an opt-in path to the consistent behavior ahead of version 4.0.0, where it is planned to become the default.

    Opt-in only

    This macro must be defined before including <nlohmann/json.hpp>. Defining it after the include has no effect.

    ABI compatibility

    The value of this macro is encoded in the namespace (tag _psp), resulting in distinct symbol names. Translation units compiled with and without it can therefore be linked into the same program without One Definition Rule (ODR) violations, but they cannot exchange instances of library types.

    Bulk scanning

    The parser scans the characters in the stream buffer in bulk (see JSON_DISABLE_STREAM_BULK_SCAN), but it never reads ahead. The stream is left at the same position with and without bulk scanning, in both modes of this macro.

    Workaround without the macro

    Separate the values in the stream with whitespace. The character consumed after a number is then the separator, and whitespace before the next value is skipped anyway.

    "},{"location":"api/macros/json_precise_stream_position/#examples","title":"Examples","text":"Example: default behavior (macro not defined)

    Without the macro, the character after a number is consumed:

    #include <iostream>\n#include <sstream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    std::istringstream input(\"1true\");\n    json j1, j2;\n    input >> j1;  // j1 == 1\n    input >> j2;  // throws parse_error.101: the stream now starts at \"rue\"\n}\n
    Example: opt-in precise stream position (macro defined to 1)

    With the macro, the stream is positioned right after the number:

    #define JSON_PRECISE_STREAM_POSITION 1\n#include <iostream>\n#include <sstream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    std::istringstream input(\"1true\");\n    json j1, j2;\n    input >> j1;  // j1 == 1\n    input >> j2;  // j2 == true\n}\n
    "},{"location":"api/macros/json_precise_stream_position/#see-also","title":"See also","text":"
    • operator>> - deserialize from stream
    • sax_parse - generate SAX events
    • Large, Streamed, and Partial Input - chunked, concatenated, and very large input
    "},{"location":"api/macros/json_precise_stream_position/#version-history","title":"Version history","text":"
    • Added in version 3.13.0 unreleased.
    • Planned to become the default (with the macro removed) in version 4.0.0.
    "},{"location":"api/macros/json_skip_library_version_check/","title":"JSON_SKIP_LIBRARY_VERSION_CHECK","text":"
    #define JSON_SKIP_LIBRARY_VERSION_CHECK\n

    When defined, the library will not create a compiler warning when a different version of the library was already included.

    "},{"location":"api/macros/json_skip_library_version_check/#default-definition","title":"Default definition","text":"

    By default, the macro is not defined.

    #undef JSON_SKIP_LIBRARY_VERSION_CHECK\n
    "},{"location":"api/macros/json_skip_library_version_check/#notes","title":"Notes","text":"

    ABI compatibility

    Mixing different library versions in the same code can be a problem as the different versions may not be ABI compatible.

    "},{"location":"api/macros/json_skip_library_version_check/#examples","title":"Examples","text":"Example: switch off the version check

    The code below switches off the warning about including a different version of the library.

    #define JSON_SKIP_LIBRARY_VERSION_CHECK 1\n#include <nlohmann/json.hpp>\n\n...\n
    Example: warning about a different library version

    The following warning will be shown in case a different version of the library was already included:

    Already included a different version of the library!\n
    "},{"location":"api/macros/json_skip_library_version_check/#see-also","title":"See also","text":"
    • NLOHMANN_JSON_VERSION_MAJOR / NLOHMANN_JSON_VERSION_MINOR / NLOHMANN_JSON_VERSION_PATCH - library version information
    • Supported Macros - guide to all supported macros
    • Integration - integrate the library
    "},{"location":"api/macros/json_skip_library_version_check/#version-history","title":"Version history","text":"
    • Added in version 3.11.0.
    "},{"location":"api/macros/json_skip_unsupported_compiler_check/","title":"JSON_SKIP_UNSUPPORTED_COMPILER_CHECK","text":"
    #define JSON_SKIP_UNSUPPORTED_COMPILER_CHECK\n

    When defined, the library will not create a compile error when a known unsupported compiler is detected. This allows using the library with compilers that do not fully support C++11 and may only work if unsupported features are not used.

    "},{"location":"api/macros/json_skip_unsupported_compiler_check/#default-definition","title":"Default definition","text":"

    By default, the macro is not defined.

    #undef JSON_SKIP_UNSUPPORTED_COMPILER_CHECK\n
    "},{"location":"api/macros/json_skip_unsupported_compiler_check/#examples","title":"Examples","text":"Example

    The code below switches off the check whether the compiler is supported.

    #define JSON_SKIP_UNSUPPORTED_COMPILER_CHECK 1\n#include <nlohmann/json.hpp>\n\n...\n
    "},{"location":"api/macros/json_skip_unsupported_compiler_check/#see-also","title":"See also","text":"
    • JSON_HAS_CPP_11 / JSON_HAS_CPP_14 / JSON_HAS_CPP_17 / JSON_HAS_CPP_20 / JSON_HAS_CPP_23 / JSON_HAS_CPP_26 - set supported C++ standard
    • Supported Macros - guide to all supported macros
    • Integration - integrate the library
    "},{"location":"api/macros/json_skip_unsupported_compiler_check/#version-history","title":"Version history","text":"
    • Added in version 3.2.0.
    "},{"location":"api/macros/json_strict_binary_utf8/","title":"JSON_STRICT_BINARY_UTF8","text":"
    #define JSON_STRICT_BINARY_UTF8 /* value */\n

    When defined to 1, the error_handler parameter of the binary writers to_cbor, to_ubjson, to_bjdata, and to_bson defaults to error_handler_t::strict instead of error_handler_t::keep. These writers then check every string value and object key for valid UTF-8 and throw type_error.316 for ill-formed UTF-8, like dump does. Without it, they write the bytes unchanged. An error_handler passed explicitly always takes precedence.

    The macro does not affect:

    • to_msgpack: the MessagePack specification allows a str value to contain bytes that are not valid UTF-8, so its error_handler always defaults to keep.
    • to_bon8: BON8 always checks, because the UTF-8 lead bytes mark where a string ends.
    • The binary readers (from_cbor, from_msgpack, from_ubjson, from_bjdata, from_bson): none of these formats requires a decoder to reject ill-formed UTF-8, so by default they return the bytes unchanged (error_handler_t::keep), independent of this macro. Pass an error_handler argument explicitly to validate or sanitize the strings they read.
    • from_bon8: BON8 always validates, because the UTF-8 lead bytes mark where a string ends.
    "},{"location":"api/macros/json_strict_binary_utf8/#default-definition","title":"Default definition","text":"

    The default value is 0 (disabled, the behavior of version 3.12.0 and earlier is preserved).

    #define JSON_STRICT_BINARY_UTF8 0\n
    "},{"location":"api/macros/json_strict_binary_utf8/#notes","title":"Notes","text":"

    Background

    CBOR, UBJSON, BJData, and BSON all require strings to be UTF-8. Up to version 3.12.0, the writers did not check this, so they could produce output that other decoders reject. Checking by default would break code that stores other encodings (for instance ISO 8859-1) in a string and only ever writes it to a binary format. You can pass error_handler_t::strict to each call, or use this macro to check by default ahead of version 4.0.0, where strict is planned to become the default (see #5529 and #5651).

    Opt-in only

    This macro must be defined before including <nlohmann/json.hpp>. Defining it after the include has no effect.

    ABI compatibility

    The value of this macro is encoded in the namespace (tag _sbu8), resulting in distinct symbol names. Translation units compiled with and without it can therefore be linked into the same program without One Definition Rule (ODR) violations, but they cannot exchange instances of library types.

    "},{"location":"api/macros/json_strict_binary_utf8/#examples","title":"Examples","text":"Example: default behavior (macro not defined)

    Without the macro, the bytes are written unchanged:

    #include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    auto v = json::to_cbor(json(\"\\xFF\"));\n    // v is {0x61, 0xFF}\n}\n
    Example: opt-in check (macro defined to 1)

    With the macro, ill-formed UTF-8 is rejected:

    #define JSON_STRICT_BINARY_UTF8 1\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    auto v = json::to_cbor(json(\"\\xFF\"));\n    // throws type_error.316: invalid UTF-8 byte at index 0: 0xFF\n}\n
    "},{"location":"api/macros/json_strict_binary_utf8/#see-also","title":"See also","text":"
    • Binary formats - overview of the supported binary formats
    • from_cbor - also affected when parsing CBOR strings
    • to_cbor - create a CBOR serialization of a JSON value
    • to_ubjson - create a UBJSON serialization of a JSON value
    • to_bjdata - create a BJData serialization of a JSON value
    • to_bson - create a BSON serialization of a JSON value
    • error_handler_t - how dump treats ill-formed UTF-8
    "},{"location":"api/macros/json_strict_binary_utf8/#version-history","title":"Version history","text":"
    • Added in version 3.13.0 unreleased.
    • Planned to become the default (with the macro removed) in version 4.0.0.
    "},{"location":"api/macros/json_strict_nul_handling/","title":"JSON_STRICT_NUL_HANDLING","text":"
    #define JSON_STRICT_NUL_HANDLING /* value */\n

    When defined to 1, a '\\0' (NUL) byte in JSON text input is rejected with parse_error.101, like any other unexpected byte, instead of being silently treated as end of input.

    The macro only affects the JSON text parser (parse, accept, sax_parse, and operator>>). There are three cases where a NUL byte is still not rejected:

    • The binary formats (from_bjdata, from_bon8, from_bson, from_cbor, from_msgpack, from_ubjson) are never affected: there, 0x00 is ordinary data.
    • A bare const char* pointer has no length of its own, so its length is still determined with strlen(). The first NUL byte therefore still marks the end of the input, and nothing after it is read.
    • One trailing '\\0' at the end of a char, wchar_t, char16_t, char32_t, or (C++20) char8_t array (e.g., a string literal) is trimmed; see the warning below.
    "},{"location":"api/macros/json_strict_nul_handling/#default-definition","title":"Default definition","text":"

    The default value is 0 (disabled \u2014 existing behavior is preserved).

    #define JSON_STRICT_NUL_HANDLING 0\n
    "},{"location":"api/macros/json_strict_nul_handling/#notes","title":"Notes","text":"

    Background

    By default, a '\\0' byte anywhere in the input is treated the same as the real end of the input, rather than as an ordinary (and, outside of a string, invalid) byte. Everything from that byte onward is silently ignored, without a parse error - including further, otherwise well-formed JSON:

    json::parse(std::string(\"123\") + '\\0');          // == 123, no error\njson::parse(std::string(\"123\") + '\\0' + \"true\"); // == 123, the \"true\" is silently ignored too\n

    This falls out of the same convention used when no explicit input length is given at all: parsing from a const char* already stops at the first NUL byte via strlen(), since a bare pointer has no length of its own. The library applies that same NUL-terminated-C-string convention uniformly, rather than only when a length is genuinely unavailable - so a std::string, iterator range, or container whose content happens to include a NUL byte is affected the same way a raw const char* would be (see the FAQ entry for a fuller explanation).

    This was not fixed unconditionally, because doing so is backwards-incompatible for any caller who happens to depend on the current behavior - even unknowingly, for instance because their input already contains trailing padding they never noticed was being discarded (see #5530). This macro instead offers an opt-in path to the corrected behavior ahead of version 4.0.0, where it is planned to become the default.

    Opt-in only

    This macro must be defined before including <nlohmann/json.hpp>. Defining it after the include has no effect.

    Enabling it also changes how an array of a text-literal element type (char, wchar_t, char16_t, char32_t, or, since C++20, char8_t - including a string literal, e.g. json::parse(\"123\") or json::parse(L\"123\")) is read: such an array normally carries a trailing '\\0' contributed by the compiler, not by the source text. With this macro enabled, that one trailing element is trimmed if present so that parsing a string literal keeps working, for any of these character types; every other element in the array - including any '\\0' that is not the very last element - is read as real data and rejected like any other unexpected byte. Arrays of any other element type (unsigned char, std::uint8_t, ...), as used for CBOR or MessagePack, are never affected by this trimming; their full extent - including a genuine trailing 0x00 - is always preserved, in both states of this macro.

    ABI compatibility

    The value of this macro is encoded in the namespace (tag _snul), resulting in distinct symbol names. Translation units compiled with and without it can therefore be linked into the same program without One Definition Rule (ODR) violations, but they cannot exchange instances of library types.

    Workaround without the macro

    To reject a NUL byte without enabling this macro, trim your input yourself before calling parse():

    s.resize(s.find('\\0')); // drop everything from the first NUL onward, if any\njson::parse(s);\n
    "},{"location":"api/macros/json_strict_nul_handling/#examples","title":"Examples","text":"Example: default behavior (macro not defined)

    Without the macro, a NUL byte silently ends parsing at that point:

    #include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    json j = json::parse(std::string(\"123\") + '\\0' + \"true\");\n    // j is 123 -- the '\\0' and everything after it is silently ignored\n}\n
    Example: opt-in strict handling (macro defined to 1)

    With the macro, a NUL byte is rejected like any other unexpected byte:

    #define JSON_STRICT_NUL_HANDLING 1\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    json j = json::parse(std::string(\"123\") + '\\0' + \"true\");\n    // throws parse_error.101 -- the NUL byte is now invalid input,\n    // exactly like any other unexpected trailing byte\n\n    json ok = json::parse(\"123\");\n    // ok is 123 -- parsing from a string literal still works\n}\n
    "},{"location":"api/macros/json_strict_nul_handling/#see-also","title":"See also","text":"
    • JSON_StrictNulHandling - CMake option to control the macro
    • FAQ: NUL bytes in the input - how NUL bytes in the input are handled
    • parse - deserialize from a compatible input
    • accept - check if the input is valid JSON
    • operator>> - deserialize from stream
    • Parsing Untrusted Input - limits and checks for input you do not control
    "},{"location":"api/macros/json_strict_nul_handling/#version-history","title":"Version history","text":"
    • Added in version 3.13.0 unreleased.
    • Planned to become the default (with the macro removed) in version 4.0.0.
    "},{"location":"api/macros/json_throw_user/","title":"JSON_CATCH_USER, JSON_THROW_USER, JSON_TRY_USER","text":"
    // (1)\n#define JSON_CATCH_USER(exception) /* value */\n// (2)\n#define JSON_THROW_USER(exception) /* value */\n// (3)\n#define JSON_TRY_USER /* value */\n

    Controls how exceptions are handled by the library.

    1. This macro overrides catch calls inside the library. The argument is the type of the exception to catch. The library uses it in a single place: to swallow any exception escaping the parent-pointer check that JSON_DIAGNOSTICS adds to the class invariant. The places where the library catches its own json::out_of_range exceptions use JSON_INTERNAL_CATCH instead, which JSON_CATCH_USER also overrides unless JSON_INTERNAL_CATCH_USER is defined. The macro is always followed by a scope.
    2. This macro overrides throw calls inside the library. The argument is the exception to be thrown. Note that JSON_THROW_USER should leave the current scope (e.g., by throwing or aborting), as continuing after it may yield undefined behavior.
    3. This macro overrides try calls inside the library. It has no arguments and is always followed by a scope.
    "},{"location":"api/macros/json_throw_user/#parameters","title":"Parameters","text":"exception (in) an exception type"},{"location":"api/macros/json_throw_user/#default-definition","title":"Default definition","text":"

    By default, the macros map to their respective C++ keywords:

    #define JSON_CATCH_USER(exception) catch(exception)\n#define JSON_THROW_USER(exception) throw exception\n#define JSON_TRY_USER              try\n

    When exceptions are switched off, the try block is executed unconditionally, and throwing exceptions is replaced by calling std::abort to make reaching the throw branch abort the process.

    #define JSON_THROW_USER(exception) std::abort()\n#define JSON_TRY_USER              if (true)\n#define JSON_CATCH_USER(exception) if (false)\n
    "},{"location":"api/macros/json_throw_user/#examples","title":"Examples","text":"Example

    The code below switches off exceptions and creates a log entry with a detailed error message in case of errors.

    #include <iostream>\n\n#define JSON_TRY_USER if(true)\n#define JSON_CATCH_USER(exception) if(false)\n#define JSON_THROW_USER(exception)                           \\\n    {std::clog << \"Error in \" << __FILE__ << \":\" << __LINE__ \\\n               << \" (function \" << __FUNCTION__ << \") - \"    \\\n               << (exception).what() << std::endl;           \\\n     std::abort();}\n\n#include <nlohmann/json.hpp>\n
    "},{"location":"api/macros/json_throw_user/#see-also","title":"See also","text":"
    • Switch off exceptions - more information how to switch off exceptions
    • JSON_NOEXCEPTION - switch off exceptions
    • Supported Macros - guide to all supported macros
    • Working Without Exceptions - using the library without exceptions
    • exception - base class of all exceptions thrown by the library
    "},{"location":"api/macros/json_throw_user/#version-history","title":"Version history","text":"
    • Added in version 3.1.0.
    "},{"location":"api/macros/json_use_global_udls/","title":"JSON_USE_GLOBAL_UDLS","text":"
    #define JSON_USE_GLOBAL_UDLS /* value */\n

    When defined to 1, the user-defined string literals (UDLs) are placed into the global namespace instead of nlohmann::literals::json_literals.

    "},{"location":"api/macros/json_use_global_udls/#default-definition","title":"Default definition","text":"

    The default value is 1.

    #define JSON_USE_GLOBAL_UDLS 1\n

    When the macro is not defined, the library behaves as if it were defined to its default value.

    "},{"location":"api/macros/json_use_global_udls/#notes","title":"Notes","text":"

    Future behavior change

    The user-defined string literals will be removed from the global namespace in the next major release of the library.

    To prepare existing code, define JSON_USE_GLOBAL_UDLS to 0 and bring the string literals into scope where needed. Refer to any of the string literals for details.

    See the migration guide for how to update existing code.

    CMake option

    The placement of user-defined string literals can also be controlled with the CMake option JSON_GlobalUDLs (ON by default) which defines JSON_USE_GLOBAL_UDLS accordingly.

    Leaving out the literals

    If JSON_NO_AUTOMATIC_UDLS is defined, the literals are only declared where <nlohmann/json_literals.hpp> is included; this macro then applies to that header.

    "},{"location":"api/macros/json_use_global_udls/#examples","title":"Examples","text":"Example: Default behavior

    The code below shows the default behavior using the _json UDL.

    #include <nlohmann/json.hpp>\n\n#include <iostream>\n\nint main()\n{\n    auto j = \"42\"_json;\n\n    std::cout << j << std::endl;\n}\n

    Output:

    42\n
    Example: Namespaced UDLs

    The code below shows how UDLs need to be brought into scope before using _json when JSON_USE_GLOBAL_UDLS is defined to 0.

    #define JSON_USE_GLOBAL_UDLS 0\n#include <nlohmann/json.hpp>\n\n#include <iostream>\n\nint main()\n{\n    // auto j = \"42\"_json; // This line would fail to compile,\n                           // because the UDLs are not in the global namespace\n\n    // Bring the UDLs into scope\n    using namespace nlohmann::json_literals;\n\n    auto j = \"42\"_json;\n\n    std::cout << j << std::endl;\n}\n

    Output:

    42\n
    "},{"location":"api/macros/json_use_global_udls/#see-also","title":"See also","text":"
    • operator\"\"_json - user-defined string literal for JSON values
    • operator\"\"_json_pointer - user-defined string literal for JSON pointers
    • JSON_NO_AUTOMATIC_UDLS - do not include the user-defined string literals automatically
    • JSON_GlobalUDLs - CMake option to control the macro
    • Creating JSON values - the article on creating JSON values
    "},{"location":"api/macros/json_use_global_udls/#version-history","title":"Version history","text":"
    • Added in version 3.11.0.
    "},{"location":"api/macros/json_use_implicit_conversions/","title":"JSON_USE_IMPLICIT_CONVERSIONS","text":"
    #define JSON_USE_IMPLICIT_CONVERSIONS /* value */\n

    When defined to 0, implicit conversions are switched off. By default, implicit conversions are switched on. The value directly affects operator ValueType and the converting constructor from a basic_json specialization with a different string type (overload 4).

    "},{"location":"api/macros/json_use_implicit_conversions/#default-definition","title":"Default definition","text":"

    By default, implicit conversions are enabled.

    #define JSON_USE_IMPLICIT_CONVERSIONS 1\n
    "},{"location":"api/macros/json_use_implicit_conversions/#notes","title":"Notes","text":"

    Future behavior change

    Implicit conversions will be switched off by default in the next major release of the library.

    You can prepare existing code by already defining JSON_USE_IMPLICIT_CONVERSIONS to 0 and replace any implicit conversions with calls to get.

    See the migration guide for how to update existing code.

    Automatic migration

    The community-maintained clang-tidy check modernize-nlohmann-json-explicit-conversions rewrites implicit conversions into explicit calls to get; for example, int i = j; becomes int i = j.get<int>();. The check is not part of clang-tidy itself, and it does not catch every case (for example, constructing a std::optional from a JSON value), so review the result. See discussion #4610 for how to build and use it.

    CMake option

    Implicit conversions can also be controlled with the CMake option JSON_ImplicitConversions (ON by default) which defines JSON_USE_IMPLICIT_CONVERSIONS accordingly.

    "},{"location":"api/macros/json_use_implicit_conversions/#examples","title":"Examples","text":"Example: implicit and explicit conversions

    This is an example for an implicit conversion:

    json j = \"Hello, world!\";\nstd::string s = j;\n

    When JSON_USE_IMPLICIT_CONVERSIONS is defined to 0, the code above does no longer compile. Instead, it must be written like this:

    json j = \"Hello, world!\";\nauto s = j.get<std::string>();\n
    Example: conversion between basic_json specializations

    A basic_json specialization with a different string type is also no longer converted implicitly when JSON_USE_IMPLICIT_CONVERSIONS is defined to 0:

    using wjson = nlohmann::json::with_string_t<std::wstring>;\n\nvoid load(const nlohmann::json& j);\n\nwjson wj = /* ... */;\nload(wj);                            // error: no implicit conversion\nload(nlohmann::json(wj));            // OK: explicit conversion\nload(wj.get<nlohmann::json>());      // OK: explicit conversion\n

    Specializations that share the same string type, such as json and ordered_json, remain implicitly convertible.

    "},{"location":"api/macros/json_use_implicit_conversions/#see-also","title":"See also","text":"
    • operator ValueType - get a value (implicit)
    • get - get a value (explicit)
    • JSON_ImplicitConversions - CMake option to control the macro
    • Converting values - implicit conversions and how to disable them
    "},{"location":"api/macros/json_use_implicit_conversions/#version-history","title":"Version history","text":"
    • Added in version 3.9.0.
    • Also affects the conversion between basic_json specializations with different string types since version 3.13.0 unreleased.
    "},{"location":"api/macros/json_use_legacy_discarded_value_comparison/","title":"JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON","text":"
    #define JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON /* value */\n

    This macro enables the (incorrect) legacy comparison behavior of discarded JSON values. Possible values are 1 to enable or 0 to disable (default).

    When enabled, comparisons involving at least one discarded JSON value yield results as follows:

    Operator Result == false != true < false <= true >= true > false

    Otherwise, comparisons involving at least one discarded JSON value yield false, except for !=, which is the negation of == and yields true.

    "},{"location":"api/macros/json_use_legacy_discarded_value_comparison/#default-definition","title":"Default definition","text":"

    The default value is 0.

    #define JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON 0\n

    When the macro is not defined, the library will define it to its default value.

    "},{"location":"api/macros/json_use_legacy_discarded_value_comparison/#notes","title":"Notes","text":"

    Inconsistent behavior in C++20 and beyond

    When targeting C++20 or above, enabling the legacy comparison behavior is strongly discouraged.

    • The 3-way comparison operator (<=>) will always give the correct result (std::partial_ordering::unordered) regardless of the value of JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON.
    • Overloads for the equality and relational operators emulate the legacy behavior.

    Code outside your control may use either 3-way comparison or the equality and relational operators, resulting in inconsistent and unpredictable behavior.

    See operator<=> for more information on 3-way comparison.

    Deprecation

    The legacy comparison behavior is deprecated and may be removed in a future major version release.

    New code should not depend on it and existing code should try to remove or rewrite expressions relying on it.

    See the migration guide for how to update existing code.

    CMake option

    Legacy comparison can also be controlled with the CMake option JSON_LegacyDiscardedValueComparison (OFF by default) which defines JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON accordingly.

    "},{"location":"api/macros/json_use_legacy_discarded_value_comparison/#examples","title":"Examples","text":"Example

    The code below switches on the legacy discarded value comparison behavior in the library.

    #define JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON 1\n#include <nlohmann/json.hpp>\n\n...\n
    "},{"location":"api/macros/json_use_legacy_discarded_value_comparison/#see-also","title":"See also","text":"
    • JSON_LegacyDiscardedValueComparison - CMake option to control the macro
    "},{"location":"api/macros/json_use_legacy_discarded_value_comparison/#version-history","title":"Version history","text":"
    • Added in version 3.11.0.
    • Fixed in version 3.13.0 unreleased so <= and >= also emulate the legacy behavior in C++20 when the JSON value is the right-hand operand of a scalar comparison; before, only the 3-way-comparison-rewritten candidate was found, which yielded false instead of true.
    "},{"location":"api/macros/json_use_objects_for_enum_keyed_maps/","title":"JSON_USE_OBJECTS_FOR_ENUM_KEYED_MAPS","text":"
    #define JSON_USE_OBJECTS_FOR_ENUM_KEYED_MAPS /* value */\n

    When defined to 1, maps whose keys are enums (such as std::map<E, T> or std::unordered_map<E, T>) are stored as JSON objects, using the enum's own conversion for the keys. By default, they are stored as arrays of [key, value] pairs.

    "},{"location":"api/macros/json_use_objects_for_enum_keyed_maps/#default-definition","title":"Default definition","text":"

    The default value is 0 (disabled \u2014 existing behavior is preserved).

    #define JSON_USE_OBJECTS_FOR_ENUM_KEYED_MAPS 0\n
    "},{"location":"api/macros/json_use_objects_for_enum_keyed_maps/#notes","title":"Notes","text":"

    Background

    JSON object keys are strings, so a map is only stored as an object if its keys can be converted to a string type. Enums are not, even if NLOHMANN_JSON_SERIALIZE_ENUM maps them to strings, so a map with enum keys becomes an array of [key, value] pairs:

    [[\"stopped\", \"aa\"], [\"completed\", \"bb\"]]\n

    With this macro, the same map becomes an object (see #4378):

    {\"completed\": \"bb\", \"stopped\": \"aa\"}\n

    Maps with non-unique keys

    Maps that allow duplicate keys, such as std::multimap<E, T> or std::unordered_multimap<E, T>, are not affected by the macro and are still stored as arrays of [key, value] pairs, as an object cannot hold duplicate keys.

    Reading

    Reading is not affected by the macro: a map with enum keys can always be read from both an array of pairs and an object. For the latter, each key is converted to the enum with its from_json function, e.g., the one defined by NLOHMANN_JSON_SERIALIZE_ENUM. Data written without the macro can therefore still be read after enabling it.

    Keys must serialize to distinct strings

    Each key is converted with the enum's to_json function. If a key is not converted to a string (for instance, an enum without NLOHMANN_JSON_SERIALIZE_ENUM, which is stored as an integer, or an enumerator mapped to nullptr), type_error.302 is thrown. If two keys are converted to the same string (for instance, because NLOHMANN_JSON_SERIALIZE_ENUM maps an unlisted enumerator to the first entry), type_error.318 is thrown. In both cases, the target value is not changed.

    Opt-in only

    This macro must be defined before including <nlohmann/json.hpp>. Defining it after the include has no effect.

    ABI compatibility

    The value of this macro is encoded in the namespace (tag _ekmo), resulting in distinct symbol names. Translation units compiled with and without it can therefore be linked into the same program without One Definition Rule (ODR) violations, but they cannot exchange instances of library types.

    "},{"location":"api/macros/json_use_objects_for_enum_keyed_maps/#examples","title":"Examples","text":"Example: default behavior (macro not defined)

    Without the macro, a map with enum keys is stored as an array of pairs:

    #include <map>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nenum TaskState { TS_STOPPED, TS_RUNNING, TS_COMPLETED };\n\nNLOHMANN_JSON_SERIALIZE_ENUM(TaskState, {\n    {TS_STOPPED, \"stopped\"},\n    {TS_RUNNING, \"running\"},\n    {TS_COMPLETED, \"completed\"},\n})\n\nint main()\n{\n    std::map<TaskState, std::string> m = {{TS_STOPPED, \"aa\"}, {TS_COMPLETED, \"bb\"}};\n\n    json j = m;\n    // j is [[\"stopped\",\"aa\"],[\"completed\",\"bb\"]]\n}\n
    Example: objects for enum-keyed maps (macro defined to 1)

    With the macro, the same map is stored as an object:

    #define JSON_USE_OBJECTS_FOR_ENUM_KEYED_MAPS 1\n#include <map>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nenum TaskState { TS_STOPPED, TS_RUNNING, TS_COMPLETED };\n\nNLOHMANN_JSON_SERIALIZE_ENUM(TaskState, {\n    {TS_STOPPED, \"stopped\"},\n    {TS_RUNNING, \"running\"},\n    {TS_COMPLETED, \"completed\"},\n})\n\nint main()\n{\n    std::map<TaskState, std::string> m = {{TS_STOPPED, \"aa\"}, {TS_COMPLETED, \"bb\"}};\n\n    json j = m;\n    // j is {\"completed\":\"bb\",\"stopped\":\"aa\"}\n\n    auto m2 = j.get<std::map<TaskState, std::string>>();\n    // m2 == m\n}\n
    "},{"location":"api/macros/json_use_objects_for_enum_keyed_maps/#see-also","title":"See also","text":"
    • Specializing enum conversion - serializing enums as JSON strings
    • NLOHMANN_JSON_SERIALIZE_ENUM - serialize/deserialize an enum
    • NLOHMANN_JSON_SERIALIZE_ENUM_STRICT - serialize/deserialize an enum with exceptions
    "},{"location":"api/macros/json_use_objects_for_enum_keyed_maps/#version-history","title":"Version history","text":"
    • Added in version 3.13.0 unreleased.
    "},{"location":"api/macros/json_use_simdutf/","title":"JSON_USE_SIMDUTF","text":"
    #define JSON_USE_SIMDUTF\n

    When defined, the parser validates the UTF-8 content of JSON strings that come from a contiguous byte input (std::string, std::vector<char>/<std::uint8_t>, string literals, const char* ranges, \u2026) using the simdutf library instead of the built-in validator (which uses SSSE3 or NEON where available, see JSON_NO_SIMD). On text with many non-ASCII characters (e.g. CJK or emoji) this can validate faster, depending on the CPU.

    This is an opt-in external dependency. The library itself remains header-only and its behavior is unchanged: the same input is accepted or rejected either way, and every parse error is reported at the same position with the same message (simdutf is only used to fast-path valid runs; anything it flags falls back to the scalar path so the exact diagnostic is preserved). A std::istream uses simdutf for the characters its stream buffer holds (see JSON_DISABLE_STREAM_BULK_SCAN); other streaming inputs (FILE*, wide strings, user-defined adapters) always use the scalar path.

    When JSON_USE_SIMDUTF is defined you must make the simdutf.h header available on the include path and link the simdutf library. When it is not defined, no simdutf header is included and there is no dependency.

    Requires C++17

    simdutf requires C++17 and its header rejects older standards with an #error. The backend is therefore only compiled in from C++17 on. In C++11 and C++14 the macro has no effect and the scalar validator is used, which accepts and rejects exactly the same input \u2014 only throughput differs. Setting the macro project-wide is therefore safe even when some translation units are built with an older standard.

    Define consistently

    The macro selects between two definitions of the same inline validation function. It must therefore be defined identically for every translation unit that includes the library; mixing translation units that define it with ones that do not is an ODR violation. Prefer setting it as a compile definition on the target rather than with #define in individual source files.

    "},{"location":"api/macros/json_use_simdutf/#default-definition","title":"Default definition","text":"

    By default, JSON_USE_SIMDUTF is not defined and the portable C++11 scalar validator is used.

    #undef JSON_USE_SIMDUTF\n
    "},{"location":"api/macros/json_use_simdutf/#examples","title":"Examples","text":"Example

    The code below enables the simdutf backend for UTF-8 validation.

    #define JSON_USE_SIMDUTF 1\n#include <nlohmann/json.hpp>\n\n...\n

    The project must also link against simdutf, e.g. with CMake:

    target_compile_definitions(your_target PRIVATE JSON_USE_SIMDUTF)\ntarget_link_libraries(your_target PRIVATE simdutf::simdutf)\n

    Testing this configuration

    The unit tests can be built against the simdutf backend with the CMake option JSON_TestSimdutf (OFF by default), which fetches simdutf and defines JSON_USE_SIMDUTF for every test target. The ci_test_simdutf target runs the whole test suite in that configuration.

    "},{"location":"api/macros/json_use_simdutf/#see-also","title":"See also","text":"
    • JSON_TestSimdutf - CMake option to build the unit tests against the simdutf backend
    • Parsing - overview of the parsing functions
    • Serialization - pretty-printing, UTF-8 handling, and number output
    "},{"location":"api/macros/json_use_simdutf/#version-history","title":"Version history","text":"
    • Added in version 3.13.0 unreleased.
    "},{"location":"api/macros/nlohmann_define_derived_type/","title":"NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE, NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_WITH_DEFAULT, NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_ONLY_SERIALIZE, NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE, NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_WITH_DEFAULT, NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE","text":"NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE, NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_WITH_DEFAULT, NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_ONLY_SERIALIZE, NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE, NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_WITH_DEFAULT, NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE
    // (1)\n#define NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE(type, base_type, member...)\n// (2)\n#define NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_WITH_DEFAULT(type, base_type, member...)\n// (3)\n#define NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_ONLY_SERIALIZE(type, base_type, member...)\n\n// (4)\n#define NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE(type, base_type, member...)\n// (5)\n#define NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_WITH_DEFAULT(type, base_type, member...)\n// (6)\n#define NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE(type, base_type, member...)\n

    These macros can be used to simplify the serialization/deserialization of derived types if you want to use a JSON object as serialization and want to use the member variable names as object keys in that object.

    • Macros 1, 2, and 3 are to be defined inside the class/struct to create code for. Like NLOHMANN_DEFINE_TYPE_INTRUSIVE, they can access private members.
    • Macros 4, 5, and 6 are to be defined outside the class/struct to create code for, but inside its namespace. Like NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE, they cannot access private members.

    The first parameter is the name of the derived class/struct, the second parameter is the name of the base class/struct and all remaining parameters name the members. The base type must be already serializable/deserializable.

    • Macros 1 and 4 will use at during deserialization and will throw out_of_range.403 if a key is missing in the JSON object.
    • Macros 2 and 5 will use value during deserialization and fall back to the default value for the respective type of the member variable if a key in the JSON object is missing. The generated from_json() function default constructs an object and uses its values as the defaults when calling the value function.

    Summary:

    Need access to private members Need only serialization Allow missing values when de-serializing macro NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_WITH_DEFAULT NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_ONLY_SERIALIZE NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_WITH_DEFAULT NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE"},{"location":"api/macros/nlohmann_define_derived_type/#parameters","title":"Parameters","text":"type (in) name of the type (class, struct) to serialize/deserialize base_type (in) name of the base type (class, struct) type is derived from member (in) name of the member variable to serialize/deserialize; up to 63 members can be given as a comma-separated list, which may also be empty"},{"location":"api/macros/nlohmann_define_derived_type/#default-definition","title":"Default definition","text":"

    Macros 1 and 2 add two friend functions to the class which take care of the serialization and deserialization:

    template<typename BasicJsonType>\nfriend void to_json(BasicJsonType&, const type&);\ntemplate<typename BasicJsonType>\nfriend void from_json(const BasicJsonType&, type&);\n

    Macros 4 and 5 add two functions to the namespace which take care of the serialization and deserialization:

    template<typename BasicJsonType>\nvoid to_json(BasicJsonType&, const type&);\ntemplate<typename BasicJsonType>\nvoid from_json(const BasicJsonType&, type&);\n

    Macros 3 and 6 add one function to the namespace, which takes care of the serialization only:

    template<typename BasicJsonType>\nvoid to_json(BasicJsonType&, const type&);\n

    In first two cases, they call the to_json/from_json functions of the base type before serializing/deserializing the members of the derived type:

    class A { /* ... */ };\nclass B : public A { /* ... */ };\n\ntemplate<typename BasicJsonType>\nvoid to_json(BasicJsonType& j, const B& b) {\n    nlohmann::to_json(j, static_cast<const A&>(b));\n    // ...\n}\n\ntemplate<typename BasicJsonType>\nvoid from_json(const BasicJsonType& j, B& b) {\n    nlohmann::from_json(j, static_cast<A&>(b));\n    // ...\n}\n

    In the third case, only to_json will be called:

    class A { /* ... */ };\nclass B : public A { /* ... */ };\n\ntemplate<typename BasicJsonType>\nvoid to_json(BasicJsonType& j, const B& b) {\n    nlohmann::to_json(j, static_cast<const A&>(b));\n    // ...\n}\n
    "},{"location":"api/macros/nlohmann_define_derived_type/#notes","title":"Notes","text":"

    Prerequisites

    • Macros 1, 2, and 3 have the same prerequisites of NLOHMANN_DEFINE_TYPE_INTRUSIVE.
    • Macros 4, 5, and 6 have the same prerequisites of NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE.
    • Serialization/deserialization of base types must be defined.

    Derived types without own members

    The member list may be empty. The macro then generates a to_json/from_json pair that only delegates to the base type, so type serializes exactly like base_type:

    struct derived : base\n{\n    NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE(derived, base)\n};\n

    The WITH_NAMES variants do not support this.

    Implementation limits

    See Implementation limits for NLOHMANN_DEFINE_TYPE_INTRUSIVE and NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE, respectively.

    Views

    The generated from_json() also reads the views of json_documents (<nlohmann/json_view.hpp>): get<T>() on a view looks the members up in the view, without building a json value first. The base part is read from the view as well if the base's from_json() accepts views, and from materialize() otherwise.

    "},{"location":"api/macros/nlohmann_define_derived_type/#examples","title":"Examples","text":"Example: (1) NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE

    Consider the following complete example:

    #include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nclass A\n{\n  private:\n    double Aa = 0.0;\n    double Ab = 0.0;\n\n  public:\n    A() = default;\n    A(double a, double b) : Aa(a), Ab(b) {}\n    NLOHMANN_DEFINE_TYPE_INTRUSIVE(A, Aa, Ab)\n};\n\nclass B : public A\n{\n  private:\n    int Ba = 0;\n    int Bb = 0;\n\n  public:\n    B() = default;\n    B(int a, int b, double aa, double ab) : A(aa, ab), Ba(a), Bb(b) {}\n    NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE(B, A, Ba, Bb)\n};\n\nint main()\n{\n    B example(23, 42, 3.142, 1.777);\n    json example_json = example;\n\n    std::cout << std::setw(4) << example_json << '\\n';\n}\n

    Output:

    {\n    \"Aa\": 3.142,\n    \"Ab\": 1.777,\n    \"Ba\": 23,\n    \"Bb\": 42\n}\n

    Notes:

    • A and B are default-constructible. This is a requirement for using the macro.
    • A has private members and is not a derived class. Hence, macro NLOHMANN_DEFINE_TYPE_INTRUSIVE is used.
    • As B is a derived class, NLOHMANN_DEFINE_TYPE_INTRUSIVE is not applicable, but NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE must be used.
    • The macro NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE is used inside the class use as NLOHMANN_DEFINE_TYPE_INTRUSIVE.
    "},{"location":"api/macros/nlohmann_define_derived_type/#see-also","title":"See also","text":"
    • NLOHMANN_DEFINE_TYPE_INTRUSIVE / NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT / NLOHMANN_DEFINE_TYPE_INTRUSIVE_ONLY_SERIALIZE - similar macros that can be defined inside a non-derived type
    • NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE / NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT / NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE - similar macros that can be defined outside a non-derived type
    • Arbitrary Type Conversions - overview of the supported conversions
    • Recipes for Common Types - class hierarchies
    "},{"location":"api/macros/nlohmann_define_derived_type/#version-history","title":"Version history","text":"
    1. Added in version 3.12.0.
    2. Added in version 3.12.0.
    3. Added in version 3.12.0.
    4. Added in version 3.12.0.
    5. Added in version 3.12.0.
    6. Added in version 3.12.0.

    All six macros were changed to allow an empty member list in version 3.13.0 unreleased.

    The generated from_json() reads the views of json_documents since version 3.13.0 unreleased.

    "},{"location":"api/macros/nlohmann_define_type_intrusive/","title":"NLOHMANN_DEFINE_TYPE_INTRUSIVE, NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT, NLOHMANN_DEFINE_TYPE_INTRUSIVE_ONLY_SERIALIZE","text":"
    #define NLOHMANN_DEFINE_TYPE_INTRUSIVE(type, member...)              // (1)\n#define NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(type, member...) // (2)\n#define NLOHMANN_DEFINE_TYPE_INTRUSIVE_ONLY_SERIALIZE(type, member...) // (3)\n

    These macros can be used to simplify the serialization/deserialization of types if you want to use a JSON object as serialization and want to use the member variable names as object keys in that object. The macro is to be defined inside the class/struct to create code for. Unlike NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE, it can access private members. The first parameter is the name of the class/struct, and all remaining parameters name the members.

    1. Will use at during deserialization and will throw out_of_range.403 if a key is missing in the JSON object.
    2. Will use value during deserialization and fall back to the default value for the respective type of the member variable if a key in the JSON object is missing. The generated from_json() function default constructs an object and uses its values as the defaults when calling the value function.
    3. Only defines the serialization. Useful in cases when the type does not have a default constructor and only serialization is required.

    Summary:

    Need access to private members Need only serialization Allow missing values when de-serializing macro NLOHMANN_DEFINE_TYPE_INTRUSIVE NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT NLOHMANN_DEFINE_TYPE_INTRUSIVE_ONLY_SERIALIZE"},{"location":"api/macros/nlohmann_define_type_intrusive/#parameters","title":"Parameters","text":"type (in) name of the type (class, struct) to serialize/deserialize member (in) name of the member variable to serialize/deserialize; up to 63 members can be given as a comma-separated list, which may also be empty"},{"location":"api/macros/nlohmann_define_type_intrusive/#default-definition","title":"Default definition","text":"

    The macros add two friend functions to the class which take care of the serialization and deserialization:

    template<typename BasicJsonType>\nfriend void to_json(BasicJsonType&, const type&);\ntemplate<typename BasicJsonType>\nfriend void from_json(const BasicJsonType&, type&); // except (3)\n

    See the examples below for the concrete generated code.

    "},{"location":"api/macros/nlohmann_define_type_intrusive/#notes","title":"Notes","text":"

    Prerequisites

    1. The type type must be default constructible (except (3)). See How can I use get() for non-default constructible/non-copyable types? for how to overcome this limitation.
    2. The macro must be used inside the type (class/struct).

    Types without members

    The member list may be empty. The macro then generates a to_json that produces an empty JSON object {}, and a from_json that reads no members:

    struct marker\n{\n    NLOHMANN_DEFINE_TYPE_INTRUSIVE(marker)\n};\n

    The WITH_NAMES variants do not support this.

    Implementation limits

    • The current implementation is limited to at most 63 member variables. If you want to serialize/deserialize types with more than 63 member variables, you need to define the to_json/from_json functions manually.
    • These macros always produce object-style (named-key) JSON, one key per member. There is no macro variant that serializes a struct's members positionally into a JSON array; for that, write to_json/from_json by hand, building/reading a json::array() of the members in order.

    Views

    The generated from_json() also reads the views of json_documents (<nlohmann/json_view.hpp>): get<T>() on a view looks the members up in the view, without building a json value first.

    "},{"location":"api/macros/nlohmann_define_type_intrusive/#examples","title":"Examples","text":"Example: (1) NLOHMANN_DEFINE_TYPE_INTRUSIVE

    Consider the following complete example:

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\nusing namespace nlohmann::literals;\n\nnamespace ns\n{\nclass person\n{\n  private:\n    std::string name = \"John Doe\";\n    std::string address = \"123 Fake St\";\n    int age = -1;\n\n  public:\n    person() = default;\n    person(std::string name_, std::string address_, int age_)\n        : name(std::move(name_)), address(std::move(address_)), age(age_)\n    {}\n\n    NLOHMANN_DEFINE_TYPE_INTRUSIVE(person, name, address, age)\n};\n} // namespace ns\n\nint main()\n{\n    ns::person p = {\"Ned Flanders\", \"744 Evergreen Terrace\", 60};\n\n    // serialization: person -> json\n    json j = p;\n    std::cout << \"serialization: \" << j << '\\n';\n\n    // deserialization: json -> person\n    json j2 = R\"({\"address\": \"742 Evergreen Terrace\", \"age\": 40, \"name\": \"Homer Simpson\"})\"_json;\n    auto p2 = j2.get<ns::person>();\n\n    // incomplete deserialization:\n    json j3 = R\"({\"address\": \"742 Evergreen Terrace\", \"name\": \"Maggie Simpson\"})\"_json;\n    try\n    {\n        auto p3 = j3.get<ns::person>();\n    }\n    catch (const json::exception& e)\n    {\n        std::cout << \"deserialization failed: \" << e.what() << '\\n';\n    }\n}\n

    Output:

    serialization: {\"address\":\"744 Evergreen Terrace\",\"age\":60,\"name\":\"Ned Flanders\"}\ndeserialization failed: [json.exception.out_of_range.403] key 'age' not found\n

    Notes:

    • ns::person is default-constructible. This is a requirement for using the macro.
    • ns::person has private member variables. This makes NLOHMANN_DEFINE_TYPE_INTRUSIVE applicable, but not NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE.
    • The macro NLOHMANN_DEFINE_TYPE_INTRUSIVE is used inside the class.
    • A missing key \"age\" in the deserialization yields an exception. To fall back to the default value, NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT can be used.

    The macro is equivalent to:

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\nusing namespace nlohmann::literals;\n\nnamespace ns\n{\nclass person\n{\n  private:\n    std::string name = \"John Doe\";\n    std::string address = \"123 Fake St\";\n    int age = -1;\n\n  public:\n    person() = default;\n    person(std::string name_, std::string address_, int age_)\n        : name(std::move(name_)), address(std::move(address_)), age(age_)\n    {}\n\n    template<typename BasicJsonType>\n    friend void to_json(BasicJsonType& nlohmann_json_j, const person& nlohmann_json_t)\n    {\n        nlohmann_json_j[\"name\"] = nlohmann_json_t.name;\n        nlohmann_json_j[\"address\"] = nlohmann_json_t.address;\n        nlohmann_json_j[\"age\"] = nlohmann_json_t.age;\n    }\n\n    template<typename BasicJsonType>\n    friend void from_json(const BasicJsonType& nlohmann_json_j, person& nlohmann_json_t)\n    {\n        nlohmann_json_t.name = nlohmann_json_j.at(\"name\");\n        nlohmann_json_t.address = nlohmann_json_j.at(\"address\");\n        nlohmann_json_t.age = nlohmann_json_j.at(\"age\");\n    }\n};\n} // namespace ns\n\nint main()\n{\n    ns::person p = {\"Ned Flanders\", \"744 Evergreen Terrace\", 60};\n\n    // serialization: person -> json\n    json j = p;\n    std::cout << \"serialization: \" << j << '\\n';\n\n    // deserialization: json -> person\n    json j2 = R\"({\"address\": \"742 Evergreen Terrace\", \"age\": 40, \"name\": \"Homer Simpson\"})\"_json;\n    auto p2 = j2.get<ns::person>();\n\n    // incomplete deserialization:\n    json j3 = R\"({\"address\": \"742 Evergreen Terrace\", \"name\": \"Maggie Simpson\"})\"_json;\n    try\n    {\n        auto p3 = j3.get<ns::person>();\n    }\n    catch (const json::exception& e)\n    {\n        std::cout << \"deserialization failed: \" << e.what() << '\\n';\n    }\n}\n
    Example: (2) NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT

    Consider the following complete example:

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\nusing namespace nlohmann::literals;\n\nnamespace ns\n{\nclass person\n{\n  private:\n    std::string name = \"John Doe\";\n    std::string address = \"123 Fake St\";\n    int age = -1;\n\n  public:\n    person() = default;\n    person(std::string name_, std::string address_, int age_)\n        : name(std::move(name_)), address(std::move(address_)), age(age_)\n    {}\n\n    NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(person, name, address, age)\n};\n} // namespace ns\n\nint main()\n{\n    ns::person p = {\"Ned Flanders\", \"744 Evergreen Terrace\", 60};\n\n    // serialization: person -> json\n    json j = p;\n    std::cout << \"serialization: \" << j << '\\n';\n\n    // deserialization: json -> person\n    json j2 = R\"({\"address\": \"742 Evergreen Terrace\", \"age\": 40, \"name\": \"Homer Simpson\"})\"_json;\n    auto p2 = j2.get<ns::person>();\n\n    // incomplete deserialization:\n    json j3 = R\"({\"address\": \"742 Evergreen Terrace\", \"name\": \"Maggie Simpson\"})\"_json;\n    auto p3 = j3.get<ns::person>();\n    std::cout << \"roundtrip: \" << json(p3) << '\\n';\n}\n

    Output:

    serialization: {\"address\":\"744 Evergreen Terrace\",\"age\":60,\"name\":\"Ned Flanders\"}\nroundtrip: {\"address\":\"742 Evergreen Terrace\",\"age\":-1,\"name\":\"Maggie Simpson\"}\n

    Notes:

    • ns::person is default-constructible. This is a requirement for using the macro.
    • ns::person has private member variables. This makes NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT applicable, but not NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT.
    • The macro NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT is used inside the class.
    • A missing key \"age\" in the deserialization does not yield an exception. Instead, the default value -1 is used.

    The macro is equivalent to:

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\nusing namespace nlohmann::literals;\n\nnamespace ns\n{\nclass person\n{\n  private:\n    std::string name = \"John Doe\";\n    std::string address = \"123 Fake St\";\n    int age = -1;\n\n  public:\n    person() = default;\n    person(std::string name_, std::string address_, int age_)\n        : name(std::move(name_)), address(std::move(address_)), age(age_)\n    {}\n\n    template<typename BasicJsonType>\n    friend void to_json(BasicJsonType& nlohmann_json_j, const person& nlohmann_json_t)\n    {\n        nlohmann_json_j[\"name\"] = nlohmann_json_t.name;\n        nlohmann_json_j[\"address\"] = nlohmann_json_t.address;\n        nlohmann_json_j[\"age\"] = nlohmann_json_t.age;\n    }\n\n    template<typename BasicJsonType>\n    friend void from_json(const BasicJsonType& nlohmann_json_j, person& nlohmann_json_t)\n    {\n        person nlohmann_json_default_obj;\n        nlohmann_json_t.name = nlohmann_json_j.value(\"name\", nlohmann_json_default_obj.name);\n        nlohmann_json_t.address = nlohmann_json_j.value(\"address\", nlohmann_json_default_obj.address);\n        nlohmann_json_t.age = nlohmann_json_j.value(\"age\", nlohmann_json_default_obj.age);\n    }\n};\n} // namespace ns\n\nint main()\n{\n    ns::person p = {\"Ned Flanders\", \"744 Evergreen Terrace\", 60};\n\n    // serialization: person -> json\n    json j = p;\n    std::cout << \"serialization: \" << j << '\\n';\n\n    // deserialization: json -> person\n    json j2 = R\"({\"address\": \"742 Evergreen Terrace\", \"age\": 40, \"name\": \"Homer Simpson\"})\"_json;\n    auto p2 = j2.get<ns::person>();\n\n    // incomplete deserialization:\n    json j3 = R\"({\"address\": \"742 Evergreen Terrace\", \"name\": \"Maggie Simpson\"})\"_json;\n    auto p3 = j3.get<ns::person>();\n    std::cout << \"roundtrip: \" << json(p3) << '\\n';\n}\n

    Note how a default-initialized person object is used in the from_json to fill missing values.

    Example: (3) NLOHMANN_DEFINE_TYPE_INTRUSIVE_ONLY_SERIALIZE

    Consider the following complete example:

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\nusing namespace nlohmann::literals;\n\nnamespace ns\n{\nclass person\n{\n  private:\n    std::string name = \"John Doe\";\n    std::string address = \"123 Fake St\";\n    int age = -1;\n\n  public:\n    // No default constructor\n    person(std::string name_, std::string address_, int age_)\n        : name(std::move(name_)), address(std::move(address_)), age(age_)\n    {}\n\n    NLOHMANN_DEFINE_TYPE_INTRUSIVE(person, name, address, age)\n};\n} // namespace ns\n\nint main()\n{\n    ns::person p = {\"Ned Flanders\", \"744 Evergreen Terrace\", 60};\n\n    // serialization: person -> json\n    json j = p;\n    std::cout << \"serialization: \" << j << '\\n';\n}\n

    Output:

    serialization: {\"address\":\"744 Evergreen Terrace\",\"age\":60,\"name\":\"Ned Flanders\"}\n

    Notes:

    • ns::person is non-default-constructible. This allows this macro to be used instead of NLOHMANN_DEFINE_TYPE_INTRUSIVE and NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT.
    • ns::person has private member variables. This makes NLOHMANN_DEFINE_TYPE_INTRUSIVE_ONLY_SERIALIZE applicable, but not NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE.
    • The macro NLOHMANN_DEFINE_TYPE_INTRUSIVE_ONLY_SERIALIZE is used inside the class.

    The macro is equivalent to:

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\nusing namespace nlohmann::literals;\n\nnamespace ns\n{\nclass person\n{\n  private:\n    std::string name = \"John Doe\";\n    std::string address = \"123 Fake St\";\n    int age = -1;\n\n  public:\n    // No default constructor\n    person(std::string name_, std::string address_, int age_)\n        : name(std::move(name_)), address(std::move(address_)), age(age_)\n    {}\n\n    template<typename BasicJsonType>\n    friend void to_json(BasicJsonType& nlohmann_json_j, const person& nlohmann_json_t)\n    {\n        nlohmann_json_j[\"name\"] = nlohmann_json_t.name;\n        nlohmann_json_j[\"address\"] = nlohmann_json_t.address;\n        nlohmann_json_j[\"age\"] = nlohmann_json_t.age;\n    }\n};\n} // namespace ns\n\nint main()\n{\n    ns::person p = {\"Ned Flanders\", \"744 Evergreen Terrace\", 60};\n\n    // serialization: person -> json\n    json j = p;\n    std::cout << \"serialization: \" << j << '\\n';\n}\n
    "},{"location":"api/macros/nlohmann_define_type_intrusive/#see-also","title":"See also","text":"
    • NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE / NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT / NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE - a similar macro that can be defined outside the type
    • NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE / NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_WITH_DEFAULT / NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_ONLY_SERIALIZE / NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE / NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_WITH_DEFAULT / NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE - similar macros for derived types
    • Arbitrary Type Conversions - overview of the supported conversions
    "},{"location":"api/macros/nlohmann_define_type_intrusive/#version-history","title":"Version history","text":"
    1. Added in version 3.9.0.
    2. Added in version 3.11.0.
    3. Added in version 3.11.3.

    All three macros were changed to work with any basic_json specialization (not only nlohmann::json) in version 3.12.0, and to allow an empty member list in version 3.13.0 unreleased.

    The generated from_json() reads the views of json_documents since version 3.13.0 unreleased.

    "},{"location":"api/macros/nlohmann_define_type_non_intrusive/","title":"NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE, NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT, NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE","text":"
    #define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(type, member...)              // (1)\n#define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT(type, member...) // (2)\n#define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE(type, member...) // (3)\n

    These macros can be used to simplify the serialization/deserialization of types if you want to use a JSON object as serialization and want to use the member variable names as object keys in that object. The macro is to be defined outside the class/struct to create code for, but inside its namespace. Unlike NLOHMANN_DEFINE_TYPE_INTRUSIVE, it cannot access private members. The first parameter is the name of the class/struct, and all remaining parameters name the members.

    1. Will use at during deserialization and will throw out_of_range.403 if a key is missing in the JSON object.
    2. Will use value during deserialization and fall back to the default value for the respective type of the member variable if a key in the JSON object is missing. The generated from_json() function default constructs an object and uses its values as the defaults when calling the value function.
    3. Only defines the serialization. Useful in cases when the type does not have a default constructor and only serialization is required.

    Summary:

    Need access to private members Need only serialization Allow missing values when de-serializing macro NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE"},{"location":"api/macros/nlohmann_define_type_non_intrusive/#parameters","title":"Parameters","text":"type (in) name of the type (class, struct) to serialize/deserialize member (in) name of the (public) member variable to serialize/deserialize; up to 63 members can be given as a comma-separated list, which may also be empty"},{"location":"api/macros/nlohmann_define_type_non_intrusive/#default-definition","title":"Default definition","text":"

    The macros add two functions to the namespace which take care of the serialization and deserialization:

    template<typename BasicJsonType>\nvoid to_json(BasicJsonType&, const type&);\ntemplate<typename BasicJsonType>\nvoid from_json(const BasicJsonType&, type&); // except (3)\n

    See the examples below for the concrete generated code.

    "},{"location":"api/macros/nlohmann_define_type_non_intrusive/#notes","title":"Notes","text":"

    Prerequisites

    1. The type type must be default constructible (except (3). See How can I use get() for non-default constructible/non-copyable types? for how to overcome this limitation.
    2. The macro must be used outside the type (class/struct).
    3. The passed members must be public.

    Types without members

    The member list may be empty. The macro then generates a to_json that produces an empty JSON object {}, and a from_json that reads no members:

    struct marker {};\nNLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(marker)\n

    The WITH_NAMES variants do not support this.

    Implementation limits

    • The current implementation is limited to at most 63 member variables. If you want to serialize/deserialize types with more than 63 member variables, you need to define the to_json/from_json functions manually.
    • These macros always produce object-style (named-key) JSON, one key per member. There is no macro variant that serializes a struct's members positionally into a JSON array; for that, write to_json/from_json by hand, building/reading a json::array() of the members in order.

    Views

    The generated from_json() also reads the views of json_documents (<nlohmann/json_view.hpp>): get<T>() on a view looks the members up in the view, without building a json value first.

    "},{"location":"api/macros/nlohmann_define_type_non_intrusive/#examples","title":"Examples","text":"Example: (1) NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE

    Consider the following complete example:

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\nusing namespace nlohmann::literals;\n\nnamespace ns\n{\nstruct person\n{\n    std::string name;\n    std::string address;\n    int age;\n};\n\nNLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(person, name, address, age)\n} // namespace ns\n\nint main()\n{\n    ns::person p = {\"Ned Flanders\", \"744 Evergreen Terrace\", 60};\n\n    // serialization: person -> json\n    json j = p;\n    std::cout << \"serialization: \" << j << '\\n';\n\n    // deserialization: json -> person\n    json j2 = R\"({\"address\": \"742 Evergreen Terrace\", \"age\": 40, \"name\": \"Homer Simpson\"})\"_json;\n    auto p2 = j2.get<ns::person>();\n\n    // incomplete deserialization:\n    json j3 = R\"({\"address\": \"742 Evergreen Terrace\", \"name\": \"Maggie Simpson\"})\"_json;\n    try\n    {\n        auto p3 = j3.get<ns::person>();\n    }\n    catch (const json::exception& e)\n    {\n        std::cout << \"deserialization failed: \" << e.what() << '\\n';\n    }\n}\n

    Output:

    serialization: {\"address\":\"744 Evergreen Terrace\",\"age\":60,\"name\":\"Ned Flanders\"}\ndeserialization failed: [json.exception.out_of_range.403] key 'age' not found\n

    Notes:

    • ns::person is default-constructible. This is a requirement for using the macro.
    • ns::person has only public member variables. This makes NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE applicable.
    • The macro NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE is used outside the class, but inside its namespace ns.
    • A missing key \"age\" in the deserialization yields an exception. To fall back to the default value, NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT can be used.

    The macro is equivalent to:

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\nusing namespace nlohmann::literals;\n\nnamespace ns\n{\nstruct person\n{\n    std::string name;\n    std::string address;\n    int age;\n};\n\ntemplate<typename BasicJsonType>\nvoid to_json(BasicJsonType& nlohmann_json_j, const person& nlohmann_json_t)\n{\n    nlohmann_json_j[\"name\"] = nlohmann_json_t.name;\n    nlohmann_json_j[\"address\"] = nlohmann_json_t.address;\n    nlohmann_json_j[\"age\"] = nlohmann_json_t.age;\n}\n\ntemplate<typename BasicJsonType>\nvoid from_json(const BasicJsonType& nlohmann_json_j, person& nlohmann_json_t)\n{\n    nlohmann_json_t.name = nlohmann_json_j.at(\"name\");\n    nlohmann_json_t.address = nlohmann_json_j.at(\"address\");\n    nlohmann_json_t.age = nlohmann_json_j.at(\"age\");\n}\n} // namespace ns\n\nint main()\n{\n    ns::person p = {\"Ned Flanders\", \"744 Evergreen Terrace\", 60};\n\n    // serialization: person -> json\n    json j = p;\n    std::cout << \"serialization: \" << j << '\\n';\n\n    // deserialization: json -> person\n    json j2 = R\"({\"address\": \"742 Evergreen Terrace\", \"age\": 40, \"name\": \"Homer Simpson\"})\"_json;\n    auto p2 = j2.get<ns::person>();\n\n    // incomplete deserialization:\n    json j3 = R\"({\"address\": \"742 Evergreen Terrace\", \"name\": \"Maggie Simpson\"})\"_json;\n    try\n    {\n        auto p3 = j3.get<ns::person>();\n    }\n    catch (const json::exception& e)\n    {\n        std::cout << \"deserialization failed: \" << e.what() << '\\n';\n    }\n}\n
    Example: (2) NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT

    Consider the following complete example:

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\nusing namespace nlohmann::literals;\n\nnamespace ns\n{\nstruct person\n{\n    std::string name = \"John Doe\";\n    std::string address = \"123 Fake St\";\n    int age = -1;\n\n    person() = default;\n    person(std::string name_, std::string address_, int age_)\n        : name(std::move(name_)), address(std::move(address_)), age(age_)\n    {}\n};\n\nNLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT(person, name, address, age)\n} // namespace ns\n\nint main()\n{\n    ns::person p = {\"Ned Flanders\", \"744 Evergreen Terrace\", 60};\n\n    // serialization: person -> json\n    json j = p;\n    std::cout << \"serialization: \" << j << '\\n';\n\n    // deserialization: json -> person\n    json j2 = R\"({\"address\": \"742 Evergreen Terrace\", \"age\": 40, \"name\": \"Homer Simpson\"})\"_json;\n    auto p2 = j2.get<ns::person>();\n\n    // incomplete deserialization:\n    json j3 = R\"({\"address\": \"742 Evergreen Terrace\", \"name\": \"Maggie Simpson\"})\"_json;\n    auto p3 = j3.get<ns::person>();\n    std::cout << \"roundtrip: \" << json(p3) << '\\n';\n}\n

    Output:

    serialization: {\"address\":\"744 Evergreen Terrace\",\"age\":60,\"name\":\"Ned Flanders\"}\nroundtrip: {\"address\":\"742 Evergreen Terrace\",\"age\":-1,\"name\":\"Maggie Simpson\"}\n

    Notes:

    • ns::person is default-constructible. This is a requirement for using the macro.
    • ns::person has only public member variables. This makes NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT applicable.
    • The macro NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT is used outside the class, but inside its namespace ns.
    • A missing key \"age\" in the deserialization does not yield an exception. Instead, the default value -1 is used.

    The macro is equivalent to:

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\nusing namespace nlohmann::literals;\n\nnamespace ns\n{\nstruct person\n{\n    std::string name = \"John Doe\";\n    std::string address = \"123 Fake St\";\n    int age = -1;\n\n    person() = default;\n    person(std::string name_, std::string address_, int age_)\n        : name(std::move(name_)), address(std::move(address_)), age(age_)\n    {}\n};\n\ntemplate<typename BasicJsonType>\nvoid to_json(BasicJsonType& nlohmann_json_j, const person& nlohmann_json_t)\n{\n    nlohmann_json_j[\"name\"] = nlohmann_json_t.name;\n    nlohmann_json_j[\"address\"] = nlohmann_json_t.address;\n    nlohmann_json_j[\"age\"] = nlohmann_json_t.age;\n}\n\ntemplate<typename BasicJsonType>\nvoid from_json(const BasicJsonType& nlohmann_json_j, person& nlohmann_json_t)\n{\n    person nlohmann_json_default_obj;\n    nlohmann_json_t.name = nlohmann_json_j.value(\"name\", nlohmann_json_default_obj.name);\n    nlohmann_json_t.address = nlohmann_json_j.value(\"address\", nlohmann_json_default_obj.address);\n    nlohmann_json_t.age = nlohmann_json_j.value(\"age\", nlohmann_json_default_obj.age);\n}\n} // namespace ns\n\nint main()\n{\n    ns::person p = {\"Ned Flanders\", \"744 Evergreen Terrace\", 60};\n\n    // serialization: person -> json\n    json j = p;\n    std::cout << \"serialization: \" << j << '\\n';\n\n    // deserialization: json -> person\n    json j2 = R\"({\"address\": \"742 Evergreen Terrace\", \"age\": 40, \"name\": \"Homer Simpson\"})\"_json;\n    auto p2 = j2.get<ns::person>();\n\n    // incomplete deserialization:\n    json j3 = R\"({\"address\": \"742 Evergreen Terrace\", \"name\": \"Maggie Simpson\"})\"_json;\n    auto p3 = j3.get<ns::person>();\n    std::cout << \"roundtrip: \" << json(p3) << '\\n';\n}\n

    Note how a default-initialized person object is used in the from_json to fill missing values.

    Example: (3) NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE

    Consider the following complete example:

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\nusing namespace nlohmann::literals;\n\nnamespace ns\n{\nstruct person\n{\n    std::string name;\n    std::string address;\n    int age;\n};\n\nNLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE(person, name, address, age)\n} // namespace ns\n\nint main()\n{\n    ns::person p = {\"Ned Flanders\", \"744 Evergreen Terrace\", 60};\n\n    // serialization: person -> json\n    json j = p;\n    std::cout << \"serialization: \" << j << '\\n';\n}\n

    Output:

    serialization: {\"address\":\"744 Evergreen Terrace\",\"age\":60,\"name\":\"Ned Flanders\"}\n

    Notes:

    • ns::person is non-default-constructible. This allows this macro to be used instead of NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE and NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT.
    • ns::person has only public member variables. This makes NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE applicable.
    • The macro NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE is used outside the class, but inside its namespace ns.

    The macro is equivalent to:

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\nusing namespace nlohmann::literals;\n\nnamespace ns\n{\nstruct person\n{\n    std::string name;\n    std::string address;\n    int age;\n};\n\ntemplate<typename BasicJsonType>\nvoid to_json(BasicJsonType& nlohmann_json_j, const person& nlohmann_json_t)\n{\n    nlohmann_json_j[\"name\"] = nlohmann_json_t.name;\n    nlohmann_json_j[\"address\"] = nlohmann_json_t.address;\n    nlohmann_json_j[\"age\"] = nlohmann_json_t.age;\n}\n} // namespace ns\n\nint main()\n{\n    ns::person p = {\"Ned Flanders\", \"744 Evergreen Terrace\", 60};\n\n    // serialization: person -> json\n    json j = p;\n    std::cout << \"serialization: \" << j << '\\n';\n}\n
    "},{"location":"api/macros/nlohmann_define_type_non_intrusive/#see-also","title":"See also","text":"
    • NLOHMANN_DEFINE_TYPE_INTRUSIVE / NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT / NLOHMANN_DEFINE_TYPE_INTRUSIVE_ONLY_SERIALIZE - a similar macro that can be defined inside the type
    • NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE / NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_WITH_DEFAULT / NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_ONLY_SERIALIZE / NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE / NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_WITH_DEFAULT / NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE - similar macros for derived types
    • Arbitrary Type Conversions - overview of the supported conversions
    "},{"location":"api/macros/nlohmann_define_type_non_intrusive/#version-history","title":"Version history","text":"
    1. Added in version 3.9.0.
    2. Added in version 3.11.0.
    3. Added in version 3.11.3.

    All three macros were changed to work with any basic_json specialization (not only nlohmann::json) in version 3.12.0, and to allow an empty member list in version 3.13.0 unreleased.

    The generated from_json() reads the views of json_documents since version 3.13.0 unreleased.

    "},{"location":"api/macros/nlohmann_define_type_with_names/","title":"NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_NAMES, NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT_WITH_NAMES, NLOHMANN_DEFINE_TYPE_INTRUSIVE_ONLY_SERIALIZE_WITH_NAMES, NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_NAMES, NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT_WITH_NAMES, NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE_WITH_NAMES, NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_WITH_NAMES, NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_WITH_DEFAULT_WITH_NAMES, NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_ONLY_SERIALIZE_WITH_NAMES, NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_WITH_NAMES, NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_WITH_DEFAULT_WITH_NAMES, NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE_WITH_NAMES","text":"NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_NAMES, NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT_WITH_NAMES, NLOHMANN_DEFINE_TYPE_INTRUSIVE_ONLY_SERIALIZE_WITH_NAMES, NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_NAMES, NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT_WITH_NAMES, NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE_WITH_NAMES, NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_WITH_NAMES, NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_WITH_DEFAULT_WITH_NAMES, NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_ONLY_SERIALIZE_WITH_NAMES, NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_WITH_NAMES, NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_WITH_DEFAULT_WITH_NAMES, NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE_WITH_NAMES
    #define NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_NAMES(type, \"json_member_name\", member...)\n#define NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT_WITH_NAMES(type, \"json_member_name\", member...)\n#define NLOHMANN_DEFINE_TYPE_INTRUSIVE_ONLY_SERIALIZE_WITH_NAMES(type, \"json_member_name\", member...)\n#define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_NAMES(type, \"json_member_name\", member...)\n#define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT_WITH_NAMES(type, \"json_member_name\", member...)\n#define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE_WITH_NAMES(type, \"json_member_name\", member...)\n#define NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_WITH_NAMES(type, base_type, \"json_member_name\", member...)\n#define NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_WITH_DEFAULT_WITH_NAMES(type, base_type, \"json_member_name\", member...)\n#define NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_ONLY_SERIALIZE_WITH_NAMES(type, base_type, \"json_member_name\", member...)\n#define NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_WITH_NAMES(type, base_type, \"json_member_name\", member...)\n#define NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_WITH_DEFAULT_WITH_NAMES(type, base_type, \"json_member_name\", member...)\n#define NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE_WITH_NAMES(type, base_type, \"json_member_name\", member...)\n

    These macros can be used in case you want to use the custom names for the member variables in the resulting JSON. They behave exactly as their non-WITH_NAMES counterparts, but require an additional parameter for each member variable which will be used in JSON. Both serialization and deserialization will only use the custom names for JSON, the names of the member variables themselves will be ignored.

    Using the named conversion macros will halve the maximum number of member variables from 63 to 31.

    For further information please refer to the corresponding macros without WITH_NAMES.

    "},{"location":"api/macros/nlohmann_define_type_with_names/#parameters","title":"Parameters","text":"type (in) name of the type (class, struct) to serialize/deserialize base_type (in) name of the base type (class, struct) type is derived from (used only in DEFINE_DERIVED_TYPE macros) json_member_name (in) the string that will be used as the name for the next value member (in) name of the member variable to serialize/deserialize"},{"location":"api/macros/nlohmann_define_type_with_names/#examples","title":"Examples","text":"Example: NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_NAMES

    Consider the following complete example:

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\nusing namespace nlohmann::literals;\n\nnamespace ns\n{\nstruct person\n{\n    std::string name;\n    std::string address;\n    int age;\n};\n\nNLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_NAMES(person, \"json_name\", name, \"json_address\", address, \"json_age\", age)\n} // namespace ns\n\nint main()\n{\n    ns::person p = {\"Ned Flanders\", \"744 Evergreen Terrace\", 60};\n\n    // serialization: person -> json\n    json j = p;\n    std::cout << \"serialization: \" << j << '\\n';\n\n    // deserialization: json -> person\n    json j2 = R\"({\"json_address\": \"742 Evergreen Terrace\", \"json_age\": 40, \"json_name\": \"Homer Simpson\"})\"_json;\n    auto p2 = j2.template get<ns::person>();\n\n    // incomplete deserialization:\n    json j3 = R\"({\"json_address\": \"742 Evergreen Terrace\", \"json_name\": \"Maggie Simpson\"})\"_json;\n    try\n    {\n        auto p3 = j3.template get<ns::person>();\n    }\n    catch (const json::exception& e)\n    {\n        std::cout << \"deserialization failed: \" << e.what() << '\\n';\n    }\n}\n

    Output:

    serialization: {\"json_address\":\"744 Evergreen Terrace\",\"json_age\":60,\"json_name\":\"Ned Flanders\"}\ndeserialization failed: [json.exception.out_of_range.403] key 'json_age' not found\n

    Notes:

    • ns::person is default-constructible. This is a requirement for using the macro.
    • ns::person has only public member variables. This makes NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_NAMES applicable.
    • The macro NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_NAMES is used outside the class, but inside its namespace ns.
    • A missing key \"age\" in the deserialization yields an exception. To fall back to the default value, NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT_WITH_NAMES can be used.

    The macro is equivalent to:

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\nusing namespace nlohmann::literals;\n\nnamespace ns\n{\nstruct person\n{\n    std::string name;\n    std::string address;\n    int age;\n};\n\ntemplate <typename BasicJsonType, nlohmann::detail::enable_if_t<nlohmann::detail::is_basic_json<BasicJsonType>::value, int> = 0>\nvoid to_json(BasicJsonType& nlohmann_json_j, const person& nlohmann_json_t)\n{\n    nlohmann_json_j[\"json_name\"] = nlohmann_json_t.name;\n    nlohmann_json_j[\"json_address\"] = nlohmann_json_t.address;\n    nlohmann_json_j[\"json_age\"] = nlohmann_json_t.age;\n}\n\ntemplate <typename BasicJsonType, nlohmann::detail::enable_if_t<nlohmann::detail::is_basic_json<BasicJsonType>::value, int> = 0>\nvoid from_json(const BasicJsonType& nlohmann_json_j, person& nlohmann_json_t)\n{\n    nlohmann_json_j.at(\"json_name\").get_to(nlohmann_json_t.name);\n    nlohmann_json_j.at(\"json_address\").get_to(nlohmann_json_t.address);\n    nlohmann_json_j.at(\"json_age\").get_to(nlohmann_json_t.age);\n}\n} // namespace ns\n\nint main()\n{\n    ns::person p = {\"Ned Flanders\", \"744 Evergreen Terrace\", 60};\n\n    // serialization: person -> json\n    json j = p;\n    std::cout << \"serialization: \" << j << '\\n';\n\n    // deserialization: json -> person\n    json j2 = R\"({\"json_address\": \"742 Evergreen Terrace\", \"json_age\": 40, \"json_name\": \"Homer Simpson\"})\"_json;\n    auto p2 = j2.template get<ns::person>();\n\n    // incomplete deserialization:\n    json j3 = R\"({\"json_address\": \"742 Evergreen Terrace\", \"json_name\": \"Maggie Simpson\"})\"_json;\n    try\n    {\n        auto p3 = j3.template get<ns::person>();\n    }\n    catch (const json::exception& e)\n    {\n        std::cout << \"deserialization failed: \" << e.what() << '\\n';\n    }\n}\n
    "},{"location":"api/macros/nlohmann_define_type_with_names/#see-also","title":"See also","text":"
    • NLOHMANN_DEFINE_TYPE_INTRUSIVE / NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT / NLOHMANN_DEFINE_TYPE_INTRUSIVE_ONLY_SERIALIZE - the macros these variants add custom JSON key names to
    • NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE / NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT / NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE - the macros these variants add custom JSON key names to
    • NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE / NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_WITH_DEFAULT / NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_ONLY_SERIALIZE / NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE / NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_WITH_DEFAULT / NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE - similar macros for derived types, also available with custom names
    • Arbitrary Type Conversions - overview of type conversion mechanisms
    "},{"location":"api/macros/nlohmann_define_type_with_names/#version-history","title":"Version history","text":"
    • Added in version 3.13.0 unreleased.
    "},{"location":"api/macros/nlohmann_json_namespace/","title":"NLOHMANN_JSON_NAMESPACE","text":"
    #define NLOHMANN_JSON_NAMESPACE /* value */\n

    This macro evaluates to the full name of the nlohmann namespace.

    "},{"location":"api/macros/nlohmann_json_namespace/#default-definition","title":"Default definition","text":"

    The default value consists of the root namespace (nlohmann) and an inline ABI namespace. See nlohmann Namespace for details.

    When the macro is not defined, the library will define it to its default value. Overriding this value has no effect on the library.

    "},{"location":"api/macros/nlohmann_json_namespace/#examples","title":"Examples","text":"Example

    The example shows how to use NLOHMANN_JSON_NAMESPACE instead of just nlohmann, as well as how to output the value of NLOHMANN_JSON_NAMESPACE.

    #include <iostream>\n#include <nlohmann/json.hpp>\n\n// possible use case: use NLOHMANN_JSON_NAMESPACE instead of nlohmann\nusing NLOHMANN_JSON_NAMESPACE::json;\n\n// macro needed to output the NLOHMANN_JSON_NAMESPACE as string literal\n#define Q(x) #x\n#define QUOTE(x) Q(x)\n\nint main()\n{\n    std::cout << QUOTE(NLOHMANN_JSON_NAMESPACE) << '\\n';\n}\n

    Output:

    nlohmann::json_abi_v3_12_0\n
    "},{"location":"api/macros/nlohmann_json_namespace/#see-also","title":"See also","text":"
    • NLOHMANN_JSON_NAMESPACE_BEGIN, NLOHMANN_JSON_NAMESPACE_END - macros to open and close the library namespace
    • NLOHMANN_JSON_NAMESPACE_NO_VERSION - disable the inline versioned namespace
    • Supported Macros - guide to all supported macros
    • nlohmann Namespace - the library namespace
    "},{"location":"api/macros/nlohmann_json_namespace/#version-history","title":"Version history","text":"
    • Added in version 3.11.0. Changed inline namespace name in version 3.11.2. Added the ABI tag _dp in version 3.12.0, and the ABI tags _bics, _psp, _snul, _sbu8, _ekmo, _dsbs, _dufio, and _ns in version 3.13.0 unreleased; see nlohmann Namespace.
    "},{"location":"api/macros/nlohmann_json_namespace_begin/","title":"NLOHMANN_JSON_NAMESPACE_BEGIN, NLOHMANN_JSON_NAMESPACE_END","text":"
    #define NLOHMANN_JSON_NAMESPACE_BEGIN /* value */  // (1)\n#define NLOHMANN_JSON_NAMESPACE_END   /* value */  // (2)\n

    These macros can be used to open and close the nlohmann namespace. See nlohmann Namespace for details.

    1. Opens the namespace.
    2. Closes the namespace.
    "},{"location":"api/macros/nlohmann_json_namespace_begin/#default-definition","title":"Default definition","text":"

    The default definitions open and close the nlohmann namespace. The precise definition of NLOHMANN_JSON_NAMESPACE_BEGIN varies as described here.

    1. Default definition of NLOHMANN_JSON_NAMESPACE_BEGIN:

      namespace nlohmann\n{\ninline namespace json_abi_v3_12_0\n{\n
    2. Default definition of NLOHMANN_JSON_NAMESPACE_END:

      }  // namespace json_abi_v3_12_0\n}  // namespace nlohmann\n

    When these macros are not defined, the library will define them to their default definitions.

    "},{"location":"api/macros/nlohmann_json_namespace_begin/#examples","title":"Examples","text":"Example

    The example shows how to use NLOHMANN_JSON_NAMESPACE_BEGIN/NLOHMANN_JSON_NAMESPACE_END from the How do I convert third-party types? page.

    #include <iostream>\n#include <optional>\n#include <nlohmann/json.hpp>\n\n// partial specialization (see https://json.nlohmann.me/features/arbitrary_types/)\nNLOHMANN_JSON_NAMESPACE_BEGIN\ntemplate <typename T>\nstruct adl_serializer<std::optional<T>>\n{\n    static void to_json(json& j, const std::optional<T>& opt)\n    {\n        if (opt == std::nullopt)\n        {\n            j = nullptr;\n        }\n        else\n        {\n            j = *opt;\n        }\n    }\n};\nNLOHMANN_JSON_NAMESPACE_END\n\nint main()\n{\n    std::optional<int> o1 = 1;\n    std::optional<int> o2 = std::nullopt;\n\n    NLOHMANN_JSON_NAMESPACE::json j;\n    j.push_back(o1);\n    j.push_back(o2);\n    std::cout << j << '\\n';\n}\n

    Output:

    [1,null]\n
    "},{"location":"api/macros/nlohmann_json_namespace_begin/#see-also","title":"See also","text":"
    • nlohmann Namespace - how the library's namespace is defined and versioned
    • NLOHMANN_JSON_NAMESPACE - macro expanding to the library namespace
    • NLOHMANN_JSON_NAMESPACE_NO_VERSION - disable the inline versioned namespace
    • Supported Macros - guide to all supported macros
    "},{"location":"api/macros/nlohmann_json_namespace_begin/#version-history","title":"Version history","text":"
    • Added in version 3.11.0. Changed inline namespace name in version 3.11.2.
    "},{"location":"api/macros/nlohmann_json_namespace_no_version/","title":"NLOHMANN_JSON_NAMESPACE_NO_VERSION","text":"
    #define NLOHMANN_JSON_NAMESPACE_NO_VERSION /* value */\n

    If defined to 1, the version component is omitted from the inline namespace. See nlohmann Namespace for details.

    "},{"location":"api/macros/nlohmann_json_namespace_no_version/#default-definition","title":"Default definition","text":"

    The default value is 0.

    #define NLOHMANN_JSON_NAMESPACE_NO_VERSION 0\n

    When the macro is not defined, the library will define it to its default value.

    "},{"location":"api/macros/nlohmann_json_namespace_no_version/#examples","title":"Examples","text":"Example

    The example shows how to use NLOHMANN_JSON_NAMESPACE_NO_VERSION to disable the version component of the inline namespace.

    #include <iostream>\n\n#define NLOHMANN_JSON_NAMESPACE_NO_VERSION 1\n#include <nlohmann/json.hpp>\n\n// macro needed to output the NLOHMANN_JSON_NAMESPACE as string literal\n#define Q(x) #x\n#define QUOTE(x) Q(x)\n\nint main()\n{\n    std::cout << QUOTE(NLOHMANN_JSON_NAMESPACE) << '\\n';\n}\n

    Output:

    nlohmann::json_abi\n
    "},{"location":"api/macros/nlohmann_json_namespace_no_version/#see-also","title":"See also","text":"
    • nlohmann Namespace - how the library's namespace is defined and versioned
    • NLOHMANN_JSON_NAMESPACE - macro expanding to the library namespace
    • NLOHMANN_JSON_NAMESPACE_BEGIN, NLOHMANN_JSON_NAMESPACE_END - macros to open and close the library namespace
    • Supported Macros - guide to all supported macros
    "},{"location":"api/macros/nlohmann_json_namespace_no_version/#version-history","title":"Version history","text":"
    • Added in version 3.11.2.
    "},{"location":"api/macros/nlohmann_json_serialize_enum/","title":"NLOHMANN_JSON_SERIALIZE_ENUM","text":"
    #define NLOHMANN_JSON_SERIALIZE_ENUM(type, conversion...)\n

    By default, enum values are serialized to JSON as integers. In some cases, this could result in undesired behavior. If an enum is modified or re-ordered after data has been serialized to JSON, the later deserialized JSON data may be undefined or a different enum value than was originally intended.

    The NLOHMANN_JSON_SERIALIZE_ENUM allows to define a user-defined serialization for every enumerator.

    "},{"location":"api/macros/nlohmann_json_serialize_enum/#parameters","title":"Parameters","text":"type (in) name of the enum to serialize/deserialize conversion (in) a pair of an enumerator and a JSON serialization; arbitrary pairs can be given as a comma-separated list"},{"location":"api/macros/nlohmann_json_serialize_enum/#default-definition","title":"Default definition","text":"

    The macro adds two functions to the namespace which take care of the serialization and deserialization:

    template<typename BasicJsonType>\ninline void to_json(BasicJsonType& j, const type& e);\ntemplate<typename BasicJsonType>\ninline void from_json(const BasicJsonType& j, type& e);\n
    "},{"location":"api/macros/nlohmann_json_serialize_enum/#notes","title":"Notes","text":"

    Prerequisites

    The macro must be used inside the namespace of the enum.

    Important notes

    • When using get<ENUM_TYPE>(), undefined JSON values will default to the first specified conversion. Select this default pair carefully. See example 1 below.
    • If an enum or JSON value is specified in multiple conversions, the first matching conversion from the top of the list will be returned when converting to or from JSON. See example 2 below.
    • Maps with enum keys (e.g., std::map<ENUM_TYPE, T>) are stored as arrays of [key, value] pairs by default. Define JSON_USE_OBJECTS_FOR_ENUM_KEYED_MAPS to store them as objects with the converted keys. Such maps can be read from both forms.

    Views

    The generated from_json() also reads the views of json_documents (<nlohmann/json_view.hpp>), comparing the view with the entries of the mapping, without building a json value first.

    "},{"location":"api/macros/nlohmann_json_serialize_enum/#examples","title":"Examples","text":"Example: Basic usage

    The example shows how NLOHMANN_JSON_SERIALIZE_ENUM can be used to serialize/deserialize both classical enums and C++11 enum classes:

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nnamespace ns\n{\nenum TaskState\n{\n    TS_STOPPED,\n    TS_RUNNING,\n    TS_COMPLETED,\n    TS_INVALID = -1\n};\n\nNLOHMANN_JSON_SERIALIZE_ENUM(TaskState,\n{\n    { TS_INVALID, nullptr },\n    { TS_STOPPED, \"stopped\" },\n    { TS_RUNNING, \"running\" },\n    { TS_COMPLETED, \"completed\" }\n})\n\nenum class Color\n{\n    red, green, blue, unknown\n};\n\nNLOHMANN_JSON_SERIALIZE_ENUM(Color,\n{\n    { Color::unknown, \"unknown\" }, { Color::red, \"red\" },\n    { Color::green, \"green\" }, { Color::blue, \"blue\" }\n})\n} // namespace ns\n\nint main()\n{\n    // serialization\n    json j_stopped = ns::TS_STOPPED;\n    json j_red = ns::Color::red;\n    std::cout << \"ns::TS_STOPPED -> \" << j_stopped\n              << \", ns::Color::red -> \" << j_red << '\\n';\n\n    // deserialization\n    json j_running = \"running\";\n    json j_blue = \"blue\";\n    auto running = j_running.get<ns::TaskState>();\n    auto blue = j_blue.get<ns::Color>();\n    std::cout << j_running << \" -> \" << running\n              << \", \" << j_blue << \" -> \" << static_cast<int>(blue) << '\\n';\n\n    // deserializing undefined JSON value to enum\n    // (where the first map entry above is the default)\n    json j_pi = 3.14;\n    auto invalid = j_pi.get<ns::TaskState>();\n    auto unknown = j_pi.get<ns::Color>();\n    std::cout << j_pi << \" -> \" << invalid << \", \"\n              << j_pi << \" -> \" << static_cast<int>(unknown) << '\\n';\n}\n

    Output:

    ns::TS_STOPPED -> \"stopped\", ns::Color::red -> \"red\"\n\"running\" -> 1, \"blue\" -> 2\n3.14 -> -1, 3.14 -> 3\n
    Example: Multiple conversions for one enumerator

    The example shows how to use multiple conversions for a single enumerator. In the example, Color::red will always be serialized to \"red\", because the first occurring conversion. The second conversion, however, offers an alternative deserialization from \"rot\" to Color::red.

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nnamespace ns\n{\nenum class Color\n{\n    red, green, blue, unknown\n};\n\nNLOHMANN_JSON_SERIALIZE_ENUM(Color,\n{\n    { Color::unknown, \"unknown\" }, { Color::red, \"red\" },\n    { Color::green, \"green\" }, { Color::blue, \"blue\" },\n    { Color::red, \"rot\" } // a second conversion for Color::red\n})\n}\n\nint main()\n{\n    // serialization\n    json j_red = ns::Color::red;\n    std::cout << static_cast<int>(ns::Color::red) << \" -> \" << j_red << '\\n';\n\n    // deserialization\n    json j_rot = \"rot\";\n    auto rot = j_rot.get<ns::Color>();\n    auto red = j_red.get<ns::Color>();\n    std::cout << j_rot << \" -> \" << static_cast<int>(rot) << '\\n';\n    std::cout << j_red << \" -> \" << static_cast<int>(red) << '\\n';\n}\n

    Output:

    0 -> \"red\"\n\"rot\" -> 0\n\"red\" -> 0\n
    "},{"location":"api/macros/nlohmann_json_serialize_enum/#see-also","title":"See also","text":"
    • Specializing enum conversion - serializing enums as JSON strings
    • NLOHMANN_JSON_SERIALIZE_ENUM_STRICT - strict variant that throws on unmapped values
    • JSON_DISABLE_ENUM_SERIALIZATION - disable the default enum conversion
    • JSON_USE_OBJECTS_FOR_ENUM_KEYED_MAPS - serialize maps with enum keys as objects
    "},{"location":"api/macros/nlohmann_json_serialize_enum/#version-history","title":"Version history","text":"

    Added in version 3.4.0.

    The generated from_json() reads the views of json_documents since version 3.13.0 unreleased.

    "},{"location":"api/macros/nlohmann_json_serialize_enum_strict/","title":"NLOHMANN_JSON_SERIALIZE_ENUM_STRICT","text":"
    #define NLOHMANN_JSON_SERIALIZE_ENUM_STRICT(type, conversion...)\n

    By default, enum values are serialized to JSON as integers. In some cases, this could result in undesired behavior. If an enum is modified or re-ordered after data has been serialized to JSON, the later deserialized JSON data may be undefined or a different enum value than was originally intended.

    NLOHMANN_JSON_SERIALIZE_ENUM_STRICT allows to define a user-defined serialization for every enumerator that throws an exception on undefined input.

    "},{"location":"api/macros/nlohmann_json_serialize_enum_strict/#parameters","title":"Parameters","text":"type (in) name of the enum to serialize/deserialize conversion (in) a pair of an enumerator and a JSON serialization; arbitrary pairs can be given as a comma-separated list"},{"location":"api/macros/nlohmann_json_serialize_enum_strict/#default-definition","title":"Default definition","text":"

    The macro adds two functions to the namespace which take care of the serialization and deserialization:

    template<typename BasicJsonType>\ninline void to_json(BasicJsonType& j, const type& e);\ntemplate<typename BasicJsonType>\ninline void from_json(const BasicJsonType& j, type& e);\n
    "},{"location":"api/macros/nlohmann_json_serialize_enum_strict/#notes","title":"Notes","text":"

    Prerequisites

    The macro must be used inside the namespace of the enum.

    Important notes

    • Undefined input throws out_of_range.410 in both directions: when serializing an enum value not listed in the conversions, and when deserializing (e.g., via get<ENUM_TYPE>()) a JSON value that matches no conversion; example: \"enum value out of range for <type>\".
    • If an enum or JSON value is specified in multiple conversions, the first matching conversion from the top of the list will be returned when converting to or from JSON. See example 2 below.
    • Maps with enum keys (e.g., std::map<ENUM_TYPE, T>) are stored as arrays of [key, value] pairs by default. Define JSON_USE_OBJECTS_FOR_ENUM_KEYED_MAPS to store them as objects with the converted keys. Such maps can be read from both forms.

    Views

    The generated from_json() also reads the views of json_documents (<nlohmann/json_view.hpp>), comparing the view with the entries of the mapping, without building a json value first.

    "},{"location":"api/macros/nlohmann_json_serialize_enum_strict/#examples","title":"Examples","text":"Example: Basic usage

    The example shows how NLOHMANN_JSON_SERIALIZE_ENUM_STRICT can be used to serialize/deserialize both classical enums and C++11 enum classes:

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nnamespace ns\n{\nenum TaskState\n{\n    TS_STOPPED,\n    TS_RUNNING,\n    TS_COMPLETED,\n    TS_INVALID = -1\n};\n\nNLOHMANN_JSON_SERIALIZE_ENUM_STRICT(TaskState,\n{\n    { TS_INVALID, nullptr },\n    { TS_STOPPED, \"stopped\" },\n    { TS_RUNNING, \"running\" },\n    { TS_COMPLETED, \"completed\" }\n})\n\nenum class Color\n{\n    red, green, blue, unknown\n};\n\nNLOHMANN_JSON_SERIALIZE_ENUM_STRICT(Color,\n{\n    { Color::unknown, \"unknown\" }, { Color::red, \"red\" },\n    { Color::green, \"green\" }, { Color::blue, \"blue\" }\n})\n} // namespace ns\n\nint main()\n{\n    // serialization\n    json j_stopped = ns::TS_STOPPED;\n    json j_red = ns::Color::red;\n    std::cout << \"ns::TS_STOPPED -> \" << j_stopped\n              << \", ns::Color::red -> \" << j_red << '\\n';\n\n    // deserialization\n    json j_running = \"running\";\n    json j_blue = \"blue\";\n    auto running = j_running.get<ns::TaskState>();\n    auto blue = j_blue.get<ns::Color>();\n    std::cout << j_running << \" -> \" << running\n              << \", \" << j_blue << \" -> \" << static_cast<int>(blue) << '\\n';\n\n}\n

    Output:

    ns::TS_STOPPED -> \"stopped\", ns::Color::red -> \"red\"\n\"running\" -> 1, \"blue\" -> 2\n
    Example: Multiple conversions for one enumerator

    The example shows how to use multiple conversions for a single enumerator. In the example, Color::red will always be serialized to \"red\", because the first occurring conversion. The second conversion, however, offers an alternative deserialization from \"rot\" to Color::red.

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nnamespace ns\n{\nenum class Color\n{\n    red, green, blue, unknown\n};\n\nNLOHMANN_JSON_SERIALIZE_ENUM_STRICT(Color,\n{\n    { Color::unknown, \"unknown\" }, { Color::red, \"red\" },\n    { Color::green, \"green\" }, { Color::blue, \"blue\" },\n    { Color::red, \"rot\" } // a second conversion for Color::red\n})\n}\n\nint main()\n{\n    // serialization\n    json j_red = ns::Color::red;\n    std::cout << static_cast<int>(ns::Color::red) << \" -> \" << j_red << '\\n';\n\n    // deserialization\n    json j_rot = \"rot\";\n    auto rot = j_rot.get<ns::Color>();\n    auto red = j_red.get<ns::Color>();\n    std::cout << j_rot << \" -> \" << static_cast<int>(rot) << '\\n';\n    std::cout << j_red << \" -> \" << static_cast<int>(red) << '\\n';\n}\n

    Output:

    0 -> \"red\"\n\"rot\" -> 0\n\"red\" -> 0\n
    Example: exceptions on invalid serialization

    The example shows how an invalid serialization causes an exception to be thrown. In the example, Color::unknown is not defined in the mapping used to call NLOHMANN_JSON_SERIALIZE_ENUM_STRICT so causes an exception when used to serialize. Similarly, \"what\" does not refer to an enum value so also causes an exception when deserialization is attempted.

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nnamespace ns\n{\n\nenum class Color\n{\n    red,\n    green,\n    blue,\n    unknown // not mapped in JSON_SERIALIZE_ENUM_STRICT\n};\n\nNLOHMANN_JSON_SERIALIZE_ENUM_STRICT(Color,\n{\n    {Color::red, \"red\"},\n    {Color::green, \"green\"},\n    {Color::blue, \"blue\"}\n})\n\n} // namespace ns\n\n\nint main()\n{\n    // invalid serialization\n    try\n    {\n        // ns::color::unknown was not mapped in macro\n        json invalid_serialization = ns::Color::unknown;\n    }\n    catch (const json::exception e)\n    {\n        std::cout << \"deserialization failed: \" << e.what() << '\\n';\n    }\n\n    // invalid deserialization\n    try\n    {\n        // what does not map to an enum\n        json invalid_deserialization(\"what\");\n        ns::Color color = invalid_deserialization.get<ns::Color>();\n    }\n    catch (const json::exception e)\n    {\n        std::cout << \"deserialization failed: \" << e.what() << '\\n';\n    }\n\n    return 0;\n}\n

    Output:

    deserialization failed: [json.exception.out_of_range.410] enum value out of range for Color\ndeserialization failed: [json.exception.out_of_range.410] enum value out of range for Color: \"what\"\n

    "},{"location":"api/macros/nlohmann_json_serialize_enum_strict/#see-also","title":"See also","text":"
    • Specializing enum conversion - serializing enums as JSON strings
    • NLOHMANN_JSON_SERIALIZE_ENUM - non-strict variant that uses the first mapping as default
    • JSON_DISABLE_ENUM_SERIALIZATION - disable the default enum conversion
    • JSON_USE_OBJECTS_FOR_ENUM_KEYED_MAPS - serialize maps with enum keys as objects
    • Arbitrary Type Conversions - converting your own types
    "},{"location":"api/macros/nlohmann_json_serialize_enum_strict/#version-history","title":"Version history","text":"

    Added in version 3.13.0 unreleased.

    "},{"location":"api/macros/nlohmann_json_version_major/","title":"NLOHMANN_JSON_VERSION_MAJOR, NLOHMANN_JSON_VERSION_MINOR, NLOHMANN_JSON_VERSION_PATCH","text":"
    #define NLOHMANN_JSON_VERSION_MAJOR /* value */\n#define NLOHMANN_JSON_VERSION_MINOR /* value */\n#define NLOHMANN_JSON_VERSION_PATCH /* value */\n

    These macros are defined by the library and contain the version numbers according to Semantic Versioning 2.0.0.

    "},{"location":"api/macros/nlohmann_json_version_major/#default-definition","title":"Default definition","text":"

    The macros are defined according to the current library version.

    "},{"location":"api/macros/nlohmann_json_version_major/#examples","title":"Examples","text":"Example

    The example below shows how NLOHMANN_JSON_VERSION_MAJOR, NLOHMANN_JSON_VERSION_MINOR, and NLOHMANN_JSON_VERSION_PATCH are defined by the library.

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    std::cout << \"JSON for Modern C++ version \"\n              << NLOHMANN_JSON_VERSION_MAJOR << \".\"\n              << NLOHMANN_JSON_VERSION_MINOR << \".\"\n              << NLOHMANN_JSON_VERSION_PATCH << '\\n';\n}\n

    Output:

    JSON for Modern C++ version 3.12.0\n
    "},{"location":"api/macros/nlohmann_json_version_major/#see-also","title":"See also","text":"
    • meta - returns version information on the library
    • JSON_SKIP_LIBRARY_VERSION_CHECK - skip library version check
    • Supported Macros - guide to all supported macros
    • Integration - integrate the library
    "},{"location":"api/macros/nlohmann_json_version_major/#version-history","title":"Version history","text":"
    • Added in version 3.1.0.
    "},{"location":"community/","title":"Community","text":"
    • Ecosystem - third-party projects built on top of this library
    • Code of Conduct - the rules and norms of this project
    • Contribution Guidelines - guidelines how to contribute to this project
    • Governance - the governance model of this project
    • Quality Assurance - how the quality of this project is assured
    • Roadmap - what the project will and will not do
    • Security Policy - the security policy of the project
    • Assurance Case - why the library meets its security requirements
    "},{"location":"community/assurance_case/","title":"Assurance case","text":"

    This page argues why the library meets its security requirements. It describes the threats the library faces, where the trust boundaries lie, and how the library's design and the quality assurance counter these threats. To report a vulnerability, see the security policy.

    "},{"location":"community/assurance_case/#threat-model","title":"Threat model","text":"

    The library parses, stores, and serializes JSON values in memory. It does not open network connections, does not open files (it only reads from streams or std::FILE* handles that the caller has already opened), does not read environment variables, and does not implement cryptography or handle credentials.

    The primary threat is therefore untrusted input: JSON text or binary data (BJData, BON8, BSON, CBOR, MessagePack, UBJSON) that an attacker controls, passed to parse, accept, sax_parse, or one of the from_* functions such as from_cbor. Such input may try to

    • make the library read or write out of bounds (malformed lengths, truncated input, invalid UTF-8),
    • trigger undefined behavior (integer overflow in sizes or numbers, invalid casts),
    • exhaust memory (huge announced sizes), or
    • exhaust the call stack (deeply nested arrays and objects).
    "},{"location":"community/assurance_case/#trust-boundaries","title":"Trust boundaries","text":"
    • Untrusted: all serialized input read by the parser, the SAX interface, and the binary readers. The library must handle every possible input by either producing a value or throwing a parse_error (or returning false when exceptions are disabled for the call).
    • Trusted: the C++ code that calls the library. Calling a function with violated preconditions, for instance accessing an array with operator[] out of range, is a programming error and not a security boundary. Such preconditions are checked with runtime assertions in debug builds; functions such as at offer checked access with exceptions.
    flowchart LR\n    A[Untrusted input] --> B[Parser]\n    A --> C[SAX interface]\n    A --> D[Binary readers]\n    B --> E[\"Value tree (basic_json)\"]\n    C --> E\n    D --> E\n    E --> F[Trusted caller]

    The trust boundary: untrusted input enters on the left through the parser, the SAX interface, or the binary readers, and only a value tree reaches the trusted caller on the right.

    "},{"location":"community/assurance_case/#secure-design","title":"Secure design","text":"
    • Strict parsing. The parser accepts exactly the JSON grammar of RFC 8259. Extensions such as comments and trailing commas must be enabled explicitly. Invalid UTF-8 is rejected.
    • Errors are reported, not ignored. Malformed input results in a parse_error with the byte position of the error. Binary readers do not trust announced sizes: strings and binary values grow only as bytes are actually read, arrays reserve at most a fixed number of elements up front, and sizes that no container can hold are rejected.
    • Memory is owned by values. Each basic_json value owns its content, and there is no manual memory management in user code. The destructor does not recurse, so destroying a deeply nested value does not exhaust the stack.
    • Bounded recursion. The JSON parser and the binary readers keep their state in explicit stacks instead of recursing per nesting level. Operations that walk a value, such as dump, copying, comparison, hashing, merge_patch, diff, flatten, and the binary writers, recurse only up to a fixed depth and continue with an explicit stack below it. Applications that process untrusted input can limit its nesting depth with a parser callback.
    • Invariants are checked. The class invariant (for instance, that the pointer for the stored type is never null) is checked with runtime assertions throughout the test suite.
    "},{"location":"community/assurance_case/#common-weaknesses","title":"Common weaknesses","text":"

    The following table maps the relevant classes of the Common Weakness Enumeration to the measures that counter them. The measures are described in detail in Quality assurance.

    Weakness Countermeasures Out-of-bounds read/write (CWE-125, CWE-787) bounds checks on all reads from the input; AddressSanitizer and Valgrind on the test suite; OSS-Fuzz Integer overflow (CWE-190) UndefinedBehaviorSanitizer with integer overflow detection; Clang-Tidy; Cppcheck Use after free, double free (CWE-416, CWE-415) ownership of all memory by values; AddressSanitizer and Valgrind; Clang Static Analyzer Memory leaks (CWE-401) Valgrind (Memcheck) on the test suite Uncontrolled recursion (CWE-674) iterative parser, binary readers, and destructor; bounded recursion in value operations; tests with deeply nested inputs Uncontrolled resource consumption (CWE-400) allocations based on announced sizes are capped; OSS-Fuzz with memory limits Undefined behavior in general (CWE-758) UndefinedBehaviorSanitizer; runtime assertions; Clang-Tidy, Cppcheck, Clang Static Analyzer, Infer

    In addition, every line of the library is covered by the unit tests, and all parsers are fuzz-tested around the clock by OSS-Fuzz.

    "},{"location":"community/code_of_conduct/","title":"Contributor Covenant Code of Conduct","text":""},{"location":"community/code_of_conduct/#our-pledge","title":"Our Pledge","text":"

    We as members, contributors, and leaders pledge to make participation in our community a harassment-free experience for everyone, regardless of age, body size, visible or invisible disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, caste, color, religion, or sexual identity and orientation.

    We pledge to act and interact in ways that contribute to an open, welcoming, diverse, inclusive, and healthy community.

    "},{"location":"community/code_of_conduct/#our-standards","title":"Our Standards","text":"

    Examples of behavior that contributes to a positive environment for our community include:

    • Demonstrating empathy and kindness toward other people
    • Being respectful of differing opinions, viewpoints, and experiences
    • Giving and gracefully accepting constructive feedback
    • Accepting responsibility and apologizing to those affected by our mistakes, and learning from the experience
    • Focusing on what is best not just for us as individuals, but for the overall community

    Examples of unacceptable behavior include:

    • The use of sexualized language or imagery, and sexual attention or advances of any kind
    • Trolling, insulting or derogatory comments, and personal or political attacks
    • Public or private harassment
    • Publishing others' private information, such as a physical or email address, without their explicit permission
    • Other conduct which could reasonably be considered inappropriate in a professional setting
    "},{"location":"community/code_of_conduct/#enforcement-responsibilities","title":"Enforcement Responsibilities","text":"

    Community leaders are responsible for clarifying and enforcing our standards of acceptable behavior and will take appropriate and fair corrective action in response to any behavior that they deem inappropriate, threatening, offensive, or harmful.

    Community leaders have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, and will communicate reasons for moderation decisions when appropriate.

    "},{"location":"community/code_of_conduct/#scope","title":"Scope","text":"

    This Code of Conduct applies within all community spaces, and also applies when an individual is officially representing the community in public spaces. Examples of representing our community include using an official email address, posting via an official social media account, or acting as an appointed representative at an online or offline event.

    "},{"location":"community/code_of_conduct/#enforcement","title":"Enforcement","text":"

    Instances of abusive, harassing, or otherwise unacceptable behavior may be reported to the community leaders responsible for enforcement at mail@nlohmann.me. All complaints will be reviewed and investigated promptly and fairly.

    All community leaders are obligated to respect the privacy and security of the reporter of any incident.

    "},{"location":"community/code_of_conduct/#enforcement-guidelines","title":"Enforcement Guidelines","text":"

    Community leaders will follow these Community Impact Guidelines in determining the consequences for any action they deem in violation of this Code of Conduct:

    "},{"location":"community/code_of_conduct/#1-correction","title":"1. Correction","text":"

    Community Impact: Use of inappropriate language or other behavior deemed unprofessional or unwelcome in the community.

    Consequence: A private, written warning from community leaders, providing clarity around the nature of the violation and an explanation of why the behavior was inappropriate. A public apology may be requested.

    "},{"location":"community/code_of_conduct/#2-warning","title":"2. Warning","text":"

    Community Impact: A violation through a single incident or series of actions.

    Consequence: A warning with consequences for continued behavior. No interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, for a specified period of time. This includes avoiding interactions in community spaces as well as external channels like social media. Violating these terms may lead to a temporary or permanent ban.

    "},{"location":"community/code_of_conduct/#3-temporary-ban","title":"3. Temporary Ban","text":"

    Community Impact: A serious violation of community standards, including sustained inappropriate behavior.

    Consequence: A temporary ban from any sort of interaction or public communication with the community for a specified period of time. No public or private interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, is allowed during this period. Violating these terms may lead to a permanent ban.

    "},{"location":"community/code_of_conduct/#4-permanent-ban","title":"4. Permanent Ban","text":"

    Community Impact: Demonstrating a pattern of violation of community standards, including sustained inappropriate behavior, harassment of an individual, or aggression toward or disparagement of classes of individuals.

    Consequence: A permanent ban from any sort of public interaction within the community.

    "},{"location":"community/code_of_conduct/#attribution","title":"Attribution","text":"

    This Code of Conduct is adapted from the Contributor Covenant, version 2.1, available at https://www.contributor-covenant.org/version/2/1/code_of_conduct.html.

    Community Impact Guidelines were inspired by Mozilla's code of conduct enforcement ladder.

    For answers to common questions about this code of conduct, see the FAQ at https://www.contributor-covenant.org/faq. Translations are available at https://www.contributor-covenant.org/translations.

    "},{"location":"community/contribution_guidelines/","title":"Contribution Guidelines","text":"

    Thank you for your interest in contributing to this project! What began as an exercise to explore the exciting features of C++11 has evolved into a widely used JSON library. I truly appreciate all the contributions from the community, whether it's proposing features, identifying bugs, or fixing mistakes! To ensure that our collaboration is efficient and effective, please follow these guidelines.

    Feel free to discuss or suggest improvements to this document by submitting a pull request.

    "},{"location":"community/contribution_guidelines/#ways-to-contribute","title":"Ways to Contribute","text":"

    There are multiple ways to contribute.

    "},{"location":"community/contribution_guidelines/#reporting-an-issue","title":"Reporting an issue","text":"

    Please create an issue, assuming one does not already exist, and describe your concern. Note you need a GitHub account for this.

    Clearly describe the issue:

    • If it is a bug, please describe how to reproduce it. If possible, attach a complete example which demonstrates the error. Please also state what you expected to happen instead of the error.
    • If you propose a change or addition, try to give an example what the improved code could look like or how to use it.
    • If you found a compilation error, please tell us which compiler (version and operating system) you used and paste the (relevant part of) the error messages to the ticket.

    Please stick to the provided issue template bug report if possible.

    "},{"location":"community/contribution_guidelines/#reporting-a-security-vulnerability","title":"Reporting a security vulnerability","text":"

    You can report a security vulnerability according to our security policy.

    "},{"location":"community/contribution_guidelines/#discussing-a-new-feature","title":"Discussing a new feature","text":"

    For questions, feature or support requests, please open a discussion. If you find a proposed answer satisfactory, please use the \"Mark as answer\" button to make it easier for readers to see what helped and for the community to filter for open questions.

    "},{"location":"community/contribution_guidelines/#proposing-a-fix-or-an-improvement","title":"Proposing a fix or an improvement","text":"

    Join an ongoing discussion or comment on an existing issue before starting to code. This can help to avoid duplicate efforts or other frustration during the later review.

    Create a pull request against the develop branch and follow the pull request template. In particular,

    • describe the changes in detail, both the what and why,
    • reference existing issues where applicable,
    • add tests to maintain 100% test coverage,
    • update the documentation as needed, and
    • ensure the source code is amalgamated.

    We describe all points in detail below.

    All contributions (including pull requests) must agree to the Developer Certificate of Origin (DCO) version 1.1. This is exactly the same one created and used by the Linux kernel developers and posted on http://developercertificate.org/. This is a developer's certification that he or she has the right to submit the patch for inclusion into the project.

    "},{"location":"community/contribution_guidelines/#how-to","title":"How to...","text":""},{"location":"community/contribution_guidelines/#describe-your-changes","title":"Describe your changes","text":"

    This library is primarily maintained as a spare-time project. As such, I cannot make any guarantee how quickly changes are merged and released. Therefore, it is very important to make the review as smooth as possible by explaining not only what you changed, but why. This rationale can be very valuable down the road when improvements or bugs are discussed years later.

    "},{"location":"community/contribution_guidelines/#reference-an-existing-issue","title":"Reference an existing issue","text":"

    Link a pull request to an issue to clarify that a fix is forthcoming and which issue can be closed after merging. Only a few cases (e.g., fixing typos) do not require prior discussions.

    "},{"location":"community/contribution_guidelines/#write-tests","title":"Write tests","text":"

    The library has an extensive test suite that currently covers 100 % of the library's code. These tests are crucial to maintain API stability and give future contributors confidence that they do not accidentally break things. As Titus Winters aptly put it:

    If you liked it, you should have put a test on it.

    "},{"location":"community/contribution_guidelines/#run-the-tests","title":"Run the tests","text":"

    First, ensure the test suite runs before making any changes:

    $ cmake -S. -B build\n$ cmake --build build -j 10\n$ ctest --test-dir build -j 10\n

    The test suite should report:

    100% tests passed, 0 tests failed out of <number of tests>\n
    "},{"location":"community/contribution_guidelines/#add-tests","title":"Add tests","text":"

    The tests are located in tests/src/unit-*.cpp and contain doctest assertions like CHECK. The tests are structured along the features of the library or the nature of the tests. Usually, it should be clear from the context which existing file needs to be extended, and only very few cases require creating new test files.

    When fixing a bug, edit unit-regression3.cpp and add a section referencing the fixed issue. unit-regression2.cpp holds the older tests; the two files exist because a single one grew large enough for the MinGW linker to fail relocating it, so please keep adding to the smaller file rather than growing the larger one.

    "},{"location":"community/contribution_guidelines/#exceptions","title":"Exceptions","text":"

    When you test exceptions, please use CHECK_THROWS_WITH_AS which also takes the what() argument of the thrown exception into account.

    "},{"location":"community/contribution_guidelines/#coverage","title":"Coverage","text":"

    If test coverage decreases, an automatic warning comment will be posted on the pull request. You can access a code coverage report as an artifact to the \u201cUbuntu\u201d workflow.

    "},{"location":"community/contribution_guidelines/#update-the-documentation","title":"Update the documentation","text":"

    The main documentation of the library is generated from the files docs/mkdocs/docs. This folder contains dedicated pages for certain features, a list of all exceptions, and extensive API documentation with details on every public API function.

    Build the documentation locally using:

    make install_venv -C docs/mkdocs\nmake serve -C docs/mkdocs\n

    The documentation will then be available at http://127.0.0.1:8000/. See the documentation of mkdocs and Material for MkDocs for more information.

    Before opening a pull request, check the documentation like the CI does:

    make build -C docs/mkdocs          # strict build: fails on broken links, anchors, and structure problems\nmake check_mermaid -C docs/mkdocs  # checks the Mermaid diagrams (requires Node.js)\n

    The search index of the docset is generated from mkdocs.yml and each page's title (H1) and declaration by docs/docset/generate_docset.py; make build reports API pages that cannot be classified.

    "},{"location":"community/contribution_guidelines/#amalgamate-the-source-code","title":"Amalgamate the source code","text":"

    The single-header files single_include/nlohmann/json.hpp, single_include/nlohmann/json_fwd.hpp, and single_include/nlohmann/json_literals.hpp are generated from the source files in the include/nlohmann directory. Do not edit the files directly; instead, modify the include/nlohmann sources and regenerate the files by executing:

    make amalgamate\n

    Running make amalgamate will also apply automatic formatting to the source files using Artistic Style. This formatting may modify your source files in-place. Be certain to review and commit any changes to avoid unintended formatting diffs in commits.

    If you add, rename, or remove a header in include/nlohmann, also regenerate the header list in BUILD.bazel (requires CMake) by executing:

    make BUILD.bazel\n

    The amalgamation check in CI fails if any of these generated files is out of date.

    "},{"location":"community/contribution_guidelines/#recommended-documentation","title":"Recommended documentation","text":"
    • The library\u2019s README file is an excellent starting point to understand its functionality.
    • The documentation page is the reference documentation of the library.
    • RFC 8259 is the reference for the JavaScript Object Notation (JSON) Data Interchange Format.
    "},{"location":"community/contribution_guidelines/#please-dont","title":"Please don't...","text":"

    Certain contributions are not helpful.

    "},{"location":"community/contribution_guidelines/#break-the-public-api","title":"Break the public API","text":"

    We take pride in the library being used by numerous customers across various industries. They all rely on the guarantees provided by semantic versioning. Please do not change the library such that the public API of the 3.x.y version is broken. This includes:

    • Changing function signatures (altering parameter types, return types, number of parameters) or changing the const-ness of member functions.
    • Removing functions.
    • Renaming functions or classes.
    • Changing exception handling.
    • Changing exception ids.
    • Changing access specifiers.
    • Changing default arguments.

    What is and is not covered by this guarantee is described in the roadmap.

    Although these guidelines may seem restrictive, they are essential for maintaining the library\u2019s utility.

    Breaking changes may be introduced when they are guarded with a feature macro such as JSON_USE_IMPLICIT_CONVERSIONS which allows selectively changing the behavior of the library. In next steps, the current behavior can then be deprecated. Using feature macros then allows users to test their code against the library in the next major release.

    "},{"location":"community/contribution_guidelines/#break-c11-language-conformance","title":"Break C++11 language conformance","text":"

    This library is designed to work with C++11 and later. This means that any supported C++11 compiler should compile the library without problems. Some compilers like GCC 4.7 (and earlier), Clang 3.3 (and earlier), or Microsoft Visual C++ 2013 and earlier are known not to work due to missing or incomplete C++11 support.

    Please do not add features that do not work with the mentioned supported compilers. Please guard features from C++14 and later against the respective JSON_HAS_CPP_14 macros.

    "},{"location":"community/contribution_guidelines/#break-json-conformance","title":"Break JSON conformance","text":"

    Please refrain from proposing changes that would break JSON conformance. If you propose a conformant extension of JSON to be supported by the library, please motivate this extension.

    "},{"location":"community/contribution_guidelines/#wanted","title":"Wanted","text":"

    The following areas really need contribution and are always welcomed:

    • Extending the continuous integration toward more exotic compilers such as Android NDK, Intel's Compiler, or the bleeding-edge versions of Clang.
    • Improving the efficiency of the JSON parser. The current parser is a hand-written iterative parser that keeps an explicit stack instead of recursing, with hand-coded string handling. Speeding up the lexer or the value construction would be appreciated. Parser generators like Bison or ANTLR do not play nice with single-header files -- I really would like to keep the parser inside the json.hpp header.
    • Extending and updating existing benchmarks to include (the most recent version of) this library. Though efficiency is not everything, speed and memory consumption are very important characteristics for C++ developers, so having proper comparisons would be interesting.

    We look forward to your contributions and collaboration to enhance the library!

    "},{"location":"community/ecosystem/","title":"Ecosystem","text":"

    The projects below build on top of nlohmann::json rather than merely using it - schema validators, language bindings, format converters, and similar building blocks. The list is not exhaustive, and is curated rather than automatically generated. If you maintain or know of a project that belongs here, please let me know.

    For products, applications, and organizations that use the library, see Customers instead.

    "},{"location":"community/ecosystem/#schema-validation","title":"Schema validation","text":"
    • json-schema-validator, a JSON Schema (draft 7) validator with human-readable error messages
    "},{"location":"community/ecosystem/#serialization-and-reflection","title":"Serialization and reflection","text":"
    • nlohmann_json_reflect, a reflection extension for (de)serializing nested containers-in-structs-in-containers
    "},{"location":"community/ecosystem/#encodings","title":"Encodings","text":"
    • base-encode-decode, a header-only Base64/32/16/8/4/2 (and DNA/RNA) encoding library, with an adapter that serializes binary data through nlohmann::json
    "},{"location":"community/ecosystem/#language-bindings-and-interop","title":"Language bindings and interop","text":"
    • pybind11_json, a bidirectional type caster between nlohmann::json and Python objects for pybind11 bindings
    • nanobind_json, the same idea for nanobind bindings
    • nlohmann_json_qt, deserialization helpers for Qt types (QString, QUrl, QDateTime, QVector, ...) from nlohmann::json
    • vulkan2json, serialization and deserialization of Vulkan API structs
    "},{"location":"community/ecosystem/#format-converters","title":"Format converters","text":"
    • tojson, a header-only converter between YAML/XML documents and nlohmann::json
    • json2xml, a header-only converter from nlohmann::json to XML for simple configuration documents
    "},{"location":"community/governance/","title":"Governance","text":"

    The governance model for the JSON for Modern C++ project is a Benevolent Dictator for Life (BDFL) structure. As the sole maintainer, Niels Lohmann is responsible for all key aspects of the project. The project governance may evolve as the project grows, but any changes will be documented here and communicated to contributors.

    "},{"location":"community/governance/#overview","title":"Overview","text":"

    This project is led by a benevolent dictator, Niels Lohmann, and managed by the community. That is, the community actively contributes to the day-to-day maintenance of the project, but the general strategic line is drawn by the benevolent dictator. In case of disagreement, they have the last word. It is the benevolent dictator\u2019s job to resolve disputes within the community and to ensure that the project is able to progress in a coordinated way. In turn, it is the community\u2019s job to guide the decisions of the benevolent dictator through active engagement and contribution.

    "},{"location":"community/governance/#roles-and-responsibilities","title":"Roles and responsibilities","text":""},{"location":"community/governance/#benevolent-dictator-project-lead","title":"Benevolent dictator (project lead)","text":"

    Typically, the benevolent dictator, or project lead, is self-appointed. However, because the community always has the ability to fork, this person is fully answerable to the community. The project lead\u2019s role is a difficult one: they set the strategic objectives of the project and communicate these clearly to the community. They also have to understand the community as a whole and strive to satisfy as many conflicting needs as possible, while ensuring that the project survives in the long term.

    In many ways, the role of the benevolent dictator is less about dictatorship and more about diplomacy. The key is to ensure that, as the project expands, the right people are given influence over it and the community rallies behind the vision of the project lead. The lead\u2019s job is then to ensure that the committers (see below) make the right decisions on behalf of the project. Generally speaking, as long as the committers are aligned with the project\u2019s strategy, the project lead will allow them to proceed as they desire.

    "},{"location":"community/governance/#committers","title":"Committers","text":"

    Committers are contributors who have made several valuable contributions to the project and are now relied upon to both write code directly to the repository and screen the contributions of others. In many cases they are programmers but it is also possible that they contribute in a different role. Typically, a committer will focus on a specific aspect of the project, and will bring a level of expertise and understanding that earns them the respect of the community and the project lead. The role of committer is not an official one, it is simply a position that influential members of the community will find themselves in as the project lead looks to them for guidance and support.

    Committers have no authority over the overall direction of the project. However, they do have the ear of the project lead. It is a committer\u2019s job to ensure that the lead is aware of the community\u2019s needs and collective objectives, and to help develop or elicit appropriate contributions to the project. Often, committers are given informal control over their specific areas of responsibility, and are assigned rights to directly modify certain areas of the source code. That is, although committers do not have explicit decision-making authority, they will often find that their actions are synonymous with the decisions made by the lead.

    "},{"location":"community/governance/#contributors","title":"Contributors","text":"

    Contributors are community members who either have no desire to become committers, or have not yet been given the opportunity by the benevolent dictator. They make valuable contributions, such as those outlined in the list below, but generally do not have the authority to make direct changes to the project code. Contributors engage with the project through communication tools, such as email lists, and via reports and patches attached to issues in the issue tracker, as detailed in our community tools document.

    Anyone can become a contributor. There is no expectation of commitment to the project, no specific skill requirements and no selection process. To become a contributor, a community member simply has to perform one or more actions that are beneficial to the project.

    Some contributors will already be engaging with the project as users, but will also find themselves doing one or more of the following:

    • supporting new users (current users often provide the most effective new user support)
    • reporting bugs
    • identifying requirements
    • supplying graphics and web design
    • programming
    • assisting with project infrastructure
    • writing documentation
    • fixing bugs
    • adding features

    As contributors gain experience and familiarity with the project, they may find that the project lead starts relying on them more and more. When this begins to happen, they gradually adopt the role of committer, as described above.

    "},{"location":"community/governance/#users","title":"Users","text":"

    Users are community members who have a need for the project. They are the most important members of the community: without them, the project would have no purpose. Anyone can be a user; there are no specific requirements.

    Users should be encouraged to participate in the life of the project and the community as much as possible. User contributions enable the project team to ensure that they are satisfying the needs of those users. Common user activities include (but are not limited to):

    • evangelising about the project
    • informing developers of project strengths and weaknesses from a new user\u2019s perspective
    • providing moral support (a \u2018thank you\u2019 goes a long way)
    • providing financial support

    Users who continue to engage with the project and its community will often find themselves becoming more and more involved. Such users may then go on to become contributors, as described above.

    "},{"location":"community/governance/#access-to-project-resources","title":"Access to project resources","text":"

    The project's resources are the GitHub repository with its settings, CI workflows and secrets, and the documentation at json.nlohmann.me, which is built and deployed from the repository. Currently, the project lead is the only person with write or admin access to them.

    "},{"location":"community/governance/#granting-access","title":"Granting access","text":"

    Write or admin access is only granted by the project lead, and only to a contributor whose track record in the project the project lead has reviewed first. The role is assigned manually and is the lowest one that is needed for the task. Access is removed when it is no longer needed. GitHub requires two-factor authentication for everyone who can modify the repository.

    "},{"location":"community/governance/#secrets","title":"Secrets","text":"

    The CI workflows mostly use the token that GitHub creates for each workflow run. It is read-only by default, and each workflow requests only the additional permissions it needs. The few other credentials, such as the token for Semgrep, are stored as encrypted GitHub Actions secrets:

    • Only people with admin access can create, change, or delete them. Their values cannot be read back, not even by admins.
    • They are not passed to workflows that run for pull requests from forks.
    • They must never be committed to the repository or printed in logs.
    • They are rotated whenever someone with admin access leaves the project, and immediately if a leak is suspected.
    "},{"location":"community/governance/#support","title":"Support","text":"

    All participants in the community are encouraged to provide support for new users within the project management infrastructure. This support is provided as a way of growing the community. Those seeking support should recognise that all support activity within the project is voluntary and is therefore provided as and when time allows. A user requiring guaranteed response times or results should therefore seek to purchase a support contract from a vendor. (Of course, that vendor should be an active member of the community.) However, for those willing to engage with the project on its own terms, and willing to help support other users, the community support channels are ideal.

    "},{"location":"community/governance/#contribution-process","title":"Contribution Process","text":"

    Anyone can contribute to the project, regardless of their skills, as there are many ways to contribute. For instance, a contributor might be active on the project mailing list and issue tracker, or might supply patches. The various ways of contributing are described in more detail in our roles in open source document.

    The developer mailing list is the most appropriate place for a contributor to ask for help when making their first contribution.

    "},{"location":"community/governance/#decision-making-process","title":"Decision-Making Process","text":"

    The benevolent dictatorship model does not need a formal conflict resolution process, since the project lead\u2019s word is final. If the community chooses to question the wisdom of the actions of a committer, the project lead can review their decisions by checking the email archives, and either uphold or reverse them.

    Source

    The text was taken from http://oss-watch.ac.uk/resources/benevolentdictatorgovernancemodel.

    "},{"location":"community/quality_assurance/","title":"Quality assurance","text":"

    Ensuring quality is paramount for this project, particularly because numerous other projects depend on it. Each commit to the library undergoes rigorous checks against the following requirements, and any violations will result in a failed build.

    The overview shows the checks a change passes on its way from a push or pull request to a release; the sections below describe each of them.

    Quality assurance pipeline Every push or pull request starts these checks in parallel: Build matrix (every push / PR): 50+ compilers: G\u200bCC, Clang, M\u200bSVC, AppleClang, Intel, NVIDIA, ... C++11, 14, 17, 20, 23, and 26 libc++ and libstdc++ warnings: Clang -Weverything, G\u200bCC 300+ warnings; Unit tests (doctest) (every push / PR): every public A\u200bPI function every exception id and message all Unicode code points single header and split headers custom number, string, array, and object types; Coverage (every push / PR): unit tests cover all lines of the code base; Static analysis (every push / PR, scheduled): Clang-Tidy, Cppcheck, Infer Clang Static Analyzer (52 checkers), I\u200bWYU, Codacy CodeQL, Semgrep, Flawfinder (also scheduled); Dynamic analysis (every push / PR): runtime assertions Valgrind (Memcheck) address and undefined behavior sanitizers, integer overflow, nullability violations; Fuzzing (every PR, continuous): CIFuzz on every pull request OSS-Fuzz: billions of inputs every crash fixed with a reproducing unit test; Style (every push / PR): Artistic Style (astyle), enforced in the C\u200bI cpplint with 61 rules; Docs and examples (every push / PR, scheduled): every documentation example is tested; changed output fails site built with warnings as errors; links checked regularly (scheduled); Integration, supply chain (every push / PR, scheduled): CMake 3.5, 3.31.6, and 4.0.0 Meson, Swift Package Manager dependency review on every PR Dependabot daily, OpenSSF Scorecard, R\u200bEUSE. When they pass, the change is merged into develop; a release is made only when no vulnerability alert is open. push or pull request checks, run in parallel on GitHub Actions and AppVeyor Build matrix every push / PR 50+ compilers: G\u200bCC, Clang, M\u200bSVC, AppleClang, Intel, NVIDIA, ... C++11, 14, 17, 20, 23, and 26 libc++ and libstdc++ warnings: Clang -Weverything, G\u200bCC 300+ warnings Unit tests (doctest) every push / PR every public A\u200bPI function every exception id and message all Unicode code points single header and split headers custom number, string, array, and object types Coverage every push / PR unit tests cover all lines of the code base Static analysis every push / PR scheduled Clang-Tidy, Cppcheck, Infer Clang Static Analyzer (52 checkers), I\u200bWYU, Codacy CodeQL, Semgrep, Flawfinder (also scheduled) Dynamic analysis every push / PR runtime assertions Valgrind (Memcheck) address and undefined behavior sanitizers, integer overflow, nullability violations Fuzzing every PR continuous CIFuzz on every pull request OSS-Fuzz: billions of inputs every crash fixed with a reproducing unit test Style every push / PR Artistic Style (astyle), enforced in the C\u200bI cpplint with 61 rules Docs and examples every push / PR scheduled every documentation example is tested; changed output fails site built with warnings as errors; links checked regularly (scheduled) Integration, supply chain every push / PR scheduled CMake 3.5, 3.31.6, and 4.0.0 Meson, Swift Package Manager dependency review on every PR Dependabot daily, OpenSSF Scorecard, R\u200bEUSE merge into develop release no open vulnerability alert Quality assurance pipeline Every push or pull request starts these checks in parallel: Build matrix (every push / PR): 50+ compilers: G\u200bCC, Clang, M\u200bSVC, AppleClang, Intel, NVIDIA, ... C++11, 14, 17, 20, 23, and 26 libc++ and libstdc++ warnings: Clang -Weverything, G\u200bCC 300+ warnings; Unit tests (doctest) (every push / PR): every public A\u200bPI function every exception id and message all Unicode code points single header and split headers custom number, string, array, and object types; Coverage (every push / PR): unit tests cover all lines of the code base; Static analysis (every push / PR, scheduled): Clang-Tidy, Cppcheck, Infer Clang Static Analyzer (52 checkers), I\u200bWYU, Codacy CodeQL, Semgrep, Flawfinder (also scheduled); Dynamic analysis (every push / PR): runtime assertions Valgrind (Memcheck) address and undefined behavior sanitizers, integer overflow, nullability violations; Fuzzing (every PR, continuous): CIFuzz on every pull request OSS-Fuzz: billions of inputs every crash fixed with a reproducing unit test; Style (every push / PR): Artistic Style (astyle), enforced in the C\u200bI cpplint with 61 rules; Docs and examples (every push / PR, scheduled): every documentation example is tested; changed output fails site built with warnings as errors; links checked regularly (scheduled); Integration, supply chain (every push / PR, scheduled): CMake 3.5, 3.31.6, and 4.0.0 Meson, Swift Package Manager dependency review on every PR Dependabot daily, OpenSSF Scorecard, R\u200bEUSE. When they pass, the change is merged into develop; a release is made only when no vulnerability alert is open. push or pull request checks, run in parallel Build matrix every push / PR 50+ compilers: G\u200bCC, Clang, M\u200bSVC, AppleClang, Intel, NVIDIA, ... C++11, 14, 17, 20, 23, and 26 libc++ and libstdc++ warnings: Clang -Weverything, G\u200bCC 300+ warnings Unit tests (doctest) every push / PR every public A\u200bPI function every exception id and message all Unicode code points single header and split headers custom number, string, array, and object types Coverage every push / PR unit tests cover all lines of the code base Static analysis every push / PR scheduled Clang-Tidy, Cppcheck, Infer Clang Static Analyzer (52 checkers), I\u200bWYU, Codacy CodeQL, Semgrep, Flawfinder (also scheduled) Dynamic analysis every push / PR runtime assertions Valgrind (Memcheck) address and undefined behavior sanitizers, integer overflow, nullability violations Fuzzing every PR continuous CIFuzz on every pull request OSS-Fuzz: billions of inputs every crash fixed with a reproducing unit test Style every push / PR Artistic Style (astyle), enforced in the C\u200bI cpplint with 61 rules Docs and examples every push / PR scheduled every documentation example is tested; changed output fails site built with warnings as errors; links checked regularly (scheduled) Integration, supply chain every push / PR scheduled CMake 3.5, 3.31.6, and 4.0.0 Meson, Swift Package Manager dependency review on every PR Dependabot daily, OpenSSF Scorecard, R\u200bEUSE merge into develop release no open vulnerability alert

    The checks grouped by the stage at which they run, from push or pull request through the merge into develop to a release. The badge on each card says whether the check runs on every push or PR, on a schedule, or continuously.

    "},{"location":"community/quality_assurance/#c-language-compliance-and-compiler-compatibility","title":"C++ language compliance and compiler compatibility","text":"

    Requirement: Compiler support

    Any compiler with complete C++11 support can compile the library without warnings.

    Note: C++20 modules support may hit compiler-specific issues not covered by the general compiler matrix below. See Modules for known issues and workarounds.

    Note: Some modern features (like C++20 ranges or filesystem support) may be disabled on specific broken or incomplete toolchains even when standard feature-test macros indicate support. See JSON_HAS_RANGES, JSON_HAS_RANGE_VIEW_CONVERSION, and JSON_HAS_FILESYSTEM for details on known exclusions.

    • The library is compiled with 50+ different C++ compilers with different operating systems and platforms, including the oldest versions known to compile the library.

      Compilers used in continuous integration Compiler Architecture Operating System CI AppleClang 16.0.0.16000026; Xcode 16 arm64 macOS 15.2 (Sequoia) GitHub AppleClang 16.0.0.16000026; Xcode 16.1 arm64 macOS 15.2 (Sequoia) GitHub AppleClang 16.0.0.16000026; Xcode 16.2 arm64 macOS 15.2 (Sequoia) GitHub AppleClang 17.0.0.17000013; Xcode 16.3 arm64 macOS 15.5 (Sequoia) GitHub AppleClang 17.0.0.17000013; Xcode 16.4 arm64 macOS 15.5 (Sequoia) GitHub AppleClang 17.0.0.17000319; Xcode 26.0.1 arm64 macOS 15.5 (Sequoia) GitHub AppleClang 17.0.0.17000404; Xcode 26.1.1 arm64 macOS 15.7.9 (Sequoia) GitHub AppleClang 17.0.0.17000603; Xcode 26.2 arm64 macOS 15.7.9 (Sequoia) GitHub AppleClang 17.0.0.17000604; Xcode 26.3 arm64 macOS 15.7.9 (Sequoia) GitHub AppleClang 21.0.0.21000099; Xcode 26.4.1 arm64 macOS 26.6.2 (Tahoe) GitHub AppleClang 21.0.0.21000101; Xcode 26.5 arm64 macOS 26.6.2 (Tahoe) GitHub AppleClang 21.0.0.21000101; Xcode 26.6 arm64 macOS 26.6.2 (Tahoe) GitHub Clang 3.4.2 x86_64 Ubuntu 22.04.1 LTS GitHub Clang 3.5.2 x86_64 Ubuntu 22.04.1 LTS GitHub Clang 3.6.2 x86_64 Ubuntu 22.04.1 LTS GitHub Clang 3.7.1 x86_64 Ubuntu 22.04.1 LTS GitHub Clang 3.8.1 x86_64 Ubuntu 22.04.1 LTS GitHub Clang 3.9.1 x86_64 Ubuntu 22.04.1 LTS GitHub Clang 4.0.1 x86_64 Ubuntu 22.04.1 LTS GitHub Clang 5.0.2 x86_64 Ubuntu 22.04.1 LTS GitHub Clang 6.0.1 x86_64 Ubuntu 22.04.1 LTS GitHub Clang 7.1.0 x86_64 Ubuntu 22.04.1 LTS GitHub Clang 8.0.1 x86_64 Ubuntu 22.04.1 LTS GitHub Clang 9.0.1 x86_64 Ubuntu 22.04.1 LTS GitHub Clang 10.0.1 x86_64 Ubuntu 22.04.1 LTS GitHub Clang 11.0.1 with GNU-like command-line x86_64 Windows Server 2022 (Build 20348) GitHub Clang 11.1.0 x86_64 Ubuntu 22.04.1 LTS GitHub Clang 12.0.1 with GNU-like command-line x86_64 Windows Server 2022 (Build 20348) GitHub Clang 12.0.1 x86_64 Ubuntu 22.04.1 LTS GitHub Clang 13.0.1 with GNU-like command-line x86_64 Windows Server 2022 (Build 20348) GitHub Clang 13.0.1 x86_64 Ubuntu 22.04.1 LTS GitHub Clang 14.0.6 x86_64 Ubuntu 22.04.1 LTS GitHub Clang 14.0.6 with GNU-like command-line x86_64 Windows Server 2022 (Build 20348) GitHub Clang 15.0.7 x86_64 Ubuntu 22.04.1 LTS GitHub Clang 15.0.7 with GNU-like command-line x86_64 Windows Server 2022 (Build 20348) GitHub Clang 16.0.6 x86_64 Ubuntu 22.04.1 LTS GitHub Clang 16.0.6 with GNU-like command-line x86_64 Windows Server 2022 (Build 20348) GitHub Clang 17.0.6 x86_64 Ubuntu 22.04.1 LTS GitHub Clang 18.1.8 x86_64 Ubuntu 22.04.1 LTS GitHub Clang 18.1.8 with GNU-like command-line x86_64 Windows Server 2022 (Build 20348) GitHub Clang 19.1.5 with MSVC-like command-line x86_64 Windows Server 2022 (Build 20348) GitHub Clang 19.1.7 x86_64 Ubuntu 22.04.1 LTS GitHub Clang 19.1.7 with GNU-like command-line x86_64 Windows Server 2022 (Build 20348) GitHub Clang 20.1.1 x86_64 Ubuntu 22.04.1 LTS GitHub Clang 20.1.8 with GNU-like command-line x86_64 Windows Server 2022 (Build 20348) GitHub Clang 21.1.8 x86_64 Ubuntu 22.04.1 LTS GitHub Clang 22.1.8 x86_64 Ubuntu 22.04.1 LTS GitHub CUDA 11.8.0 (nvcc) x86_64 Ubuntu 22.04 LTS GitHub CUDA 12.1.1 (nvcc) x86_64 Ubuntu 22.04 LTS GitHub CUDA 12.6.3 (nvcc) x86_64 Ubuntu 22.04 LTS GitHub Emscripten 4.0.6 x86_64 Ubuntu 22.04.1 LTS GitHub GNU 4.8.5 x86_64 Ubuntu 20.04 LTS GitHub GNU 4.9.3 x86_64 Ubuntu 20.04 LTS GitHub GNU 5.5.0 x86_64 Ubuntu 20.04 LTS GitHub GNU 6.4.0 x86_64 Ubuntu 20.04 LTS GitHub GNU 7.5.0 x86_64 Ubuntu 22.04.1 LTS GitHub GNU 8.5.0 x86_64 Ubuntu 22.04.1 LTS GitHub GNU 9.3.0 x86_64 Ubuntu 22.04.1 LTS GitHub GNU 9.4.0 x86_64 Ubuntu 22.04.1 LTS GitHub GNU 9.5.0 x86_64 Ubuntu 22.04.1 LTS GitHub GNU 10.5.0 x86_64 Ubuntu 22.04.1 LTS GitHub GNU 11.4.0 x86_64 Ubuntu 22.04.1 LTS GitHub GNU 11.5.0 x86_64 Ubuntu 22.04.1 LTS GitHub GNU 12.2.0 (MinGW-W64 i686-ucrt-posix-dwarf) x86_64 Windows Server 2022 (Build 20348) GitHub GNU 12.2.0 (MinGW-W64 x86_64-ucrt-posix-seh) x86_64 Windows Server 2022 (Build 20348) GitHub GNU 12.4.0 x86_64 Ubuntu 22.04.1 LTS GitHub GNU 13.3.0 x86_64 Ubuntu 22.04.1 LTS GitHub GNU 14.2.0 x86_64 Ubuntu 22.04.1 LTS GitHub GNU 15.1.0 x86_64 Ubuntu 22.04.1 LTS GitHub GNU 16.2.0 x86_64 Ubuntu 22.04.1 LTS GitHub GNU 16.1.0 arm64 Ubuntu 24.04 GitHub icpc (ICC) 2021.10.0 20230609 x86_64 Ubuntu 22.04 LTS GitHub icpx (Intel oneAPI DPC++/C++) 2025.3.2 x86_64 Ubuntu 24.04 LTS GitHub nvc++ (NVIDIA HPC SDK) 25.5-0 x86_64 Ubuntu 22.04 LTS GitHub MSVC 19.0.24241.7 x86 Windows 8.1 AppVeyor MSVC 19.16.27035.0 x86 Windows-10 (Build 14393) AppVeyor MSVC 19.29.30157.0 x86 Windows-10 (Build 17763) AppVeyor MSVC 19.44.35207.0 arm64 Windows 11 (Build 26200) GitHub MSVC 19.44.35214.0 x86 Windows Server 2022 (Build 20348) GitHub MSVC 19.44.35214.0 x86_64 Windows Server 2022 (Build 20348) GitHub MSVC 19.51.36231.0 x86 Windows Server 2025 (Build 26100) GitHub MSVC 19.51.36231.0 x86_64 Windows Server 2025 (Build 26100) GitHub
    • The library is compiled with all C++ language revisions (C++11, C++14, C++17, C++20, C++23, and C++26) to detect and fix language deprecations early.

    • The library is checked for compiler warnings:
    • On Clang, -Weverything is used with 7 exceptions.

      Clang warnings
      # Ignored Clang warnings:\n# -Wno-c++98-compat               The library targets C++11.\n# -Wno-c++98-compat-pedantic      The library targets C++11.\n# -Wno-deprecated-declarations    The library contains annotations for deprecated functions.\n# -Wno-padded                     We do not care about padding warnings.\n# -Wno-covered-switch-default     All switches list all cases and a default case.\n# -Wno-c2y-extensions             Clang 22.1 diagnoses __COUNTER__ as a C2y extension, also in\n#                                 C++ mode. The library does not use __COUNTER__; the warnings\n#                                 all come from vendored Doctest (SECTION/TEST_CASE macros).\n# -Wno-unsafe-buffer-usage        Pervasive: the library's own low-level numeric/buffer code\n#                                 (to_chars, serializer, lexer, binary reader/writer, input\n#                                 adapters, json_pointer) plus vendored Doctest itself (~208\n#                                 distinct sites measured 2026-07-08 on clang trunk) all use\n#                                 raw pointer arithmetic / libc string calls by necessity.\n\nset(CLANG_CXXFLAGS\n    -Werror\n    -Weverything\n    -Wno-c++98-compat\n    -Wno-c++98-compat-pedantic\n    -Wno-deprecated-declarations\n    -Wno-padded\n    -Wno-covered-switch-default\n    -Wno-c2y-extensions\n    -Wno-unsafe-buffer-usage\n)\n
    • On GCC, 300+ warnings are enabled with 8 exceptions.

      GCC warnings
      # Warning flags determined for GCC 16.2.0 with https://github.com/nlohmann/gcc_flags:\n# Ignored GCC warnings:\n# -Wno-abi-tag           We do not care about ABI tags.\n# -Wno-aggregate-return  The library uses aggregate returns.\n# -Wno-long-long         The library uses the long long type to interface with system functions.\n# -Wno-namespaces        The library uses namespaces.\n# -Wno-nrvo              Doctest triggers this warning.\n# -Wno-padded            We do not care about padding warnings.\n# -Wno-system-headers    We do not care about warnings in system headers.\n# -Wno-templates         The library uses templates.\n\nset(GCC_CXXFLAGS\n    -pedantic\n    -Werror\n    --all-warnings\n    --extra-warnings\n    -W\n    -WNSObject-attribute\n    -Wabbreviated-auto-in-template-arg\n    -Wabi\n    -Wno-abi-tag\n    -Waddress\n    -Waddress-of-packed-member\n    -Wno-aggregate-return\n    -Waggressive-loop-optimizations\n    -Waligned-new=all\n    -Wall\n    -Walloc-size\n    -Walloc-zero\n    -Walloca\n    -Wanalyzer-allocation-size\n    -Wanalyzer-deref-before-check\n    -Wanalyzer-double-fclose\n    -Wanalyzer-double-free\n    -Wanalyzer-exposure-through-output-file\n    -Wanalyzer-exposure-through-uninit-copy\n    -Wanalyzer-fd-access-mode-mismatch\n    -Wanalyzer-fd-double-close\n    -Wanalyzer-fd-leak\n    -Wanalyzer-fd-phase-mismatch\n    -Wanalyzer-fd-type-mismatch\n    -Wanalyzer-fd-use-after-close\n    -Wanalyzer-fd-use-without-check\n    -Wanalyzer-file-leak\n    -Wanalyzer-free-of-non-heap\n    -Wanalyzer-imprecise-fp-arithmetic\n    -Wanalyzer-infinite-loop\n    -Wanalyzer-infinite-recursion\n    -Wanalyzer-jump-through-null\n    -Wanalyzer-malloc-leak\n    -Wanalyzer-mismatching-deallocation\n    -Wanalyzer-null-argument\n    -Wanalyzer-null-dereference\n    -Wanalyzer-out-of-bounds\n    -Wanalyzer-overlapping-buffers\n    -Wanalyzer-possible-null-argument\n    -Wanalyzer-possible-null-dereference\n    -Wanalyzer-putenv-of-auto-var\n    -Wanalyzer-shift-count-negative\n    -Wanalyzer-shift-count-overflow\n    -Wanalyzer-stale-setjmp-buffer\n    -Wanalyzer-symbol-too-complex\n    -Wanalyzer-tainted-allocation-size\n    -Wanalyzer-tainted-array-index\n    -Wanalyzer-tainted-assertion\n    -Wanalyzer-tainted-divisor\n    -Wanalyzer-tainted-offset\n    -Wanalyzer-tainted-size\n    -Wanalyzer-throw-of-unexpected-type\n    -Wanalyzer-too-complex\n    -Wanalyzer-undefined-behavior-ptrdiff\n    -Wanalyzer-undefined-behavior-strtok\n    -Wanalyzer-unsafe-call-within-signal-handler\n    -Wanalyzer-use-after-free\n    -Wanalyzer-use-of-pointer-in-stale-stack-frame\n    -Wanalyzer-use-of-uninitialized-value\n    -Wanalyzer-va-arg-type-mismatch\n    -Wanalyzer-va-list-exhausted\n    -Wanalyzer-va-list-leak\n    -Wanalyzer-va-list-use-after-va-end\n    -Wanalyzer-write-to-const\n    -Wanalyzer-write-to-string-literal\n    -Warith-conversion\n    -Warray-bounds=2\n    -Warray-compare\n    -Warray-parameter\n    -Warray-parameter=2\n    -Wattribute-alias=2\n    -Wattribute-warning\n    -Wattributes\n    -Wauto-profile\n    -Wbidi-chars=any\n    -Wbool-compare\n    -Wbool-operation\n    -Wbuiltin-declaration-mismatch\n    -Wbuiltin-macro-redefined\n    -Wc++0x-compat\n    -Wc++11-compat\n    -Wc++11-extensions\n    -Wc++14-compat\n    -Wc++14-extensions\n    -Wc++17-compat\n    -Wc++17-extensions\n    -Wc++1z-compat\n    -Wc++20-compat\n    -Wc++20-extensions\n    -Wc++23-extensions\n    -Wc++26-compat\n    -Wc++26-extensions\n    -Wc++2a-compat\n    -Wcalloc-transposed-args\n    -Wcannot-profile\n    -Wcast-align\n    -Wcast-align=strict\n    -Wcast-function-type\n    -Wcast-qual\n    -Wcast-user-defined\n    -Wcatch-value=3\n    -Wchanges-meaning\n    -Wchar-subscripts\n    -Wclass-conversion\n    -Wclass-memaccess\n    -Wclobbered\n    -Wcomma-subscript\n    -Wcomment\n    -Wcomments\n    -Wcomplain-wrong-lang\n    -Wconditionally-supported\n    -Wconversion\n    -Wconversion-null\n    -Wcoverage-invalid-line-number\n    -Wcoverage-mismatch\n    -Wcoverage-too-many-conditions\n    -Wcoverage-too-many-paths\n    -Wcpp\n    -Wctad-maybe-unsupported\n    -Wctor-dtor-privacy\n    -Wdangling-else\n    -Wdangling-pointer=2\n    -Wdangling-reference\n    -Wdate-time\n    -Wdefaulted-function-deleted\n    -Wdelete-incomplete\n    -Wdelete-non-virtual-dtor\n    -Wdeprecated\n    -Wdeprecated-copy\n    -Wdeprecated-copy-dtor\n    -Wdeprecated-declarations\n    -Wdeprecated-enum-enum-conversion\n    -Wdeprecated-enum-float-conversion\n    -Wdeprecated-literal-operator\n    -Wdeprecated-openmp\n    -Wdeprecated-variadic-comma-omission\n    -Wdisabled-optimization\n    -Wdiv-by-zero\n    -Wdouble-promotion\n    -Wduplicated-branches\n    -Wduplicated-cond\n    -Weffc++\n    -Welaborated-enum-base\n    -Wempty-body\n    -Wendif-labels\n    -Wenum-compare\n    -Wenum-conversion\n    -Wexceptions\n    -Wexpansion-to-defined\n    -Wexpose-global-module-tu-local\n    -Wexternal-tu-local\n    -Wextra\n    -Wextra-semi\n    -Wflex-array-member-not-at-end\n    -Wfloat-conversion\n    -Wfloat-equal\n    -Wformat-diag\n    -Wformat-overflow=2\n    -Wformat-signedness\n    -Wformat-truncation=2\n    -Wformat=2\n    -Wframe-address\n    -Wfree-nonheap-object\n    -Wglobal-module\n    -Whardened\n    -Wheader-guard\n    -Whsa\n    -Wif-not-aligned\n    -Wignored-attributes\n    -Wignored-qualifiers\n    -Wimplicit-fallthrough=5\n    -Winaccessible-base\n    -Winfinite-recursion\n    -Winherited-variadic-ctor\n    -Winit-list-lifetime\n    -Winit-self\n    -Winline\n    -Wint-in-bool-context\n    -Wint-to-pointer-cast\n    -Winterference-size\n    -Winvalid-constexpr\n    -Winvalid-imported-macros\n    -Winvalid-memory-model\n    -Winvalid-offsetof\n    -Winvalid-pch\n    -Winvalid-utf8\n    -Wkeyword-macro\n    -Wleading-whitespace=spaces\n    -Wliteral-suffix\n    -Wlogical-not-parentheses\n    -Wlogical-op\n    -Wno-long-long\n    -Wlto-type-mismatch\n    -Wmain\n    -Wmaybe-musttail-local-addr\n    -Wmaybe-uninitialized\n    -Wmemset-elt-size\n    -Wmemset-transposed-args\n    -Wmisleading-indentation\n    -Wmismatched-dealloc\n    -Wmismatched-new-delete\n    -Wmismatched-tags\n    -Wmissing-attributes\n    -Wmissing-braces\n    -Wmissing-declarations\n    -Wmissing-field-initializers\n    -Wmissing-include-dirs\n    -Wmissing-profile\n    -Wmissing-requires\n    -Wmissing-template-keyword\n    -Wmultichar\n    -Wmultiple-inheritance\n    -Wmultistatement-macros\n    -Wmusttail-local-addr\n    -Wno-namespaces\n    -Wnarrowing\n    -Wnoexcept\n    -Wnoexcept-type\n    -Wnon-c-typedef-for-linkage\n    -Wnon-template-friend\n    -Wnon-virtual-dtor\n    -Wnonnull\n    -Wnonnull-compare\n    -Wnormalized=nfkc\n    -Wno-nrvo\n    -Wnull-dereference\n    -Wodr\n    -Wold-style-cast\n    -Wopenacc-parallelism\n    -Wopenmp\n    -Wopenmp-simd\n    -Woverflow\n    -Woverlength-strings\n    -Woverloaded-virtual=2\n    -Wpacked\n    -Wpacked-bitfield-compat\n    -Wpacked-not-aligned\n    -Wno-padded\n    -Wparentheses\n    -Wpedantic\n    -Wpessimizing-move\n    -Wplacement-new=2\n    -Wpmf-conversions\n    -Wpointer-arith\n    -Wpointer-compare\n    -Wpragma-once-outside-header\n    -Wpragmas\n    -Wprio-ctor-dtor\n    -Wpsabi\n    -Wrange-loop-construct\n    -Wredundant-decls\n    -Wredundant-move\n    -Wredundant-tags\n    -Wregister\n    -Wreorder\n    -Wrestrict\n    -Wreturn-local-addr\n    -Wreturn-type\n    -Wscalar-storage-order\n    -Wself-move\n    -Wsequence-point\n    -Wsfinae-incomplete\n    -Wsfinae-incomplete=2\n    -Wshadow=compatible-local\n    -Wshadow=global\n    -Wshadow=local\n    -Wshift-count-negative\n    -Wshift-count-overflow\n    -Wshift-negative-value\n    -Wshift-overflow=2\n    -Wsign-compare\n    -Wsign-conversion\n    -Wsign-promo\n    -Wsized-deallocation\n    -Wsizeof-array-argument\n    -Wsizeof-array-div\n    -Wsizeof-pointer-div\n    -Wsizeof-pointer-memaccess\n    -Wstack-protector\n    -Wstrict-aliasing\n    -Wstrict-aliasing=3\n    -Wstrict-null-sentinel\n    -Wstrict-overflow\n    -Wstrict-overflow=5\n    -Wstring-compare\n    -Wstringop-overflow\n    -Wstringop-overflow=4\n    -Wstringop-overread\n    -Wstringop-truncation\n    -Wsubobject-linkage\n    -Wsuggest-attribute=cold\n    -Wsuggest-attribute=const\n    -Wsuggest-attribute=format\n    -Wsuggest-attribute=malloc\n    -Wsuggest-attribute=noreturn\n    -Wsuggest-attribute=pure\n    -Wsuggest-attribute=returns_nonnull\n    -Wsuggest-final-methods\n    -Wsuggest-final-types\n    -Wsuggest-override\n    -Wswitch\n    -Wswitch-bool\n    -Wswitch-default\n    -Wswitch-enum\n    -Wswitch-outside-range\n    -Wswitch-unreachable\n    -Wsync-nand\n    -Wsynth\n    -Wno-system-headers\n    -Wtautological-compare\n    -Wtemplate-body\n    -Wtemplate-id-cdtor\n    -Wtemplate-names-tu-local\n    -Wno-templates\n    -Wterminate\n    -Wtrailing-whitespace\n    -Wtrampolines\n    -Wtrigraphs\n    -Wtrivial-auto-var-init\n    -Wtsan\n    -Wtype-limits\n    -Wundef\n    -Wunicode\n    -Wuninitialized\n    -Wunknown-pragmas\n    -Wunreachable-code\n    -Wunsafe-loop-optimizations\n    -Wunused\n    -Wunused-but-set-parameter=3\n    -Wunused-but-set-variable=3\n    -Wunused-const-variable=2\n    -Wunused-function\n    -Wunused-label\n    -Wunused-local-typedefs\n    -Wunused-macros\n    -Wunused-parameter\n    -Wunused-result\n    -Wunused-value\n    -Wunused-variable\n    -Wuse-after-free=3\n    -Wuseless-cast\n    -Wvarargs\n    -Wvariadic-macros\n    -Wvector-operation-performance\n    -Wvexing-parse\n    -Wvirtual-inheritance\n    -Wvirtual-move-assign\n    -Wvla\n    -Wvla-parameter\n    -Wvolatile\n    -Wvolatile-register-var\n    -Wwrite-strings\n    -Wxor-used-as-pow\n    -Wzero-as-null-pointer-constant\n    -Wzero-length-bounds\n)\n
    "},{"location":"community/quality_assurance/#c-standard-library-compliance","title":"C++ standard library compliance","text":"

    Requirement: No prerequisites

    The library has no prerequisites other than the Standard Template Library (STL).

    • The library is compiled and tested with both libc++ and libstdc++ to detect subtle differences or incompatibilities.
    • The code checked with Include What You Use (IWYU) that all required standard headers are included.
    • On Windows, the library is compiled with <Windows.h> being included to detect and avoid common bugs (see unit-windows_h.cpp).
    • The library is compiled with Qt's keyword macros (slots, signals, emit, foreach, forever) being defined to make sure it does not use them as identifiers (see unit-qt_keywords.cpp).
    • The library is compiled with exceptions disabled to support alternative means of error handling.
    "},{"location":"community/quality_assurance/#stable-public-api","title":"Stable public API","text":"

    Requirement: Stable public API

    Any change to the library does not break the public API.

    • All public API functions are tested with a variety of arguments.
    • The library is compiled and tested with different template arguments for number, string, array, and object types.
    • Unit tests cover all lines of the code base.
    • Every exception of the library is thrown in the test suite, and the error messages and exception ids are checked.

    Requirement: Complete documentation

    The public API is extensively documented.

    • Every public API function has a dedicated page in the API reference documentation with a self-contained code example.
    • All examples in the documentation are tested, and changes in their output are treated as an error.
    "},{"location":"community/quality_assurance/#robust-input-processing","title":"Robust input processing","text":"

    Requirement: Standards compliance

    The library is compliant to JSON as defined in RFC 8259.

    • The lexer is tested with all valid Unicode code points and all prefixes of all invalid Unicode code points.
    • The parser is tested against extensive correctness suites for JSON compliance.
    • In addition, the library is continuously fuzz-tested at OSS-Fuzz where the library is checked against billions of inputs.
    • Every crash reported by OSS-Fuzz is fixed together with a unit test that reproduces it, and the fix references the OSS-Fuzz issue. The round-trip checks of the fuzzer drivers are also part of the unit tests. See the fuzz testing documentation.
    "},{"location":"community/quality_assurance/#static-analysis","title":"Static analysis","text":"

    Requirement: State-of-the-art code analysis

    The code is checked with state-of-the-art static code analysis tools.

    • The code is checked with the latest Clang-Tidy.

      Clang-Tidy configuration (.clang-tidy)
      # Style or vendor rule sets that do not fit a header-only library:\n#   altera-*, fuchsia-*, llvmlibc-*, android-cloexec-fopen, boost-use-ranges, llvm-header-guard,\n#   llvm-include-order, llvm-prefer-static-over-anonymous-namespace, llvm-use-ranges,\n#   misc-use-anonymous-namespace, google-runtime-float, google-runtime-int, hicpp-signed-bitwise,\n#   bugprone-signed-bitwise, hicpp-explicit-conversions, google-explicit-constructor,\n#   cppcoreguidelines-explicit-constructor, misc-explicit-constructor (implicit conversions are the\n#   API), readability-trailing-comma,\n#   hicpp-avoid-goto / cppcoreguidelines-avoid-goto, hicpp-no-array-decay,\n#   hicpp-uppercase-literal-suffix, readability-uppercase-literal-suffix, modernize-use-trailing-return-type.\n# Constructs the library needs on purpose (the library supports C++11 and legacy compilers):\n#   cppcoreguidelines-macro-usage, cppcoreguidelines-avoid-do-while (macros),\n#   cppcoreguidelines-pro-bounds-*, cppcoreguidelines-pro-type-reinterpret-cast,\n#   cppcoreguidelines-pro-type-union-access (parsers, serializers, basic_json's value union),\n#   cppcoreguidelines-avoid-const-or-ref-data-members, cppcoreguidelines-rvalue-reference-param-not-moved,\n#   cppcoreguidelines-avoid-non-const-global-variables, misc-non-private-member-variables-in-classes,\n#   misc-no-recursion (value walks are recursive, bounded by detail::recursion_depth_limit()),\n#   modernize-type-traits, modernize-use-constraints, modernize-use-ranges, modernize-use-std-numbers,\n#   modernize-use-designated-initializers, modernize-use-nodiscard, modernize-concat-nested-namespaces,\n#   readability-redundant-typename, readability-redundant-parentheses,\n#   readability-redundant-access-specifiers, readability-simplify-boolean-expr,\n#   readability-use-concise-preprocessor-directives, modernize-use-string-view,\n#   modernize-use-integer-sign-comparison (needs std::cmp_less; the flagged\n#   static_cast<std::size_t>(end - pos) < n comparisons are deliberate)\n#   (all need a newer standard or compiler than C++11, or would change macro-generated or\n#   deliberately explicit code).\n# Too noisy to be useful (numeric parsing/formatting code, doctest, tests):\n#   bugprone-easily-swappable-parameters, cppcoreguidelines-avoid-magic-numbers, readability-magic-numbers,\n#   readability-identifier-length, readability-function-cognitive-complexity, performance-enum-size,\n#   concurrency-mt-unsafe, misc-confusable-identifiers, misc-include-cleaner (run on its own for\n#   the consumer headers in cmake/ci.cmake).\n# portability-avoid-pragma-once: kept disabled on purpose. #pragma once is accepted\n# by every supported compiler, and tools/amalgamate/amalgamate.py strips it from\n# single_include, so there is nothing left to fix here.\n\nChecks: '*,\n\n         -altera-id-dependent-backward-branch,\n         -altera-struct-pack-align,\n         -altera-unroll-loops,\n         -android-cloexec-fopen,\n         -boost-use-ranges,\n         -bugprone-easily-swappable-parameters,\n         -bugprone-signed-bitwise,\n         -concurrency-mt-unsafe,\n         -cppcoreguidelines-avoid-const-or-ref-data-members,\n         -cppcoreguidelines-avoid-do-while,\n         -cppcoreguidelines-avoid-goto,\n         -cppcoreguidelines-avoid-magic-numbers,\n         -cppcoreguidelines-avoid-non-const-global-variables,\n         -cppcoreguidelines-explicit-constructor,\n         -cppcoreguidelines-macro-usage,\n         -cppcoreguidelines-pro-bounds-avoid-unchecked-container-access,\n         -cppcoreguidelines-pro-bounds-array-to-pointer-decay,\n         -cppcoreguidelines-pro-bounds-constant-array-index,\n         -cppcoreguidelines-pro-bounds-pointer-arithmetic,\n         -cppcoreguidelines-pro-type-reinterpret-cast,\n         -cppcoreguidelines-pro-type-union-access,\n         -cppcoreguidelines-rvalue-reference-param-not-moved,\n         -fuchsia-default-arguments-calls,\n         -fuchsia-default-arguments-declarations,\n         -fuchsia-overloaded-operator,\n         -google-explicit-constructor,\n         -google-runtime-float,\n         -google-runtime-int,\n         -hicpp-avoid-goto,\n         -hicpp-explicit-conversions,\n         -hicpp-no-array-decay,\n         -hicpp-signed-bitwise,\n         -hicpp-uppercase-literal-suffix,\n         -llvm-header-guard,\n         -llvm-include-order,\n         -llvm-prefer-static-over-anonymous-namespace,\n         -llvm-use-ranges,\n         -llvmlibc-*,\n         -misc-use-anonymous-namespace,\n         -misc-confusable-identifiers,\n         -misc-explicit-constructor,\n         -misc-include-cleaner,\n         -misc-no-recursion,\n         -misc-non-private-member-variables-in-classes,\n         -modernize-concat-nested-namespaces,\n         -modernize-type-traits,\n         -modernize-use-constraints,\n         -modernize-use-designated-initializers,\n         -modernize-use-integer-sign-comparison,\n         -modernize-use-nodiscard,\n         -modernize-use-ranges,\n         -modernize-use-string-view,\n         -modernize-use-std-numbers,\n         -modernize-use-trailing-return-type,\n         -performance-enum-size,\n         -portability-avoid-pragma-once,\n         -readability-function-cognitive-complexity,\n         -readability-identifier-length,\n         -readability-magic-numbers,\n         -readability-redundant-access-specifiers,\n         -readability-redundant-parentheses,\n         -readability-redundant-typename,\n         -readability-simplify-boolean-expr,\n         -readability-trailing-comma,\n         -readability-uppercase-literal-suffix,\n         -readability-use-concise-preprocessor-directives'\n\nCheckOptions:\n  - key: hicpp-special-member-functions.AllowSoleDefaultDtor\n    value: 1\n  # clang-tidy 22.1 extended this check to classes and enums; the test files\n  # define many such helper types at namespace scope, which is harmless\n  - key: misc-use-internal-linkage.AnalyzeTypes\n    value: false\n\nWarningsAsErrors: '*'\n\nHeaderFilterRegex: '.*hpp$'\n
    • The code is checked with the latest Cppcheck with all warnings enabled.

    • The code is checked with the latest Clang Static Analyzer with 52 enabled checkers.
    • The code is checked with Infer.
    • The code is checked with Codacy.
    • The code is scanned with CodeQL, Semgrep, and Flawfinder on every push and pull request and on a schedule; the findings are reported to GitHub's code scanning.
    "},{"location":"community/quality_assurance/#dynamic-analysis","title":"Dynamic analysis","text":"

    Requirement: Correctness

    The library is checked for memory correctness and absence of undefined behavior.

    • The test suite is executed with enabled runtime assertions to check invariants and preconditions of functions to detect undefined behavior.
    • The test suite is executed with Valgrind (Memcheck) to detect memory leaks.
    • The test suite is executed with Sanitizers (address sanitizer, undefined behavior sanitizer, integer overflow detection, nullability violations).
    • The fuzz targets are run with CIFuzz on every pull request to catch regressions before they are merged.
    "},{"location":"community/quality_assurance/#dependencies","title":"Dependencies","text":"

    Requirement: No vulnerable dependencies

    The library has no dependencies besides the C++ standard library. The tools used to build, test, and document it are kept free of known vulnerabilities.

    • GitHub Actions are pinned to a commit hash, and the Python packages used by the documentation and the tools are pinned to exact versions.
    • Dependabot checks these dependencies daily and proposes updates as pull requests.
    • Every pull request is checked with the dependency review action. A pull request that adds a dependency with a known vulnerability of any severity fails this check and is not merged.
    • Vulnerability alerts for dependencies are fixed or dismissed with a documented reason before the next release. No release is made while such an alert is open.
    • Third-party code included in the repository for testing, such as doctest, is updated manually.
    • The repository is evaluated with the OpenSSF Scorecard on a schedule and on every push to the default branch, and the results are reported to GitHub's code scanning.
    "},{"location":"community/quality_assurance/#style-check","title":"Style check","text":"

    Requirement: Common code style

    A common code style is used throughout all code files of the library.

    • The code is formatted with Artistic Style (astyle) against a style configuration that is also enforced in the CI.

      Astyle configuration (tools/astyle/.astylerc)
      # Configuration for Artistic Style\n# see https://astyle.sourceforge.net/astyle.html\n\n#######################\n# Brace Style Options #\n#######################\n\n# use Allman style for braces\n--style=allman\n\n###############\n# Tab Options #\n###############\n\n# indent using 4 spaces\n--indent=spaces=4\n\n#######################\n# Indentation Options #\n#######################\n\n# indent access modifiers one half indent\n--indent-modifiers\n\n# indent switch cases to the switch block\n--indent-switches\n\n# indent preprocessor blocks\n--indent-preproc-block\n\n# indent preprocessor defines\n--indent-preproc-define\n\n# indent C++ comments\n--indent-col1-comments\n\n###################\n# Padding Options #\n###################\n\n# insert space padding around operators\n--pad-oper\n\n# insert space between if/for/while... and the following parentheses\n--pad-header\n\n# attach the pointer to the variable type (left)\n--align-pointer=type\n\n# attach the reference to the variable type (left)\n--align-reference=type\n\n######################\n# Formatting Options #\n######################\n\n# add braces to unbraced one line conditional statements\n--add-braces\n\n# convert tabs to spaces\n--convert-tabs\n\n# closes whitespace between the ending angle brackets of template definitions\n--close-templates\n\n#################\n# Other Options #\n#################\n\n# do not create backup files\n--suffix=none\n\n# preserve the original file date\n--preserve-date\n\n# display only the files that have been formatted\n--formatted\n\n# for the linux (LF) line end style\n--lineend=linux\n
    • The code style is checked with cpplint with 61 enabled rules.

    "},{"location":"community/quality_assurance/#simple-integration","title":"Simple integration","text":"

    Requirement: Single header

    The library can be used by adding a single header to a C++ project.

    • An amalgamation script is used to check if the source code is exposed as a self-contained single-header file.
    • The test suite is checked against the amalgamated source file as well as the individual source file.

    Requirement: CMake as primary development tool

    All library functions are exposed and usable by CMake.

    • All library options are exposed as CMake options and tested.
    • The library is tested against relevant CMake versions:
    • CMake 3.5 (the earliest supported)
    • CMake 3.31.6 (the latest 3.x release)
    • CMake 4.0.0 (the first 4.x release)

    Requirement: Other build systems

    The library can be used with build systems and package managers other than CMake.

    • The library can be consumed with Meson and the Swift Package Manager; the installation with Meson and the resolution of Package.swift are tested in the CI.

    Requirement: Reproducible and verifiable builds

    The library can be built and tested without network access or a Git checkout, and its licensing is machine-readable.

    • The test suite is executed from an exported source tree without the .git directory and with the test data being available offline.
    • The test suite is executed without the tests that change installed files to check that builds are reproducible.
    • The repository is checked for compliance with the REUSE specification so that the license and copyright of every file is machine-readable.
    • The documentation is built with warnings treated as errors, and its links are checked regularly.
    "},{"location":"community/roadmap/","title":"Roadmap","text":"

    This page describes what the project intends to do, and what it does not intend to do, over the next year. Concrete work items are tracked in the GitHub milestones and the issue tracker.

    "},{"location":"community/roadmap/#what-the-project-will-do","title":"What the project will do","text":"
    • Keep the C++11 baseline. The library will continue to compile with every supported C++11 compiler. Features of later standards are only used when they are guarded by the JSON_HAS_CPP_* macros.
    • Stay conformant to JSON. The parser and serializer follow RFC 8259. Extensions such as comments or trailing commas remain opt-in.
    • Keep the 3.x public API stable. Releases follow semantic versioning. Changes that would break existing code are only added behind a feature macro, so users can opt in and test their code before a next major release, see Version 4.0.
    • Support a broad range of compilers and platforms. The CI keeps testing old and new versions of GCC, Clang, MSVC, and other compilers on Linux, macOS, and Windows.
    • Keep the quality assurance up. Every change keeps the test coverage at 100%, passes the static and dynamic analysis, and is fuzz-tested by OSS-Fuzz, see Quality assurance.
    • Harden the library against hostile input. Handling deeply nested values without exhausting the call stack is ongoing work.
    • Fix bugs and security issues reported through the issue tracker and the security policy.
    "},{"location":"community/roadmap/#what-the-project-will-not-do","title":"What the project will not do","text":"
    • Break the public API of version 3.x. See API stability for what this covers.
    • Require a newer C++ standard than C++11.
    • Break JSON conformance or enable non-standard extensions by default.
    • Add dependencies or require a build step. The library remains header-only, and the single header json.hpp remains a complete distribution.
    • Trade simplicity for speed or memory efficiency. Performance improvements are welcome, but the library is not meant to compete with the fastest JSON libraries, see Design goals.
    "},{"location":"community/roadmap/#api-stability","title":"API stability","text":"

    Releases follow semantic versioning: a minor or patch release of version 3.x does not break code that uses the public API, unless that code opts in to a change with a macro as described below. In particular, a 3.x release does not:

    • make breaking changes to the signature of a function: the types or order of its existing parameters, its return type, its noexcept or constexpr specifier, or the const-ness of a member function. New parameters may be added if they have a default value;
    • remove or rename a function or class, or change the template parameters of a public class template;
    • change which exceptions a function throws, or the exception ids;
    • change access specifiers, or change or remove existing default arguments. New default arguments may be added;
    • change the JSON type that a valid input parses to, or the text that dump() produces for a valid value;
    • accept input that was rejected before, or reject input that was accepted before;
    • change the order in which the keys of an object are iterated. The default type sorts keys, and ordered_json keeps insertion order;
    • change when iterators, pointers, or references are invalidated, or the state of a moved-from basic_json;
    • add or remove implicit conversions from basic_json;
    • change how to_json and from_json functions are found, or the behavior of adl_serializer;
    • add pure virtual functions to the json_sax interface;
    • remove, rename, renumber, or add enumerators of value_t;
    • remove or rename a documented macro, CMake option, CMake target, or header, or change what a documented macro does.

    Exceptions to these rules, for instance when fixing a bug requires changing the exception a function throws, are documented in the release notes.

    The following are not part of the public API and may change in any release, including patch releases:

    • The text of exception messages returned by what(). Use the exception id to tell errors apart.
    • The ABI, including sizeof(basic_json) and the memory layout of its values. The versioned inline namespace turns mixing versions into a link error.
    • The hash values returned by std::hash for basic_json. Numbers that compare equal still hash equally.
    • Everything in namespace nlohmann::detail, and macros and type traits that are not documented in the API reference.

    Breaking changes are only added behind a macro whose default keeps the 3.x behavior. See Version 4.0 and the macro overview.

    "},{"location":"community/roadmap/#version-40","title":"Version 4.0","text":"

    There is no release date for version 4.0 yet. Proposals that need a major version, for instance stricter type conversions, are collected in issue #3453.

    Not final

    The plan for version 4.0 described below is not final and may still change: macros may be added to or removed from the list, and planned defaults may be revised. Any such change will be documented on this page.

    "},{"location":"community/roadmap/#trying-out-40-today","title":"Trying out 4.0 today","text":"

    Version 4.0 will not be developed on a separate branch. Instead, every breaking change is first added to a 3.x release behind a macro whose default keeps the 3.x behavior. Version 4.0 then switches the defaults and removes the macros. Version 4.0 is therefore the sum of these macros: you can try it on the 3.x release train today by defining each macro to its 4.0 value and fixing what no longer compiles or behaves differently. Once your code works with all of them, it is ready for version 4.0.

    Each macro has a default value in 3.x and a different value in version 4.0. Define the macro to the 4.0 value to try it on the 3.x release train today; version 4.0 makes that value the default:

    Two lanes: the 3.x release train, whose minor and patch releases do not break code that uses the public A\u200bPI, followed by version 4.0, which has no release date yet. Each breaking change is a macro that is available in 3.x today with its 3.x default and becomes the default in 4.0: JSON_USE_IMPLICIT_CONVERSIONS, added in 3.9.0, 3.x default 1, 4.0 value 0; JSON_USE_GLOBAL_UDLS, added in 3.11.0, 3.x default 1, 4.0 value 0; JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON, added in 3.11.0, 3.x default 0, 4.0 value 0, macro removed; JSON_BRACE_INIT_COPY_SEMANTICS, added in 3.13.0, 3.x default 0, 4.0 value 1; JSON_PRECISE_STREAM_POSITION, added in 3.13.0, 3.x default 0, 4.0 value 1; JSON_STRICT_NUL_HANDLING, added in 3.13.0, 3.x default 0, 4.0 value 1; JSON_STRICT_BINARY_UTF8, added in 3.13.0, 3.x default 0, 4.0 value 1; JSON_DISABLE_TUPLE_REFERENCE_CONVERSION, added in 3.13.0, 3.x default 0, 4.0 value 1; JSON_DELETE_DEPRECATED_FUNCTIONS, added in 3.13.0, 3.x default 0, 4.0 value 1, macro removed. 3.x release train available today 3.9.0 3.11.0 3.13.0 4.0 no release date yet A minor or patch release of 3.x does not break code that uses the public A\u200bPI, unless that code opts in with a macro. 4.0 is not developed on a separate branch: it switches the defaults of these macros and removes the macros. Macro added 3.x default define to try today 4.0 default JSON_USE_IMPLICIT_CONVERSIONS 3.9.0 1 0 JSON_USE_GLOBAL_UDLS 3.11.0 1 0 JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON 3.11.0 0 removed JSON_BRACE_INIT_COPY_SEMANTICS 3.13.0 0 1 JSON_PRECISE_STREAM_POSITION 3.13.0 0 1 JSON_STRICT_NUL_HANDLING 3.13.0 0 1 JSON_STRICT_BINARY_UTF8 3.13.0 0 1 JSON_DISABLE_TUPLE_REFERENCE_CONVERSION 3.13.0 0 1 JSON_DELETE_DEPRECATED_FUNCTIONS 3.13.0 0 removed Versions on the 3.x lane are the ones that added a macro, not to scale. \u201cremoved\u201d: see the 4.0 behavior column of the table.

    Each row is one macro: the 3.x release that added it, its default in 3.x, and its value in version 4.0 (highlighted) or \"removed\". Versions on the 3.x lane are not to scale.

    The following macros guard changes that are planned to become the default in version 4.0:

    Macro 3.x default 4.0 behavior CMake option Added JSON_USE_IMPLICIT_CONVERSIONS 1 0: no implicit conversions from basic_json to other types; use get instead JSON_ImplicitConversions 3.9.0 JSON_USE_GLOBAL_UDLS 1 0: the string literals _json and _json_pointer are only available in namespace nlohmann::literals JSON_GlobalUDLs 3.11.0 JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON 0 removed: the deprecated legacy comparison of discarded values can no longer be enabled JSON_LegacyDiscardedValueComparison 3.11.0 JSON_BRACE_INIT_COPY_SEMANTICS 0 1: single-element brace initialization such as json j{obj}; copies the element instead of creating an array \u2013 3.13.0 JSON_PRECISE_STREAM_POSITION 0 1: reading from a stream does not consume the character after a number \u2013 3.13.0 JSON_STRICT_NUL_HANDLING 0 1: a NUL byte in the input is a parse error instead of the end of input JSON_StrictNulHandling 3.13.0 JSON_STRICT_BINARY_UTF8 0 1: to_cbor, to_ubjson, to_bjdata, and to_bson throw for strings that are not valid UTF-8 by default JSON_StrictBinaryUTF8 3.13.0 JSON_DISABLE_TUPLE_REFERENCE_CONVERSION 0 1: a basic_json value can no longer be created from a one-element tuple of a reference to it, such as std::forward_as_tuple(j) JSON_DisableTupleReferenceConversion 3.13.0 JSON_DELETE_DEPRECATED_FUNCTIONS 0 removed: the deprecated functions are removed (see below); the from_*(ptr, len) overloads stay deleted JSON_DeleteDeprecatedFunctions 3.13.0

    Opt-in macros for the version 4.0 behavior. \"3.x default\" is the value the library uses when the macro is not defined, \"Added\" is the release that introduced the macro, and \u2013 means there is no CMake option.

    For example, the following makes a 3.x release behave like version 4.0 with respect to these changes:

    #define JSON_USE_IMPLICIT_CONVERSIONS 0\n#define JSON_USE_GLOBAL_UDLS 0\n#define JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON 0\n#define JSON_BRACE_INIT_COPY_SEMANTICS 1\n#define JSON_PRECISE_STREAM_POSITION 1\n#define JSON_STRICT_NUL_HANDLING 1\n#define JSON_STRICT_BINARY_UTF8 1\n#define JSON_DISABLE_TUPLE_REFERENCE_CONVERSION 1\n#define JSON_DELETE_DEPRECATED_FUNCTIONS 1\n#include <nlohmann/json.hpp>\n

    The macros must be defined before the library header is included; setting them once in the build system is the easiest way to achieve this.

    "},{"location":"community/roadmap/#removal-of-deprecated-functions","title":"Removal of deprecated functions","text":"

    Version 4.0 will remove all deprecated functions. Compiling with deprecation warnings enabled shows which of them your code still uses. Defining JSON_DELETE_DEPRECATED_FUNCTIONS to 1 turns these warnings into errors, as the deprecated functions are then deleted. The migration guide shows how to replace each of them.

    The from_* overloads taking a pointer and a length are not removed in version 4.0, but stay deleted. Without them, a call like from_cbor(ptr, len) would still compile: it would read ptr as a NUL-terminated string and convert len to the strict parameter.

    Deprecated Since Migration operator<<(basic_json&, std::istream&) 3.0.0 Parsing operator>>(const basic_json&, std::ostream&) 3.0.0 Miscellaneous functions iterator_wrapper 3.1.0 Miscellaneous functions parse, accept, and sax_parse with an initializer list {ptr, len} or {first, last} 3.8.0 Parsing from_bson, from_cbor, from_msgpack, and from_ubjson with (ptr, len) or an initializer list 3.8.0 Parsing json_pointer::operator string_t 3.11.0 JSON Pointers json_pointer with a basic_json type as template argument, and the overloads of value, contains, operator[], and at accepting such a pointer 3.11.0 JSON Pointers Comparing a json_pointer with a string via operator== or operator!= 3.11.2 JSON Pointers from_bjdata and from_bon8 with (ptr, len) 3.13.0 Parsing

    Deprecated functions, with the release that deprecated each one and the section of the migration guide that shows its replacement.

    The deprecated legacy comparison of discarded values is controlled by a macro and therefore listed in the table above.

    New breaking changes will follow the same path: they are added to these tables when they land in a 3.x release.

    "},{"location":"community/security_policy/","title":"Security Policy","text":""},{"location":"community/security_policy/#reporting-a-vulnerability","title":"Reporting a Vulnerability","text":"

    We value the security of our users and appreciate your efforts to responsibly disclose vulnerabilities. If you have identified a security vulnerability in this repository, please use the GitHub Security Advisory \"Report a Vulnerability\" tab.

    Until it is published, this draft security advisory will only be visible to the maintainers of this project. Other users and teams may be added once the advisory is created.

    We will send a first response within 14 days, indicating the next steps in handling your report. After the initial reply to your report, we will keep you informed of the progress towards a fix and full announcement and may ask for additional information or guidance.

    For vulnerabilities in third-party dependencies or modules, please report them directly to the respective maintainers.

    "},{"location":"community/security_policy/#disclosure-and-credit","title":"Disclosure and credit","text":"

    Once a fix is released, we publish the security advisory and list the fixed vulnerability in the release notes. We credit the reporter in both, unless they ask not to be named.

    "},{"location":"community/security_policy/#supported-versions","title":"Supported versions","text":"

    Security fixes are made on the develop branch and shipped with the next release. Only the latest release receives security fixes; they are not backported to older releases. A release stops receiving security fixes when the next release is published, so please update to the latest release to get them.

    "},{"location":"community/security_policy/#unofficial-packages","title":"Unofficial packages","text":"

    This project does not publish an official npm package. The npm package nlohmann-json (or similarly named packages) is not maintained or endorsed by this project. See the package managers documentation for supported integration options.

    "},{"location":"community/security_policy/#additional-resources","title":"Additional Resources","text":"
    • Explore security-related topics and contribute to tools and projects through GitHub Security Lab.
    • Learn more about responsible disclosure and reporting vulnerabilities in GitHub at About coordinated disclosure of security vulnerabilities.

    We sincerely thank you for contributing to the security and integrity of this project!

    "},{"location":"features/","title":"Features","text":"

    This section describes the features of the library in detail. If you are new to the library, the pages below are roughly ordered along a typical workflow: create or parse a value, access and modify it, convert it to and from your own C++ types, and finally serialize it again.

    "},{"location":"features/#creating-and-reading-values","title":"Creating and reading values","text":"
    • Creating JSON values \u2014 build values from literals, initializer lists, and STL containers, and understand the {} vs. [] ambiguity.
    • Parsing \u2014 read a JSON value from a string, file, or stream, including JSON Lines, callbacks, the SAX interface, error handling, large and partial input, and parsing untrusted input.
    • Zero-copy JSON views \u2014 read a JSON text through a flat index instead of building a json tree; strings and numbers stay in the input and are only decoded when needed.
    • Editable documents \u2014 modify a parsed document without building a json tree.
    • Images \u2014 save a parsed document and load it again without parsing it.
    • Comments and trailing commas \u2014 opt-in relaxations of the JSON grammar.
    "},{"location":"features/#accessing-and-modifying-values","title":"Accessing and modifying values","text":"
    • Element access \u2014 unchecked (operator[]), checked (at), and access with a default value.
    • JSON Pointer \u2014 address values deep inside a document with RFC 6901 pointers.
    • Iterators \u2014 traverse arrays and objects.
    • Modifying values \u2014 add, update, merge, and remove elements.
    • JSON Patch and Diff and JSON Merge Patch \u2014 apply and compute structured changes.
    "},{"location":"features/#converting-to-and-from-c-types","title":"Converting to and from C++ types","text":"
    • Converting values \u2014 get values out with get/get_to, and understand implicit conversions.
    • Arbitrary types conversions \u2014 teach the library about your own structs and classes.
    • Recipes for common types \u2014 convert smart pointers, std::variant, std::chrono types, and class hierarchies, which the library deliberately leaves to you.
    • Specializing enum conversion \u2014 map enums to strings instead of integers.
    "},{"location":"features/#serializing-values","title":"Serializing values","text":"
    • Serialization \u2014 turn a value back into JSON text with dump, including pretty-printing and handling of non-ASCII and invalid UTF-8.
    • Binary formats \u2014 encode values more compactly as BJData, BON8, BSON, CBOR, MessagePack, or UBJSON.
    • Binary values \u2014 store and exchange raw byte sequences.
    "},{"location":"features/#how-values-are-stored-and-configured","title":"How values are stored and configured","text":"
    • Types and number handling \u2014 how JSON types map to C++ types and how numbers are treated.
    • Template parameter requirements \u2014 what a type passed as one of basic_json's template parameters has to provide.
    • Object order \u2014 keep insertion order with ordered_json.
    • Performance \u2014 practical advice on parsing, memory use, serialization, and compile times.
    • Working without exceptions \u2014 what to use when exceptions are unwanted or unavailable.
    • Runtime assertions, supported macros, the nlohmann namespace, and C++ modules \u2014 build-time and runtime configuration.

    Looking for a specific function?

    This section gives conceptual overviews. For the precise signature, parameters, and return value of a function, see the API Documentation.

    "},{"location":"features/#see-also","title":"See also","text":"
    • API documentation - reference of all classes and functions
    • FAQ - answers to common questions
    • Exceptions - all exceptions and their error codes
    • Design goals - the goals behind the library
    • Integration - how to add the library to a project
    • Macros - reference of all macros
    • json_pointer - the JSON Pointer class
    • adl_serializer - customization point for type conversions
    • json_sax - interface of the SAX parser events
    • json_document - an immutable document with a flat index
    • json_view - a non-owning view of a value in a document
    • byte_container_with_subtype - binary values with a subtype
    • ordered_json - a JSON type preserving insertion order
    • Supported Macros - all supported macros
    • nlohmann Namespace - the library namespace
    "},{"location":"features/arbitrary_types/","title":"Arbitrary Type Conversions","text":"

    Every type can be serialized in JSON, not just STL containers and scalar types. Usually, you would do something along those lines:

    namespace ns {\n    // a simple struct to model a person\n    struct person {\n        std::string name;\n        std::string address;\n        int age;\n    };\n} // namespace ns\n\nns::person p = {\"Ned Flanders\", \"744 Evergreen Terrace\", 60};\n\n// convert to JSON: copy each value into the JSON object\njson j;\nj[\"name\"] = p.name;\nj[\"address\"] = p.address;\nj[\"age\"] = p.age;\n\n// ...\n\n// convert from JSON: copy each value from the JSON object\nns::person p {\n    j[\"name\"].get<std::string>(),\n    j[\"address\"].get<std::string>(),\n    j[\"age\"].get<int>()\n};\n

    It works, but that's quite a lot of boilerplate... Fortunately, there's a better way:

    // create a person\nns::person p {\"Ned Flanders\", \"744 Evergreen Terrace\", 60};\n\n// conversion: person -> json\njson j = p;\n\nstd::cout << j << std::endl;\n// {\"address\":\"744 Evergreen Terrace\",\"age\":60,\"name\":\"Ned Flanders\"}\n\n// conversion: json -> person\nauto p2 = j.get<ns::person>();\n\n// that's it\nassert(p == p2);\n
    "},{"location":"features/arbitrary_types/#basic-usage","title":"Basic usage","text":"

    To make this work with one of your types, you only need to provide two functions:

    using nlohmann::json;\n\nnamespace ns {\n    void to_json(json& j, const person& p) {\n        j = json{ {\"name\", p.name}, {\"address\", p.address}, {\"age\", p.age} };\n    }\n\n    void from_json(const json& j, person& p) {\n        j.at(\"name\").get_to(p.name);\n        j.at(\"address\").get_to(p.address);\n        j.at(\"age\").get_to(p.age);\n    }\n} // namespace ns\n

    That's all! When calling the json constructor with your type, your custom to_json method will be automatically called. Likewise, when calling get<your_type>() or get_to(your_type&), the from_json method will be called.

    Some important things:

    • Those methods MUST be in your type's namespace (which can be the global namespace), or the library will not be able to locate them (in this example, they are in namespace ns, where person is defined).
    • Those methods MUST be available (e.g., proper headers must be included) everywhere you use these conversions. Look at #1108 for errors that may occur otherwise.
    • When using get<your_type>(), your_type MUST be DefaultConstructible. (There is a way to bypass this requirement described later.)
    • In function from_json, use function at() to access the object values rather than operator[]. In case a key does not exist, at throws an exception that you can handle, whereas operator[] exhibits undefined behavior.
    • You do not need to add serializers or deserializers for STL types like std::vector: the library already implements these.
    • If you control the type, consider defining to_json/from_json as friend functions inside the class (\"hidden friends\"). Argument-dependent lookup then only finds them for your type, which also avoids a GCC < 11 compilation error.
    Example: serialize a person to JSON with to_json
    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nnamespace ns\n{\n// a simple struct to model a person\nstruct person\n{\n    std::string name;\n    std::string address;\n    int age;\n};\n} // namespace ns\n\nnamespace ns\n{\nvoid to_json(json& j, const person& p)\n{\n    j = json{ {\"name\", p.name}, {\"address\", p.address}, {\"age\", p.age} };\n}\n} // namespace ns\n\nint main()\n{\n    ns::person p = {\"Ned Flanders\", \"744 Evergreen Terrace\", 60};\n\n    json j = p;\n\n    std::cout << j << '\\n';\n}\n

    Output:

    {\"address\":\"744 Evergreen Terrace\",\"age\":60,\"name\":\"Ned Flanders\"}\n
    Example: deserialize a person from JSON with from_json
    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nnamespace ns\n{\n// a simple struct to model a person\nstruct person\n{\n    std::string name;\n    std::string address;\n    int age;\n};\n} // namespace ns\n\nnamespace ns\n{\nvoid from_json(const json& j, person& p)\n{\n    j.at(\"name\").get_to(p.name);\n    j.at(\"address\").get_to(p.address);\n    j.at(\"age\").get_to(p.age);\n}\n} // namespace ns\n\nint main()\n{\n    json j;\n    j[\"name\"] = \"Ned Flanders\";\n    j[\"address\"] = \"744 Evergreen Terrace\";\n    j[\"age\"] = 60;\n\n    auto p = j.get<ns::person>();\n\n    std::cout << p.name << \" (\" << p.age << \") lives in \" << p.address << '\\n';\n}\n

    Output:

    Ned Flanders (60) lives in 744 Evergreen Terrace\n
    "},{"location":"features/arbitrary_types/#simplify-your-life-with-macros","title":"Simplify your life with macros","text":"

    If you just want to serialize/deserialize some structs, the to_json/from_json functions can be a lot of boilerplate.

    There are several macros to make your life easier as long as you want to use a JSON object as serialization. The macros are following the naming pattern, and you can choose the macro based on the needed features:

    • All the macros start with NLOHMANN_DEFINE.
    • If you want a macro for the derived object, use the DERIVED_TYPE variant, otherwise use TYPE.
      • The DERIVED_TYPE variant requires an additional parameter of a base type, which should have the to_json/from_json functions defined. For instance, with a macro of its own.
    • If you need access to the private fields use INTRUSIVE variant, otherwise use NON_INTRUSIVE.
      • The INTRUSIVE macro should be defined inside the target class/struct, NON_INTRUSIVE should be defined within the same namespace.
    • If you want to deserialize the incomplete JSONs, use the WITH_DEFAULTS variant, which will use the default values for the member variables absent in JSON, the variant without WITH_DEFAULTS will raise an exception.
    • If you do not need deserialization at all and only interested in to_json function, you can use the ONLY_SERIALIZE variant.
    • If you want to use the custom JSON names for member variables, use WITH_NAMES variant, otherwise the JSON name of the variable will be the same as its regular name.

    For all the macros, the first parameter is the name of the class/struct. The DERIVED_TYPE macros require a second parameter of a base class. All the remaining parameters name the member variables. The WITH_NAMES macros require a JSON name before each of the variables.

    flowchart TD\n    A[\"choosing a NLOHMANN_DEFINE_* macro\"] --> B{{\"adding fields to a base class?\"}}\n    B -->|\"yes\"| C[\"...DERIVED_TYPE...\"]\n    B -->|\"no\"| D[\"...TYPE...\"]\n    C --> E{{\"need access to private members?\"}}\n    D --> E\n    E -->|\"yes\"| F[\"...INTRUSIVE... (used inside the class)\"]\n    E -->|\"no\"| G[\"...NON_INTRUSIVE... (used in the namespace)\"]\n    F --> H{{\"only serializing, never parsing back?\"}}\n    G --> H\n    H -->|\"yes\"| I[\"...ONLY_SERIALIZE\"]\n    H -->|\"no\"| J{{\"allow missing keys when parsing?\"}}\n    J -->|\"yes\"| K[\"...WITH_DEFAULT\"]\n    J -->|\"no\"| L[\"plain (missing keys throw)\"]\n    I --> M{{\"need custom JSON key names?\"}}\n    K --> M\n    L --> M\n    M -->|\"yes\"| N[\"...WITH_NAMES\"]\n    M -->|\"no\"| O[\"done\"]

    Decision tree for choosing a NLOHMANN_DEFINE_* macro: answer the questions from top to bottom; each answer picks one part of the macro name, and the parts are combined in this order. The table below lists the resulting macros.

    Need access to private members Need only serialization Allow missing values when de-serializing macro NLOHMANN_DEFINE_TYPE_INTRUSIVE NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT NLOHMANN_DEFINE_TYPE_INTRUSIVE_ONLY_SERIALIZE NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE

    Macros for classes and structs without a base class. A green check means yes, a red cross means no, and a grey skip sign means the column does not apply, as a macro that only serializes never reads values.

    For derived classes and structs, use the following macros

    Need access to private members Need only serialization Allow missing values when de-serializing macro NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_WITH_DEFAULT NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_ONLY_SERIALIZE NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_WITH_DEFAULT NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE

    Macros for derived classes and structs, read as Table 1.

    Implementation limits

    • The current macro implementations are limited to at most 63 member variables. If you want to serialize/deserialize types with more than 63 member variables, you need to define the to_json/from_json functions manually.
    • For the WITH_NAMES variants the limit is halved to 31 member variables.

    To pick the macro for your own type and get code to start from, answer the questions below.

    • Members are private: use an INTRUSIVE macro inside the class (reference).
    • All members are public, or you cannot edit the class: use a NON_INTRUSIVE macro in the class's namespace (reference).
    • The class adds members to a serializable base class: use a DERIVED_TYPE macro with the base class as second argument (reference).
    • Missing keys should keep their default values: append _WITH_DEFAULT; otherwise a missing key throws.
    • You only convert to JSON: append _ONLY_SERIALIZE instead.
    • JSON keys differ from the member names: append _WITH_NAMES and write \"key\", member pairs (reference).
    • Private members of a class you cannot edit: no macro works; write the conversion by hand (third-party types).
    • The type is not default constructible and is converted in both directions: no macro works; specialize adl_serializer with a from_json that returns the value, or append _ONLY_SERIALIZE if you only convert to JSON (non-default-constructible types).

    Macro chooser: each answer selects one part of the macro name; the generated program defines the type, calls the macro and converts a value to JSON and back. Combinations that no macro supports show the alternative instead of code.

    Example: using the NLOHMANN_DEFINE_TYPE_* macros

    The to_json/from_json functions for the person struct above can be created with:

    namespace ns {\n    NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(person, name, address, age)\n}\n

    If you want to inherit the person struct and add a field to it, it can be done with:

    namespace ns {\n    struct person_derived : person {\n        std::string email;\n    };\n\n    NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE(person_derived, person, email)\n}\n

    Here is another example with private members, where NLOHMANN_DEFINE_TYPE_INTRUSIVE is needed:

    namespace ns {\n    class address {\n      private:\n        std::string street;\n        int housenumber;\n        int postcode;\n\n      public:\n        NLOHMANN_DEFINE_TYPE_INTRUSIVE(address, street, housenumber, postcode)\n    };\n}\n

    Or in case if you use some naming convention that you do not want to expose to JSON:

    namespace ns {\n    class address {\n      private:\n        std::string m_street;\n        int m_housenumber;\n        int m_postcode;\n\n      public:\n        NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_NAMES(address, \"street\", m_street,\n                                                           \"housenumber\", m_housenumber,\n                                                           \"postcode\", m_postcode)\n    };\n}\n

    Overriding conversions for natively-supported types

    The library already provides built-in to_json/from_json conversions for STL containers such as std::vector, std::array, and std::map. Defining your own free-function to_json/from_json overload for one of these container types directly (instead of for your own type) can conflict with the built-in overload during overload resolution, producing compiler errors (\"no matching overloaded function\", \"call is ambiguous\") that vary by compiler and library version. If you need different conversion behavior for a container type the library already handles, wrap it in your own type (or use adl_serializer specialization, as shown above for boost::optional) instead of trying to re-specialize to_json/from_json for the container type itself.

    Raw C-style arrays

    Members declared as raw C-style arrays (e.g., char buf[1024]) do not round-trip safely through NLOHMANN_DEFINE_TYPE_* macros or the default (de)serializers: to_json serializes any char array as a JSON string (matching the std::string-constructible overload), but the from_json overload for fixed-size arrays expects a JSON array and iterates it element-wise, which fails with a type_error when given a string. Use std::string, std::array<char, N>, or a manually written to_json/from_json pair for such members instead.

    Macros and nlohmann::ordered_json

    The NLOHMANN_DEFINE_TYPE_*/NLOHMANN_DEFINE_DERIVED_TYPE_* macros are generic over any basic_json specialization, including nlohmann::ordered_json. Simply use ordered_json as the target type and members are serialized in declaration order \u2014 no separate macro or extra code is needed.

    namespace ns {\n    NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(person, name, address, age)\n}\n\nns::person p{\"Ned Flanders\", \"744 Evergreen Terrace\", 60};\nnlohmann::ordered_json j = p; // keys appear in declaration order: name, address, age\n

    Zero-member types

    All 12 NLOHMANN_DEFINE_TYPE_*/NLOHMANN_DEFINE_DERIVED_TYPE_* macros (excluding the WITH_NAMES variants) also accept types with no member variables to serialize, producing/accepting an empty JSON object {} (or, for the derived-type macros, just the base class's own JSON representation):

    namespace ns {\n    struct marker {\n        bool operator==(const marker&) const { return true; }\n        NLOHMANN_DEFINE_TYPE_INTRUSIVE(marker)\n    };\n}\n\nns::marker m{};\nnlohmann::json j = m; // {}\n

    No macro for non-default-constructible types

    There is currently no NLOHMANN_DEFINE_TYPE_*-style macro for types that are not DefaultConstructible. This is not an intentional omission of documentation \u2014 no such macro exists yet; see How can I use get() for non-default constructible/non-copyable types? for the manual pattern to use instead.

    "},{"location":"features/arbitrary_types/#how-do-i-convert-third-party-types","title":"How do I convert third-party types?","text":"

    This requires a bit more advanced technique. But first, let us see how this conversion mechanism works:

    flowchart LR\n    A[\"construct json j = t, or call j.get() for T\"] --> B[\"JSONSerializer for T: to_json / from_json\"]\n    B -->|\"default JSONSerializer\"| C[\"adl_serializer for T: to_json / from_json\"]\n    C -->|\"unqualified call, found via ADL\"| D[\"free to_json(j, t) / from_json(j, t) in T's namespace\"]\n    B -->|\"user specialization replaces the default\"| E[\"user's adl_serializer specialization for T\"]

    How a conversion between json and a type T is dispatched: the default adl_serializer calls the free to_json/from_json functions found by argument-dependent lookup, while a user specialization of adl_serializer replaces this path.

    The library uses JSON Serializers to convert types to JSON. The default serializer for nlohmann::json is nlohmann::adl_serializer (ADL means Argument-Dependent Lookup).

    It is implemented like this (simplified):

    template <typename T>\nstruct adl_serializer {\n    static void to_json(json& j, const T& value) {\n        // calls the \"to_json\" method in T's namespace\n    }\n\n    static void from_json(const json& j, T& value) {\n        // same thing, but with the \"from_json\" method\n    }\n};\n

    This serializer works fine when you have control over the type's namespace. However, what about boost::optional or std::filesystem::path (C++17)? Hijacking the boost namespace is pretty bad, and it's illegal to add something other than template specializations to std...

    To solve this, you need to add a specialization of adl_serializer to the nlohmann namespace, here's an example:

    // partial specialization (full specialization works too)\nNLOHMANN_JSON_NAMESPACE_BEGIN\ntemplate <typename T>\nstruct adl_serializer<boost::optional<T>> {\n    static void to_json(json& j, const boost::optional<T>& opt) {\n        if (opt == boost::none) {\n            j = nullptr;\n        } else {\n            j = *opt; // this will call adl_serializer<T>::to_json which will\n                      // find the free function to_json in T's namespace!\n        }\n    }\n\n    static void from_json(const json& j, boost::optional<T>& opt) {\n        if (j.is_null()) {\n            opt = boost::none;\n        } else {\n            opt = j.get<T>(); // same as above, but with\n                              // adl_serializer<T>::from_json\n        }\n    }\n};\nNLOHMANN_JSON_NAMESPACE_END\n

    std::optional needs no serializer

    Since version 3.12.0, std::optional<T> is supported out of the box when compiling with C++17 (std::nullopt is converted to and from null). Do not write an adl_serializer for it; this pattern is only needed for types such as boost::optional or for custom semantics. See Conversions and Omitting a field when serializing std::optional.

    ABI compatibility

    Use NLOHMANN_JSON_NAMESPACE_BEGIN and NLOHMANN_JSON_NAMESPACE_END instead of namespace nlohmann { } in code which may be linked with different versions of this library.

    "},{"location":"features/arbitrary_types/#how-can-i-use-get-for-non-default-constructiblenon-copyable-types","title":"How can I use get() for non-default constructible/non-copyable types?","text":"

    For a type that is not DefaultConstructible but is otherwise an ordinary value type, specialize adl_serializer with a from_json overload that returns the value instead of writing into a reference:

    Example: get() for a non-default-constructible type
    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nnamespace ns\n{\n// a simple struct to model a person (not default constructible)\nstruct person\n{\n    person(std::string n, std::string a, int aa)\n        : name(std::move(n)), address(std::move(a)), age(aa)\n    {}\n\n    std::string name;\n    std::string address;\n    int age;\n};\n} // namespace ns\n\nnamespace nlohmann\n{\ntemplate <>\nstruct adl_serializer<ns::person>\n{\n    static ns::person from_json(const json& j)\n    {\n        return {j.at(\"name\"), j.at(\"address\"), j.at(\"age\")};\n    }\n\n    // Here's the catch! You must provide a to_json method! Otherwise, you\n    // will not be able to convert person to json, since you fully\n    // specialized adl_serializer on that type\n    static void to_json(json& j, ns::person p)\n    {\n        j[\"name\"] = p.name;\n        j[\"address\"] = p.address;\n        j[\"age\"] = p.age;\n    }\n};\n} // namespace nlohmann\n\nint main()\n{\n    json j;\n    j[\"name\"] = \"Ned Flanders\";\n    j[\"address\"] = \"744 Evergreen Terrace\";\n    j[\"age\"] = 60;\n\n    auto p = j.get<ns::person>();\n\n    std::cout << p.name << \" (\" << p.age << \") lives in \" << p.address << '\\n';\n}\n

    Output:

    Ned Flanders (60) lives in 744 Evergreen Terrace\n

    The same technique also works if your type is not copyable, as long as it is MoveConstructible:

    struct move_only_type {\n    move_only_type() = delete;\n    move_only_type(int ii): i(ii) {}\n    move_only_type(const move_only_type&) = delete;\n    move_only_type(move_only_type&&) = default;\n\n    int i;\n};\n\nnamespace nlohmann {\n    template <>\n    struct adl_serializer<move_only_type> {\n        // note: the return type is no longer 'void', and the method only takes\n        // one argument\n        static move_only_type from_json(const json& j) {\n            return {j.get<int>()};\n        }\n\n        // Here's the catch! You must provide a to_json method! Otherwise, you\n        // will not be able to convert move_only_type to json, since you fully\n        // specialized adl_serializer on that type\n        static void to_json(json& j, move_only_type t) {\n            j = t.i;\n        }\n    };\n}\n
    "},{"location":"features/arbitrary_types/#why-isnt-my-to_json-or-from_json-found","title":"Why isn't my to_json or from_json found?","text":"

    The library calls to_json and from_json without qualification, so the compiler finds them by argument-dependent lookup in the namespace of the type, or in the namespaces of its template arguments. The usual reasons for a function that is \"not found\" are:

    • The type is an alias of a standard type. After using Hash = std::array<std::uint8_t, 6>; the type is std::array<std::uint8_t, 6>, which lives in namespace std. A to_json(json&, const Hash&) in your namespace is never selected. Either give the type its own identity, for example struct Hash : std::array<std::uint8_t, 6> {}; (the function is then found in Hash's namespace), or specialize adl_serializer<Hash>.
    • The function is in the wrong namespace. It must be in the namespace of the type (a global type needs a global function), not in the namespace of the code that calls the conversion. Specializations of adl_serializer belong in namespace nlohmann.
    • It is declared too late. A conversion can only use what has been declared when it is instantiated. If json j = std::vector<third_party::string>{...}; appears before the adl_serializer specialization, the compiler reports an error such as \"explicit specialization of adl_serializer<...> after instantiation\". Put the specialization in a small header that every file includes before it uses the type with json.
    • It is a template. For template <class T> struct box, write template <class T> void to_json(json&, const box<T>&), not an overload for one T.
    • It worked by accident. Some versions found to_json overloads in nlohmann::detail through argument-dependent lookup of the base class of basic_json. Do not rely on this; it is not part of the interface.

    For smart pointers, class hierarchies, std::variant, and std::chrono, see Recipes for common types.

    "},{"location":"features/arbitrary_types/#why-cant-i-convert-tofrom-stdany","title":"Why can't I convert to/from std::any?","text":"

    std::any is intentionally excluded from get<T>()/generic conversion support, so get<std::any>() and containers like std::map<std::string, std::any> fail to compile by design \u2014 there is no way to know, from a json value alone, which concrete type to store inside the std::any. To work with heterogeneous JSON values, dispatch on the value's type manually and construct the std::any (or extract from it) yourself:

    std::any value_to_any(const json& j) {\n    if (j.is_boolean())      { return j.get<bool>(); }\n    if (j.is_number_integer()) { return j.get<int>(); }\n    if (j.is_number_float()) { return j.get<double>(); }\n    if (j.is_string())       { return j.get<std::string>(); }\n    // ... handle other types (arrays, objects) as needed for your use case\n    return {};\n}\n\njson any_to_json(const std::any& a) {\n    if (a.type() == typeid(bool))        { return std::any_cast<bool>(a); }\n    if (a.type() == typeid(int))         { return std::any_cast<int>(a); }\n    if (a.type() == typeid(double))      { return std::any_cast<double>(a); }\n    if (a.type() == typeid(std::string)) { return std::any_cast<std::string>(a); }\n    return nullptr;\n}\n
    "},{"location":"features/arbitrary_types/#why-does-serializing-a-stdmapstdunordered_map-with-non-string-keys-produce-an-array","title":"Why does serializing a std::map/std::unordered_map with non-string keys produce an array?","text":"

    A std::map/std::unordered_map whose key type is not string-like (e.g., std::map<int, std::string>) cannot be serialized as a JSON object, because JSON object keys must be strings. See Converting maps with non-string keys in the types article for what the library does instead.

    "},{"location":"features/arbitrary_types/#why-does-stdwstring-convert-or-dump-incorrectly","title":"Why does std::wstring convert or dump incorrectly?","text":"

    The library assumes UTF-8 encoding internally, so std::wstring is not supported out of the box \u2014 see the FAQ entry on wide string handling for why, and for a UTF-8 conversion recipe.

    "},{"location":"features/arbitrary_types/#can-i-write-my-own-serializer-advanced-use","title":"Can I write my own serializer? (Advanced use)","text":"

    Yes. You might want to take a look at unit-udt.cpp in the test suite, to see a few examples.

    If you write your own serializer, you will need to do a few things:

    • use a different basic_json alias than nlohmann::json (the last template parameter of basic_json is the JSONSerializer)
    • use your basic_json alias (or a template parameter) in all your to_json/from_json methods
    • use nlohmann::to_json and nlohmann::from_json when you need ADL

    Here is an example, without simplifications, that only accepts types with a size <= 32, and uses ADL.

    // You should use void as a second template argument\n// if you don't need compile-time checks on T\ntemplate<typename T, typename SFINAE = typename std::enable_if<sizeof(T) <= 32>::type>\nstruct less_than_32_serializer {\n    template <typename BasicJsonType>\n    static void to_json(BasicJsonType& j, T value) {\n        // we want to use ADL, and call the correct to_json overload\n        using nlohmann::to_json; // this method is called by adl_serializer,\n                                 // this is where the magic happens\n        to_json(j, value);\n    }\n\n    template <typename BasicJsonType>\n    static void from_json(const BasicJsonType& j, T& value) {\n        // same thing here\n        using nlohmann::from_json;\n        from_json(j, value);\n    }\n};\n

    Be very careful when reimplementing your serializer, you can stack overflow if you don't pay attention:

    template <typename T, typename = void>\nstruct bad_serializer\n{\n    template <typename BasicJsonType>\n    static void to_json(BasicJsonType& j, const T& value) {\n      // this calls BasicJsonType::json_serializer<T>::to_json(j, value);\n      // if BasicJsonType::json_serializer == bad_serializer ... oops!\n      j = value;\n    }\n\n    template <typename BasicJsonType>\n    static void from_json(const BasicJsonType& j, T& value) {\n      // this calls BasicJsonType::json_serializer<T>::from_json(j, value);\n      // if BasicJsonType::json_serializer == bad_serializer ... oops!\n      value = j.template get<T>(); // oops!\n    }\n};\n
    "},{"location":"features/arbitrary_types/#see-also","title":"See also","text":"
    • Recipes for common types - smart pointers, class hierarchies, std::variant, and std::chrono
    • Converting values - the general overview of get/get_to and implicit conversions
    • Specializing enum conversion - map enums to JSON strings instead of integers
    • Supported macros - reference for NLOHMANN_DEFINE_TYPE_* and related macros
    • adl_serializer - the default JSONSerializer used in the conversion dispatch
    • NLOHMANN_DEFINE_TYPE_INTRUSIVE - generate the conversion functions inside the type
    • NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE - generate the conversion functions outside the type
    • NLOHMANN_DEFINE_TYPE_WITH_NAMES - use JSON keys that differ from the member names
    • NLOHMANN_DEFINE_DERIVED_TYPE - generate the conversion functions for derived classes
    • NLOHMANN_JSON_SERIALIZE_ENUM - map enum values to JSON values
    • get - convert a JSON value to a C++ type
    • get_to - convert a JSON value into an existing variable
    • json_serializer - the JSONSerializer template parameter
    "},{"location":"features/assertions/","title":"Runtime Assertions","text":"

    The code contains numerous debug assertions to ensure class invariants are valid or to detect undefined behavior. Whereas the former class invariants are nothing to be concerned with, the latter checks for undefined behavior are to detect bugs in client code.

    "},{"location":"features/assertions/#switch-off-runtime-assertions","title":"Switch off runtime assertions","text":"

    Runtime assertions can be switched off by defining the preprocessor macro NDEBUG (see the documentation of assert) which is the default for release builds. Without NDEBUG, the assertions are compiled in and contain the name of the source file (__FILE__); see notes for builds and distribution if that path must not end up in your binaries.

    "},{"location":"features/assertions/#change-assertion-behavior","title":"Change assertion behavior","text":"

    The behavior of runtime assertions can be changed by defining macro JSON_ASSERT(x) before including the json.hpp header.

    "},{"location":"features/assertions/#function-with-runtime-assertions","title":"Function with runtime assertions","text":""},{"location":"features/assertions/#unchecked-access-to-a-const-value","title":"Unchecked access to a const value","text":"

    Function operator[] implements unchecked access for arrays and objects. Whereas a missing element is added in the case of non-const values, accessing a const value with a missing object key or an invalid array index is undefined behavior (think of a dereferenced null pointer) and yields a runtime assertion. This also applies to a JSON pointer that refers to a missing key or an invalid index.

    If you are not sure whether an element exists, use checked access with the at function or call the contains function before.

    See also the documentation on element access.

    Example: missing object key

    The following code will trigger an assertion at runtime:

    #include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    const json j = {{\"key\", \"value\"}};\n    auto v = j[\"missing\"];\n}\n

    Output:

    Assertion failed: (it != m_data.m_value.object->end()), function operator[], file json.hpp, line 28795.\n
    Example 2: Invalid array index in a JSON pointer

    The following code will trigger an assertion at runtime:

    #include <nlohmann/json.hpp>\n\nusing nlohmann::json;\nusing namespace nlohmann::literals;\n\nint main()\n{\n    const json j = {{\"array\", {1, 2, 3}}};\n    auto v = j[\"/array/5\"_json_pointer];\n}\n

    Output:

    Assertion failed: (idx < m_data.m_value.array->size()), function operator[], file json.hpp, line 28758.\n
    "},{"location":"features/assertions/#constructing-from-an-uninitialized-iterator-range","title":"Constructing from an uninitialized iterator range","text":"

    Constructing a JSON value from an iterator range (see constructor) with an uninitialized iterator is undefined behavior and yields a runtime assertion.

    Example: uninitialized iterator range

    The following code will trigger an assertion at runtime:

    #include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    json::iterator it1, it2;\n    json j(it1, it2);\n}\n

    Output:

    Assertion failed: (m_object != nullptr), function operator++, file iter_impl.hpp, line 368.\n
    "},{"location":"features/assertions/#operations-on-uninitialized-iterators","title":"Operations on uninitialized iterators","text":"

    Any operation on uninitialized iterators (i.e., iterators that are not associated with any JSON value) is undefined behavior and yields a runtime assertion.

    Example: uninitialized iterator

    The following code will trigger an assertion at runtime:

    #include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n  json::iterator it;\n  ++it;\n}\n

    Output:

    Assertion failed: (m_object != nullptr), function operator++, file iter_impl.hpp, line 368.\n
    "},{"location":"features/assertions/#changes","title":"Changes","text":""},{"location":"features/assertions/#reading-from-a-null-file-or-char-pointer","title":"Reading from a null FILE or char pointer","text":"

    Reading from a null FILE or char pointer in C++ is undefined behavior. Until version 3.12.0, this library asserted that the pointer was not nullptr using a runtime assertion. If assertions were disabled, this would result in undefined behavior. Since version 3.12.0, this library checks for nullptr and throws a parse_error.101 to prevent the undefined behavior.

    Example: reading from null pointer

    The following code will trigger an assertion at runtime:

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    std::FILE* f = std::fopen(\"nonexistent_file.json\", \"r\");\n    try {\n        json j = json::parse(f);\n    } catch (std::exception& e) {\n        std::cerr << e.what() << std::endl;\n    }\n}\n

    Output:

    [json.exception.parse_error.101] parse error: attempting to parse an empty input; check that your input string or stream contains the expected JSON\n
    "},{"location":"features/assertions/#see-also","title":"See also","text":"
    • JSON_ASSERT - control behavior of runtime assertions
    • Supported Macros - all supported macros
    • Working Without Exceptions - using the library without exceptions
    • Exceptions - all exceptions and their error codes
    • Macros - reference of all macros
    "},{"location":"features/binary_values/","title":"Binary Values","text":"

    The library implements several binary formats that encode JSON in an efficient way. Most of these formats support binary values; that is, values that have semantics defined outside the library and only define a sequence of bytes to be stored.

    JSON itself does not have a binary value. As such, binary values are an extension that this library implements to store values received by a binary format. Binary values are never created by the JSON parser and are only part of a serialized JSON text if they have been created manually or via a binary format.

    "},{"location":"features/binary_values/#api-for-binary-values","title":"API for binary values","text":"
    classDiagram\n\nclass binary_t [\"json::binary_t\"] {\n    +void set_subtype(std::uint64_t subtype)\n    +void clear_subtype()\n    +std::uint64_t subtype() const\n    +bool has_subtype() const\n}\n\nclass vector [\"std::vector<uint8_t>\"]\n\nvector <|-- binary_t

    Class diagram of json::binary_t: it derives from std::vector<uint8_t> and adds functions to set, clear, query, and test an optional subtype.

    By default, binary values are stored as std::vector<std::uint8_t>. This type can be changed by providing a template parameter to the basic_json type. To store binary subtypes, the storage type is extended and exposed as json::binary_t:

    auto binary = json::binary_t({0xCA, 0xFE, 0xBA, 0xBE});\nauto binary_with_subtype = json::binary_t({0xCA, 0xFE, 0xBA, 0xBE}, 42);\n

    There are several convenience functions to check and set the subtype:

    binary.has_subtype();                   // returns false\nbinary_with_subtype.has_subtype();      // returns true\n\nbinary_with_subtype.clear_subtype();\nbinary_with_subtype.has_subtype();      // returns false\n\nbinary_with_subtype.set_subtype(42);\nbinary.set_subtype(23);\n\nbinary.subtype();                       // returns 23\n

    As json::binary_t is subclassing std::vector<std::uint8_t>, all member functions are available:

    binary.size();  // returns 4\nbinary[1];      // returns 0xFE\n

    JSON values can be constructed from json::binary_t:

    json j = binary;\n

    Binary values are primitive values just like numbers or strings, as reflected by is_binary() and is_primitive():

    j.is_binary();    // returns true\nj.is_primitive(); // returns true\n

    Given a binary JSON value, the binary_t can be accessed by reference via get_binary():

    j.get_binary().has_subtype();  // returns true\nj.get_binary().size();         // returns 4\n

    For convenience, binary JSON values can be constructed via json::binary:

    auto j2 = json::binary({0xCA, 0xFE, 0xBA, 0xBE}, 23);\nauto j3 = json::binary({0xCA, 0xFE, 0xBA, 0xBE});\n\nj2 == j;                        // returns true\nj3.get_binary().has_subtype();  // returns false\nj3.get_binary().subtype();      // returns std::uint64_t(-1) as j3 has no subtype\n
    "},{"location":"features/binary_values/#serialization","title":"Serialization","text":"

    Binary values are serialized differently according to the formats.

    "},{"location":"features/binary_values/#json","title":"JSON","text":"

    JSON does not have a binary type, and this library does not introduce a new type as this would break conformance. Instead, binary values are serialized as an object with two keys: bytes holds an array of integers, and subtype is an integer or null.

    Example: serialize a binary value to JSON

    Code:

    // create a binary value of subtype 42\njson j;\nj[\"binary\"] = json::binary({0xCA, 0xFE, 0xBA, 0xBE}, 42);\n\n// serialize to standard output\nstd::cout << j.dump(2) << std::endl;\n

    Output:

    {\n  \"binary\": {\n    \"bytes\": [202, 254, 186, 190],\n    \"subtype\": 42\n  }\n}\n

    No roundtrip for binary values

    The JSON parser will not parse the objects generated by binary values back to binary values. This is by design to remain standards compliant. Serializing binary values to JSON is only implemented for debugging purposes.

    "},{"location":"features/binary_values/#bjdata","title":"BJData","text":"

    BJData Draft 3 supports binary values as optimized arrays of B (byte) elements, but no subtypes. With version = bjdata_version_t::draft3 and both use_size and use_type set, to_bjdata writes a binary value as [$B#..., and from_bjdata reads it back as a binary value (without subtype). In all other cases, including the default Draft 2 mode, the library follows the Draft 2 proposal and writes an array of integers (U in Draft 2, B in Draft 3), which is read back as an array.

    Example: serialize a binary value to BJData

    Code:

    // create a binary value of subtype 42 (will be ignored in BJData)\njson j;\nj[\"binary\"] = json::binary({0xCA, 0xFE, 0xBA, 0xBE}, 42);\n\n// convert to BJData\nauto v = json::to_bjdata(j);      \n

    v is a std::vector<std::uint8_t> with the following 20 elements:

    0x7B                                             // '{'\n    0x69 0x06                                    // i 6 (length of the key)\n    0x62 0x69 0x6E 0x61 0x72 0x79                // \"binary\"\n    0x5B                                         // '['\n        0x55 0xCA 0x55 0xFE 0x55 0xBA 0x55 0xBE  // content (each byte prefixed with 'U')\n    0x5D                                         // ']'\n0x7D                                             // '}'\n

    The following code uses the type and size optimization for BJData:

    // convert to BJData using the size and type optimization\nauto v = json::to_bjdata(j, true, true);\n

    The resulting vector has 22 elements; the optimization is not effective for examples with few values:

    0x7B                                // '{'\n    0x23 0x69 0x01                  // '#' 'i' 1 number of object members\n    0x69 0x06                       // i 6 (length of the key)\n    0x62 0x69 0x6E 0x61 0x72 0x79   // \"binary\"\n    0x5B                            // '[' array\n        0x24 0x55                   // '$' 'U' type of the array elements: unsigned integers\n        0x23 0x69 0x04              // '#' i 4 number of array elements\n        0xCA 0xFE 0xBA 0xBE         // content\n

    Note that subtype (42) is not serialized and that, in Draft 2 mode, BJData has no binary type, and deserializing v would yield the following value:

    {\n  \"binary\": [202, 254, 186, 190]\n}\n
    "},{"location":"features/binary_values/#bon8","title":"BON8","text":"

    BON8 neither supports binary values nor subtypes. The library serializes binary values as an array of integers.

    Example: serialize a binary value to BON8

    Code:

    // create a binary value of subtype 42 (will be ignored in BON8)\njson j;\nj[\"binary\"] = json::binary({0xCA, 0xFE, 0xBA, 0xBE}, 42);\n\n// convert to BON8\nauto v = json::to_bon8(j);\n

    v is a std::vector<std::uint8_t> with the following 16 elements:

    0x87                                     // object with 1 member\n    0x62 0x69 0x6E 0x61 0x72 0x79        // \"binary\"\n    0x84                                 // array with 4 elements\n        0xC3 0x22 0xC3 0x56 0xC3 0x12 0xC3 0x16  // content (each byte, here all above 39, as a 2-byte integer)\n

    Note that the subtype is lost, and deserializing v would yield the following value:

    {\n  \"binary\": [202, 254, 186, 190]\n}\n
    "},{"location":"features/binary_values/#bson","title":"BSON","text":"

    BSON supports binary values and subtypes. If a subtype is given, it is used and added as an unsigned 8-bit integer; a subtype above 255 throws out_of_range.415. If no subtype is given, the generic binary subtype 0x00 is used. The payload of the \"old binary\" subtype 0x02 is preceded by a second length, which the library writes and removes again when reading; it is not part of the payload.

    Example: serialize a binary value to BSON

    Code:

    // create a binary value of subtype 42\njson j;\nj[\"binary\"] = json::binary({0xCA, 0xFE, 0xBA, 0xBE}, 42);\n\n// convert to BSON\nauto v = json::to_bson(j);      \n

    v is a std::vector<std::uint8_t> with the following 22 elements:

    0x16 0x00 0x00 0x00                         // number of bytes in the document\n    0x05                                    // binary value\n        0x62 0x69 0x6E 0x61 0x72 0x79 0x00  // key \"binary\" + null byte\n        0x04 0x00 0x00 0x00                 // number of bytes\n        0x2a                                // subtype\n        0xCA 0xFE 0xBA 0xBE                 // content\n0x00                                        // end of the document\n

    Note that the serialization preserves the subtype, and deserializing v would yield the following value:

    {\n  \"binary\": {\n    \"bytes\": [202, 254, 186, 190],\n    \"subtype\": 42\n  }\n}\n
    "},{"location":"features/binary_values/#cbor","title":"CBOR","text":"

    CBOR supports binary values and subtypes. Any binary value will be serialized as a byte string; a subtype is serialized as a tag preceding it. When parsing, tags are only read back as subtypes with cbor_tag_handler_t::store (see from_cbor). The library will choose the smallest representation using the length of the byte array.

    Example: serialize a binary value to CBOR

    Code:

    // create a binary value of subtype 42\njson j;\nj[\"binary\"] = json::binary({0xCA, 0xFE, 0xBA, 0xBE}, 42);\n\n// convert to CBOR\nauto v = json::to_cbor(j);      \n

    v is a std::vector<std::uint8_t> with the following 15 elements:

    0xA1                                   // map(1)\n    0x66                               // text(6)\n        0x62 0x69 0x6E 0x61 0x72 0x79  // \"binary\"\n    0xD8 0x2A                          // tag(42)\n    0x44                               // bytes(4)\n        0xCA 0xFE 0xBA 0xBE            // content\n

    Note that the subtype is serialized as tag. However, parsing tagged values yield a parse error unless json::cbor_tag_handler_t::ignore or json::cbor_tag_handler_t::store is passed to json::from_cbor (see cbor_tag_handler_t).

    With ignore, the subtype is dropped (\"subtype\": null); with store, the tag is kept (\"subtype\": 42):

    {\n  \"binary\": {\n    \"bytes\": [202, 254, 186, 190],\n    \"subtype\": null\n  }\n}\n
    {\n  \"binary\": {\n    \"bytes\": [202, 254, 186, 190],\n    \"subtype\": 42\n  }\n}\n
    "},{"location":"features/binary_values/#messagepack","title":"MessagePack","text":"

    MessagePack supports binary values and subtypes. If a subtype is given, the ext family is used. The library will choose the smallest representation among fixext1, fixext2, fixext4, fixext8, fixext16, ext8, ext16, and ext32. The subtype is then written as the signed 8-bit ext type: subtypes 128 to 255 map to the negative (reserved) ext types, and on reading the ext type is exposed as an unsigned subtype from 0 to 255.

    If no subtype is given, the bin family (bin8, bin16, bin32) is used.

    Example: serialize a binary value to MessagePack

    Code:

    // create a binary value of subtype 42\njson j;\nj[\"binary\"] = json::binary({0xCA, 0xFE, 0xBA, 0xBE}, 42);\n\n// convert to MessagePack\nauto v = json::to_msgpack(j);      \n

    v is a std::vector<std::uint8_t> with the following 14 elements:

    0x81                                   // fixmap1\n    0xA6                               // fixstr6\n        0x62 0x69 0x6E 0x61 0x72 0x79  // \"binary\"\n    0xD6                               // fixext4\n        0x2A                           // subtype\n        0xCA 0xFE 0xBA 0xBE            // content\n

    Note that the serialization preserves the subtype, and deserializing v would yield the following value:

    {\n  \"binary\": {\n    \"bytes\": [202, 254, 186, 190],\n    \"subtype\": 42\n  }\n}\n
    "},{"location":"features/binary_values/#ubjson","title":"UBJSON","text":"

    UBJSON neither supports binary values nor subtypes and proposes to serialize binary values as an array of uint8 values. The library implements this translation.

    Example: serialize a binary value to UBJSON

    Code:

    // create a binary value of subtype 42 (will be ignored in UBJSON)\njson j;\nj[\"binary\"] = json::binary({0xCA, 0xFE, 0xBA, 0xBE}, 42);\n\n// convert to UBJSON\nauto v = json::to_ubjson(j);      \n

    v is a std::vector<std::uint8_t> with the following 20 elements:

    0x7B                                             // '{'\n    0x69 0x06                                    // i 6 (length of the key)\n    0x62 0x69 0x6E 0x61 0x72 0x79                // \"binary\"\n    0x5B                                         // '['\n        0x55 0xCA 0x55 0xFE 0x55 0xBA 0x55 0xBE  // content (each byte prefixed with 'U')\n    0x5D                                         // ']'\n0x7D                                             // '}'\n

    The following code uses the type and size optimization for UBJSON:

    // convert to UBJSON using the size and type optimization\nauto v = json::to_ubjson(j, true, true);\n

    The resulting vector has 23 elements; the optimization is not effective for examples with few values:

    0x7B                                // '{'\n    0x24                            // '$' type of the object elements\n    0x5B                            // '[' array\n    0x23 0x69 0x01                  // '#' i 1 number of object elements\n    0x69 0x06                       // i 6 (length of the key)\n    0x62 0x69 0x6E 0x61 0x72 0x79   // \"binary\"\n        0x24 0x55                   // '$' 'U' type of the array elements: unsigned integers\n        0x23 0x69 0x04              // '#' i 4 number of array elements\n        0xCA 0xFE 0xBA 0xBE         // content\n

    Note that subtype (42) is not serialized and that UBJSON has no binary type, and deserializing v would yield the following value:

    {\n  \"binary\": [202, 254, 186, 190]\n}\n
    "},{"location":"features/binary_values/#see-also","title":"See also","text":"
    • Binary formats - the formats that can store binary values
    • binary_t - type for binary values
    • byte_container_with_subtype - container for binary values with subtype
    • binary - create a binary value
    • get_binary - access the stored binary value
    • is_binary - check whether a value is binary
    • cbor_tag_handler_t - store or ignore CBOR tags when parsing
    "},{"location":"features/comments/","title":"Comments","text":"

    This library does not support comments by default. It does so for three reasons:

    1. Comments are not part of the JSON specification. You may argue that // or /* */ are allowed in JavaScript, but JSON is not JavaScript.
    2. This was not an oversight: Douglas Crockford wrote on this in May 2012:

      I removed comments from JSON because I saw people were using them to hold parsing directives, a practice which would have destroyed interoperability. I know that the lack of comments makes some people sad, but it shouldn't.

      Suppose you are using JSON to keep configuration files, which you would like to annotate. Go ahead and insert all the comments you like. Then pipe it through JSMin before handing it to your JSON parser.

    3. It is dangerous for interoperability if some libraries add comment support while others do not. Please check The Harmful Consequences of the Robustness Principle on this.

    However, you can set parameter ignore_comments to true in the parse function to ignore // or /* */ comments. Comments will then be treated as whitespace. Combined with ignore_trailing_commas (also a parse parameter), this covers what is commonly referred to as JSONC (JSON with Comments, as used e.g. by Visual Studio Code's .jsonc files) \u2014 comments and trailing commas, nothing more. This is a different, smaller extension than JSON5, which additionally allows unquoted keys, single-quoted strings, and other syntax changes that this library does not support.

    For more information, see JSON With Commas and Comments (JWCC).

    Example

    Consider the following JSON with comments.

    {\n    // update in 2006: removed Pluto\n    \"planets\": [\"Mercury\", \"Venus\", \"Earth\", \"Mars\",\n                \"Jupiter\", \"Uranus\", \"Neptune\" /*, \"Pluto\" */]\n}\n

    When calling parse without additional argument, a parse error exception is thrown. If ignore_comments is set to true, the comments are ignored during parsing:

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    std::string s = R\"(\n    {\n        // update in 2006: removed Pluto\n        \"planets\": [\"Mercury\", \"Venus\", \"Earth\", \"Mars\",\n                    \"Jupiter\", \"Uranus\", \"Neptune\" /*, \"Pluto\" */]\n    }\n    )\";\n\n    try\n    {\n        json j = json::parse(s);\n    }\n    catch (json::exception& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n\n    json j = json::parse(s,\n                         /* callback */ nullptr,\n                         /* allow exceptions */ true,\n                         /* ignore_comments */ true);\n    std::cout << j.dump(2) << '\\n';\n}\n

    Output:

    [json.exception.parse_error.101] parse error at line 3, column 9: syntax error while parsing object key - invalid literal; last read: '<U+000A>    {<U+000A>        /'; expected string literal\n{\n  \"planets\": [\n    \"Mercury\",\n    \"Venus\",\n    \"Earth\",\n    \"Mars\",\n    \"Jupiter\",\n    \"Uranus\",\n    \"Neptune\"\n  ]\n}\n
    "},{"location":"features/comments/#see-also","title":"See also","text":"
    • parse - deserialize from a compatible input
    • Trailing Commas - accept trailing commas in arrays and objects
    • Parsing - overview of the parsing functions
    • Parsing Untrusted Input - limits and checks for input you do not control
    "},{"location":"features/conversions/","title":"Converting values","text":"

    A basic_json value stores JSON data, but most of the time you want to move that data into ordinary C++ types (an int, a std::string, a std::vector, or one of your own structs) and back. This page describes how these conversions work.

    "},{"location":"features/conversions/#getting-values-out","title":"Getting values out","text":"

    The get function template returns a copy of the stored value converted to the requested type:

    json j = R\"({\"name\": \"Mary\", \"age\": 42, \"hobbies\": [\"hiking\", \"reading\"]})\"_json;\n\nauto name = j[\"name\"].get<std::string>();               // \"Mary\"\nauto age  = j[\"age\"].get<int>();                        // 42\nauto hobbies = j[\"hobbies\"].get<std::vector<std::string>>();  // {\"hiking\", \"reading\"}\n

    Getting a string without quotes

    A frequent point of confusion: use get, not dump, to read a string value. j[\"name\"].get<std::string>() yields Mary, whereas j[\"name\"].dump() yields the JSON text \"Mary\" (with quotes), because dump always produces a JSON text.

    Alternatively, get_to writes into an existing variable and deduces the target type, which avoids repeating it:

    Example
    #include <iostream>\n#include <map>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create a JSON value with different types\n    json json_types =\n    {\n        {\"boolean\", true},\n        {\n            \"number\", {\n                {\"integer\", 42},\n                {\"floating-point\", 17.23}\n            }\n        },\n        {\"string\", \"Hello, world!\"},\n        {\"array\", {1, 2, 3, 4, 5}},\n        {\"null\", nullptr}\n    };\n\n    bool v1;\n    int v2;\n    short v3;\n    float v4;\n    int v5;\n    std::string v6;\n    std::vector<short> v7;\n    std::map<std::string, json> v8;\n\n    // use explicit conversions\n    json_types[\"boolean\"].get_to(v1);\n    json_types[\"number\"][\"integer\"].get_to(v2);\n    json_types[\"number\"][\"integer\"].get_to(v3);\n    json_types[\"number\"][\"floating-point\"].get_to(v4);\n    json_types[\"number\"][\"floating-point\"].get_to(v5);\n    json_types[\"string\"].get_to(v6);\n    json_types[\"array\"].get_to(v7);\n    json_types.get_to(v8);\n\n    // print the conversion results\n    std::cout << v1 << '\\n';\n    std::cout << v2 << ' ' << v3 << '\\n';\n    std::cout << v4 << ' ' << v5 << '\\n';\n    std::cout << v6 << '\\n';\n\n    for (auto i : v7)\n    {\n        std::cout << i << ' ';\n    }\n    std::cout << \"\\n\\n\";\n\n    for (const auto& i : v8)\n    {\n        std::cout << i.first << \": \" << i.second << '\\n';\n    }\n}\n

    Output:

    1\n42 42\n17.23 17\nHello, world!\n1 2 3 4 5 \n\narray: [1,2,3,4,5]\nboolean: true\nnull: null\nnumber: {\"floating-point\":17.23,\"integer\":42}\nstring: \"Hello, world!\"\n

    Getting values out of a document or a view

    A view offers the same get<T>() conversion. For the built-in types (booleans, numbers, strings, std::vector, std::map, ...) it reads the value straight from the document's index, without building a basic_json value first; user-defined types with a from_json() are converted from a basic_json value, see the list. Two conversions never copy at all: get_string() returns a string as a view into the source text, and number_token() returns a number exactly as it was written. Every other type is obtained from a subtree that is built on demand with materialize(). See Zero-copy JSON views.

    The library already knows how to convert to and from the scalar types and the STL containers (such as std::vector, std::map, std::array, std::optional, and many more). Converting a JSON object back to a std::map or a JSON array back to a std::vector therefore works without any extra code:

    json j = {{\"one\", 1}, {\"two\", 2}};\nauto m = j.get<std::map<std::string, int>>();  // {{\"one\", 1}, {\"two\", 2}}\n

    std::pair and std::tuple are also supported, converting positionally to and from a JSON array:

    json j = {1.0, \"hello\", 42};\nauto t = j.get<std::tuple<double, std::string, int>>();  // {1.0, \"hello\", 42}\n

    Serializing a std::pair/std::tuple whose every element is a string-keyed pair

    When every element of a std::pair or std::tuple is itself a two-element array whose first element is a string (for example std::pair<std::string, int>), serializing it produces a JSON object instead of the expected array:

    using kv = std::pair<std::string, int>;\njson j = std::pair<kv, kv>{{\"a\", 1}, {\"b\", 2}};  // {\"a\":1,\"b\":2}, not [[\"a\",1],[\"b\",2]]\n

    This is a consequence of the brace-initializer object-detection rule: the same rule that lets json{{\"a\", 1}, {\"b\", 2}} create an object also fires here. The resulting object cannot be read back into the original type (get<std::pair<kv, kv>>() throws type_error.302), and duplicate keys collapse into one, losing elements. This only affects std::pair/std::tuple themselves; a std::vector<std::pair<std::string, int>>, or a pair/tuple with at least one element that is not a string-keyed pair, serializes to an array as expected. To force an array, build one explicitly from the elements with array:

    std::pair<kv, kv> p{{\"a\", 1}, {\"b\", 2}};\njson a = json::array({p.first, p.second});  // [[\"a\",1],[\"b\",2]]\n

    Extracting references into a tuple

    A tuple type may also hold references (e.g. std::tuple<double&, std::string&>) to avoid copying: get then returns a tuple of references pointing directly at the elements stored inside the basic_json array, rather than a tuple of copies:

    json j = {1.0, \"hello\"};\nauto refs = j.get<std::tuple<double&, std::string&>>();\nstd::get<1>(refs) = \"world\";  // modifies j[1] in place\n

    A referenced element must name the type the library actually stores \u2014 one of boolean_t, number_integer_t, number_unsigned_t, number_float_t, string_t, binary_t, array_t, or object_t. There is nothing else to refer to, so a reference to any other type is a compile error even when a conversion would exist: std::tuple<int&> is rejected, because the library stores a number_integer_t (std::int64_t by default) and not an int. This restriction applies only to reference elements \u2014 a plain std::tuple<int> converts by value as usual.

    "},{"location":"features/conversions/#implicit-conversions","title":"Implicit conversions","text":"

    By default, a JSON value implicitly converts to a compatible C++ type, so the explicit get call can often be omitted:

    json j = \"Hello\";\nstd::string s = j;   // implicit conversion, same as j.get<std::string>()\n

    Implicit conversions are convenient but can be surprising (for example, in overload resolution or with auto). They can be disabled by defining JSON_USE_IMPLICIT_CONVERSIONS to 0, which forces the explicit get form and can catch unintended conversions at compile time.

    auto copies the JSON value; it does not convert it

    The type of j[\"name\"] is json, not the C++ type of the value inside. auto therefore deduces json:

    json j = {{\"name\", \"Mary\"}, {\"age\", 42}};\n\nauto name = j[\"name\"];                       // json: a copy of the value; prints as \"Mary\" (with quotes)\nstd::string s1 = j[\"name\"];                  // std::string: implicit conversion\nauto s2 = j[\"name\"].get<std::string>();      // std::string: explicit conversion\nauto& age = j[\"age\"];                        // json&: a reference, no copy\nage = 43;                                    // changes j\n

    This is also why std::cout << j[\"name\"] prints the quotes (see getting a string without quotes), and why a json value cannot be passed to printf: the argument is not an int or a char*, and a compiler either rejects passing it through ... (Clang does) or compiles it and prints garbage. Convert first: std::printf(\"%d\", j[\"age\"].get<int>());.

    Prefer get<T>() over auto when you want the C++ value, and auto& or const auto& when you want to avoid a copy of a large value.

    Conversions do not range-check numbers

    Just like C++ itself, the get family performs numeric conversions without range checks \u2014 retrieving a floating-point value as an integer truncates it, and narrowing conversions may overflow. See number conversion for details and how to guard against it.

    std::optional direct construction from JSON null throws

    Constructing or assigning std::optional<T> directly from a JSON value does not correctly produce std::nullopt for a JSON null:

    json j_null;\nstd::optional<std::string> opt = j_null;  // \u274c throws type_error 302\n

    This is due to C++ language rules: std::optional<T> has its own converting constructor that is chosen over basic_json::operator T() when both are viable. Use get<std::optional<T>>() or get_to() instead:

    auto opt = j_null.get<std::optional<std::string>>();  // \u2705 std::nullopt\nj_null.get_to(opt);                                     // \u2705 std::nullopt\n

    static_cast and get<std::optional<T>>() are not guaranteed equivalent

    operator ValueType() (used by static_cast and implicit conversions) intentionally excludes std::optional<T> from delegating to get<T>(), to avoid a constructor ambiguity with std::optional<T>'s own converting constructor from basic_json. As a result, static_cast<std::optional<T>>(json_value) goes through std::optional<T>'s own converting constructor rather than through get<std::optional<T>>(), which can behave differently \u2014 for example, with a custom adl_serializer<std::optional<T>> specialization. Prefer get<std::optional<T>>()/get_to() over static_cast for optional types.

    Converting to a fixed-size destination does not check the array size

    Some destination types have a size that is fixed by their C++ type rather than by the JSON value: std::pair<A, B>, std::tuple<Ts...>, std::array<T, N>, C arrays T[N], and std::map/std::unordered_map with a non-string key type (which is read from an array of two-element arrays). All of them read exactly as many elements as they need via at and never compare the JSON array's size to that number. The two mismatch directions therefore behave differently:

    • The JSON array has too many elements: the surplus is silently discarded, and no exception is thrown.
    • The JSON array has too few elements: at throws out_of_range.401 for the first missing index \u2014 an out-of-range error, not a type_error, even though the cause is a shape mismatch.
    json j = {1, 2, 3, 4, 5};\n\nauto a = j.get<std::array<int, 3>>();       // {1, 2, 3} -- elements 4 and 5 silently dropped\nauto p = j.get<std::pair<int, int>>();      // (1, 2)    -- elements 3, 4, and 5 silently dropped\n\njson k = {1};\nauto q = k.get<std::pair<int, int>>();      // \u274c throws out_of_range.401\n

    If a size mismatch is an error in your application, check the size yourself before converting.

    "},{"location":"features/conversions/#omitting-a-field-when-serializing-stdoptional","title":"Omitting a field when serializing std::optional","text":"

    By default, to_json for std::optional<T> writes either the value or null \u2014 there is no built-in way to make a field disappear from the serialized object entirely when the std::optional is std::nullopt. Because a specialization of adl_serializer<std::optional<T>> only controls how the value is converted (it cannot prevent the containing object's to_json from inserting the key in the first place), omission has to be implemented in the containing type's to_json:

    struct person {\n    std::string name;\n    std::optional<int> age;\n};\n\nvoid to_json(json& j, const person& p) {\n    j = json{{\"name\", p.name}};\n    if (p.age) {\n        j[\"age\"] = *p.age;  // key is only inserted when the optional has a value\n    }\n}\n
    "},{"location":"features/conversions/#putting-values-in","title":"Putting values in","text":"

    The reverse direction works the same way: assigning or constructing a json from a C++ value converts it to JSON.

    std::vector<int> numbers = {1, 2, 3};\njson j = numbers;   // [1,2,3]\n

    Constructing from a C++20 range view

    A json array can also be constructed directly from a C++20 range view (std::ranges::view), such as the result of std::views::filter or std::views::transform \u2014 no intermediate container is needed:

    std::vector<int> nums{1, 2, 37, 42, 21};\nauto filtered = nums | std::views::filter([](int i) { return i > 10; });\njson j(filtered);   // [37,42,21]\n

    This requires JSON_HAS_RANGES to be enabled and is unavailable on MinGW due to incomplete C++20 ranges support there; see JSON_HAS_RANGE_VIEW_CONVERSION.

    "},{"location":"features/conversions/#your-own-types","title":"Your own types","text":"

    The conversions above are built in for standard types. To make the same syntax work for your own types, provide to_json/from_json functions (or use one of the convenience macros). This is described in detail on the arbitrary types conversions page. Enums can be mapped to strings as described in specializing enum conversion.

    "},{"location":"features/conversions/#see-also","title":"See also","text":"
    • get - get a copy converted to a given type
    • get_to - convert into an existing variable
    • get_ref - / get_ptr - access the stored value without copying
    • Arbitrary types conversions - support your own types
    • JSON_USE_IMPLICIT_CONVERSIONS - toggle implicit conversions
    • Zero-copy JSON views - get values out of a document or a view
    • adl_serializer - the default serializer behind the conversions
    • type - query the type of a value
    • JSON_DISABLE_TUPLE_REFERENCE_CONVERSION - toggle conversion to tuples of references
    • JSON_HAS_RANGE_VIEW_CONVERSION - toggle conversion from ranges
    "},{"location":"features/creating_values/","title":"Creating JSON values","text":"

    There are several ways to create a JSON value in memory. This page gives an overview; to read a value from JSON text instead, see parsing. A JSON text can also be parsed into a document and read through a view instead of into a value; see Zero-copy JSON views.

    "},{"location":"features/creating_values/#from-c-values","title":"From C++ values","text":"

    Any value of a supported C++ type can be assigned to or used to construct a json:

    json j_number  = 42;\njson j_float   = 3.141;\njson j_string  = \"Hello\";\njson j_boolean = true;\njson j_null    = nullptr;\njson j_vector  = std::vector<int>{1, 2, 3};   // array\n

    See converting values for the full set of supported types.

    "},{"location":"features/creating_values/#with-initializer-lists","title":"With initializer lists","text":"

    Objects and arrays can be written concisely with brace-enclosed initializer lists:

    // an array\njson array = {1, 2, 3, 4};\n\n// an object (a list of key/value pairs)\njson object = {\n    {\"pi\", 3.141},\n    {\"happy\", true},\n    {\"name\", \"Niels\"},\n    {\"nothing\", nullptr},\n    {\"list\", {1, 0, 2}},\n    {\"object\", {{\"currency\", \"USD\"}, {\"value\", 42.99}}}\n};\n

    The library decides between an array and an object based on the content: a list whose elements are all two-element lists with a string as the first element is treated as an object, everything else as an array.

    Ambiguous cases: {} vs. []

    Because the same {} syntax is used for both arrays and objects, some cases are ambiguous. To force a particular type, use the explicit factory functions json::array and json::object:

    json empty_array_explicit = json::array();               // []\njson empty_object_explicit = json::object();             // {}\n\n// a JSON array with one object, not an object with one member\njson array_of_objects = json::array({{\"key\", \"value\"}}); // [{\"key\":\"value\"}]\n

    Related to this, single-element brace initialization such as json j{value}; wraps the element in a single-element array by default, and its behavior even differs between compilers. See the FAQ for details and the opt-in JSON_BRACE_INIT_COPY_SEMANTICS macro.

    "},{"location":"features/creating_values/#what-does-this-produce","title":"What does this produce?","text":"

    The following table shows how some common spellings are interpreted. When in doubt, use json::array(), json::object(), or the json(value) form with parentheses.

    code result note json j = {}; / json j{}; null use json::object() or json::array() json j = json::object(); {} json j = json::array(); [] json j(true); true parentheses create the value itself json j = {true}; [true] braces create a one-element array (json j{true}; depends on the compiler, see the FAQ) json j = {{\"a\", 1}}; {\"a\":1} all elements are [string, value] pairs: object json j = {{\"a\", 1}, {\"b\"}}; [[\"a\",1],[\"b\"]] one element is not a pair: array json j = {{\"a\", 1}, 2}; [[\"a\",1],2] a plain value among pairs: array json j = {{\"a\", 1, 2}}; [[\"a\",1,2]] a three-element list is not a pair: array json j = \"{\\\"a\\\":1}\"; \"{\\\"a\\\":1}\" a string value; it is not parsed json j = json::parse(\"{\\\"a\\\":1}\"); {\"a\":1} parse text with parse or _json"},{"location":"features/creating_values/#building-incrementally","title":"Building incrementally","text":"

    A value can also be built up piece by piece. Accessing a non-existing object key or array index with operator[] creates the element on the fly:

    json j;                    // null\nj[\"answer\"][\"everything\"] = 42;   // becomes an object\nj[\"list\"] = {1, 0, 2};\nj[\"list\"].push_back(3);           // [1,0,2,3]\n

    See modifying values for push_back, emplace, and related functions.

    "},{"location":"features/creating_values/#with-the-_json-literal","title":"With the _json literal","text":"

    The _json user-defined literal parses a string at the call site and is a convenient way to write a JSON value inline:

    Example
    #include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\nusing namespace nlohmann::literals;\n\nint main()\n{\n    json j = R\"( {\"hello\": \"world\", \"answer\": 42} )\"_json;\n\n    std::cout << std::setw(2) << j << '\\n';\n}\n

    Output:

    {\n  \"answer\": 42,\n  \"hello\": \"world\"\n}\n

    Note this parses the string, so \"42\"_json is the number 42, whereas json(\"42\") is the JSON string \"42\".

    "},{"location":"features/creating_values/#see-also","title":"See also","text":"
    • basic_json constructors - all ways to construct a value
    • array - / object - force array or object type
    • operator\"\"_json - the _json literal
    • Converting values - which C++ types can be used
    • Parsing - create a value from JSON text
    • Zero-copy JSON views - create a document and a view from JSON text instead of a value
    • basic_json - the class template and its member functions
    • Types - the JSON value types
    • JSON_BRACE_INIT_COPY_SEMANTICS - change how a single braced value is interpreted
    • operator= - assign a new value
    "},{"location":"features/enum_conversion/","title":"Specializing enum conversion","text":"

    By default, enum values are serialized to JSON as integers. In some cases, this could result in undesired behavior. If the integer values of any enum values are changed after data using those enum values has been serialized to JSON, then deserializing that JSON would result in a different enum value being restored, or the value not being found at all.

    It is possible to more precisely specify how a given enum is mapped to and from JSON as shown below:

    // example enum type declaration\nenum TaskState {\n    TS_STOPPED,\n    TS_RUNNING,\n    TS_COMPLETED,\n    TS_INVALID=-1,\n};\n\n// map TaskState values to JSON as strings\nNLOHMANN_JSON_SERIALIZE_ENUM( TaskState, {\n    {TS_INVALID, nullptr},\n    {TS_STOPPED, \"stopped\"},\n    {TS_RUNNING, \"running\"},\n    {TS_COMPLETED, \"completed\"},\n})\n

    The NLOHMANN_JSON_SERIALIZE_ENUM() macro declares a set of to_json() / from_json() functions for type TaskState while avoiding repetition and boilerplate serialization code.

    "},{"location":"features/enum_conversion/#usage","title":"Usage","text":"

    Serialization converts an enum value to its mapped string, deserialization does the reverse, and an unrecognized JSON value deserializes to the first pair in the map:

    // enum to JSON as string\njson j = TS_STOPPED;\nassert(j == \"stopped\");\n\n// json string to enum\njson j3 = \"running\";\nassert(j3.get<TaskState>() == TS_RUNNING);\n\n// undefined json value to enum (where the first map entry above is the default)\njson jPi = 3.14;\nassert(jPi.get<TaskState>() == TS_INVALID );\n
    Example: serializing/deserializing enums, including a second enum type
    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nnamespace ns\n{\nenum TaskState\n{\n    TS_STOPPED,\n    TS_RUNNING,\n    TS_COMPLETED,\n    TS_INVALID = -1\n};\n\nNLOHMANN_JSON_SERIALIZE_ENUM(TaskState,\n{\n    { TS_INVALID, nullptr },\n    { TS_STOPPED, \"stopped\" },\n    { TS_RUNNING, \"running\" },\n    { TS_COMPLETED, \"completed\" }\n})\n\nenum class Color\n{\n    red, green, blue, unknown\n};\n\nNLOHMANN_JSON_SERIALIZE_ENUM(Color,\n{\n    { Color::unknown, \"unknown\" }, { Color::red, \"red\" },\n    { Color::green, \"green\" }, { Color::blue, \"blue\" }\n})\n} // namespace ns\n\nint main()\n{\n    // serialization\n    json j_stopped = ns::TS_STOPPED;\n    json j_red = ns::Color::red;\n    std::cout << \"ns::TS_STOPPED -> \" << j_stopped\n              << \", ns::Color::red -> \" << j_red << '\\n';\n\n    // deserialization\n    json j_running = \"running\";\n    json j_blue = \"blue\";\n    auto running = j_running.get<ns::TaskState>();\n    auto blue = j_blue.get<ns::Color>();\n    std::cout << j_running << \" -> \" << running\n              << \", \" << j_blue << \" -> \" << static_cast<int>(blue) << '\\n';\n\n    // deserializing undefined JSON value to enum\n    // (where the first map entry above is the default)\n    json j_pi = 3.14;\n    auto invalid = j_pi.get<ns::TaskState>();\n    auto unknown = j_pi.get<ns::Color>();\n    std::cout << j_pi << \" -> \" << invalid << \", \"\n              << j_pi << \" -> \" << static_cast<int>(unknown) << '\\n';\n}\n

    Output:

    ns::TS_STOPPED -> \"stopped\", ns::Color::red -> \"red\"\n\"running\" -> 1, \"blue\" -> 2\n3.14 -> -1, 3.14 -> 3\n
    "},{"location":"features/enum_conversion/#maps-with-enum-keys","title":"Maps with enum keys","text":"

    By default, maps with enum keys, such as std::map<TaskState, std::string>, are stored as arrays of [key, value] pairs, because JSON object keys must be strings. Define JSON_USE_OBJECTS_FOR_ENUM_KEYED_MAPS before including the library to store them as objects, with the keys converted by the enum's to_json() function:

    std::map<TaskState, std::string> m = {{TS_STOPPED, \"aa\"}, {TS_COMPLETED, \"bb\"}};\n\njson j = m;\n// default:                                   [[\"stopped\",\"aa\"],[\"completed\",\"bb\"]]\n// with JSON_USE_OBJECTS_FOR_ENUM_KEYED_MAPS: {\"completed\":\"bb\",\"stopped\":\"aa\"}\n

    Either form can be read back, with or without the macro.

    "},{"location":"features/enum_conversion/#notes","title":"Notes","text":"

    Just as in Arbitrary Type Conversions above,

    • NLOHMANN_JSON_SERIALIZE_ENUM() MUST be declared in your enum type's namespace (which can be the global namespace), or the library will not be able to locate it, and it will default to integer serialization.
    • It MUST be available (e.g., proper headers must be included) everywhere you use the conversions.

    Other Important points:

    • When using get<ENUM_TYPE>(), undefined JSON values will default to the first pair specified in your map. Select this default pair carefully. If you desire an exception in this circumstance use NLOHMANN_JSON_SERIALIZE_ENUM_STRICT() which behaves identically except for throwing an out_of_range.410 exception on unrecognized values, both when serializing an enum value not listed in the map and when deserializing a JSON value that matches none of the map's entries.
    • If an enum or JSON value is specified more than once in your map, the first matching occurrence from the top of the map will be returned when converting to or from JSON.
    • To disable the default serialization of enumerators as integers and force a compiler error instead, see JSON_DISABLE_ENUM_SERIALIZATION.
    Example: NLOHMANN_JSON_SERIALIZE_ENUM_STRICT throwing on unrecognized values
    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nnamespace ns\n{\n\nenum class Color\n{\n    red,\n    green,\n    blue,\n    unknown // not mapped in JSON_SERIALIZE_ENUM_STRICT\n};\n\nNLOHMANN_JSON_SERIALIZE_ENUM_STRICT(Color,\n{\n    {Color::red, \"red\"},\n    {Color::green, \"green\"},\n    {Color::blue, \"blue\"}\n})\n\n} // namespace ns\n\n\nint main()\n{\n    // invalid serialization\n    try\n    {\n        // ns::color::unknown was not mapped in macro\n        json invalid_serialization = ns::Color::unknown;\n    }\n    catch (const json::exception e)\n    {\n        std::cout << \"deserialization failed: \" << e.what() << '\\n';\n    }\n\n    // invalid deserialization\n    try\n    {\n        // what does not map to an enum\n        json invalid_deserialization(\"what\");\n        ns::Color color = invalid_deserialization.get<ns::Color>();\n    }\n    catch (const json::exception e)\n    {\n        std::cout << \"deserialization failed: \" << e.what() << '\\n';\n    }\n\n    return 0;\n}\n

    Output:

    deserialization failed: [json.exception.out_of_range.410] enum value out of range for Color\ndeserialization failed: [json.exception.out_of_range.410] enum value out of range for Color: \"what\"\n
    "},{"location":"features/enum_conversion/#see-also","title":"See also","text":"
    • Arbitrary Type Conversions - convert your own types
    • Converting values - the general overview of get/get_to
    • NLOHMANN_JSON_SERIALIZE_ENUM - define the enum-to-JSON mapping
    • NLOHMANN_JSON_SERIALIZE_ENUM_STRICT - throw on unmapped values
    • JSON_DISABLE_ENUM_SERIALIZATION - disable the default enum conversion
    • JSON_USE_OBJECTS_FOR_ENUM_KEYED_MAPS - serialize maps with enum keys as objects
    "},{"location":"features/iterators/","title":"Iterators","text":""},{"location":"features/iterators/#overview","title":"Overview","text":"

    A basic_json value is a container and allows access via iterators. Depending on the value type, basic_json stores zero or more values.

    As for other containers, begin() returns an iterator to the first value and end() returns an iterator to the value following the last value. The latter iterator is a placeholder and cannot be dereferenced. In case of null values, empty arrays, or empty objects, begin() will return end().

    A row of fifteen elements followed by a dashed past-the-last position. begin() points to the first element and end() points to the past-the-last position. begin end Past-the-last element

    The range of begin() and end(): begin() refers to the first element, end() to the position after the last element, which must not be dereferenced.

    "},{"location":"features/iterators/#iteration-order-for-objects","title":"Iteration order for objects","text":"

    When iterating over objects, values are ordered with respect to the object_comparator_t type which defaults to std::less. See the types documentation for more information.

    Example: iteration order of object values
    // create JSON object {\"one\": 1, \"two\": 2, \"three\": 3}\njson j;\nj[\"one\"] = 1;\nj[\"two\"] = 2;\nj[\"three\"] = 3;\n\nfor (auto it = j.begin(); it != j.end(); ++it)\n{\n    std::cout << *it << std::endl;\n}\n

    Output:

    1\n3\n2\n

    The reason for the order is the lexicographic ordering of the object keys \"one\", \"three\", \"two\".

    "},{"location":"features/iterators/#access-object-keys-during-iteration","title":"Access object keys during iteration","text":"

    The JSON iterators have two member functions, key() and value() to access the object key and stored value, respectively. When calling key() on a non-object iterator, an invalid_iterator.207 exception is thrown.

    Example: access object keys with key() and value()
    // create JSON object {\"one\": 1, \"two\": 2, \"three\": 3}\njson j;\nj[\"one\"] = 1;\nj[\"two\"] = 2;\nj[\"three\"] = 3;\n\nfor (auto it = j.begin(); it != j.end(); ++it)\n{\n    std::cout << it.key() << \" : \" << it.value() << std::endl;\n}\n

    Output:

    one : 1\nthree : 3\ntwo : 2\n
    "},{"location":"features/iterators/#range-based-for-loops","title":"Range-based for loops","text":"

    C++11 allows using range-based for loops to iterate over a container.

    for (auto it : j_object)\n{\n    // \"it\" is of type json::reference and has no key() member\n    std::cout << \"value: \" << it << '\\n';\n}\n

    For this reason, the items() function allows accessing iterator::key() and iterator::value() during range-based for loops. In these loops, a reference to the JSON values is returned, so there is no access to the underlying iterator.

    for (auto& el : j_object.items())\n{\n    std::cout << \"key: \" << el.key() << \", value:\" << el.value() << '\\n';\n}\n

    The items() function also allows using structured bindings (C++17):

    for (auto& [key, val] : j_object.items())\n{\n    std::cout << \"key: \" << key << \", value:\" << val << '\\n';\n}\n

    Note

    When iterating over an array, key() will return the index of the element as string. For primitive types (e.g., numbers), key() returns an empty string.

    Warning

    Using items() on temporary objects is dangerous. Make sure the object's lifetime exceeds the iteration. See #2040 for more information.

    "},{"location":"features/iterators/#reverse-iteration-order","title":"Reverse iteration order","text":"

    rbegin() and rend() return iterators in the reverse sequence.

    Two rows of sixteen cells. The upper row shows the reversed sequence: rend() points to a dashed position before the first element and rbegin() to the last element. The lower row shows the forward sequence: begin() points to the first element and end() to a dashed position after the last element. A reverse iterator stores an iterator to the next element, so rend() corresponds to begin() and rbegin() to end(). rend rbegin Reverse past-the-last element A reverse iterator stores an iterator to the next element begin end Past-the-last element

    The range of rbegin() and rend() over the same elements: rbegin() refers to the last element and rend() to the position before the first one. Each reverse iterator stores an iterator to the element after the one it refers to.

    Example: reverse iteration with rbegin() and rend()
    json j = {1, 2, 3, 4};\n\nfor (auto it = j.rbegin(); it != j.rend(); ++it)\n{\n    std::cout << *it << std::endl;\n}\n

    Output:

    4\n3\n2\n1\n
    "},{"location":"features/iterators/#iterating-strings-and-binary-values","title":"Iterating strings and binary values","text":"

    Note that \"value\" means a JSON value in this setting, not values stored in the underlying containers. That is, *begin() returns the complete string or binary array and is also safe if the underlying string or binary array is empty.

    Example: iterate over a string value
    json j = \"Hello, world\";\nfor (auto it = j.begin(); it != j.end(); ++it)\n{\n    std::cout << *it << std::endl;\n}\n

    Output:

    \"Hello, world\"\n
    "},{"location":"features/iterators/#iterator-invalidation","title":"Iterator invalidation","text":"Operations invalidated iterators clear all"},{"location":"features/iterators/#see-also","title":"See also","text":"
    • begin - / end - iterators to the first and one past the last element
    • rbegin - / rend - reverse iterators
    • cbegin - / cend - const iterators
    • items - iterate over keys and values
    • Object Order - iteration order of object keys
    • Element Access - access single elements
    • Modifying values - add and remove elements (including iterator invalidation rules)
    "},{"location":"features/json_patch/","title":"JSON Patch and Diff","text":""},{"location":"features/json_patch/#patches","title":"Patches","text":"

    JSON Patch (RFC 6902) defines a JSON document structure for expressing a sequence of operations to apply to a JSON document. Operations address locations in the document using JSON Pointer paths. With the patch function, a JSON Patch is applied to the current JSON value by executing all operations from the patch, yielding the patched document as a new value.

    The following steps through one operation of each kind. The first three operations are those of the example below; the other three continue on its result.

    Operation Before After {\"op\": \"replace\", \"path\": \"/baz\", \"value\": \"boo\"} {\"baz\": \"qux\", \"foo\": \"bar\"} {\"baz\": \"boo\", \"foo\": \"bar\"} {\"op\": \"add\", \"path\": \"/hello\", \"value\": [\"world\"]} {\"baz\": \"boo\", \"foo\": \"bar\"} {\"baz\": \"boo\", \"foo\": \"bar\", \"hello\": [\"world\"]} {\"op\": \"remove\", \"path\": \"/foo\"} {\"baz\": \"boo\", \"foo\": \"bar\", \"hello\": [\"world\"]} {\"baz\": \"boo\", \"hello\": [\"world\"]} {\"op\": \"move\", \"from\": \"/baz\", \"path\": \"/hello/1\"} {\"baz\": \"boo\", \"hello\": [\"world\"]} {\"hello\": [\"world\", \"boo\"]} {\"op\": \"copy\", \"from\": \"/hello/0\", \"path\": \"/greeting\"} {\"hello\": [\"world\", \"boo\"]} {\"greeting\": \"world\", \"hello\": [\"world\", \"boo\"]} {\"op\": \"test\", \"path\": \"/greeting\", \"value\": \"world\"} {\"greeting\": \"world\", \"hello\": [\"world\", \"boo\"]} unchanged (a failed test throws)

    Stepper through the six operations: Next applies the next operation, Back undoes it, and Reset returns to the original document. The current operation is highlighted in the patch list, and the lines it changes are marked in the document.

    Applying a patch without copying

    patch leaves the original value unchanged and returns the patched result as a copy. If the document is large and the original value is no longer needed, patch_inplace applies the same operations in place instead.

    Duplicate member names

    Duplicate member names inside an operation object are resolved by the parser before the patch is applied (the last one is kept, see object_t), so {\"op\": \"add\", \"op\": \"remove\", \"path\": \"/a\"} is a remove operation.

    Example: apply a JSON Patch

    The following code shows how a JSON patch is applied to a value.

    #include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\nusing namespace nlohmann::literals;\n\nint main()\n{\n    // the original document\n    json doc = R\"(\n        {\n          \"baz\": \"qux\",\n          \"foo\": \"bar\"\n        }\n    )\"_json;\n\n    // the patch\n    json patch = R\"(\n        [\n          { \"op\": \"replace\", \"path\": \"/baz\", \"value\": \"boo\" },\n          { \"op\": \"add\", \"path\": \"/hello\", \"value\": [\"world\"] },\n          { \"op\": \"remove\", \"path\": \"/foo\"}\n        ]\n    )\"_json;\n\n    // apply the patch\n    json patched_doc = doc.patch(patch);\n\n    // output original and patched document\n    std::cout << std::setw(4) << doc << \"\\n\\n\"\n              << std::setw(4) << patched_doc << '\\n';\n}\n

    Output:

    {\n    \"baz\": \"qux\",\n    \"foo\": \"bar\"\n}\n\n{\n    \"baz\": \"boo\",\n    \"hello\": [\n        \"world\"\n    ]\n}\n
    "},{"location":"features/json_patch/#diff","title":"Diff","text":"

    The library can also calculate a JSON patch (i.e., a diff) given two JSON values with the diff function.

    flowchart LR\n    S[\"source\"] -->|\"diff(source, target)\"| P[\"patch\"]\n    S -->|\"source.patch(patch)\"| T[\"target\"]\n    P -.->|\"applied to source, yields\"| T

    How diff and patch relate: diff(source, target) yields a patch, and applying that patch to the source yields the target.

    Invariant

    For two JSON values source and target, the following code yields true:

    source.patch(diff(source, target)) == target;\n

    The equality holds up to operator==, with these exceptions:

    • NaN and discarded values are not equal to themselves, so the invariant cannot hold for them. diff emits a replace operation for such a value, and a NaN in a patch is serialized as null.
    • Numbers that compare equal produce no operation even if their types differ or if one is zero and the other is negative zero: diff(1, 1.0), diff(1u, 1), and diff(0.0, -0.0) return [], so the patched value keeps the number type and sign of source.
    • A binary value in a patch is serialized as an object ({\"bytes\":[...],\"subtype\":null}), so a patch that was dumped and parsed again no longer holds a binary value.
    Example: create a JSON Patch from the difference of two values

    The following code shows how a JSON patch is created as a diff for two JSON values.

    #include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\nusing namespace nlohmann::literals;\n\nint main()\n{\n    // the source document\n    json source = R\"(\n        {\n            \"baz\": \"qux\",\n            \"foo\": \"bar\"\n        }\n    )\"_json;\n\n    // the target document\n    json target = R\"(\n        {\n            \"baz\": \"boo\",\n            \"hello\": [\n                \"world\"\n            ]\n        }\n    )\"_json;\n\n    // create the patch\n    json patch = json::diff(source, target);\n\n    // roundtrip\n    json patched_source = source.patch(patch);\n\n    // output patch and roundtrip result\n    std::cout << std::setw(4) << patch << \"\\n\\n\"\n              << std::setw(4) << patched_source << '\\n';\n}\n

    Output:

    [\n    {\n        \"op\": \"replace\",\n        \"path\": \"/baz\",\n        \"value\": \"boo\"\n    },\n    {\n        \"op\": \"remove\",\n        \"path\": \"/foo\"\n    },\n    {\n        \"op\": \"add\",\n        \"path\": \"/hello\",\n        \"value\": [\n            \"world\"\n        ]\n    }\n]\n\n{\n    \"baz\": \"boo\",\n    \"hello\": [\n        \"world\"\n    ]\n}\n
    "},{"location":"features/json_patch/#see-also","title":"See also","text":"
    • JSON Pointer - the addressing scheme used for patch paths
    • JSON Merge Patch - a simpler, less expressive alternative patch format
    • patch - apply a JSON Patch, returning the result as a copy
    • patch_inplace - apply a JSON Patch without copying
    • diff - compute a JSON Patch from two values
    • json_pointer - type to represent JSON Pointers
    • merge_diff - compute a JSON Merge Patch from two values
    • Modifying values - simple in-place modifications
    "},{"location":"features/json_pointer/","title":"JSON Pointer","text":""},{"location":"features/json_pointer/#introduction","title":"Introduction","text":"

    The library supports JSON Pointer (RFC 6901) as an alternative means to address structured values. A JSON Pointer is a string that identifies a specific value within a JSON document.

    Consider the following JSON document

    {\n    \"array\": [\"A\", \"B\", \"C\"],\n    \"nested\": {\n        \"one\": 1,\n        \"two\": 2,\n        \"three\": [true, false]\n    }\n}\n

    Select a pointer (or a node of the tree) to walk it through this document; each segment of the pointer goes one level deeper. The table below lists the same pointers.

    Highlighted: the path of the pointer /nested/three/1, which identifies false.

    • root object
      • \"array\" array
        • 0: \"A\"
        • 1: \"B\"
        • 2: \"C\"
      • \"nested\" object
        • \"one\": 1
        • \"two\": 2
        • \"three\" array
          • 0: true
          • 1: false

    The highlighted nodes are the path from the root to the selected level, and the line below the tree shows the value the pointer resolves to. Select a segment in the pointer bar to stop at a shallower level, or a node of the tree to select its pointer.

    Then every value inside the JSON document can be identified as follows:

    JSON Pointer JSON value `` {\"array\":[\"A\",\"B\",\"C\"],\"nested\":{\"one\":1,\"two\":2,\"three\":[true,false]}} /array [\"A\",\"B\",\"C\"] /array/0 A /array/1 B /array/2 C /nested {\"one\":1,\"two\":2,\"three\":[true,false]} /nested/one 1 /nested/two 2 /nested/three [true,false] /nested/three/0 true /nested/three/1 false

    Note / does not identify the root (i.e., the whole document), but an object entry with empty key \"\". See RFC 6901 for more information.

    RFC 6901, section 4 states that evaluation fails if an object has non-unique member names. A basic_json object holds one value per key (see object_t for how duplicate keys are handled while parsing), so evaluating a JSON Pointer never encounters duplicates.

    "},{"location":"features/json_pointer/#json-pointer-creation","title":"JSON Pointer creation","text":"

    JSON Pointers can be created from a string:

    json::json_pointer p(\"/nested/one\");\n

    Furthermore, a user-defined string literal can be used to achieve the same result:

    auto p = \"/nested/one\"_json_pointer;\n

    The escaping rules of RFC 6901 are implemented. See the constructor documentation for more information.

    URI fragment representation

    RFC 6901, section 6 also defines a URI fragment identifier representation (#/a%20b). It is not supported: json::json_pointer(\"#/a\") throws parse_error.107. Strip the leading # and percent-decode the remainder before creating the JSON pointer.

    "},{"location":"features/json_pointer/#value-access","title":"Value access","text":"

    JSON Pointers can be used in the at, operator[], and value functions just like object keys or array indices.

    // the JSON value from above\nauto j = json::parse(R\"({\n    \"array\": [\"A\", \"B\", \"C\"],\n    \"nested\": {\n        \"one\": 1,\n        \"two\": 2,\n        \"three\": [true, false]\n    }\n})\");\n\n// access values\nauto val = j[\"\"_json_pointer];                              // {\"array\":[\"A\",\"B\",\"C\"],...}\nauto val1 = j[\"/nested/one\"_json_pointer];                  // 1\nauto val2 = j.at(json::json_pointer(\"/nested/three/1\"));    // false\nauto val3 = j.value(json::json_pointer(\"/nested/four\"), 0); // 0\n

    To read a value with a fallback, use value with a JSON Pointer; to test for existence, use contains. Neither needs intermediate checks, see Nested values.

    Creating intermediate levels that don't exist

    See the operator[] notes for how array vs. object is decided when a pointer creates intermediate levels that don't exist yet.

    "},{"location":"features/json_pointer/#flatten-unflatten","title":"Flatten / unflatten","text":"

    The library implements a function flatten to convert any JSON document into a JSON object where each key is a JSON Pointer and each value is a primitive JSON value (i.e., a string, boolean, number, or null).

    // the JSON value from above\nauto j = json::parse(R\"({\n    \"array\": [\"A\", \"B\", \"C\"],\n    \"nested\": {\n        \"one\": 1,\n        \"two\": 2,\n        \"three\": [true, false]\n    }\n})\");\n\n// create flattened value\nauto j_flat = j.flatten();\n

    The resulting value j_flat is:

    {\n  \"/array/0\": \"A\",\n  \"/array/1\": \"B\",\n  \"/array/2\": \"C\",\n  \"/nested/one\": 1,\n  \"/nested/two\": 2,\n  \"/nested/three/0\": true,\n  \"/nested/three/1\": false\n}\n

    The reverse function, unflatten recreates the original value.

    auto j_original = j_flat.unflatten();\n

    Each leaf of the document becomes one key of the flat object, and unflatten() reverses the mapping:

    flatten() turns the nested example document into a flat object, and unflatten() turns it back. Left, the document as a tree: array with the elements A, B, C, and nested with one = 1, two = 2, and three with the elements true and false. Right, the flat object with one key per leaf: /array/0 = A, /array/1 = B, /array/2 = C, /nested/one = 1, /nested/two = 2, /nested/three/0 = true, /nested/three/1 = false. Each leaf is joined to its key by a line. nested value flat object: key = J\u200bSON Pointer flatten() unflatten() \"/array/0\": \"A\" \"/array/1\": \"B\" \"/array/2\": \"C\" \"/nested/one\": 1 \"/nested/two\": 2 \"/nested/three/0\": true \"/nested/three/1\": false root \"array\" 0: \"A\" 1: \"B\" 2: \"C\" \"nested\" \"one\": 1 \"two\": 2 \"three\" 0: true 1: false

    Left: the example document as a tree; right: the flat object it becomes. flatten() converts from left to right, unflatten() from right to left.

    "},{"location":"features/json_pointer/#see-also","title":"See also","text":"
    • json_pointer - the JSON Pointer class
    • Nested values - value, contains, and at accept JSON Pointers
    • flatten - convert a value to an object of JSON Pointers and primitive values
    • unflatten - restore a value from a flattened object
    • JSON Patch - paths inside a patch are JSON Pointers
    • JSON Merge Patch - an alternative patch format that does not use JSON Pointer
    • operator\"\"_json_pointer - user-defined literal to create a JSON pointer
    • Element Access - other ways to access elements
    "},{"location":"features/json_view/","title":"Zero-copy JSON views","text":"

    <nlohmann/json_view.hpp> adds a read-only, non-owning way to look at a parsed JSON text, as an alternative to building a basic_json tree with parse().

    "},{"location":"features/json_view/#the-problem","title":"The problem","text":"

    basic_json::parse() builds a tree of basic_json values: one allocation for every array and object, and every string copied into its own std::string. That is the right trade-off when the program goes on to read and write the value freely, but it does more work than necessary when only a small part of a large JSON text is actually needed, or when the same text is parsed over and over (many small messages, for instance) and most of the resulting tree is thrown away almost immediately.

    "},{"location":"features/json_view/#the-idea","title":"The idea","text":"

    basic_json_document::parse() parses the same JSON grammar, with the same options, but instead of a tree it builds a flat index of the values it found: one 16-byte entry per value (and one per object key), in document order. Integers are converted while parsing and stored in their entry. Floating-point numbers and strings are referenced in place in the source text: a float is converted when it is read, and only strings that contain escape sequences are decoded, into one shared buffer owned by the document.

    basic_json_view is a small, trivially copyable handle (two pointers) into that index. It gives you the read-only, type-inspection part of the basic_json interface \u2014 type() and the is_*() predicates, size()/empty() \u2014 as well as element access (operator[], at, front/back), lookup (find, contains, count), and iteration (begin/end, items) \u2014 without ever allocating a basic_json value. When you do need an actual basic_json value for a subtree, materialize() builds exactly the one parse() would have produced for it.

    The same small text, parsed both ways:

    The same J\u200bSON text parsed by basic_json::parse() and by json_document::parse() The text {\"port\": 6379, \"price\": 19.90, \"tags\": [\"eu\", \"a\\\"b\"]}. Top: basic_json::parse() builds a tree: the root json value points to a std::map whose three nodes are separate heap allocations; the price is stored as the double 19.9; the tags array is a std::vector of two json values, each pointing to its own std::string. Bottom: json_document::parse() keeps the 54 bytes of source text and builds a flat index of nine 16-byte nodes in document order: object, key port, unsigned integer 6379 (the converted value is in the node), key price, float, key tags, array, string eu, and an escaped string. Keys, the float, and the plain string point back into the source text; the escaped string points into the document's buffer of decoded strings. A json_view is two pointers: one to the document and one to a node, here the array. basic_json::parse(): a tree, every array, object, and string in its own heap allocation json std::map \"port\" 6379 \"price\" 19.9 double: 19.90 is gone \"tags\" \u2022 std::vector json json std::string eu std::string a\"b a separate heap allocation json_document::parse(): the source text stays where it is; one flat index of 16-byte nodes source text, 54 bytes (borrowed, or owned by the document) { \" p o r t \" : 6 3 7 9 , \" p r i c e \" : 1 9 . 9 0 , \" t a g s \" : [ \" e u \" , \" a \\ \" b \" ] } 0 10 20 30 40 50 json_document: owns the node index and the buffer of decoded strings node index: 9 nodes \u00d7 16 bytes = 144 bytes, in document order 0 object len 3 next 9 1 key off 2 len 4 2 uint 6379 (converted) 3 key off 16 len 5 4 float off 24 len 5 5 key off 32 len 4 6 array len 2 next 3 7 string off 41 len 2 8 string escaped len 3 decoded strings a \" b json_view v = doc.root()[\"tags\"] doc* node* integers are converted while parsing and kept in their node; floats and strings point back into the text

    Top: the tree of separate heap allocations that basic_json::parse() builds. Bottom: json_document::parse() keeps the source text and builds one flat index of 16-byte nodes that point back into it, plus a buffer of decoded strings.

    "},{"location":"features/json_view/#how-to-use-it","title":"How to use it","text":"

    Include <nlohmann/json_view.hpp> in addition to (or instead of) <nlohmann/json.hpp>. Parse into a json_document, inspect its root(), and materialize() when you need a real value. materialize() works on any view, not just the root, so you can turn just the subtree you need into a value:

    Example: parse a document, inspect its root, and materialize it
    #include <iostream>\n#include <nlohmann/json_view.hpp>\n\nusing nlohmann::json_document;\n\nint main()\n{\n    std::cout << std::boolalpha;\n\n    // json_document is basic_json_document<nlohmann::json>: same value types\n    // and containers as the ordinary json specialization\n    json_document doc = json_document::parse(R\"({\"pi\": 3.14, \"numbers\": [1, 2, 3]})\");\n\n    std::cout << doc.root().is_object() << '\\n';\n    std::cout << doc.root().materialize().dump() << '\\n';\n}\n

    Output:

    true\n{\"numbers\":[1,2,3],\"pi\":3.14}\n

    ordered_json_document is the equivalent for ordered_json, just as ordered_json is to json.

    "},{"location":"features/json_view/#ownership-and-lifetime","title":"Ownership and lifetime","text":"

    A document either borrows the text it was parsed from, or owns its own copy of it; call owns_source() to find out which happened. parse() decides this from the value category and type of its argument (an lvalue std::string is borrowed; an rvalue std::string is moved in, owned without a copy; a stream is read into an owned buffer; and so on \u2014 see parse's Notes for the full table). parse_copy() always owns a copy, regardless of the input.

    A borrowed document depends on your buffer

    If a document borrows its text, that text must outlive the document (and every view taken from it) and must stay unmodified for as long as the document exists, since floating-point values and unescaped strings are read from it lazily. Reading or writing through a view after the underlying buffer is gone is undefined behavior, exactly as it would be for a dangling std::string_view.

    A view is valid only while all of the following hold:

    • the document is alive,
    • the document has not been re-parsed since the view was taken (with read() or parse() into it),
    • the document has not had shrink_to_fit() called on it since, and
    • if the document borrows its source text, that text is still alive and unmodified.

    Moving the basic_json_document<> itself is fine and does not invalidate its views: the index is a separate heap allocation that keeps its address across the move. Take a fresh view from root() whenever any of the other conditions above was not met.

    When a json_view becomes invalid Four timelines. First: a document borrows a std::string; when the string is destroyed, the document and every view taken from it dangle. Second: doc.read() re-parses the document; views taken before are invalid, a fresh view from root() is valid. Third: doc.shrink_to_fit() has the same effect. Fourth: moving the document does not invalidate its views; destroying the moved-to document does. alive / valid dangling: using it is undefined behavior time \u2192 The borrowed text is destroyed std::string text json_document doc json_view v text destroyed every view, and the document itself The document is re-parsed json_document doc json_view v v = doc.root() doc.read(other) views taken before a fresh view is valid again The document is shrunk json_document doc json_view v v = doc.root() doc.shrink_to_fit() views taken before a fresh view is valid again The document is moved, then destroyed json_document doc moved = std::move(doc) json_view v std::move: views stay valid moved is destroyed

    Four timelines of a document and its views, each bar showing when an object is alive or valid and when it dangles. Destroying the borrowed text, re-parsing, or shrinking the document invalidates the views taken before; moving the document does not.

    A view can dangle, exactly like a std::string_view: nothing stops you from using it after its document is gone. This is deliberate. A view is two pointers and trivially copyable; making it safe (a std::shared_ptr in the document and a std::weak_ptr in each view) would make it larger, add reference counting to every copy, and a lock() to every access \u2014 exactly the costs the view exists to avoid. What is caught is the obvious case: because a view dies with its document, root() is not callable on a temporary document: auto v = json_document::parse(text).root(); does not compile. Give the document a name first.

    Example: borrowed and owned documents, and when views become invalid
    #include <iostream>\n#include <string>\n#include <utility>\n#include <nlohmann/json_view.hpp>\n\nusing nlohmann::json_document;\n\nint main()\n{\n    std::cout << std::boolalpha;\n\n    // BORROWED: doc only points into `text`; `text` must outlive `doc`\n    std::string text = R\"({\"a\": 1})\";\n    json_document doc = json_document::parse(text);\n    std::cout << doc.owns_source() << '\\n'; // false\n\n    // a view is valid as long as the document is alive, has not been\n    // re-parsed (read()) or shrunk (shrink_to_fit()), and -- if borrowed --\n    // the source text is alive\n    nlohmann::json_view v = doc.root();\n    std::cout << v.is_object() << '\\n';\n\n    // re-parsing the SAME document invalidates views taken before the call;\n    // `v` above must not be used after this line\n    doc.read(R\"([1, 2, 3])\");\n    v = doc.root(); // take a fresh view instead\n    std::cout << v.is_array() << '\\n';\n\n    // moving the document does not invalidate views: the node index is\n    // heap-allocated and does not move with the document object\n    json_document moved = std::move(doc);\n    std::cout << v.is_array() << '\\n';\n}\n

    Output:

    false\ntrue\ntrue\ntrue\n
    "},{"location":"features/json_view/#what-is-the-same-as-parse","title":"What is the same as parse()","text":"
    • Accept/reject. accept() and parse() accept and reject exactly the same inputs as basic_json::accept()/basic_json::parse(), with the same ignore_comments and ignore_trailing_commas options.
    • Errors. A failing parse throws the same exception \u2014 the same id, message, and position \u2014 because on failure the library's own parser is run on the same bytes to produce the diagnostic. Valid input never pays for this, and the replay builds no values: it costs about a lexing pass up to the error. allow_exceptions == false skips the replay and gives a discarded document instead of throwing, just as it gives a discarded value for basic_json::parse().
    • Number classification. An integer literal that does not fit into the 64-bit integer type becomes a floating-point value, exactly as it does for basic_json::parse().
    • Macros. JSON_STRICT_NUL_HANDLING and JSON_NOEXCEPTION/JSON_THROW_USER behave the same way they do for <nlohmann/json.hpp>. These are the macros that change what the parser accepts or how it reports errors. The others either do not apply (JSON_DIAGNOSTICS needs parent pointers in basic_json values) or only affect the values materialize() produces, through BasicJsonType.
    "},{"location":"features/json_view/#what-is-different","title":"What is different","text":"
    • Only 64-bit integers. basic_json_document<BasicJsonType> requires BasicJsonType::number_integer_t and number_unsigned_t to both be 64 bits wide; this is a compile-time static_assert.
    • A 4 GiB input limit. An input of 4294967280 bytes (4 GiB minus 16 bytes) or more throws out_of_range.416, a limit basic_json::parse() does not have. It keeps an index entry at 16 bytes: offsets and counts are 32 bits wide. The limit is 16 bytes below 2^32, because the parser reads in 16-byte steps, and a position one step past the end must still fit.
    • A stream is always read to its end. There is no partial/streaming read of an std::istream: the stream is read to its end into a buffer the document owns, and parsing starts after that.
    • Fewer source positions after edits. With JSON_DIAGNOSTIC_POSITIONS enabled, materialize() sets the same positions as basic_json::parse(). In an editable document, a value written by an edit has none, and neither has an array or object whose elements changed or whose last element has none; a basic_json value keeps its positions when it is changed. See materialize().
    • Objects iterate in document order. begin()/ end() and items() visit an object's members in the order they appear in the source text. basic_json's default object_t is a std::map, which sorts by key, so iterating a materialize()d value can print members in a different order than iterating the view they came from.
    • Chained access is safe. operator[] with a missing key, an index out of range, or an unresolvable JSON pointer returns a discarded view, and operator[] on a discarded view returns a discarded view without throwing: v[\"a\"][\"b\"][0] can be tested once at the end. Type errors on values that exist (a key on an array, an index on an object) still throw, and at throws for every missing value.
    • Duplicate keys: lookups find the first member, parse() keeps the last. See Duplicate keys below.
    • No JSON_DIAGNOSTICS path. Exceptions thrown by basic_json_view's own element access and lookup functions never carry the JSON Pointer path JSON_DIAGNOSTICS would otherwise add: the view has no basic_json value to point at, so the exception is created without one, regardless of how BasicJsonType was built.
    • Ordering comparisons are not provided by basic_json_view \u2014 there is no operator<. operator== and operator!= are provided, though: two views, or a view and a BasicJsonType value, compare equal exactly when materialize() or parse() would produce equal values for them, without ever building a tree to do it. For ordering, too, materialize() is the way to get a value you can compare.
    "},{"location":"features/json_view/#duplicate-keys","title":"Duplicate keys","text":"

    A lookup in a view and in the parsed value can give different answers

    If an object in the source text repeats a key, operator[], at, find, value, contains, and JSON pointer resolution all return the first member with that key. basic_json::parse() instead keeps the last value of a repeated key, so for {\"a\":1,\"a\":2}, view[\"a\"] is 1 while parse(text)[\"a\"] is 2. count counts every member with the key, so it is 2 here.

    begin()/end() and items() visit every occurrence, in document order, and size() counts all of them, so view.size() can be larger than view.materialize().size().

    Why the first? A lookup can stop as soon as it finds a match. Returning the last member would force every lookup to scan all members of the object, even when the key is found at the very first one: this made lookups in small objects 1.6 to 3.4 times slower. The hash index of the keys of objects with 128 members or more leads to the first member of a key as well. Other zero-copy parsers that index the source text, such as yyjson and simdjson, also return the first member. RFC 8259 only says that names within an object SHOULD be unique and that the behavior of a receiver that sees duplicates is unpredictable, so neither choice is wrong.

    The same holds for get<T>() of a type whose from_json() reads the view, such as the types of the NLOHMANN_DEFINE_TYPE_* macros: their members are looked up, so get<point>() of {\"x\":1,\"x\":2} reads x == 1, while materialize().get<point>() reads 2.

    What stays the same as parse()? materialize() and get<std::map<...>>() replay every member in order, so they keep the last value exactly like basic_json::parse() (at the position of the first occurrence of the key, for an ordered_json).

    How do I get the value parse() would give? Either call view.materialize() and look the key up in the result, or iterate the members and keep the last match:

    // the last member with the key \"a\", as parse() would keep it\njson_view last;\nfor (const auto item : view.items())\n{\n    if (item.key() == \"a\")\n    {\n        last = item.value();\n    }\n}\n

    If you cannot trust the source text to have unique keys, check size() against the number of distinct keys, or reject duplicates when iterating.

    "},{"location":"features/json_view/#getting-values-out-without-copying","title":"Getting values out without copying","text":"

    get<T>() converts most T directly from the flat index, without ever building a basic_json value for the conversion: bool, arithmetic types, std::nullptr_t, std::string/other std::basic_strings (copied once), basic_json_view itself, the standard containers and other types the library converts (std::vector, std::map, std::list, std::array, std::pair, std::tuple, std::optional, ...), and the types of the NLOHMANN_DEFINE_TYPE_* and NLOHMANN_JSON_SERIALIZE_ENUM macros. Types whose from_json() is written for basic_json only go through materialize().get<T>() instead: the subtree is built into a real basic_json value first, exactly as parse() would, and converted from there. See Writing generic code for how to write a from_json() that reads views.

    Two conversions never copy at all:

    • get_string() (equivalently, get<string_view_t>()) returns a string as a string_view_t pointing into the document's source() text \u2014 or, for a string that contains escape sequences, into the document's own buffer of decoded strings \u2014 instead of allocating a new std::string.
    • number_token() returns a number exactly as it was written in the source, e.g. \"1.50\", \"1E2\", or an integer with more digits than any number type holds, instead of rounding it into a double/int64_t the way get<T>() (and basic_json::parse()) would.

    Both results are only valid as long as the view \u2014 and, for a string with no escapes, the borrowed source text \u2014 is.

    "},{"location":"features/json_view/#writing-generic-code","title":"Writing generic code","text":"

    A view's type names its BasicJsonType and its view_mode: json_view is basic_json_view<json, view_mode::read_only>, and json_editable_view is basic_json_view<json, view_mode::editable>. These are different types. The only conversion between them turns a view of a read-only document into a view of an editable document of the same BasicJsonType, so a function written for one shortcut accepts few other views:

    void print_names(json_view v);           // accepts neither an ordered_json_view nor a json_editable_view\nvoid print_names(json_editable_view v);  // also accepts a json_view, but no ordered_json_view\n

    This is the same pitfall as a to_json/from_json written for json instead of any BasicJsonType, which then does not work for ordered_json. The shortcuts are for declaring documents and views; a function that takes a view names the views it accepts with a template:

    // views of editable documents only\ntemplate<typename BasicJsonType>\nvoid f(basic_json_view<BasicJsonType, view_mode::editable> v);\n\n// views of read-only documents only\ntemplate<typename BasicJsonType>\nvoid f(basic_json_view<BasicJsonType, view_mode::read_only> v);\n\n// views of either document type\ntemplate<typename BasicJsonType, view_mode Mode>\nvoid f(basic_json_view<BasicJsonType, Mode> v);\n

    Views are passed by value: they are two pointers, cheap to copy, like a std::string_view. A const& works as well, but a non-const reference does not bind to the views that root(), operator[], and at() return, so f(doc.root()) would not compile.

    There is no conversion from an editable view to a read-only one, by design: the mode decides how a view walks the index. A read-only view reads a container in place, while a view of an editable document follows the links that edits leave behind, so a read-only view of an edited document would read stale values. The other direction is safe: a read-only document has no edits, so a view of it converts to an editable view, which reads it like an editable document before its first edit. A template deduces the mode without conversions, so the template forms above still accept only the modes they name. Views of both modes compare with operator==.

    is_json_view<T> tells views from other types, for constraints that cannot be written as a basic_json_view<...> parameter.

    "},{"location":"features/json_view/#a-from_json-that-reads-views","title":"A from_json() that reads views","text":"

    get<T>() on a view calls T's from_json() with the view itself if that from_json() accepts views, and with materialize() otherwise. The from_json() functions of the NLOHMANN_DEFINE_TYPE_*, NLOHMANN_DEFINE_DERIVED_TYPE_*, and NLOHMANN_JSON_SERIALIZE_ENUM macros, and those of the library for the standard types, accept views, so these types need nothing else. For decoding the statuses of twitter.json into structs, reading the view is about 5 times faster than materialize().get<T>().

    A hand-written from_json() reads views if it is constrained to json values and views:

    template < typename J, typename std::enable_if <\n               nlohmann::is_json_view<J>::value || std::is_same<J, nlohmann::json>::value, int >::type = 0 >\nvoid from_json(const J& j, person& p)\n{\n    p.name = j.at(\"name\").template get<std::string>();\n    p.age = j.at(\"age\").template get<int>();\n}\n

    Its body may only use what views and basic_json have in common: the type checks, at(), operator[], contains(), value(), size(), iteration and items(), and get<T>()/get_to(). An unconstrained template<typename BasicJsonType> void from_json(const BasicJsonType& j, person& p), as in arbitrary type conversions, is never called with a view, as it might use basic_json functions a view does not have; such a type is converted through materialize(). A from_json() for json only is converted through materialize() as well.

    Two things differ when a from_json() reads the view:

    • Duplicate keys. Members looked up by name (at(), value(), ... and thus the macros) find the first member with a repeated key, see Duplicate keys; materialize().get<T>() would see the last one. Containers built from an object, such as std::map, keep the last value either way, as parse() does.
    • JSON_DIAGNOSTICS. Exceptions thrown by the view carry no path to the value.

    to_json() is unaffected: it writes basic_json values, never views.

    "},{"location":"features/json_view/#writing-a-view-back","title":"Writing a view back","text":"

    dump() serializes a view directly from the flat index, without ever building a basic_json value. An object's members are written in document order, not sorted by key, and every occurrence of a repeated key is written, not only the last one \u2014 the same two ways iteration already differs from a materialize()d value, see Duplicate keys. materialize().dump() gives a different result in both respects for a json_view.

    By default, numbers are written the way basic_json::dump() would. number_format::source instead copies every number exactly as it was written in the source text \u2014 a price like 19.90, a long order or account ID with more digits than any number type holds, or a high-precision coordinate \u2014 something basic_json cannot do at all, since parsing already reduces a number to its parsed double/int64_t value.

    operator<< writes a view to a stream the way basic_json's does, using the stream's width/fill for indentation.

    "},{"location":"features/json_view/#editing-a-document","title":"Editing a document","text":"

    Everything above is read-only: a json_document/json_view lets you look at a parsed text without copying it, but not change it. basic_json_document<BasicJsonType, view_mode::editable> \u2014 more conveniently spelled json_editable_document or ordered_json_editable_document \u2014 also lets you set a value, push_back onto or insert into an array, and erase an object member or an array element, still without ever building a basic_json tree for parts you do not touch.

    The mode defaults to view_mode::read_only, so json_document/ordered_json_document are unaffected \u2014 they carry none of the bookkeeping edits need, and calling set/push_back/insert/erase on one is a compile error, not a runtime one.

    "},{"location":"features/json_view/#why-editing-without-reformatting","title":"Why: editing without reformatting","text":"

    The 19.90 price from above is exactly the kind of value that makes editing a json or ordered_json value in place lossy. Say you parse a configuration file, patch one field, and write it back:

    • json re-sorts every key on the way in (object_t is a std::map) and rewrites every number to its shortest round-trip form on the way out \u2014 a one-field patch turns into a diff that reorders the whole file and rewrites 19.90 to 19.9.
    • ordered_json keeps the key order, but still rewrites every number the same way: parsing has already reduced it to a double/int64_t, and there is no way back to how it was spelled in the source text.

    The patch of the example below (set \"host\", add \"retries\") written back by each of them:

    json

    keys sorted, numbers rewritten

    {\"host\":\"db2\",\n \"name\":\"cache\",\n \"port\":6379,\n \"price\":19.9,\n \"retries\":3}

    ordered_json

    key order kept, numbers rewritten

    {\"name\":\"cache\",\n \"host\":\"db2\",\n \"port\":6379,\n \"price\":19.9,\n \"retries\":3}

    json_editable_document

    order and spelling kept

    {\"name\":\"cache\",\n \"host\":\"db2\",\n \"port\":6379,\n \"price\":19.90,\n \"retries\":3}

    An editable document keeps both. dump() of an edited document writes members in document order \u2014 a member set added goes at the end, exactly where it was inserted, and an erased member simply leaves a gap: everything around it keeps its place \u2014 and number_format::source keeps the exact spelling of every number an edit did not itself touch; a number an edit did touch is written the way BasicJsonType::dump() would write it, since there is no source spelling for a brand new value.

    Example: patch a configuration, keeping member order and number spellings
    #include <iostream>\n#include <nlohmann/json_view.hpp>\n\nusing nlohmann::json;\nusing nlohmann::json_editable_document;\nusing nlohmann::json_editable_view;\n\nint main()\n{\n    // a configuration file, as it might be read from disk\n    const std::string text = R\"({\"name\": \"cache\", \"host\": \"db1\", \"port\": 6379, \"price\": 19.90})\";\n    std::cout << text << \"\\n\\n\";\n\n    // patch two fields -- \"price\" is never touched\n    json_editable_document doc = json_editable_document::parse(text);\n    doc.set(doc.root(), \"host\", \"db2\");\n    doc.set(doc.root(), \"retries\", 3);\n\n    // member order (the new member at the end) and the untouched number's\n    // exact spelling survive\n    std::cout << doc.root().dump(-1, ' ', false, json_editable_view::number_format::source) << '\\n';\n\n    // the same patch on a plain json value: keys are sorted (object_t is a\n    // std::map), and \"price\" is rewritten even though the patch never\n    // touched it\n    json plain = json::parse(text);\n    plain[\"host\"] = \"db2\";\n    plain[\"retries\"] = 3;\n    std::cout << plain.dump() << '\\n';\n}\n

    Output:

    {\"name\": \"cache\", \"host\": \"db1\", \"port\": 6379, \"price\": 19.90}\n\n{\"name\":\"cache\",\"host\":\"db2\",\"port\":6379,\"price\":19.90,\"retries\":3}\n{\"host\":\"db2\",\"name\":\"cache\",\"port\":6379,\"price\":19.9,\"retries\":3}\n
    "},{"location":"features/json_view/#what-stays-valid-and-what-an-edit-costs","title":"What stays valid, and what an edit costs","text":"

    The source text itself is never written, and the parsed index never moves \u2014 a value keeps the node it was parsed into for as long as it is not itself replaced. So every view taken before an edit, including a previously obtained root(), stays valid and, if it still refers to the edited value, sees the edit; a view of a value a later edit drops or replaces just keeps showing what it last held. New values go to storage the document allocates and owns on demand. The one thing an edit does invalidate is the iterators taken over an edited array or object: the first time an element is added to it, inserted into it, erased from it, or replaced by a value that spans a different number of nodes, its elements move from the parsed, fixed layout to a growable block of links so that push_back can later grow it in amortized constant time \u2014 existing elements are not touched, but an iterator that was walking the old layout no longer matches. A string obtained with get_string() is unaffected either way and stays valid across further edits. See basic_json_document's Edits for the details, and set's Exception safety for what an edit guarantees if it throws (the basic guarantee, not the strong one dump() and the read-only functions provide). How edits are kept in the index is described in the architecture overview.

    Step through the edits of a small document (the node fields follow the architecture overview):

    Step 1 of 5: parsed After parse: nine nodes, nothing owned yet. The dump with number_format::source is {\"port\":6379,\"price\":19.90,\"tags\":[\"eu\",\"a\\\"b\"]}. parsed index: fixed, never moves the source text is never written 0 object { } 3 1 key port 2 uint 6379 3 key price 4 float 19.90 5 key tags 6 array [ ] 2 7 string \"eu\" 8 string a\"b owned storage: allocated on demand, never moves empty: a read-only json_document has none of this view v = root()[\"tags\"] (taken after parse): valid, sees every edit iterator over tags (taken after parse): valid dump(): {\"port\":6379,\"price\":19.90,\"tags\":[\"eu\",\"a\\\"b\"]} Step 1 of 5. After parsing: nine nodes in the parsed index, no owned storage yet. Step 2 of 5: doc.set(doc.root(), \"port\", 6380) set: the node of the integer is overwritten in place. The dump with number_format::source is {\"port\":6380,\"price\":19.90,\"tags\":[\"eu\",\"a\\\"b\"]}. parsed index: fixed, never moves the source text is never written 0 object { } 3 1 key port 2 uint 6380 3 key price 4 float 19.90 5 key tags 6 array [ ] 2 7 string \"eu\" 8 string a\"b owned storage: allocated on demand, never moves empty: a read-only json_document has none of this view v = root()[\"tags\"] (taken after parse): valid, sees every edit iterator over tags (taken after parse): valid dump(): {\"port\":6380,\"price\":19.90,\"tags\":[\"eu\",\"a\\\"b\"]} Step 2 of 5. doc.set(doc.root(), \"port\", 6380) overwrites the node of the integer in place; no member is added or removed, so the object keeps its parsed layout. Step 3 of 5: doc.erase(doc.root()[\"tags\"], 0) erase: the array moves to a block of links in owned storage. The dump with number_format::source is {\"port\":6380,\"price\":19.90,\"tags\":[\"a\\\"b\"]}. parsed index: fixed, never moves the source text is never written 0 object { } 3 1 key port 2 uint 6380 3 key price 4 float 19.90 5 key tags 6 array moved [ ] 2 7 string \"eu\" unreferenced 8 string a\"b owned storage: allocated on demand, never moves 0' header [ ] 1 1' link \u2192 8 free view v = root()[\"tags\"] (taken after parse): valid, sees every edit iterator over tags (taken after parse): invalid: tags no longer uses the parsed layout dump(): {\"port\":6380,\"price\":19.90,\"tags\":[\"a\\\"b\"]} Step 3 of 5. doc.erase(doc.root()[\"tags\"], 0): the array is edited for the first time, so its elements move to a block of links in owned storage. The node of \"eu\" stays in the index, but nothing refers to it any more; iterators over the array taken before are invalid. Step 4 of 5: doc.push_back(doc.root()[\"tags\"], \"new\") push_back: a new node, and a link appended to the block. The dump with number_format::source is {\"port\":6380,\"price\":19.90,\"tags\":[\"a\\\"b\",\"new\"]}. parsed index: fixed, never moves the source text is never written 0 object { } 3 1 key port 2 uint 6380 3 key price 4 float 19.90 5 key tags 6 array moved [ ] 2 7 string \"eu\" unreferenced 8 string a\"b owned storage: allocated on demand, never moves 0' header [ ] 2 1' link \u2192 8 2' link \u2192 3' 3' string \"new\" edited text new view v = root()[\"tags\"] (taken after parse): valid, sees every edit iterator over tags (taken after parse): invalid: tags no longer uses the parsed layout dump(): {\"port\":6380,\"price\":19.90,\"tags\":[\"a\\\"b\",\"new\"]} Step 4 of 5. doc.push_back(doc.root()[\"tags\"], \"new\"): the new string gets its own node, its text goes to the buffer of edited text, and a link to it is appended to the block of the array. Step 5 of 5: doc.set(doc.root(), \"retries\", 3) set of a new member: the object moves to a block as well. The dump with number_format::source is {\"port\":6380,\"price\":19.90,\"tags\":[\"a\\\"b\",\"new\"],\"retries\":3}. parsed index: fixed, never moves the source text is never written 0 object moved { } 3 1 key port 2 uint 6380 3 key price 4 float 19.90 5 key tags 6 array moved [ ] 2 7 string \"eu\" unreferenced 8 string a\"b owned storage: allocated on demand, never moves 0' header [ ] 2 1' link \u2192 8 2' link \u2192 3' 3' string \"new\" 4' uint 3 5' header { } 4 6' key port 7' link \u2192 2 8' key price 9' link \u2192 4 10' key tags 11' link \u2192 6 12' key retries 13' link \u2192 4' edited text newretries view v = root()[\"tags\"] (taken after parse): valid, sees every edit iterator over tags (taken after parse): invalid: tags no longer uses the parsed layout dump(): {\"port\":6380,\"price\":19.90,\"tags\":[\"a\\\"b\",\"new\"],\"retries\":3} Step 5 of 5. doc.set(doc.root(), \"retries\", 3): a new member, so the object moves to a block too: copies of its keys, links to the values it already had, then the new key and a link to the new integer.

    The node index and the owned storage of the document after each of five edits. Use Back, Next, or the numbered buttons to switch between the steps; without JavaScript all steps are shown one below the other.

    "},{"location":"features/json_view/#images","title":"Images","text":"

    save() writes a document as an image: a byte buffer that load() reads back into a document without parsing \u2014 no lexing, no building the node index, nothing but copying the nodes and pointing the text and the decoded strings at the image. Where parse_copy() still has to scan the whole input, load() turns that scan into a copy of the node index alone.

    Why. A document that is parsed once and then read many times \u2014 a configuration loaded at startup, a template rendered on every request, a large reference dataset a worker process needs in memory \u2014 pays for parsing once but can amortize save()'s cost across every later load. That makes images useful for a cache: save a document the first time it is parsed (to a file, a shared-memory segment, an in-process cache), and load() it on every later use instead of parsing the source text again. They are just as useful for handing a parsed document to another process (or a forked worker) running the same build of the library, since load() turns the transfer into a copy of the node index plus pointers into the received bytes, not a re-parse.

    Choosing a check. load() takes an image_check that trades validation against speed: image_check::full (the default) checks everything the parser itself guarantees, so a checked image is exactly as safe to read and serialize as a freshly parsed document \u2014 the right choice whenever the image did not come straight from this process's own save(), such as a file or a network peer. image_check::bounds only checks structure and bounds \u2014 cheaper, since it skips scanning the text and the decoded strings \u2014 and fits a cache the process trusts, one it wrote and reads back itself. image_check::none skips validation entirely, for an image trusted as much as the process's own memory. See load()'s Notes for exactly what each level does and does not guarantee.

    Example: cache a parsed configuration as an image
    #include <cstdint>\n#include <iostream>\n#include <string>\n#include <vector>\n#include <nlohmann/json_view.hpp>\n\nusing nlohmann::json_document;\n\nint main()\n{\n    std::cout << std::boolalpha;\n\n    // a configuration a service parses once and then caches as an image, so\n    // that later requests can load() it instead of parsing the text again\n    const std::string text = R\"({\"name\": \"cache\", \"host\": \"db1\", \"port\": 6379, \"replicas\": [\"db2\", \"db3\"]})\";\n    const json_document config = json_document::parse(text);\n\n    // save() turns the parsed document into a byte buffer: a 64-byte header,\n    // the node index, the source text, and the decoded strings\n    const std::vector<std::uint8_t> image = config.save();\n    std::cout << image.size() << '\\n';\n\n    // the same document always saves to the same bytes\n    std::cout << (image == json_document::parse(text).save()) << '\\n';\n\n    // loading the image back needs no parsing, yet dumps exactly what\n    // parsing the text produced\n    const json_document reloaded = json_document::load(image);\n    std::cout << (reloaded.root().dump() == config.root().dump()) << '\\n';\n}\n

    Output:

    316\ntrue\ntrue\n

    Experimental

    The image format is versioned but not yet stable, and may change in an incompatible way before it is declared stable. It is little-endian only (on big-endian targets, save() and load() do not exist), and tied to the library build that wrote it \u2014 use it to cache a document or to hand one to another process running the same build, not as a long-term storage format; keep the original JSON text if a saved document needs to be readable by a future library version.

    The idea of a document you can read without parsing comes from zero-copy formats such as FlatBuffers and YaFF; the check load() runs follows the idea of FlatBuffers' Verifier. No code is taken from either.

    "},{"location":"features/json_view/#choosing-between-json-ordered_json-the-sax-interface-and-json_view","title":"Choosing between json, ordered_json, the SAX interface, and json_view","text":"json / ordered_json SAX interface json_document / json_view json_editable_document / json_editable_view Ownership owns every value owns nothing; you decide what to keep, in your handler borrows or owns the text; the index is always owned by the document same as json_document; edits go to storage the document owns Mutability freely mutable not applicable (a one-shot event stream) read-only set/push_back/insert/erase edit in place; the source text is never rewritten What you get a full tree you can read, write, and keep as long as you like a sequence of callbacks; whatever your handler builds from them a flat index plus, on demand, materialize()d json/ordered_json values for the parts you actually use the same, plus dump() of an edited document that keeps the member order and, with number_format::source, the spelling of every untouched number Typical use general-purpose JSON handling: config, request/response bodies you build or modify, anything you hold onto validating or projecting a text into your own data structure without ever holding the whole thing as JSON large or high-volume input where you only need part of it, or need it repeatedly, and can keep the source text (or a copy) alive for as long as the document lives a document you read, patch a few fields of, and write back \u2014 a configuration file, for instance \u2014 where the rest of it should come back exactly as it was Caching/reload not applicable \u2014 re-parse, or roll your own serialization not applicable save()/load(): cache the parsed index as an image and reload it without parsing same, saving the document's current \u2014 possibly edited \u2014 state

    Each column is one way to work with JSON in this library, and each row compares one property of them.

    "},{"location":"features/json_view/#see-also","title":"See also","text":"
    • basic_json_document - the document that owns the parsed index (parse, access, images, edits)
    • basic_json_view - the non-owning handle to a value in a document
    • json_document - and ordered_json_document - the read-only documents
    • json_editable_document - and ordered_json_editable_document - the documents that can be edited in place
    • Architecture - the layout of the node index
    • SAX interface - event-based parsing without building a tree
    • Performance - benchmarks and tuning of parsing and serialization
    • Large, Streamed, and Partial Input - reading only the part of a text you need
    "},{"location":"features/json_view/#version-history","title":"Version history","text":"
    • Added in version 3.13.0 unreleased.
    "},{"location":"features/macros/","title":"Supported Macros","text":"

    Some aspects of the library can be configured by defining preprocessor macros before including the json.hpp header. See also the API documentation for macros for examples and more information.

    "},{"location":"features/macros/#json_assertx","title":"JSON_ASSERT(x)","text":"

    This macro controls which code is executed for runtime assertions of the library.

    See full documentation of JSON_ASSERT(x).

    "},{"location":"features/macros/#json_brace_init_copy_semantics","title":"JSON_BRACE_INIT_COPY_SEMANTICS","text":"

    When defined to 1, single-element brace initialization of a basic_json value (e.g., json j{value};) is treated as a copy/move of the element rather than wrapping it in a single-element array. The default value is 0, which preserves the existing behavior.

    See full documentation of JSON_BRACE_INIT_COPY_SEMANTICS.

    "},{"location":"features/macros/#json_catch_userexception","title":"JSON_CATCH_USER(exception)","text":"

    This macro overrides catch calls inside the library.

    See full documentation of JSON_CATCH_USER(exception).

    "},{"location":"features/macros/#json_delete_deprecated_functions","title":"JSON_DELETE_DEPRECATED_FUNCTIONS","text":"

    When defined to 1, all deprecated functions are declared as deleted instead of only being marked as deprecated, so code that still calls them no longer compiles. This way, you can find all calls that need to be replaced before version 4.0.0 removes these functions.

    The macro can also be set with the CMake option JSON_DeleteDeprecatedFunctions (OFF by default).

    See full documentation of JSON_DELETE_DEPRECATED_FUNCTIONS.

    "},{"location":"features/macros/#json_diagnostics","title":"JSON_DIAGNOSTICS","text":"

    This macro enables extended diagnostics for exception messages. Possible values are 1 to enable or 0 to disable (default).

    When enabled, exception messages contain a JSON Pointer to the JSON value that triggered the exception, see Extended diagnostic messages for an example. Note that enabling this macro increases the size of every JSON value by one pointer and adds some runtime overhead.

    The diagnostics messages can also be controlled with the CMake option JSON_Diagnostics (OFF by default) which sets JSON_DIAGNOSTICS accordingly.

    See full documentation of JSON_DIAGNOSTICS.

    "},{"location":"features/macros/#json_diagnostic_positions","title":"JSON_DIAGNOSTIC_POSITIONS","text":"

    When enabled, two new member functions start_pos() and end_pos() are added to basic_json values. If the value was created by calling theparse function, then these functions allow querying the byte positions of the value in the input it was parsed from. The byte positions are also used in exceptions to help locate errors.

    The diagnostics positions can also be controlled with the CMake option JSON_Diagnostic_Positions (OFF by default) which sets JSON_DIAGNOSTIC_POSITIONS accordingly.

    See full documentation of JSON_DIAGNOSTIC_POSITIONS

    "},{"location":"features/macros/#json_has_cpp_11-json_has_cpp_14-json_has_cpp_17-json_has_cpp_20-json_has_cpp_23-json_has_cpp_26","title":"JSON_HAS_CPP_11, JSON_HAS_CPP_14, JSON_HAS_CPP_17, JSON_HAS_CPP_20, JSON_HAS_CPP_23, JSON_HAS_CPP_26","text":"

    The library targets C++11, but also supports some features introduced in later C++ versions (e.g., std::string_view support for C++17). For these new features, the library implements some preprocessor checks to determine the C++ standard. By defining any of these symbols, the internal check is overridden and the provided C++ version is unconditionally assumed. This can be helpful for compilers that only implement parts of the standard and would be detected incorrectly.

    See full documentation of JSON_HAS_CPP_11, JSON_HAS_CPP_14, JSON_HAS_CPP_17, JSON_HAS_CPP_20, JSON_HAS_CPP_23, and JSON_HAS_CPP_26.

    "},{"location":"features/macros/#json_has_filesystem-json_has_experimental_filesystem","title":"JSON_HAS_FILESYSTEM, JSON_HAS_EXPERIMENTAL_FILESYSTEM","text":"

    When compiling with C++17, the library provides conversions from and to std::filesystem::path. As compiler support for filesystem is limited, the library tries to detect whether <filesystem>/std::filesystem (JSON_HAS_FILESYSTEM) or <experimental/filesystem>/std::experimental::filesystem (JSON_HAS_EXPERIMENTAL_FILESYSTEM) should be used. To override the built-in check, define JSON_HAS_FILESYSTEM or JSON_HAS_EXPERIMENTAL_FILESYSTEM to 1.

    See full documentation of JSON_HAS_FILESYSTEM and JSON_HAS_EXPERIMENTAL_FILESYSTEM.

    "},{"location":"features/macros/#json_has_ranges","title":"JSON_HAS_RANGES","text":"

    The library uses std::ranges (and concepts) where available, for example, to parse from C++20 ranges and to construct JSON arrays from range views. The library detects whether the standard library supports ranges and disables the support on toolchains with an incomplete implementation. To override the built-in check, define JSON_HAS_RANGES to 1 or 0.

    See full documentation of JSON_HAS_RANGES.

    "},{"location":"features/macros/#json_has_range_view_conversion","title":"JSON_HAS_RANGE_VIEW_CONVERSION","text":"

    When JSON_HAS_RANGES is enabled (and the compiler is not MinGW), a JSON array can be constructed directly from a C++20 range view such as std::views::filter(...). To override the built-in check, define JSON_HAS_RANGE_VIEW_CONVERSION to 1 or 0.

    See full documentation of JSON_HAS_RANGE_VIEW_CONVERSION.

    "},{"location":"features/macros/#json_has_static_rtti","title":"JSON_HAS_STATIC_RTTI","text":"

    The library detects whether the compiler supports run time type information (RTTI), which it needs, for instance, to exclude std::any from the candidate types of the implicit conversion on C++17. To override the built-in check, define JSON_HAS_STATIC_RTTI to 1 or 0.

    See full documentation of JSON_HAS_STATIC_RTTI.

    "},{"location":"features/macros/#json_has_std_format","title":"JSON_HAS_STD_FORMAT","text":"

    When compiling with C++20 and a standard library that provides <format>, the library provides a std::formatter specialization for JSON values. To override the built-in check, define JSON_HAS_STD_FORMAT to 1 or 0.

    See full documentation of JSON_HAS_STD_FORMAT.

    "},{"location":"features/macros/#json_has_three_way_comparison","title":"JSON_HAS_THREE_WAY_COMPARISON","text":"

    When the compiler and standard library support 3-way comparison (the spaceship operator <=>), the library provides it for JSON values. To override the built-in check, define JSON_HAS_THREE_WAY_COMPARISON to 1 or 0.

    See full documentation of JSON_HAS_THREE_WAY_COMPARISON.

    "},{"location":"features/macros/#json_noexception","title":"JSON_NOEXCEPTION","text":"

    Exceptions can be switched off by defining the symbol JSON_NOEXCEPTION.

    See full documentation of JSON_NOEXCEPTION.

    "},{"location":"features/macros/#json_disable_enum_serialization","title":"JSON_DISABLE_ENUM_SERIALIZATION","text":"

    When defined, default parse and serialize functions for enums are excluded and have to be provided by the user, for example, using NLOHMANN_JSON_SERIALIZE_ENUM.

    See full documentation of JSON_DISABLE_ENUM_SERIALIZATION.

    "},{"location":"features/macros/#json_disable_stream_bulk_scan","title":"JSON_DISABLE_STREAM_BULK_SCAN","text":"

    When defined to 1, parsing from a std::istream reads one character at a time instead of scanning the characters that the stream buffer holds in bulk. Results are the same either way; the macro is an escape hatch for stream buffers that do not follow the usual std::streambuf contract. The default value is 0.

    See full documentation of JSON_DISABLE_STREAM_BULK_SCAN.

    "},{"location":"features/macros/#json_disable_tuple_reference_conversion","title":"JSON_DISABLE_TUPLE_REFERENCE_CONVERSION","text":"

    When defined to 1, a JSON value can no longer be created from a one-element std::tuple holding a reference to a JSON value, such as the result of std::forward_as_tuple(j). This lets std::tuple convert such tuples element-wise. This is planned to become the default in version 4.0.0.

    See full documentation of JSON_DISABLE_TUPLE_REFERENCE_CONVERSION.

    "},{"location":"features/macros/#json_disable_unlocked_file_io","title":"JSON_DISABLE_UNLOCKED_FILE_IO","text":"

    When defined to 1, parsing from a FILE* reads every character with std::fgetc, which locks the file each time, instead of locking the file once and reading it with the unlocked stdio functions. Results are the same either way. The default value is 0.

    See full documentation of JSON_DISABLE_UNLOCKED_FILE_IO.

    "},{"location":"features/macros/#json_no_automatic_udls","title":"JSON_NO_AUTOMATIC_UDLS","text":"

    When defined, <nlohmann/json.hpp> does not include <nlohmann/json_literals.hpp> with the user-defined string literals operator\"\"_json and operator\"\"_json_pointer. This reduces the compile time of translation units that do not use them, because the literals instantiate the parser in every translation unit that includes them. Include <nlohmann/json_literals.hpp> where the literals are needed.

    See full documentation of JSON_NO_AUTOMATIC_UDLS.

    "},{"location":"features/macros/#json_no_io","title":"JSON_NO_IO","text":"

    When defined, headers <cstdio>, <ios>, <iosfwd>, <istream>, and <ostream> are not included and parse functions relying on these headers are excluded. This is relevant for environment where these I/O functions are disallowed for security reasons (e.g., Intel Software Guard Extensions (SGX)).

    See full documentation of JSON_NO_IO.

    "},{"location":"features/macros/#json_no_simd","title":"JSON_NO_SIMD","text":"

    When defined, the library uses only portable code instead of vector instructions (SSE2, SSSE3, NEON) for scanning strings and writing floating-point numbers. Results are the same either way. It is not defined by default.

    See full documentation of JSON_NO_SIMD.

    "},{"location":"features/macros/#json_no_thread_local","title":"JSON_NO_THREAD_LOCAL","text":"

    When defined, the library does not use thread_local storage. Copying a value and comparing two values then always avoid the call stack rather than descending into a bounded number of levels first, which is slower but yields the same values and the same comparisons.

    See full documentation of JSON_NO_THREAD_LOCAL.

    "},{"location":"features/macros/#json_precise_stream_position","title":"JSON_PRECISE_STREAM_POSITION","text":"

    When defined to 1, operator>> and non-strict sax_parse leave an input stream positioned right after the parsed value, instead of also consuming the character that terminates a number. The default value is 0, which preserves the existing behavior; this is planned to become the default in version 4.0.0.

    See full documentation of JSON_PRECISE_STREAM_POSITION.

    "},{"location":"features/macros/#json_skip_library_version_check","title":"JSON_SKIP_LIBRARY_VERSION_CHECK","text":"

    When defined, the library will not create a compiler warning when a different version of the library was already included.

    See full documentation of JSON_SKIP_LIBRARY_VERSION_CHECK.

    "},{"location":"features/macros/#json_skip_unsupported_compiler_check","title":"JSON_SKIP_UNSUPPORTED_COMPILER_CHECK","text":"

    When defined, the library will not create a compile error when a known unsupported compiler is detected. This allows using the library with compilers that do not fully support C++11 and may only work if unsupported features are not used.

    See full documentation of JSON_SKIP_UNSUPPORTED_COMPILER_CHECK.

    "},{"location":"features/macros/#json_strict_binary_utf8","title":"JSON_STRICT_BINARY_UTF8","text":"

    When defined to 1, to_cbor, to_ubjson, to_bjdata, and to_bson throw type_error.316 for a string value or object key that is not valid UTF-8. The default value is 0, which writes the bytes unchanged as before version 3.13.0 unreleased; this is planned to become the default in version 4.0.0.

    The check can also be enabled with the CMake option JSON_StrictBinaryUTF8 (OFF by default) which sets JSON_STRICT_BINARY_UTF8 accordingly.

    See full documentation of JSON_STRICT_BINARY_UTF8.

    "},{"location":"features/macros/#json_strict_nul_handling","title":"JSON_STRICT_NUL_HANDLING","text":"

    When defined to 1, a '\\0' (NUL) byte anywhere in the input is rejected with parse_error.101, like any other unexpected byte, instead of being silently treated as end of input (see the FAQ entry for background). The default value is 0, which preserves the existing behavior; this is planned to become the default in version 4.0.0.

    The strict handling can also be enabled with the CMake option JSON_StrictNulHandling (OFF by default) which sets JSON_STRICT_NUL_HANDLING accordingly.

    See full documentation of JSON_STRICT_NUL_HANDLING.

    "},{"location":"features/macros/#json_throw_userexception","title":"JSON_THROW_USER(exception)","text":"

    This macro overrides throw calls inside the library. The argument is the exception to be thrown.

    See full documentation of JSON_THROW_USER(exception).

    "},{"location":"features/macros/#json_try_user","title":"JSON_TRY_USER","text":"

    This macro overrides try calls inside the library.

    See full documentation of JSON_TRY_USER.

    "},{"location":"features/macros/#json_use_implicit_conversions","title":"JSON_USE_IMPLICIT_CONVERSIONS","text":"

    When defined to 0, implicit conversions are switched off. By default, implicit conversions are switched on.

    See full documentation of JSON_USE_IMPLICIT_CONVERSIONS.

    "},{"location":"features/macros/#json_use_global_udls","title":"JSON_USE_GLOBAL_UDLS","text":"

    When defined to 1 (default), the user-defined string literals operator\"\"_json and operator\"\"_json_pointer are placed into the global namespace instead of nlohmann::literals::json_literals.

    See full documentation of JSON_USE_GLOBAL_UDLS.

    "},{"location":"features/macros/#json_use_legacy_discarded_value_comparison","title":"JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON","text":"

    When defined to 1, the library restores the legacy behavior in which comparing a discarded value with <= or >= yields true instead of false. This behavior is deprecated and switched off (0) by default.

    See full documentation of JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON.

    "},{"location":"features/macros/#json_use_objects_for_enum_keyed_maps","title":"JSON_USE_OBJECTS_FOR_ENUM_KEYED_MAPS","text":"

    When defined to 1, maps with enum keys (e.g., std::map<E, T>) are stored as objects, using the enum's conversion for the keys, instead of arrays of [key, value] pairs. It is switched off (0) by default.

    See full documentation of JSON_USE_OBJECTS_FOR_ENUM_KEYED_MAPS.

    "},{"location":"features/macros/#json_use_simdutf","title":"JSON_USE_SIMDUTF","text":"

    When defined, UTF-8 validation of JSON strings read from contiguous byte input is delegated to the simdutf library instead of the built-in scalar validator. This is an opt-in external dependency and is not defined by default.

    See full documentation of JSON_USE_SIMDUTF.

    "},{"location":"features/macros/#nlohmann_define_type_-nlohmann_define_derived_type_","title":"NLOHMANN_DEFINE_TYPE_*(...), NLOHMANN_DEFINE_DERIVED_TYPE_*(...)","text":"

    The library defines 12 macros to simplify the serialization/deserialization of types. See the page on arbitrary type conversion for a detailed discussion.

    "},{"location":"features/macros/#nlohmann_json_namespace-nlohmann_json_namespace_begin-nlohmann_json_namespace_end-nlohmann_json_namespace_no_version","title":"NLOHMANN_JSON_NAMESPACE, NLOHMANN_JSON_NAMESPACE_BEGIN, NLOHMANN_JSON_NAMESPACE_END, NLOHMANN_JSON_NAMESPACE_NO_VERSION","text":"

    These macros relate to the versioned, inline nlohmann namespace:

    • NLOHMANN_JSON_NAMESPACE evaluates to the full name of the nlohmann namespace (including the inline ABI namespace).
    • NLOHMANN_JSON_NAMESPACE_BEGIN / NLOHMANN_JSON_NAMESPACE_END open and close the namespace (for example, to add specializations).
    • NLOHMANN_JSON_NAMESPACE_NO_VERSION, when defined to 1, omits the version component from the inline namespace.

    See the nlohmann Namespace page, and the full documentation of NLOHMANN_JSON_NAMESPACE, NLOHMANN_JSON_NAMESPACE_BEGIN / NLOHMANN_JSON_NAMESPACE_END, and NLOHMANN_JSON_NAMESPACE_NO_VERSION.

    "},{"location":"features/macros/#nlohmann_json_serialize_enumtype","title":"NLOHMANN_JSON_SERIALIZE_ENUM(type, ...)","text":"

    This macro simplifies the serialization/deserialization of enum types. See Specializing enum conversion for more information.

    See full documentation of NLOHMANN_JSON_SERIALIZE_ENUM.

    A strict variant NLOHMANN_JSON_SERIALIZE_ENUM_STRICT throws an exception on undefined input instead of falling back to the first mapping.

    "},{"location":"features/macros/#nlohmann_json_version_major-nlohmann_json_version_minor-nlohmann_json_version_patch","title":"NLOHMANN_JSON_VERSION_MAJOR, NLOHMANN_JSON_VERSION_MINOR, NLOHMANN_JSON_VERSION_PATCH","text":"

    These macros are defined by the library and contain the version numbers according to Semantic Versioning 2.0.0.

    See full documentation of NLOHMANN_JSON_VERSION_MAJOR, NLOHMANN_JSON_VERSION_MINOR, and NLOHMANN_JSON_VERSION_PATCH.

    "},{"location":"features/macros/#see-also","title":"See also","text":"
    • Macros - reference of all macros
    • Runtime Assertions - runtime assertions in detail
    • nlohmann Namespace - the library namespace and its macros
    • Working Without Exceptions - using the library without exceptions
    • Modules - macros and C++20 modules
    • Exceptions - all exceptions and their error codes
    • CMake - set macros via CMake options
    • Compile times - reduce compile times with macros
    • Architecture - how the library is put together
    • Specializing enum conversion - enum macros
    • Arbitrary Type Conversions - type conversion macros
    "},{"location":"features/merge_patch/","title":"JSON Merge Patch","text":"

    The library supports JSON Merge Patch (RFC 7396) as a patch format. The merge patch format is primarily intended for use with the HTTP PATCH method as a means of describing a set of modifications to a target resource's content. Applying a merge patch changes the JSON value the patch is applied to.

    Instead of using JSON Pointer to specify values to be manipulated, it describes the changes using a syntax that closely mimics the document being modified. Unlike JSON Patch, a JSON Merge Patch cannot express every kind of change (e.g., it cannot reorder array elements or remove a specific array element), but it is easier to read and write for object-shaped documents.

    The function merge_diff creates a merge patch that changes one JSON value into another.

    The example below applies one patch to one document. Here is the document before:

    {\n    \"title\": \"Goodbye!\",\n    \"author\": {\n        \"givenName\": \"John\",\n        \"familyName\": \"Doe\"\n    },\n    \"tags\": [\"example\", \"sample\"],\n    \"content\": \"This will be unchanged\"\n}\n

    This is the patch:

    {\n    \"title\": \"Hello!\",\n    \"phoneNumber\": \"+01-123-456-7890\",\n    \"author\": {\n        \"familyName\": null\n    },\n    \"tags\": [\"example\"]\n}\n

    And this is the document after applying it:

    {\n    \"title\": \"Hello!\",\n    \"author\": {\n        \"givenName\": \"John\"\n    },\n    \"tags\": [\"example\"],\n    \"content\": \"This will be unchanged\",\n    \"phoneNumber\": \"+01-123-456-7890\"\n}\n

    The table goes through the members one by one. \"Member\" is the name of an object member in the patch (and in the document); it is not a JSON Pointer and nothing of it is passed to the function: the whole patch is passed to merge_patch.

    Rule Member Before Patch After change value title \"Goodbye!\" \"Hello!\" \"Hello!\" add key phoneNumber (no member) \"+01-123-456-7890\" \"+01-123-456-7890\" object merges recursively author {\"givenName\": \"John\", \"familyName\": \"Doe\"} {\"familyName\": null} {\"givenName\": \"John\"} null removes key familyName inside author \"Doe\" null (removed) array replaced whole tags [\"example\", \"sample\"] [\"example\"] [\"example\"] unchanged key content \"This will be unchanged\" (no member) \"This will be unchanged\"

    An array in the patch replaces the array in the target, so a merge patch cannot change a single element. Each member of the patch is applied like this; a patch that is not an object replaces the whole target.

    flowchart LR\n    M[\"member of the patch\"] --> N{{\"value null?\"}}\n    N -->|yes| D[\"delete the key\"]\n    N -->|no| O{{\"value an object?\"}}\n    O -->|yes| R[\"merge recursively into the target's value\"]\n    O -->|no| S[\"set the key to the value\"]

    How one member of a merge patch is applied: a null value deletes the key, an object is merged recursively, and any other value replaces the value of the key.

    Not a general deep merge

    A merge patch is not a general deep merge: a null value in the patch deletes the key from the target. To merge two objects recursively (e.g., defaults and user settings), use update with merge_objects set to true; see Merging objects.

    Limitations of RFC 7396

    • A patch cannot set a member to null, because null removes the member: {\"a\":1} patched with {\"a\":null} gives {}.
    • Arrays are replaced as a whole, never merged, and a null inside an array is kept.
    • null members of the target that the patch does not mention are preserved.
    • A null that would remove a member of a not yet existing object still creates that object: {} patched with {\"a\":{\"b\":null}} gives {\"a\":{}}.
    • A patch that is not an object replaces the whole target (a null patch makes the target null); an object patch applied to a non-object target starts from an empty object.
    • merge_diff has a matching limitation for null members.
    Example

    The following code shows how a JSON Merge Patch is applied to a JSON document.

    #include <iostream>\n#include <nlohmann/json.hpp>\n#include <iomanip> // for std::setw\n\nusing nlohmann::json;\nusing namespace nlohmann::literals;\n\nint main()\n{\n    // the original document\n    json document = R\"({\n                \"title\": \"Goodbye!\",\n                \"author\": {\n                    \"givenName\": \"John\",\n                    \"familyName\": \"Doe\"\n                },\n                \"tags\": [\n                    \"example\",\n                    \"sample\"\n                ],\n                \"content\": \"This will be unchanged\"\n            })\"_json;\n\n    // the patch\n    json patch = R\"({\n                \"title\": \"Hello!\",\n                \"phoneNumber\": \"+01-123-456-7890\",\n                \"author\": {\n                    \"familyName\": null\n                },\n                \"tags\": [\n                    \"example\"\n                ]\n            })\"_json;\n\n    // apply the patch\n    document.merge_patch(patch);\n\n    // output original and patched document\n    std::cout << std::setw(4) << document << '\\n';\n}\n

    Output:

    {\n    \"author\": {\n        \"givenName\": \"John\"\n    },\n    \"content\": \"This will be unchanged\",\n    \"phoneNumber\": \"+01-123-456-7890\",\n    \"tags\": [\n        \"example\"\n    ],\n    \"title\": \"Hello!\"\n}\n
    "},{"location":"features/merge_patch/#see-also","title":"See also","text":"
    • JSON Patch and Diff - a more expressive alternative that describes a sequence of operations
    • JSON Pointer - the addressing scheme used by JSON Patch
    • merge_patch - apply a JSON Merge Patch to a value
    • merge_diff - create a JSON Merge Patch from two values
    • Function update - merge objects, optionally recursively
    • Modifying values - simple in-place modifications
    "},{"location":"features/modifying_values/","title":"Modifying values","text":"

    Once a JSON value exists, its content can be changed: elements can be added, replaced, merged, and removed. This page gives an overview of the available operations. For read access, see element access.

    "},{"location":"features/modifying_values/#adding-to-arrays","title":"Adding to arrays","text":"

    New elements are appended to an array with push_back or constructed in place with emplace_back. If the value is null, it is converted to an array first, so these functions can also be used to build an array from scratch.

    json j;                 // null\nj.push_back(1);         // [1]\nj.push_back(2);         // [1,2]\nj.emplace_back(3);      // [1,2,3]\n\n// operator+= is a shorthand for push_back\nj += 4;                 // [1,2,3,4]\n
    "},{"location":"features/modifying_values/#adding-to-objects","title":"Adding to objects","text":"

    The most common way to add or replace a member is operator[], which inserts the key if it does not exist yet:

    json j;\nj[\"name\"] = \"Mary\";     // {\"name\":\"Mary\"}\nj[\"name\"] = \"John\";     // {\"name\":\"John\"}  (replaced)\n

    emplace inserts a member only if the key is not already present, and reports whether the insertion happened \u2014 useful for \"add if absent\" semantics.

    "},{"location":"features/modifying_values/#merging-objects","title":"Merging objects","text":"

    To merge one object into another, update copies all members from another object (similar to Python's dict.update). This is the idiomatic way to combine two objects. It has two modes:

    • By default, the merge is shallow: existing keys are overwritten, even if both values are objects.
    • With merge_objects = #!cpp true, keys whose values are objects in both JSON values are merged recursively. Everything else is overwritten. In particular, arrays are replaced, not concatenated.
    Example
    #include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\nusing namespace nlohmann::literals;\n\nint main()\n{\n    // create two JSON objects\n    json o1 = R\"( {\"color\": \"red\", \"price\": 17.99, \"names\": {\"de\": \"Flugzeug\"}} )\"_json;\n    json o2 = R\"( {\"color\": \"blue\", \"speed\": 100, \"names\": {\"en\": \"plane\"}} )\"_json;\n    json o3 = o1;\n\n    // add all keys from o2 to o1 (updating \"color\", replacing \"names\")\n    o1.update(o2);\n\n    // add all keys from o2 to o1 (updating \"color\", merging \"names\")\n    o3.update(o2, true);\n\n    // output updated object o1 and o3\n    std::cout << std::setw(2) << o1 << '\\n';\n    std::cout << std::setw(2) << o3 << '\\n';\n}\n

    Output:

    {\n  \"color\": \"blue\",\n  \"names\": {\n    \"en\": \"plane\"\n  },\n  \"price\": 17.99,\n  \"speed\": 100\n}\n{\n  \"color\": \"blue\",\n  \"names\": {\n    \"de\": \"Flugzeug\",\n    \"en\": \"plane\"\n  },\n  \"price\": 17.99,\n  \"speed\": 100\n}\n

    A common use of the recursive mode is combining defaults with user settings. Nested defaults that the user did not set are kept:

    json defaults = {{\"log\", {{\"level\", \"info\"}, {\"file\", \"app.log\"}}}, {\"retries\", 3}};\njson user_settings = {{\"log\", {{\"level\", \"debug\"}}}};\n\njson config = defaults;\nconfig.update(user_settings, true);\n// {\"log\":{\"file\":\"app.log\",\"level\":\"debug\"},\"retries\":3}\n

    JSON Merge Patch (RFC 7396) also merges objects recursively, but it is a different tool: a null in the patch means \"remove this key\". It is meant for applying merge patch documents (e.g., received via HTTP PATCH). To merge configuration-like objects, use update(..., true). To apply a sequence of well-defined edit operations, see JSON Patch.

    "},{"location":"features/modifying_values/#removing-elements","title":"Removing elements","text":"

    Elements are removed with erase, which accepts an object key, an array index, or an iterator. clear empties a value while keeping its type, and operator[] combined with assignment can overwrite a value entirely.

    json j = {{\"a\", 1}, {\"b\", 2}, {\"c\", 3}};\nj.erase(\"b\");           // {\"a\":1,\"c\":3}\n\njson a = {1, 2, 3, 4};\na.erase(1);             // [1,3,4]  (erase by index)\n
    "},{"location":"features/modifying_values/#editing-a-document","title":"Editing a document","text":"

    The operations above work on a basic_json value. A JSON text that was parsed into a document can also be changed in place, without building a basic_json tree for the parts that are not touched: set replaces a value, adds or replaces an object member, or replaces an array element (also through a JSON pointer), push_back appends to an array, insert inserts into an array (unlike basic_json::insert, it has no object overload; members are added with set), and erase removes a member or an element. These functions are available on the editable document types, such as json_editable_document.

    "},{"location":"features/modifying_values/#see-also","title":"See also","text":"
    • push_back - / emplace_back - append to an array
    • emplace - insert into an object if the key is absent
    • update - merge objects (shallow, or recursive with merge_objects)
    • merge_patch - apply an RFC 7396 merge patch
    • erase - / clear - remove elements
    • JSON Patch and Diff - and JSON Merge Patch - structured modifications
    • Editing a document - change a parsed document in place
    • insert - insert elements at an iterator position or merge a range
    • operator+= - shorthand for push_back
    • Element Access - read elements
    • Iterators - iterate over elements
    "},{"location":"features/modules/","title":"Modules","text":"

    This library has experimental support for C++ modules, introduced in C++20. The library can be imported by writing import nlohmann.json; instead of #include <nlohmann/json.hpp>.

    Please be aware that the module is experimental and a full test is outstanding, and the exported symbols are subject to change.

    Importing the module instead of including the header reduces the compile time of every translation unit that uses the library, at the price of building the module once. The Compile times page has measurements and the one-off cost.

    "},{"location":"features/modules/#requirements","title":"Requirements","text":"

    The nlohmann.json module requires that the build system is configured to build and resolve modules when imported. Obviously, as modules were introduced in C++20, this feature can only be used in C++20 and subsequent versions.

    To enable building the nlohmann.json module (which is not done by default), the macro NLOHMANN_JSON_BUILD_MODULES must be passed to the build system.

    "},{"location":"features/modules/#example","title":"Example","text":"

    When using modules rather than headers, the previous example for creating a json object through a JSON file, would instead be:

    import std;\nimport nlohmann.json;\n\nusing nlohmann::json;\n\n// ...\n\nstd::ifstream f(\"example.json\");\njson data = json::parse(f);\n

    "},{"location":"features/modules/#modules-do-not-export-macros","title":"Modules do not export macros","text":"

    It should be noted that as modules do not export macros, the nlohmann.json module will not export any macros.

    "},{"location":"features/modules/#exported-symbols","title":"Exported symbols","text":"

    Only the following symbols are exported from nlohmann.json:

    • nlohmann::adl_serializer
    • nlohmann::basic_json
    • nlohmann::basic_json_document
    • nlohmann::basic_json_view
    • nlohmann::json
    • nlohmann::json_document
    • nlohmann::json_pointer
    • nlohmann::json_view
    • nlohmann::ordered_json
    • nlohmann::ordered_json_document
    • nlohmann::ordered_json_view
    • nlohmann::ordered_map
    • nlohmann::to_string
    • nlohmann::literals::json_literals::operator\"\"_json
    • nlohmann::literals::json_literals::operator\"\"_json_pointer

    The module always exports the two user-defined string literals, even if JSON_NO_AUTOMATIC_UDLS is defined when building it.

    Additionally, the following nlohmann::detail symbols are exported, solely to work around an MSVC compilation issue (#3970). They are implementation details, not part of the public API, and should not be used directly:

    • nlohmann::detail::json_sax_dom_callback_parser
    • nlohmann::detail::unknown_size
    "},{"location":"features/modules/#known-issues","title":"Known issues","text":"

    C++20 modules support is exercised in CI against current GCC and Clang on Ubuntu, and the default MSVC toolset on Windows Server 2022 \u2014 there is no documented minimum compiler version, unlike feature-test-macro-gated features such as JSON_HAS_RANGES.

    Known compiler issues

    • GCC may emit \"redefinition\" errors when #include <nlohmann/json.hpp> appears in a module preamble together with other imports. This is an upstream GCC bug, not yet resolved as of GCC 16. Workarounds: include nlohmann/json.hpp before other #includes, use import nlohmann.json; instead, or upgrade GCC. (issue #5103)
    • MSVC could fail with C2039: 'json_sax_dom_callback_parser' is not a member of ... detail; fixed by exporting the required internal symbols from json.cppm (see Exported symbols above). (issue #3970)

    If you hit a different module-related build failure, search existing issues before filing a new one.

    "},{"location":"features/modules/#see-also","title":"See also","text":"
    • Supported Macros - macros are not exported by modules
    • Macros - reference of all macros
    • nlohmann Namespace - the library namespace
    • CMake - enable the module build in CMake
    • Compile times - reduce compile times
    • basic_json - the main class and all its member functions
    "},{"location":"features/namespace/","title":"nlohmann Namespace","text":"

    The 3.11.0 release introduced an inline namespace to allow different parts of a codebase to safely use different versions of the JSON library as long as they never exchange instances of library types.

    "},{"location":"features/namespace/#structure","title":"Structure","text":"

    The complete default namespace name is derived as follows:

    • The root namespace is always nlohmann.
    • The inline namespace starts with json_abi and is followed by several optional ABI tags according to the value of these ABI-affecting macros, in order:
      • JSON_DIAGNOSTICS defined non-zero appends _diag.
      • JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON defined non-zero appends _ldvcmp.
      • JSON_DIAGNOSTIC_POSITIONS defined non-zero appends _dp.
      • JSON_BRACE_INIT_COPY_SEMANTICS defined non-zero appends _bics.
      • JSON_PRECISE_STREAM_POSITION defined non-zero appends _psp.
      • JSON_STRICT_NUL_HANDLING defined non-zero appends _snul.
      • JSON_STRICT_BINARY_UTF8 defined non-zero appends _sbu8.
      • JSON_USE_OBJECTS_FOR_ENUM_KEYED_MAPS defined non-zero appends _ekmo.
      • JSON_DISABLE_STREAM_BULK_SCAN defined non-zero appends _dsbs.
      • JSON_DISABLE_UNLOCKED_FILE_IO defined non-zero appends _dufio.
      • JSON_NO_SIMD defined appends _ns.
    • The inline namespace ends with the suffix _v followed by the 3 components of the version number separated by underscores. To omit the version component, see Disabling the version component below.

    For example, the namespace name for version 3.11.2 with JSON_DIAGNOSTICS defined to 1 is:

    nlohmann::json_abi_diag_v3_11_2\n

    The name is assembled from these segments; pick a version and macros to see the resulting name:

    nlohmannroot namespace :: json_abialways _diagJSON_DIAGNOSTICS=1 _v3_11_2version 3.11.2 Version 3.11.2 with JSON_DIAGNOSTICS defined to 1. ABI tags are appended in the order of the list above, the version suffix comes last.

    The name of the inline namespace, assembled from its segments. Select a version and macros to see which ABI tags appear; a tag the chosen version does not have is disabled.

    "},{"location":"features/namespace/#purpose","title":"Purpose","text":"

    Several incompatibilities have been observed. Amongst the most common ones is linking code compiled with different definitions of JSON_DIAGNOSTICS. This is illustrated in the diagram below.

    graph\n    json[\"<strong>nlohmann_json (v3.10.5)</strong><br>JSON_DIAGNOSTICS=0\"]\n    json_diag[\"<strong>nlohmann_json (v3.10.5)</strong><br>JSON_DIAGNOSTICS=1\"]\n    library[\"<strong>some library</strong>\"]\n    app[\"<strong>application</strong>\"]\n\n    library --> json\n    app --> json_diag\n    app --> library

    The application uses the library with JSON_DIAGNOSTICS=1 and links some library, which uses the same library version with JSON_DIAGNOSTICS=0. Arrows point from a component to what it uses.

    In releases prior to 3.11.0, mixing any version of the JSON library with different JSON_DIAGNOSTICS settings would result in a crashing application. If some_library never passes instances of JSON library types to the application, this scenario became safe in version 3.11.0 and above due to the inline namespace yielding distinct symbol names.

    "},{"location":"features/namespace/#limitations","title":"Limitations","text":"

    Neither the compiler nor the linker will issue as much as a warning when translation units \u2013 intended to be linked together and that include different versions and/or configurations of the JSON library \u2013 exchange and use library types.

    There is an exception when forward declarations are used (i.e., when including json_fwd.hpp) in which case the linker may complain about undefined references.

    "},{"location":"features/namespace/#disabling-the-version-component","title":"Disabling the version component","text":"

    Different versions are not necessarily ABI-incompatible, but the project does not actively track changes in the ABI and recommends that all parts of a codebase exchanging library types be built with the same version. Users can, at their own risk, disable the version component of the inline namespace, allowing different versions \u2013 but not configurations \u2013 to be used in cases where the linker would otherwise output undefined reference errors.

    To do so, define NLOHMANN_JSON_NAMESPACE_NO_VERSION to 1.

    This applies to version 3.11.2 and above only; versions 3.11.0 and 3.11.1 can apply the technique described in the next section to emulate the effect of the NLOHMANN_JSON_NAMESPACE_NO_VERSION macro.

    Use at your own risk

    Disabling the namespace version component and mixing ABI-incompatible versions will result in crashes or incorrect behavior. You have been warned!

    "},{"location":"features/namespace/#disabling-the-inline-namespace-completely","title":"Disabling the inline namespace completely","text":"

    When interoperability with code using a pre-3.11.0 version of the library is required, users can, at their own risk restore the old namespace layout by redefining NLOHMANN_JSON_NAMESPACE_BEGIN, NLOHMANN_JSON_NAMESPACE_END as follows:

    #define NLOHMANN_JSON_NAMESPACE_BEGIN  namespace nlohmann {\n#define NLOHMANN_JSON_NAMESPACE_END    }\n

    Use at your own risk

    Overriding the namespace and mixing ABI-incompatible versions will result in crashes or incorrect behavior. You have been warned!

    "},{"location":"features/namespace/#see-also","title":"See also","text":"
    • NLOHMANN_JSON_NAMESPACE - the library namespace as macro
    • NLOHMANN_JSON_NAMESPACE_BEGIN, NLOHMANN_JSON_NAMESPACE_END - open and close the library namespace
    • NLOHMANN_JSON_NAMESPACE_NO_VERSION - disable the version component
    • Supported Macros - all supported macros
    • Migration Guide - do not hard-code the library namespace
    • basic_json - the main class and all its member functions
    "},{"location":"features/namespace/#version-history","title":"Version history","text":"
    • Introduced inline namespace (json_v3_11_0[_abi-tag]*) in version 3.11.0.
    • Changed structure of inline namespace in version 3.11.2.
    • Added ABI tag _dp (JSON_DIAGNOSTIC_POSITIONS) in version 3.12.0.
    • Added ABI tags _bics (JSON_BRACE_INIT_COPY_SEMANTICS), _psp (JSON_PRECISE_STREAM_POSITION), _snul (JSON_STRICT_NUL_HANDLING), _sbu8 (JSON_STRICT_BINARY_UTF8), _ekmo (JSON_USE_OBJECTS_FOR_ENUM_KEYED_MAPS), _dsbs (JSON_DISABLE_STREAM_BULK_SCAN), _dufio (JSON_DISABLE_UNLOCKED_FILE_IO), and _ns (JSON_NO_SIMD) in version 3.13.0 unreleased.
    "},{"location":"features/no_exceptions/","title":"Working Without Exceptions","text":"

    By default, the library reports errors by throwing exceptions (see Exceptions). This page collects what to use when exceptions are unwanted or unavailable, for example in embedded systems, game engines, or code compiled with -fno-exceptions.

    "},{"location":"features/no_exceptions/#two-different-questions","title":"Two different questions","text":"
    1. Can my code avoid catching exceptions? Yes. For parsing and for accessing values there are functions that report failure through a return value. They work in a normal build and need no try/catch.
    2. Can the library be compiled without exceptions? Yes, with -fno-exceptions or by defining JSON_NOEXCEPTION. Both have the same effect: every throw in the library becomes a call to std::abort(). The functions listed below never reach a throw for the failures they report, so they keep working in this configuration. Anything else that fails aborts the program.
    "},{"location":"features/no_exceptions/#parsing","title":"Parsing","text":"function on invalid input json::parse(input, nullptr, false) returns a discarded value; test with is_discarded() accept returns false json::from_cbor(input, true, false) (and the other from_* functions) returns a discarded value sax_parse with your own handler returns false after calling parse_error Example: parse and validate without exceptions
    #include <cstdint>\n#include <iostream>\n#include <vector>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\n// None of the calls below throws, so this example also works with -fno-exceptions.\nint main()\n{\n    const std::string invalid = R\"({\"name\": \"Mary\", \"age\": )\";\n\n    // parse() with allow_exceptions = false returns a discarded value\n    json j = json::parse(invalid, nullptr, false);\n    std::cout << std::boolalpha << \"parse: discarded = \" << j.is_discarded() << '\\n';\n\n    // accept() only tells whether the input is valid JSON\n    std::cout << \"accept: \" << json::accept(invalid) << '\\n';\n\n    // the binary formats have the same parameter\n    const std::vector<std::uint8_t> truncated_cbor = {0x83, 0x01};\n    json c = json::from_cbor(truncated_cbor, true, false);\n    std::cout << \"from_cbor: discarded = \" << c.is_discarded() << '\\n';\n\n    // valid input is parsed as usual\n    json valid = json::parse(R\"({\"name\": \"Mary\"})\", nullptr, false);\n    std::cout << \"valid input: \" << valid << '\\n';\n}\n

    Output:

    parse: discarded = true\naccept: false\nfrom_cbor: discarded = true\nvalid input: {\"name\":\"Mary\"}\n

    None of the calls in this example throws, so it also compiles and runs with -fno-exceptions.

    The discarded value carries no message. If you need the position or the reason, use the SAX interface; see Parsing and exceptions.

    "},{"location":"features/no_exceptions/#accessing-values","title":"Accessing values","text":"

    The access functions are not equally safe. Only some of them never throw:

    expression if the key is missing or the type is wrong j.contains(\"k\") returns false for a missing key; never throws j.find(\"k\") returns end() for a missing key; never throws j.is_string(), ... the is_* functions test the type; never throw j.get_ptr<const std::string*>() returns nullptr for a different type; never throws j.at(\"k\") throws out_of_range.403 for a missing key j.get<int>() throws type_error.302 for a value that is not a number j.value(\"k\", 0) returns the default for a missing key, but throws type_error.302 if k exists with another type j[\"k\"] (non-const) inserts null for a missing key j[\"k\"] (const) undefined behavior for a missing key

    So reading a value that may be absent or of the wrong type without exceptions takes two steps: look up, then test the type.

    Example: look up a key and test its type
    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    json j = json::parse(R\"({\"name\": \"Mary\", \"age\": 42})\");\n\n    // look up the key, then test the type: neither step throws\n    const auto keys = {\"name\", \"age\", \"city\"};\n    for (const char* key : keys)\n    {\n        const auto it = j.find(key);\n        if (it == j.end())\n        {\n            std::cout << key << \": missing\\n\";\n        }\n        else if (it->is_string())\n        {\n            std::cout << key << \": string \\\"\" << it->get_ref<const std::string&>() << \"\\\"\\n\";\n        }\n        else\n        {\n            std::cout << key << \": not a string, but \" << it->type_name() << '\\n';\n        }\n    }\n\n    // get_ptr returns a null pointer if the value has another type\n    const std::string* name = j[\"name\"].get_ptr<const std::string*>();\n    const std::string* age = j[\"age\"].get_ptr<const std::string*>();\n    std::cout << \"get_ptr<string*>: name = \" << (name != nullptr) << \", age = \" << (age != nullptr) << '\\n';\n\n    // value() is NOT exception-free: it throws if the key exists with a different type\n    try\n    {\n        std::cout << j.value(\"name\", 0) << '\\n';\n    }\n    catch (const json::type_error& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n}\n

    Output:

    name: string \"Mary\"\nage: not a string, but number\ncity: missing\nget_ptr<string*>: name = 1, age = 0\n[json.exception.type_error.302] type must be number, but is string\n

    The last lines of the example show why value is not on the safe list: it returns the default only for a missing key.

    For numbers, test with is_number() (or is_number_integer(), is_number_unsigned(), is_number_float()) before calling get<int>(), and see number handling for range and precision. Whether a value fits into the target type is not checked by get.

    "},{"location":"features/no_exceptions/#converting-to-your-own-types","title":"Converting to your own types","text":"

    from_json functions (including the ones generated by the NLOHMANN_DEFINE_TYPE_* macros) report problems by throwing. There is no variant that returns an error code. Without exceptions you have two options:

    • Validate the JSON value yourself, as shown above, and fill your struct field by field.
    • Convert in a function that is compiled with exceptions enabled and catches them at the boundary, returning std::optional or an error code to the rest of your code:
    Example: convert to a struct and report failure as std::optional
    #include <iostream>\n#include <optional>\n#include <string>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nstruct person\n{\n    std::string name;\n    int age;\n};\n\nNLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(person, name, age)\n\n// Compile this function with exceptions enabled and call it from code that does not use them.\nstd::optional<person> to_person(const json& j)\n{\n    try\n    {\n        return j.get<person>();\n    }\n    catch (const json::exception&)\n    {\n        return std::nullopt;\n    }\n}\n\nint main()\n{\n    const json good = {{\"name\", \"Mary\"}, {\"age\", 42}};\n    const json bad = {{\"name\", \"Mary\"}, {\"age\", \"forty-two\"}};\n    const json incomplete = {{\"name\", \"Mary\"}};\n\n    const auto inputs = {good, bad, incomplete};\n\n    for (const json& j : inputs)\n    {\n        if (const auto p = to_person(j))\n        {\n            std::cout << \"person: \" << p->name << \", \" << p->age << '\\n';\n        }\n        else\n        {\n            std::cout << \"not a person: \" << j << '\\n';\n        }\n    }\n}\n

    Output:

    person: Mary, 42\nnot a person: {\"age\":\"forty-two\",\"name\":\"Mary\"}\nnot a person: {\"name\":\"Mary\"}\n
    "},{"location":"features/no_exceptions/#overriding-what-happens-instead-of-an-exception","title":"Overriding what happens instead of an exception","text":"

    With exceptions off, you can replace the abort() by your own code, for example to log the message first. See Switch off exceptions and JSON_THROW_USER. The handler must not return normally.

    "},{"location":"features/no_exceptions/#see-also","title":"See also","text":"
    • Exceptions - all exceptions and their ids
    • Parsing and exceptions - the parsing alternatives in detail
    • Parsing untrusted input - harden an application that parses data it does not control
    • JSON_NOEXCEPTION - disable exceptions in the library
    • exception - base class of all exceptions thrown by the library
    • JSON_THROW_USER - replace the throw statements of the library
    • parse - deserialize from a compatible input
    • accept - check whether the input is valid JSON
    • Supported Macros - all supported macros
    "},{"location":"features/object_order/","title":"Object Order","text":"

    The JSON standard defines objects as \"an unordered collection of zero or more name/value pairs\". As such, an implementation does not need to preserve any specific order of object keys.

    "},{"location":"features/object_order/#default-behavior-sort-keys","title":"Default behavior: sort keys","text":"

    The default type nlohmann::json uses a std::map to store JSON objects, and thus stores object keys sorted alphabetically.

    Example: json sorts object keys
    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    json j;\n    j[\"one\"] = 1;\n    j[\"two\"] = 2;\n    j[\"three\"] = 3;\n\n    std::cout << j.dump(2) << '\\n';\n}\n

    Output:

    {\n  \"one\": 1,\n  \"three\": 3,\n  \"two\": 2\n}\n
    "},{"location":"features/object_order/#alternative-behavior-preserve-insertion-order","title":"Alternative behavior: preserve insertion order","text":"

    If you do want to preserve the insertion order, you can use the type nlohmann::ordered_json.

    Example: ordered_json preserves insertion order
    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::ordered_json;\n\nint main()\n{\n    ordered_json j;\n    j[\"one\"] = 1;\n    j[\"two\"] = 2;\n    j[\"three\"] = 3;\n\n    std::cout << j.dump(2) << '\\n';\n}\n

    Output:

    {\n  \"one\": 1,\n  \"two\": 2,\n  \"three\": 3\n}\n

    Alternatively, nlohmann::fifo_map also preserves the insertion order and, unlike ordered_map, keeps a lookup index, so it does not have the quadratic cost described below. It is used through a small adapter (integration).

    If the order does not matter and you only want faster lookup, boost::unordered_flat_map, absl::flat_hash_map, absl::node_hash_map, and several other hash maps work through an adapter that restores the template argument order basic_json expects; see Template Parameter Requirements. Note these are unordered, not insertion-ordered.

    tsl::ordered_map cannot be used: its iterators expose the mapped value as const, while basic_json needs to modify it in place.

    The ordered_map behind nlohmann::ordered_json is deliberately minimal and has no lookup index, so every key access is a linear scan and building an object of n keys costs O(n\u00b2). This is unnoticeable at typical object sizes but becomes significant for objects with many thousands of keys; see ordered_map complexity. The alternatives above keep a lookup index and do not have this cost.

    "},{"location":"features/object_order/#notes-on-parsing","title":"Notes on parsing","text":"

    Note that you also need to call the right parse function when reading from a file. Assume file input.json contains the JSON object above:

    {\n  \"one\": 1,\n  \"two\": 2,\n  \"three\": 3\n}\n

    Right way

    The following code correctly calls the parse function from nlohmann::ordered_json:

    std::ifstream i(\"input.json\");\nauto j = nlohmann::ordered_json::parse(i);\nstd::cout << j.dump(2) << std::endl;\n

    The output will be:

    {\n  \"one\": 1,\n  \"two\": 2,\n  \"three\": 3\n}\n
    Wrong way

    The following code incorrectly calls the parse function from nlohmann::json which does not preserve the insertion order, but sorts object keys. Assigning the result to nlohmann::ordered_json compiles, but does not restore the order from the input file.

    std::ifstream i(\"input.json\");\nnlohmann::ordered_json j = nlohmann::json::parse(i);\nstd::cout << j.dump(2) << std::endl;\n

    The output will be:

    {\n  \"one\": 1,\n  \"three\": 3,\n  \"two\": 2\n}\n
    "},{"location":"features/object_order/#see-also","title":"See also","text":"
    • ordered_json - JSON type that preserves insertion order
    • ordered_map - the container behind ordered_json
    • object_t - type used to store JSON objects
    • Iterators - iteration order of object keys
    • Element Access - access elements by key
    "},{"location":"features/performance/","title":"Performance","text":"

    Speed was never the primary goal of this library. The design goals page says so plainly: \"There are certainly faster JSON libraries out there.\" Intuitive syntax, trivial integration, and thorough testing came first. If a hard real-time budget or the last percent of throughput matters more than convenience, a faster, more specialized library may be a better fit.

    That said, how you use this library still makes a measurable difference. This page collects practical, code-verified techniques for reducing time, memory, and compile-time cost \u2014 without repeating the detailed pages it links to.

    "},{"location":"features/performance/#parsing-input","title":"Parsing input","text":"

    parse accepts a string, a pair of iterators, a container, a std::istream, or a FILE* (see Parsing). Internally, every input is wrapped in an input adapter, and not all adapters are equally fast.

    For inputs backed by contiguous, single-byte memory \u2014 a std::string, a std::vector<char>, a string literal, or a pointer range \u2014 the library uses iterator_input_adapter, wrapped in a raw pointer so the fast paths below apply on every supported standard. This adapter exposes two optimizations the lexer detects at compile time:

    • it can reconstruct already-consumed input on demand for error messages, instead of copying every character as it is read, and
    • the lexer can scan ordinary string characters, numbers, and indentation directly out of the buffer, several bytes at a time, rather than one character (and one function call) at a time.

    A std::istream (including std::ifstream) gets the same bulk scanning: input_stream_adapter scans the characters its stream buffer already holds (the get area) and asks the stream buffer for more only when they are used up. Nothing is read ahead, so the stream is left exactly where it would be after reading one character at a time, and operator>> can still read several values from one stream. A stream buffer without a get area is read one character at a time. A FILE* is still read one character at a time, but file_input_adapter locks the file once per parse instead of once per character. See input sources and performance for the full table. According to the description of #5828, parsing from a stream is within about 10 to 20 % of parsing an equivalent std::string.

    Inputs that are still read one character at a time: iterator ranges that are not contiguous (e.g. std::list<char> or std::istreambuf_iterator<char>), wide strings, and user-defined adapters. An iterator pair over non-contiguous but random-access storage (e.g. std::deque<char>::iterator) gets the first optimization but not the second, since the byte-scanning fast path requires contiguous storage.

    Practically: a file can be passed directly to parse, which also avoids the memory for a copy of the file. Reading it into a string first is no longer necessary for speed:

    // fast: the stream buffer's get area is scanned in bulk\nstd::ifstream f(\"example.json\");\njson j = json::parse(f);\n

    Two macros switch the stream optimizations off without changing any result: JSON_DISABLE_STREAM_BULK_SCAN for stream buffers that do not follow the usual std::streambuf contract, and JSON_DISABLE_UNLOCKED_FILE_IO for programs in which another thread must use the same FILE object while it is parsed.

    For contiguous input with many non-ASCII characters, JSON_USE_SIMDUTF can additionally speed up UTF-8 validation by using the simdutf library instead of the built-in scalar validator; streaming inputs (files, std::istream, wide strings, user-defined adapters) always use the scalar path regardless of this macro.

    "},{"location":"features/performance/#large-documents","title":"Large documents","text":"

    Parsing always produces SAX events internally; parse simply feeds them to a consumer that builds a complete basic_json value tree (a DOM) in memory. For documents too large to comfortably hold as a DOM, three alternatives avoid building it:

    • Implement the SAX interface directly and pass it to sax_parse; only the parts of the input you choose to keep ever become basic_json values.
    • Pass a parser callback to parse. This still builds a DOM, but the callback can discard finished elements as soon as they are handled, so memory usage stays bounded by one element (plus the unparsed remainder of the input) instead of the whole document \u2014 see the recipe for streaming a large homogeneous array.
    • Parse into a json_document (<nlohmann/json_view.hpp>) instead of a basic_json. It keeps the input text and builds a flat index of 16 bytes per value; strings and floating-point numbers are not copied, but read from the text when needed. Read-only views give the familiar element access, and only the parts you materialize() become basic_json values. A document that borrows the text instead of owning a copy needs the text to outlive it; see choosing between json, the SAX interface, and json_view.

    If the data is naturally record-oriented, consider JSON Lines instead of one large JSON document: reading and parsing it line by line with std::getline means only one line's value is ever in memory at a time, and a malformed line does not invalidate lines already processed.

    "},{"location":"features/performance/#binary-formats","title":"Binary formats","text":"

    JSON text is not a compact format. If the data is only exchanged between programs (not read by humans), the binary formats \u2014 BJData, BON8, BSON, CBOR, MessagePack, and UBJSON \u2014 encode the same values more compactly, which reduces both the bytes transferred and, for most of them, the work needed to parse them back. The size comparison on that page, measured against minified JSON for four reference documents, shows the effect varies a lot by document shape: CBOR and MessagePack come out at 50.5% of the minified JSON size for the numeric-array-heavy canada.json, but only around 87-88% for the string-heavy jeopardy.json, where there is less numeric data to encode more compactly. BON8 is the most compact option in that comparison for text-heavy documents (63.5%-87.5%), at the cost of an incomplete serializer (no unsigned integers above int64). Which format \u2014 and whether it is worth the loss of human readability at all \u2014 depends on the actual data; see the comparison tables before choosing one.

    Size of canada.json in each binary format relative to minified J\u200bSON B\u200bJData 53.2 %; B\u200bON8 50.5 %; B\u200bSON 85.8 %; C\u200bBOR 50.5 %; MessagePack 50.5 %; U\u200bBJSON 53.2 %. Smallest: B\u200bON8 and C\u200bBOR and MessagePack. canada.json 0 % 50 % B\u200bJData canada.json, B\u200bJData: 53.2 % of minified J\u200bSON B\u200bON8 canada.json, B\u200bON8: 50.5 % of minified J\u200bSON (smallest) B\u200bSON canada.json, B\u200bSON: 85.8 % of minified J\u200bSON C\u200bBOR canada.json, C\u200bBOR: 50.5 % of minified J\u200bSON (smallest) MessagePack canada.json, MessagePack: 50.5 % of minified J\u200bSON (smallest) U\u200bBJSON canada.json, U\u200bBJSON: 53.2 % of minified J\u200bSON minified J\u200bSON = 100 % 100 % 53.2 % 50.5 % 85.8 % 50.5 % 50.5 % 53.2 %

    Size of jeopardy.json in each binary format relative to minified J\u200bSON B\u200bJData 96.6 %; B\u200bON8 87.5 %; B\u200bSON 106.7 %; C\u200bBOR 88 %; MessagePack 87.9 %; U\u200bBJSON 96.6 %. Smallest: B\u200bON8. jeopardy.json 0 % 50 % B\u200bJData jeopardy.json, B\u200bJData: 96.6 % of minified J\u200bSON B\u200bON8 jeopardy.json, B\u200bON8: 87.5 % of minified J\u200bSON (smallest) B\u200bSON jeopardy.json, B\u200bSON: 106.7 % of minified J\u200bSON C\u200bBOR jeopardy.json, C\u200bBOR: 88 % of minified J\u200bSON MessagePack jeopardy.json, MessagePack: 87.9 % of minified J\u200bSON U\u200bBJSON jeopardy.json, U\u200bBJSON: 96.6 % of minified J\u200bSON minified J\u200bSON = 100 % 100 % 96.6 % 87.5 % 106.7 % 88.0 % 87.9 % 96.6 %

    Two of the four panels from the size comparison; the smallest format per file is drawn in a stronger colour than the others.

    "},{"location":"features/performance/#object-type-json-vs-ordered_json","title":"Object type: json vs. ordered_json","text":"

    The default json type stores object keys in a std::map, giving logarithmic-time lookup, insertion, and erasure, at the cost of sorting keys alphabetically rather than preserving insertion order (see Object Order). ordered_json uses nlohmann::ordered_map instead, a std::vector-backed container with no lookup index: every key-based operation is a linear scan, so building an object of n distinct keys costs O(n\u00b2) in total \u2014 this applies equally to inserting keys one by one and to parsing an object, since the parser inserts each key as it is read. The measurements on the ordered_map page show this is negligible at typical object sizes (2000 keys: 0.7 ms for json vs. 3.6 ms for ordered_json, a 5x factor) but grows steeply for large, machine-generated objects (16 000 keys: 3.3 ms vs. 181.6 ms, a 54x factor).

    Time to parse a flat object of n keys, json against ordered_json, logarithmic axes 2000 keys: json 0.7 ms, ordered_json 3.6 ms (5x). 4000 keys: 0.8 ms and 14.0 ms (19x). 8000 keys: 1.6 ms and 67.8 ms (43x). 16000 keys: 3.3 ms and 181.6 ms (54x). 1 ms 10 ms 100 ms 2\u2009000 4\u2009000 8\u2009000 16\u2009000 json, 2000 keys: 0.7 ms json, 4000 keys: 0.8 ms json, 8000 keys: 1.6 ms json, 16000 keys: 3.3 ms json 3.3 ms 0.7 ms ordered_json, 2000 keys: 3.6 ms ordered_json, 4000 keys: 14 ms ordered_json, 8000 keys: 67.8 ms ordered_json, 16000 keys: 181.6 ms ordered_json 181.6 ms 3.6 ms

    Parsing a flat object of n keys, measured with -O2 -DNDEBUG; all four sizes from the table on the ordered_map page, both axes logarithmic.

    If insertion order matters and an object routinely has many thousands of keys, ordered_json's quadratic build cost may not be acceptable. The library's ObjectType template parameter can be set to a different container instead: nlohmann::fifo_map keeps insertion order with a real lookup index (avoiding the quadratic cost), while std::unordered_map, boost::unordered_flat_map, absl::flat_hash_map, and similar hash maps trade insertion order for average-case constant-time lookup (through an adapter, since their template argument order does not match what basic_json expects) \u2014 see Object Order for the full list.

    "},{"location":"features/performance/#avoiding-copies","title":"Avoiding copies","text":"
    • Move instead of copy. Constructing a basic_json from an existing one is linear in its size for the copy constructor but constant for the move constructor. The same applies to assigning a large std::string, std::vector, or other container into a value: pass it as std::move(x) rather than x whenever x is no longer needed afterwards. Since version 3.13.0 unreleased, converting an rvalue container (json j = std::move(vec);) moves the elements instead of copying them; the source is then left in a valid but unspecified state.
    • Access without copying. get<T>() returns a copy of the stored value converted to T. When a reference or pointer to the value already stored inside the basic_json is enough, get_ref() and get_ptr() access it directly: both pages state, word for word, \"No copies are made.\" \u2014 at the cost of that reference or pointer becoming invalid once the underlying value changes.
    • Iterate by reference. basic_json::iterator::operator*() returns a reference (an alias for basic_json&), but a range-based for loop with a by-value loop variable (for (auto el : j)) still copies each element, because plain auto drops the reference. Write for (const auto& el : j) (or auto& for a mutable loop), and use items() the same way when the key is needed too \u2014 its own examples use for (auto& el : j.items()).
    • Construct in place. emplace_back() (arrays, amortized constant time) and emplace() (objects, logarithmic in the size of the container for json) forward their arguments directly to a basic_json constructor, rather than requiring a temporary value to be constructed and then copied or moved in. push_back() has an rvalue overload (push_back(basic_json&&)) for a value that already exists: j.push_back(std::move(value)) moves it in instead of copying it.
    • Skip the bounds check when it is redundant. at() and operator[] have the same complexity (constant for a valid array index, logarithmic for an object key in json) \u2014 the difference is that at() additionally checks the key or index and throws if it is invalid, while operator[] does not (see unchecked access and checked access). Prefer operator[] when the surrounding code has already established that the access is valid.
    • Reserve array capacity. basic_json has no public reserve(), but when building a large array incrementally with a known final size, get_ref() exposes the underlying array_t so it can be reserved directly \u2014 see \"reserving array capacity\" for the one-line recipe.
    "},{"location":"features/performance/#memory","title":"Memory","text":"
    • A value is small, its content is on the heap. A basic_json is 16 bytes on a 64-bit platform (a type tag and a union). Strings, arrays, objects, and binary values are allocated on the heap and owned by the value. Destroying the value frees everything it owns.
    • Copies are deep. After json b = a;, changing b does not change a, and both own their memory. Copying a large value therefore doubles its memory; see Avoiding copies. auto x = j[\"key\"]; is a copy, auto& x = j[\"key\"]; is not.
    • A moved-from value is null. After json c = std::move(a); the value a is null and owns nothing.
    • Reading does not require a tree. If you only read the data, parse it into a json_document (<nlohmann/json_view.hpp>, added in version 3.13.0 unreleased) instead of a basic_json. It stores 16 bytes per value, does not copy floating-point numbers or strings without escape sequences out of the text, and creates no basic_json value except for the parts you materialize(). A document that borrows the text needs the text to outlive it; see Zero-copy JSON views.
    • Containers keep their capacity. clear() and erase() on an array remove the elements, but the underlying std::vector keeps its allocated capacity, like std::vector::clear does. To give the memory back, assign a new value (j = json::array();) or destroy the value.
    • Freed memory does not always go back to the operating system. The library returns memory to the allocator (std::allocator by default, or the one you configured). Whether the process size shrinks then depends on the allocator and the platform, as for any C++ program. A process that parses a large document and drops it is not leaking if its resident size stays high; run it under a tool such as Valgrind or the sanitizers to tell a leak from retained memory.
    "},{"location":"features/performance/#serialization","title":"Serialization","text":"

    dump() with the default indent = -1 selects \"the most compact representation\" (word for word from the page); any non-negative indent pretty-prints instead, which is more readable but produces more bytes and more work. dump() builds and returns a complete string_t containing the whole serialization. operator<< writes directly to a std::ostream instead, through the same serializer, but without ever materializing that intermediate string \u2014 so if the destination is a stream (a file, or std::cout), os << j; avoids the allocation and copy that os << j.dump(); would incur for large values.

    "},{"location":"features/performance/#diagnostics-overhead","title":"Diagnostics overhead","text":"

    Two opt-in macros add diagnostic information to exceptions and to every value, at a cost that is only worth paying while it is in use:

    • JSON_DIAGNOSTICS adds a JSON Pointer to exception messages, pointing at the value that triggered the exception. Quoting the page directly: \"enabling this macro increases the size of every JSON value by one pointer and adds some runtime overhead\" \u2014 every value gains a parent pointer that has to be kept up to date as the document is built and modified.
    • JSON_DIAGNOSTIC_POSITIONS adds start_pos() and end_pos(), the byte offsets a value occupied in its parsed input. Quoting the page: \"enabling this macro increases the size of every JSON value by two std::size_t fields and adds slight runtime overhead to parsing, copying JSON value objects, and the generation of error messages for exceptions.\"

    Both default to off. Enable them where better diagnostics are worth the overhead (for example, while validating untrusted input, or in a debug build), and keep them off in a release build that does not need them.

    "},{"location":"features/performance/#compile-time","title":"Compile time","text":"

    <nlohmann/json_fwd.hpp> forward-declares basic_json, json, ordered_json, json_pointer, and adl_serializer, pulling in only a handful of lightweight standard headers instead of the full json.hpp. A header that only needs to name nlohmann::json \u2014 in a function signature or a class member declaration, for instance \u2014 can include json_fwd.hpp and leave #include <nlohmann/json.hpp> to the source files that actually parse, build, or serialize values, the same way a project would forward-declare any other heavy class to keep it out of widely-included headers:

    // my_type.hpp\n#include <nlohmann/json_fwd.hpp>\n\nclass my_type\n{\n    nlohmann::json config() const;\n};\n\n// my_type.cpp\n#include <nlohmann/json.hpp>\n#include \"my_type.hpp\"\n\nnlohmann::json my_type::config() const { /* ... */ }\n

    One caveat: ABI-affecting macros such as JSON_DIAGNOSTICS and JSON_DIAGNOSTIC_POSITIONS are encoded into the library's inline namespace name. Every translation unit \u2014 whether it includes json_fwd.hpp or the full header \u2014 must define them the same way, or linking fails with undefined references instead of a compile error.

    If I/O support is not needed at all, JSON_NO_IO excludes <cstdio>, <ios>, <iosfwd>, <istream>, and <ostream> outright and drops the std::istream/FILE* parse overloads and operator<< that depend on them (dump() itself is unaffected, since it only returns a string); it exists for environments where those headers are unavailable (such as Intel SGX), and as a side effect those headers are then never processed by the compiler at all.

    "},{"location":"features/performance/#see-also","title":"See also","text":"
    • Design goals - why this library does not optimize for speed first
    • Architecture - how input adapters, the lexer, and the serializer fit together
    • Parsing - the available parsing functions and inputs
    • SAX interface - parse without building a DOM
    • Zero-copy JSON views - parse into a flat index of the text and read it without building a DOM
    • Binary formats - compact alternatives to JSON text
    • Object Order - json vs. ordered_json and other ObjectType choices
    • Template Parameter Requirements - custom container and allocator types
    • Supported macros - overview of all configuration macros, including the diagnostics ones above
    • JSON_NO_SIMD - disable SIMD acceleration
    • JSON_USE_SIMDUTF - use simdutf for UTF-8 validation
    • JSON_DISABLE_STREAM_BULK_SCAN - disable the stream bulk scan
    • parse - deserialize from a compatible input
    • sax_parse - parse with a SAX interface
    • json_view - a non-owning view of a value in a document
    "},{"location":"features/serialization/","title":"Serialization","text":"

    Serialization is the process of turning a JSON value back into JSON text. It is the counterpart to parsing. The central function is dump, which returns the JSON text as a string.

    json j = {{\"pi\", 3.141}, {\"happy\", true}};\n\nstd::string s = j.dump();   // {\"happy\":true,\"pi\":3.141}\n

    To write a value directly to a stream (for example, a file or std::cout), the operator<< is provided:

    std::cout << j << std::endl;\n

    String, not raw value

    dump always returns a JSON text. Serializing a JSON string therefore includes the surrounding quotes and escapes special characters. To obtain the contained string value without quotes, use get<std::string>() instead of dump. See the converting values page.

    "},{"location":"features/serialization/#pretty-printing","title":"Pretty-printing","text":"

    By default, dump produces the most compact representation without any superfluous whitespace. Passing a non-negative indent argument pretty-prints the output with the given number of spaces per level:

    Example: pretty-print JSON values with dump()
    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create JSON values\n    json j_object = {{\"one\", 1}, {\"two\", 2}};\n    json j_array = {1, 2, 4, 8, 16};\n    json j_string = \"Hell\u00f6 \ud83d\ude00!\";\n\n    // call dump()\n    std::cout << \"objects:\" << '\\n'\n              << j_object.dump() << \"\\n\\n\"\n              << j_object.dump(-1) << \"\\n\\n\"\n              << j_object.dump(0) << \"\\n\\n\"\n              << j_object.dump(4) << \"\\n\\n\"\n              << j_object.dump(1, '\\t') << \"\\n\\n\";\n\n    std::cout << \"arrays:\" << '\\n'\n              << j_array.dump() << \"\\n\\n\"\n              << j_array.dump(-1) << \"\\n\\n\"\n              << j_array.dump(0) << \"\\n\\n\"\n              << j_array.dump(4) << \"\\n\\n\"\n              << j_array.dump(1, '\\t') << \"\\n\\n\";\n\n    std::cout << \"strings:\" << '\\n'\n              << j_string.dump() << '\\n'\n              << j_string.dump(-1, ' ', true) << '\\n';\n\n    // create JSON value with invalid UTF-8 byte sequence\n    json j_invalid = \"\u00e4\\xA9\u00fc\";\n    try\n    {\n        std::cout << j_invalid.dump() << '\\n';\n    }\n    catch (const json::type_error& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n\n    std::cout << \"string with replaced invalid characters: \"\n              << j_invalid.dump(-1, ' ', false, json::error_handler_t::replace)\n              << \"\\nstring with ignored invalid characters: \"\n              << j_invalid.dump(-1, ' ', false, json::error_handler_t::ignore)\n              << '\\n';\n}\n

    Output:

    objects:\n{\"one\":1,\"two\":2}\n\n{\"one\":1,\"two\":2}\n\n{\n\"one\": 1,\n\"two\": 2\n}\n\n{\n    \"one\": 1,\n    \"two\": 2\n}\n\n{\n    \"one\": 1,\n    \"two\": 2\n}\n\narrays:\n[1,2,4,8,16]\n\n[1,2,4,8,16]\n\n[\n1,\n2,\n4,\n8,\n16\n]\n\n[\n    1,\n    2,\n    4,\n    8,\n    16\n]\n\n[\n    1,\n    2,\n    4,\n    8,\n    16\n]\n\nstrings:\n\"Hell\u00f6 \ud83d\ude00!\"\n\"Hell\\u00f6 \\ud83d\\ude00!\"\n[json.exception.type_error.316] invalid UTF-8 byte at index 2: 0xA9\nstring with replaced invalid characters: \"\u00e4\ufffd\u00fc\"\nstring with ignored invalid characters: \"\u00e4\u00fc\"\n

    The indentation character can be changed with the second argument (e.g., a tab '\\t'). An indent of 0 inserts newlines but no leading spaces, and the default of -1 selects the compact single-line form.

    "},{"location":"features/serialization/#non-ascii-characters","title":"Non-ASCII characters","text":"

    Strings are stored and serialized as UTF-8 (see types). By default, dump copies valid non-ASCII characters as-is. Setting the third argument ensure_ascii to true escapes all non-ASCII characters with \\uXXXX sequences, so that the output contains only ASCII characters:

    json j = \"\u82f9\u679c\";\nj.dump();               // \"\u82f9\u679c\"\nj.dump(-1, ' ', true);  // \"\\u82f9\\u679c\"\n
    "},{"location":"features/serialization/#handling-invalid-utf-8","title":"Handling invalid UTF-8","text":"

    If a string contains invalid UTF-8 sequences (for example, because it holds data in another encoding such as Latin-1), serialization fails by default. The fourth argument of dump selects an error_handler:

    • strict (default) \u2014 throw a type_error.316 exception.
    • replace \u2014 replace invalid bytes with the Unicode replacement character U+FFFD (\ufffd).
    • ignore \u2014 silently drop invalid bytes.
    • keep \u2014 copy invalid bytes to the output unchanged; the result is not valid UTF-8.
    Example: serialize invalid UTF-8 with different error handlers
    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create JSON value with invalid UTF-8 byte sequence\n    json j_invalid = \"\u00e4\\xA9\u00fc\";\n    try\n    {\n        std::cout << j_invalid.dump() << '\\n';\n    }\n    catch (const json::type_error& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n\n    std::cout << \"string with replaced invalid characters: \"\n              << j_invalid.dump(-1, ' ', false, json::error_handler_t::replace)\n              << \"\\nstring with ignored invalid characters: \"\n              << j_invalid.dump(-1, ' ', false, json::error_handler_t::ignore)\n              << \"\\nstring with the invalid byte kept as is (\" << j_invalid.dump(-1, ' ', false, json::error_handler_t::keep).size()\n              << \" bytes, not valid UTF-8 itself)\\n\";\n}\n

    Output:

    [json.exception.type_error.316] invalid UTF-8 byte at index 2: 0xA9\nstring with replaced invalid characters: \"\u00e4\ufffd\u00fc\"\nstring with ignored invalid characters: \"\u00e4\u00fc\"\nstring with the invalid byte kept as is (7 bytes, not valid UTF-8 itself)\n

    Avoiding invalid UTF-8

    The best fix is to ensure that all strings are UTF-8 encoded before storing them. See the FAQ on non-ASCII characters for how to convert wide or Latin-1 strings.

    "},{"location":"features/serialization/#numbers-nan-and-binary-values","title":"Numbers, NaN, and binary values","text":"
    • Numbers are serialized with enough precision to round-trip; see number serialization.
    • NaN and infinity cannot be represented in JSON and are serialized as null; see NaN handling. The binary formats can preserve them.
    • Binary values have no JSON representation and are serialized as a helper object for debugging only; see binary values.
    "},{"location":"features/serialization/#using-stdformat-stdprint-and-fmt","title":"Using std::format, std::print, and fmt","text":"

    Since version 3.12.0, JSON values can be formatted directly with C++20's std::format whenever the standard library provides the <format> header (controlled by JSON_HAS_STD_FORMAT). This is enabled by the std::formatter<basic_json> specialization, which also makes JSON values work with std::format_to and with C++23's std::print/std::println:

    std::print(\"{}\", j);      // compact, like j.dump()\nstd::print(\"{:2}\", j);    // pretty-printed with indent 2 (like j.dump(2))\nstd::println(\"{:#}\", j);  // pretty-printed with the default indent\n

    The format spec mirrors the dump parameters: \"{:#}\" pretty-prints, a width such as \"{:2}\" sets the indent, and a fill-and-align prefix such as \"{:.>#}\" sets the indent character.

    For the {fmt} library, the library ships a format_as helper. Note its behavior depends on the fmt version; see the FAQ entry for the details and a recipe for a full fmt::formatter specialization.

    "},{"location":"features/serialization/#serializing-to-other-formats","title":"Serializing to other formats","text":"

    Besides JSON text, a value can also be serialized to the more compact binary formats (BJData, BON8, BSON, CBOR, MessagePack, UBJSON).

    "},{"location":"features/serialization/#see-also","title":"See also","text":"
    • dump - serialize to a JSON-formatted string
    • operator<< - serialize to a stream
    • to_string - user-defined-conversion helper
    • std::formatter<basic_json> - use JSON values with std::format and std::print
    • format_as - use JSON values with the {fmt} library
    • Parsing - the reverse operation
    • error_handler_t - how to treat invalid UTF-8 when dumping
    • basic_json_view::dump - serialize a view directly
    • JSON_NO_IO - remove stream and file I/O
    • JSON_NO_SIMD - disable SIMD acceleration
    "},{"location":"features/trailing_commas/","title":"Trailing Commas","text":"

    Like comments, this library does not support trailing commas in arrays and objects by default.

    You can set parameter ignore_trailing_commas to true in the parse function to allow trailing commas in arrays and objects. Note that a single comma as the only content of the array or object ([,] or {,}) is not allowed, and multiple trailing commas ([1,,]) are not allowed either.

    This library does not add trailing commas when serializing JSON data.

    For more information, see JSON With Commas and Comments (JWCC).

    Example

    Consider the following JSON with trailing commas.

    {\n    \"planets\": [\n        \"Mercury\",\n        \"Venus\",\n        \"Earth\",\n        \"Mars\",\n        \"Jupiter\",\n        \"Uranus\",\n        \"Neptune\",\n    ]\n}\n

    When calling parse without additional argument, a parse error exception is thrown. If ignore_trailing_commas is set to true, the trailing commas are ignored during parsing:

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    std::string s = R\"(\n    {\n        \"planets\": [\n            \"Mercury\",\n            \"Venus\",\n            \"Earth\",\n            \"Mars\",\n            \"Jupiter\",\n            \"Uranus\",\n            \"Neptune\",\n        ]\n    }\n    )\";\n\n    try\n    {\n        json j = json::parse(s);\n    }\n    catch (json::exception& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n\n    json j = json::parse(s,\n                         /* callback */ nullptr,\n                         /* allow exceptions */ true,\n                         /* ignore_comments */ false,\n                         /* ignore_trailing_commas */ true);\n    std::cout << j.dump(2) << '\\n';\n}\n

    Output:

    [json.exception.parse_error.101] parse error at line 11, column 9: syntax error while parsing value - unexpected ']'; expected '[', '{', or a literal\n{\n  \"planets\": [\n    \"Mercury\",\n    \"Venus\",\n    \"Earth\",\n    \"Mars\",\n    \"Jupiter\",\n    \"Uranus\",\n    \"Neptune\"\n  ]\n}\n
    "},{"location":"features/trailing_commas/#see-also","title":"See also","text":"
    • parse - deserialize from a compatible input
    • Comments - ignore // and /* */ comments while parsing
    • Parsing - overview of the parsing functions
    • Parsing Untrusted Input - limits and checks for input you do not control
    "},{"location":"features/type_recipes/","title":"Recipes for Common Types","text":"

    The library converts the standard containers, strings, numbers, tuples, std::optional, and std::filesystem::path (the last two since version 3.12.0, C++17) out of the box, and your own types once you write conversion functions or use the macros (see Arbitrary type conversions). It deliberately does not convert smart pointers, std::variant, std::chrono types, or class hierarchies, because there is more than one reasonable JSON representation for each of them. This page shows a representation for each that you can copy and adapt.

    All recipes use a specialization of adl_serializer, which you may provide for types you do not own, or free to_json/from_json functions in the namespace of the type. Place them where they are visible before any code that converts the type; see Why isn't my to_json found?.

    "},{"location":"features/type_recipes/#smart-pointers","title":"Smart pointers","text":"

    A std::shared_ptr<T> or std::unique_ptr<T> is written as the value it points to, or as null for an empty pointer, and read back by allocating a new T:

    Example: serialize shared_ptr and unique_ptr
    #include <iostream>\n#include <memory>\n#include <vector>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nnamespace nlohmann\n{\ntemplate <typename T>\nstruct adl_serializer<std::shared_ptr<T>>\n{\n    static void to_json(json& j, const std::shared_ptr<T>& p)\n    {\n        if (p)\n        {\n            j = *p;\n        }\n        else\n        {\n            j = nullptr;\n        }\n    }\n\n    static void from_json(const json& j, std::shared_ptr<T>& p)\n    {\n        if (j.is_null())\n        {\n            p = nullptr;\n        }\n        else\n        {\n            p = std::make_shared<T>(j.get<typename std::remove_const<T>::type>());\n        }\n    }\n};\n\ntemplate <typename T>\nstruct adl_serializer<std::unique_ptr<T>>\n{\n    static void to_json(json& j, const std::unique_ptr<T>& p)\n    {\n        if (p)\n        {\n            j = *p;\n        }\n        else\n        {\n            j = nullptr;\n        }\n    }\n\n    static void from_json(const json& j, std::unique_ptr<T>& p)\n    {\n        if (j.is_null())\n        {\n            p = nullptr;\n        }\n        else\n        {\n            p = std::make_unique<T>(j.get<T>());\n        }\n    }\n};\n} // namespace nlohmann\n\nstruct point\n{\n    int x;\n    int y;\n};\n\nNLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(point, x, y)\n\nint main()\n{\n    // an empty pointer is written as null\n    const std::vector<std::shared_ptr<point>> points = {std::make_shared<point>(point{1, 2}), nullptr};\n    const json j = points;\n    std::cout << j << '\\n';\n\n    // reading allocates new objects\n    const auto back = j.get<std::vector<std::shared_ptr<point>>>();\n    std::cout << back[0]->x << \", \" << back[0]->y << \", \" << (back[1] == nullptr) << '\\n';\n\n    // pointers to const and unique_ptr work as well\n    const auto const_ptr = j[0].get<std::shared_ptr<const point>>();\n    const auto unique = j[0].get<std::unique_ptr<point>>();\n    std::cout << const_ptr->y << \", \" << unique->x << '\\n';\n}\n

    Output:

    [{\"x\":1,\"y\":2},null]\n1, 2, 1\n2, 1\n

    With this, containers of smart pointers, pointers to const, and members of these types in your own structs convert as usual. A pointer to a base class cannot be filled this way, because T would have to be created as a derived type; see the next section.

    Reading creates a new object. Two shared_ptrs that pointed to the same object are written twice and read back as two separate objects.

    "},{"location":"features/type_recipes/#class-hierarchies","title":"Class hierarchies","text":"

    Derived classes whose type is known at compile time

    If you only need to serialize the data members of a derived class, and the code always knows the concrete type, you do not need a type tag. The NLOHMANN_DEFINE_DERIVED_TYPE_* macros (since version 3.12.0) add the members of the derived class to those of its base class. This section is for the case where the concrete type is only known at run time, such as a std::unique_ptr<shape> that holds a circle or a rectangle.

    JSON has no notion of types, so a value in a hierarchy needs a type tag that says which derived class to create. Write the tag in the object, and select the class from it when reading:

    Example: serialize a class hierarchy with a type tag
    #include <iostream>\n#include <memory>\n#include <stdexcept>\n#include <vector>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nstruct shape\n{\n    virtual ~shape() = default;\n    virtual json serialize() const = 0;\n};\n\nstruct circle : shape\n{\n    double radius;\n\n    explicit circle(double r) : radius(r) {}\n\n    json serialize() const override\n    {\n        return {{\"type\", \"circle\"}, {\"radius\", radius}};\n    }\n};\n\nstruct rectangle : shape\n{\n    double width;\n    double height;\n\n    rectangle(double w, double h) : width(w), height(h) {}\n\n    json serialize() const override\n    {\n        return {{\"type\", \"rectangle\"}, {\"width\", width}, {\"height\", height}};\n    }\n};\n\nnamespace nlohmann\n{\ntemplate <>\nstruct adl_serializer<std::unique_ptr<shape>>\n{\n    static void to_json(json& j, const std::unique_ptr<shape>& p)\n    {\n        j = p ? p->serialize() : json(nullptr);\n    }\n\n    static void from_json(const json& j, std::unique_ptr<shape>& p)\n    {\n        if (j.is_null())\n        {\n            p.reset();\n            return;\n        }\n\n        const auto& type = j.at(\"type\").get_ref<const std::string&>();\n        if (type == \"circle\")\n        {\n            p = std::make_unique<circle>(j.at(\"radius\").get<double>());\n        }\n        else if (type == \"rectangle\")\n        {\n            p = std::make_unique<rectangle>(j.at(\"width\").get<double>(), j.at(\"height\").get<double>());\n        }\n        else\n        {\n            throw std::invalid_argument(\"unknown shape type: \" + type);\n        }\n    }\n};\n} // namespace nlohmann\n\nint main()\n{\n    std::vector<std::unique_ptr<shape>> shapes;\n    shapes.push_back(std::make_unique<circle>(1.5));\n    shapes.push_back(std::make_unique<rectangle>(2, 3));\n\n    const json j = shapes;\n    std::cout << j << '\\n';\n\n    // reading creates objects of the derived types\n    const auto back = j.get<std::vector<std::unique_ptr<shape>>>();\n    std::cout << std::boolalpha;\n    std::cout << \"first is a circle: \" << (dynamic_cast<circle*>(back[0].get()) != nullptr) << '\\n';\n    std::cout << \"second is a rectangle: \" << (dynamic_cast<rectangle*>(back[1].get()) != nullptr) << '\\n';\n\n    // an unknown type tag is reported\n    try\n    {\n        json{{\"type\", \"star\"}}.get<std::unique_ptr<shape>>();\n    }\n    catch (const std::invalid_argument& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n}\n

    Output:

    [{\"radius\":1.5,\"type\":\"circle\"},{\"height\":3.0,\"type\":\"rectangle\",\"width\":2.0}]\nfirst is a circle: true\nsecond is a rectangle: true\nunknown shape type: star\n

    A std::vector<std::unique_ptr<shape>> converts to an array of tagged objects and back, creating a circle and a rectangle. The same works for std::shared_ptr<shape>. Remember the virtual destructor: without it, deleting a derived object through the base pointer is undefined behavior.

    "},{"location":"features/type_recipes/#stdvariant","title":"std::variant","text":"

    A variant has the same problem: the alternative must be recorded. If the alternatives are your own types, write a type tag next to their members, exactly as for a hierarchy:

    Example: serialize a std::variant with a type tag
    #include <iostream>\n#include <stdexcept>\n#include <variant>\n#include <vector>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nnamespace geo\n{\nstruct circ\n{\n    double radius;\n};\n\nstruct rect\n{\n    double width;\n    double height;\n};\n\nNLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(circ, radius)\nNLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(rect, width, height)\n\nusing figure = std::variant<circ, rect>;\n\nvoid to_json(json& j, const figure& f)\n{\n    std::visit([&j](const auto & alternative)\n    {\n        j = alternative;\n    }, f);\n    j[\"type\"] = std::holds_alternative<circ>(f) ? \"circ\" : \"rect\";\n}\n\nvoid from_json(const json& j, figure& f)\n{\n    const auto& type = j.at(\"type\").get_ref<const std::string&>();\n    if (type == \"circ\")\n    {\n        f = j.get<circ>();\n    }\n    else if (type == \"rect\")\n    {\n        f = j.get<rect>();\n    }\n    else\n    {\n        throw std::invalid_argument(\"unknown figure type: \" + type);\n    }\n}\n} // namespace geo\n\nint main()\n{\n    const std::vector<geo::figure> figures = {geo::circ{2}, geo::rect{3, 4}};\n\n    const json j = figures;\n    std::cout << j << '\\n';\n\n    const auto back = j.get<std::vector<geo::figure>>();\n    std::cout << \"alternatives read back: \" << back[0].index() << \", \" << back[1].index() << '\\n';\n}\n

    Output:

    [{\"radius\":2.0,\"type\":\"circ\"},{\"height\":4.0,\"type\":\"rect\",\"width\":3.0}]\nalternatives read back: 0, 1\n

    In the example, the functions are found because geo is the namespace of the template arguments of std::variant<circ, rect>; for a variant of only standard types (for example std::variant<int, std::string>) there is no such namespace, and you need an adl_serializer specialization or a wrapper type of your own.

    If the alternatives are JSON-native (numbers, strings, ...), a variant such as std::variant<int, std::string> can instead be written as the plain value, and read by testing the JSON type (is_number_integer(), is_string()) to choose the alternative.

    "},{"location":"features/type_recipes/#stdchrono","title":"std::chrono","text":"

    A duration is written as an object with the keys unit and value, for example {\"unit\": \"ms\", \"value\": 1500}, so the JSON value is self-describing. The serializer names the unit of the period (ns, us, ms, s, min, h; extend the list for other periods), and the deserializer rejects a value whose unit differs from the requested duration type instead of silently misreading it:

    Example: serialize durations and system_clock time points
    #include <chrono>\n#include <iostream>\n#include <stdexcept>\n#include <string>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\n// the name of a period; extend the list for the periods you use\ntemplate <typename Period> const char* unit_name();\ntemplate <> const char* unit_name<std::nano>()\n{\n    return \"ns\";\n}\ntemplate <> const char* unit_name<std::micro>()\n{\n    return \"us\";\n}\ntemplate <> const char* unit_name<std::milli>()\n{\n    return \"ms\";\n}\ntemplate <> const char* unit_name<std::ratio<1>>()\n{\n    return \"s\";\n}\ntemplate <> const char* unit_name<std::ratio<60>>()\n{\n    return \"min\";\n}\ntemplate <> const char* unit_name<std::ratio<3600>>()\n{\n    return \"h\";\n}\n\nnamespace nlohmann\n{\ntemplate <typename Rep, typename Period>\nstruct adl_serializer<std::chrono::duration<Rep, Period>>\n{\n    static void to_json(json& j, const std::chrono::duration<Rep, Period>& d)\n    {\n        j = {{\"unit\", unit_name<Period>()}, {\"value\", d.count()}};\n    }\n\n    static void from_json(const json& j, std::chrono::duration<Rep, Period>& d)\n    {\n        if (j.at(\"unit\").get<std::string>() != unit_name<Period>())\n        {\n            throw std::invalid_argument(\"unexpected unit \" + j.at(\"unit\").dump());\n        }\n        d = std::chrono::duration<Rep, Period>(j.at(\"value\").get<Rep>());\n    }\n};\n\ntemplate <typename Duration>\nstruct adl_serializer<std::chrono::time_point<std::chrono::system_clock, Duration>>\n{\n    static void to_json(json& j, const std::chrono::time_point<std::chrono::system_clock, Duration>& t)\n    {\n        j = t.time_since_epoch();\n    }\n\n    static void from_json(const json& j, std::chrono::time_point<std::chrono::system_clock, Duration>& t)\n    {\n        t = std::chrono::time_point<std::chrono::system_clock, Duration>(j.get<Duration>());\n    }\n};\n} // namespace nlohmann\n\nint main()\n{\n    using namespace std::chrono;\n\n    std::cout << std::boolalpha;\n\n    // the unit is part of the JSON value\n    const json timeout = milliseconds(1500);\n    std::cout << \"duration: \" << timeout << '\\n';\n    std::cout << \"as milliseconds: \" << timeout.get<milliseconds>().count() << '\\n';\n\n    // reading with a different unit is rejected\n    try\n    {\n        timeout.get<seconds>();\n    }\n    catch (const std::invalid_argument& e)\n    {\n        std::cout << \"error: \" << e.what() << '\\n';\n    }\n\n    // a system_clock time point is the time since the Unix epoch\n    const time_point<system_clock, milliseconds> t(milliseconds(1700000000123));\n    const json stamp = t;\n    std::cout << \"time point: \" << stamp << '\\n';\n\n    const auto back = stamp.get<time_point<system_clock, milliseconds>>();\n    std::cout << \"round trip: \" << (back == t) << '\\n';\n}\n

    Output:

    duration: {\"unit\":\"ms\",\"value\":1500}\nas milliseconds: 1500\nerror: unexpected unit \"ms\"\ntime point: {\"unit\":\"ms\",\"value\":1700000000123}\nround trip: true\n

    A system_clock::time_point with millisecond precision is written as the duration since the Unix epoch, that is, as an object with unit and value. The time point serializer is limited to system_clock, because the epoch of other clocks (for example steady_clock) has no meaning outside the running program.

    If you prefer a text representation such as ISO 8601 (2023-11-14T22:13:20Z), write the string with std::format(\"{:%FT%TZ}\", t) and read it with std::chrono::parse (both C++20), or with a date library, in the same two functions.

    "},{"location":"features/type_recipes/#see-also","title":"See also","text":"
    • Arbitrary type conversions - the conversion mechanism and macros
    • Why isn't my to_json found? - troubleshoot conversion functions that are not picked up
    • Converting values - get, implicit conversions, and std::optional
    • NLOHMANN_DEFINE_DERIVED_TYPE - conversion functions for derived classes
    • adl_serializer - customize conversions for third-party types
    • get - convert a JSON value to a C++ type
    "},{"location":"features/binary_formats/","title":"Binary Formats","text":"

    Though JSON is a ubiquitous data format, it is not a very compact format suitable for data exchange, for instance, over a network. Hence, the library supports

    • BJData (Binary JData),
    • BON8 (Binary Object Notation 8),
    • BSON (Binary JSON),
    • CBOR (Concise Binary Object Representation),
    • MessagePack, and
    • UBJSON (Universal Binary JSON)

    to efficiently encode JSON values to byte vectors and to decode such vectors.

    "},{"location":"features/binary_formats/#comparison","title":"Comparison","text":""},{"location":"features/binary_formats/#completeness","title":"Completeness","text":"Format Serialization Deserialization BJData complete incomplete: no column-major ND-arrays, no Draft 4 SoA/extension types BON8 incomplete: no unsigned integers above int64 complete BSON incomplete: top-level value must be an object incomplete, but all JSON types are supported CBOR complete incomplete, but all JSON types are supported MessagePack complete incomplete, but all JSON types are supported UBJSON complete complete"},{"location":"features/binary_formats/#binary-values","title":"Binary values","text":"Format Binary values Binary subtypes BJData supported (Draft 3 only) not supported BON8 not supported not supported BSON supported supported CBOR supported supported MessagePack supported supported UBJSON not supported not supported

    See binary values for more information.

    "},{"location":"features/binary_formats/#sizes","title":"Sizes","text":"Format canada.json twitter.json citm_catalog.json jeopardy.json BJData 53.2 % 91.1 % 78.1 % 96.6 % BJData (size) 58.6 % 92.1 % 86.7 % 97.4 % BJData (size+type) 58.6 % 92.1 % 86.5 % 97.4 % BON8 50.5 % 83.8 % 63.5 % 87.5 % BSON 85.8 % 95.2 % 95.8 % 106.7 % CBOR 50.5 % 86.3 % 68.4 % 88.0 % MessagePack 50.5 % 86.0 % 68.5 % 87.9 % UBJSON 53.2 % 91.3 % 78.2 % 96.6 % UBJSON (size) 58.6 % 92.3 % 86.8 % 97.4 % UBJSON (size+type) 55.9 % 92.3 % 85.0 % 95.0 %

    Size of each test file in each format, in percent of the minified JSON value; the smallest size per file is printed in bold. The (size) and (size+type) rows are written with the use_size and use_type options of to_bjdata and to_ubjson.

    Size of canada.json in each binary format relative to minified J\u200bSON B\u200bJData 53.2 %; B\u200bON8 50.5 %; B\u200bSON 85.8 %; C\u200bBOR 50.5 %; MessagePack 50.5 %; U\u200bBJSON 53.2 %. Smallest: B\u200bON8 and C\u200bBOR and MessagePack. canada.json 0 % 50 % B\u200bJData canada.json, B\u200bJData: 53.2 % of minified J\u200bSON B\u200bON8 canada.json, B\u200bON8: 50.5 % of minified J\u200bSON (smallest) B\u200bSON canada.json, B\u200bSON: 85.8 % of minified J\u200bSON C\u200bBOR canada.json, C\u200bBOR: 50.5 % of minified J\u200bSON (smallest) MessagePack canada.json, MessagePack: 50.5 % of minified J\u200bSON (smallest) U\u200bBJSON canada.json, U\u200bBJSON: 53.2 % of minified J\u200bSON minified J\u200bSON = 100 % 100 % 53.2 % 50.5 % 85.8 % 50.5 % 50.5 % 53.2 %

    Size of twitter.json in each binary format relative to minified J\u200bSON B\u200bJData 91.1 %; B\u200bON8 83.8 %; B\u200bSON 95.2 %; C\u200bBOR 86.3 %; MessagePack 86 %; U\u200bBJSON 91.3 %. Smallest: B\u200bON8. twitter.json 0 % 50 % B\u200bJData twitter.json, B\u200bJData: 91.1 % of minified J\u200bSON B\u200bON8 twitter.json, B\u200bON8: 83.8 % of minified J\u200bSON (smallest) B\u200bSON twitter.json, B\u200bSON: 95.2 % of minified J\u200bSON C\u200bBOR twitter.json, C\u200bBOR: 86.3 % of minified J\u200bSON MessagePack twitter.json, MessagePack: 86 % of minified J\u200bSON U\u200bBJSON twitter.json, U\u200bBJSON: 91.3 % of minified J\u200bSON minified J\u200bSON = 100 % 100 % 91.1 % 83.8 % 95.2 % 86.3 % 86.0 % 91.3 %

    Size of citm_catalog.json in each binary format relative to minified J\u200bSON B\u200bJData 78.1 %; B\u200bON8 63.5 %; B\u200bSON 95.8 %; C\u200bBOR 68.4 %; MessagePack 68.5 %; U\u200bBJSON 78.2 %. Smallest: B\u200bON8. citm_catalog.json 0 % 50 % B\u200bJData citm_catalog.json, B\u200bJData: 78.1 % of minified J\u200bSON B\u200bON8 citm_catalog.json, B\u200bON8: 63.5 % of minified J\u200bSON (smallest) B\u200bSON citm_catalog.json, B\u200bSON: 95.8 % of minified J\u200bSON C\u200bBOR citm_catalog.json, C\u200bBOR: 68.4 % of minified J\u200bSON MessagePack citm_catalog.json, MessagePack: 68.5 % of minified J\u200bSON U\u200bBJSON citm_catalog.json, U\u200bBJSON: 78.2 % of minified J\u200bSON minified J\u200bSON = 100 % 100 % 78.1 % 63.5 % 95.8 % 68.4 % 68.5 % 78.2 %

    Size of jeopardy.json in each binary format relative to minified J\u200bSON B\u200bJData 96.6 %; B\u200bON8 87.5 %; B\u200bSON 106.7 %; C\u200bBOR 88 %; MessagePack 87.9 %; U\u200bBJSON 96.6 %. Smallest: B\u200bON8. jeopardy.json 0 % 50 % B\u200bJData jeopardy.json, B\u200bJData: 96.6 % of minified J\u200bSON B\u200bON8 jeopardy.json, B\u200bON8: 87.5 % of minified J\u200bSON (smallest) B\u200bSON jeopardy.json, B\u200bSON: 106.7 % of minified J\u200bSON C\u200bBOR jeopardy.json, C\u200bBOR: 88 % of minified J\u200bSON MessagePack jeopardy.json, MessagePack: 87.9 % of minified J\u200bSON U\u200bBJSON jeopardy.json, U\u200bBJSON: 96.6 % of minified J\u200bSON minified J\u200bSON = 100 % 100 % 96.6 % 87.5 % 106.7 % 88.0 % 87.9 % 96.6 %

    The table above as charts: size per base format relative to minified JSON (vertical line at 100 %); the smallest format per file is drawn in a stronger colour than the others. The size and size+type variants of BJData and UBJSON are omitted here; see the table.

    "},{"location":"features/binary_formats/#see-also","title":"See also","text":"
    • cbor_tag_handler_t - how CBOR tags are handled when parsing
    • JSON_STRICT_BINARY_UTF8 - reject ill-formed UTF-8 in strings
    • Binary values - binary values and subtypes
    • to_cbor - / from_cbor, to_msgpack / from_msgpack, to_bson / from_bson, to_ubjson / from_ubjson, to_bjdata / from_bjdata, to_bon8 / from_bon8 - the conversion functions
    • Parsing untrusted input - harden an application that parses untrusted binary data
    • SAX interface - decode binary formats without building a value
    "},{"location":"features/binary_formats/bjdata/","title":"BJData","text":"

    The BJData format was derived from and improved upon Universal Binary JSON(UBJSON) specification (Draft 12). Specifically, it introduces an optimized array container for efficient storage of N-dimensional packed arrays (ND-arrays); it also adds four new type markers - [u] - uint16, [m] - uint32, [M] - uint64, and [h] - float16 - to unambiguously map common binary numeric types (Draft 3 adds [B] - byte); furthermore, it uses little-endian (LE) to store all numerics instead of big-endian (BE) as in UBJSON to avoid unnecessary conversions on commonly available platforms.

    Compared to other binary JSON-like formats such as MessagePack and CBOR, both BJData and UBJSON demonstrate a rare combination of being both binary and quasi-human-readable. This is because all semantic elements in BJData and UBJSON, including the data-type markers and name/string types, are directly human-readable. Data stored in the BJData/UBJSON format is not only compact in size, fast to read/write, but also can be directly searched or read using simple processing.

    References

    • BJData Specification (Draft 3)
    • BJData Specification (Draft 2)

    Supported drafts

    The library supports BJData Draft 2 (the default) and Draft 3, except for column-major N-dimensional arrays (see below). The draft used for writing is selected with the version parameter of to_bjdata; from_bjdata has no such parameter and reads the markers of both drafts.

    Draft 4 and column-major ND-arrays are not supported

    BJData Draft 4 (April 2026) adds structure-of-arrays (SoA) containers ([$ or {$ followed by a schema object) and the extension type E. from_bjdata does not implement them and throws parse_error.112 for such input; to_bjdata never writes them.

    Likewise, column-major ND-arrays of Draft 3 (the # marker followed by an array that wraps the dimension vector) are rejected with parse_error.113.

    "},{"location":"features/binary_formats/bjdata/#byte-layout","title":"Byte layout","text":"

    BJData follows the structure of UBJSON: a one-byte, human-readable ASCII type marker followed by the payload of that type, with strings prefixed by a length that is itself an integer value. In contrast to UBJSON, numbers are stored in little-endian byte order, and additional markers cover unsigned 16/32/64-bit integers, half-precision floats, and bytes. Containers can be written unoptimized (opened with [ or {, closed with ] or }) or optimized with a count (#), optionally preceded by a declared element type ($). BJData extends the optimized form: the count can be a list of dimensions, which stores an N-dimensional packed array as a flat sequence of values without any per-element markers.

    Consider the following JSON value (shown formatted for readability):

    {\n  \"id\": 300,\n  \"name\": \"json\",\n  \"pi\": 3.14,\n  \"tags\": [\n    \"a\",\n    \"b\"\n  ]\n}\n

    to_bjdata encodes it to 51 bytes (shown in hexadecimal; the encoding contains no whitespace). The colors mark the role of each byte: type/marker length/count/size data.

    JSONBytesMeaning {7Bobject start ({) \"id\": 300,69 02 69 64 49 2C 01key: length 2 as int8 (i), then UTF-8 bytes; value: int16 (I), little-endian \"name\": \"json\",69 04 6E 61 6D 65 53 69 04 6A 73 6F 6Ekey: length 4; value: string (S), length 4 as int8, UTF-8 bytes \"pi\": 3.14,69 02 70 69 44 1F 85 EB 51 B8 1E 09 40key: length 2; value: float64 (D), little-endian \"tags\": [69 04 74 61 67 73 5Bkey: length 4; value: array start ([) \"a\",53 69 01 61string, length 1 \"b\"53 69 01 62string, length 1 ]5Darray end (]) }7Dobject end (})"},{"location":"features/binary_formats/bjdata/#serialization","title":"Serialization","text":"

    The library uses the following mapping from JSON values types to BJData types according to the BJData specification:

    JSON value type value/range BJData type marker null null null Z boolean true true T boolean false false F number_integer -9223372036854775808..-2147483649 int64 L number_integer -2147483648..-32769 int32 l number_integer -32768..-129 int16 I number_integer -128..127 int8 i number_integer 128..255 uint8 U number_integer 256..32767 int16 I number_integer 32768..65535 uint16 u number_integer 65536..2147483647 int32 l number_integer 2147483648..4294967295 uint32 m number_integer 4294967296..9223372036854775807 int64 L number_integer 9223372036854775808..18446744073709551615 uint64 M number_unsigned 0..127 int8 i number_unsigned 128..255 uint8 U number_unsigned 256..32767 int16 I number_unsigned 32768..65535 uint16 u number_unsigned 65536..2147483647 int32 l number_unsigned 2147483648..4294967295 uint32 m number_unsigned 4294967296..9223372036854775807 int64 L number_unsigned 9223372036854775808..18446744073709551615 uint64 M number_float any value float64 D string with shortest length indicator string S array see notes on optimized format/ND-array array [ object see notes on optimized format map { binary see notes on binary values array [$B (Draft 3 with use_size and use_type), [U, or [B otherwise

    Complete mapping

    The mapping is complete in the sense that any JSON value type can be converted to a BJData value.

    Any BJData output created by to_bjdata can be successfully parsed by from_bjdata.

    Size constraints

    The following values can not be converted to a BJData value:

    • strings with more than 18446744073709551615 bytes, i.e., 264-1 bytes (theoretical)

    UTF-8 validation of string values and object keys

    BJData strings must use UTF-8 encoding. By default (the error_handler parameter left at keep), to_bjdata() writes the bytes of string values and object keys unchanged, even if they are not valid UTF-8. With error_handler_t::strict, it throws type_error.316 for ill-formed UTF-8 instead; replace/ignore sanitize the string. JSON_STRICT_BINARY_UTF8 makes strict the default.

    Unused BJData markers

    The following markers are not written:

    • N: no-op values are not created (they are skipped when reading).
    • C: single-character strings are serialized with S markers (C is read, and written for the elements of ND-arrays with \"_ArrayType_\": \"char\").
    • h: floating-point numbers are written as D, not as float16 (h is read).
    • B: only written in Draft 3 mode.
    • d is only written for single ND-arrays or if number_float_t is float; H is only written for integers wider than 64 bits (custom number_integer_t/number_unsigned_t). An unsigned integer above 9223372036854775807 is written as M.

    NaN/infinity handling

    If NaN or Infinity are stored inside a JSON number, they are serialized properly. This behavior differs from the dump() function which serializes NaN or Infinity to null.

    Endianness

    A breaking difference between BJData and UBJSON is the endianness of numerical values. In BJData, all numerical data types (integers UiuImlML and floating-point values hdD) are stored in the little-endian (LE) byte order as opposed to big-endian as used by UBJSON. Adopting LE to store numeric records avoids unnecessary byte swapping on most modern computers where LE is used as the default byte order.

    Optimized formats

    Optimized formats for containers are supported via two parameters of to_bjdata:

    • Parameter use_size adds size information to the beginning of a container and removes the closing marker.
    • Parameter use_type further checks whether all elements of a container have the same type and adds the type marker to the beginning of the container. The use_type parameter must only be used together with use_size = true.

    Note that use_size = true alone may result in larger representations - the benefit of this parameter is that the receiving side is immediately informed of the number of elements in the container.

    ND-array optimized format

    BJData extends UBJSON's optimized array size marker to support ND-arrays of uniform numerical data types (referred to as packed arrays). For example, the 2-D uint8 integer array [[1,2],[3,4],[5,6]], stored as nested optimized array in UBJSON [ [$U#i2 1 2 [$U#i2 3 4 [$U#i2 5 6 ], can be further compressed in BJData to [$U#[$i#i2 3 2 1 2 3 4 5 6 or [$U#[i3 i2] 1 2 3 4 5 6.

    To maintain type and size information, ND-arrays are converted to JSON objects following the annotated array format (defined in the JData specification (Draft 3)), when parsed using from_bjdata. For example, the above 2-D uint8 array can be parsed and accessed as

    {\n    \"_ArrayType_\": \"uint8\",\n    \"_ArraySize_\": [3,2],\n    \"_ArrayData_\": [1,2,3,4,5,6]\n}\n

    ND-arrays with the element type h (float16) are returned with \"_ArrayType_\": \"half\". to_bjdata does not pack \"half\" objects; they are written as regular objects, which read back as an equal value.

    Likewise, when a JSON object in the above form is serialized using to_bjdata, it is automatically converted into a compact BJData ND-array.

    When parsing, an ND-array whose dimension vector is empty, contains a single integer, contains two integers with the first being 1, or contains a 0 is returned as a regular (possibly empty) array rather than an annotated object.

    An object is only converted if the annotation describes a packed array that is parsed back into the same annotated object; otherwise it is serialized as a regular JSON object, so the annotation is never lost in a round trip. This requires all of the following:

    • the object has exactly the three keys \"_ArrayType_\", \"_ArraySize_\", and \"_ArrayData_\" (any other key, e.g., \"_ArrayOrder_\", makes it a regular object),
    • \"_ArrayType_\" is one of uint8, int8, uint16, int16, uint32, int32, uint64, int64, single, double, char, or (only with version = bjdata_version_t::draft3, since the B marker is not part of Draft 2) byte; the names are case-sensitive,
    • \"_ArraySize_\" is an array, since the dimensions are written as the ND-array header's length,
    • \"_ArraySize_\" has at least two entries and is not a two-entry row vector ([1,N]), since other shapes are parsed back as a regular array ([1,2,2] is packed, [1,4] is not),
    • every entry of \"_ArraySize_\" is a positive integer, and their product is representable as a std::size_t,
    • \"_ArrayData_\" is an array holding exactly that many elements, and
    • every element of \"_ArrayData_\" is a number of the kind named by \"_ArrayType_\": for the integer types, an integer (a floating-point number such as 1.0 does not qualify) that fits the named width (for char, 0..127); for double, a floating-point number (an integer such as 1 does not qualify); for single, a floating-point number that survives narrowing to float and back without change (for instance, 0.1 does not, since it is not exactly representable as float).

    With ordered_json, an annotated object read from BJData has its keys in the order \"_ArrayType_\", \"_ArraySize_\", \"_ArrayData_\"; with json, they are sorted like those of any other object.

    The current version of this library does not yet support automatic detection of and conversion from a nested JSON array input to a BJData ND-array.

    Restrictions in optimized data types for arrays and objects

    Due to diminished space saving, hampered readability, and increased security risks, in BJData, the allowed data types following the $ marker in an optimized array and object container are restricted to non-zero-fixed-length data types. Therefore, the valid optimized type markers can only be one of UiuImlMLhdDC, plus B since Draft 3 (the reader accepts B in both drafts). This also means other variable ([{SH) or zero-length types (TFZN) can not be used in an optimized array or object in BJData. The library enforces this restriction for both drafts. A C (char) element above 127 is rejected on read with parse_error.113, in 1-D and in N-dimensional arrays. With use_type, the elements must have the same marker ([1,200,3] is not optimized, since it mixes i and U); booleans, null, strings, arrays, and objects are never optimized with $.

    Binary values

    BJData provides a dedicated B marker (defined in the BJData specification (Draft 3)) that is used in optimized arrays to designate binary data. This means that, unlike UBJSON, binary data can be both serialized and deserialized.

    To preserve compatibility with BJData Draft 2, the Draft 3 optimized binary array must be explicitly enabled: pass version = bjdata_version_t::draft3 together with use_size = true and use_type = true to to_bjdata. With Draft 3 and only use_size (or neither), a binary value is written as an array of B elements.

    In Draft 2 mode (default), if the JSON data contains the binary type, the value is stored as a list of integers, as suggested by the BJData documentation. In particular, this means that the serialization and the deserialization of JSON containing binary values into BJData and back will result in a different JSON object.

    Example: serialize JSON values to BJData, with and without size/type optimization
    #include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\nusing namespace nlohmann::literals;\n\n// function to print BJData's diagnostic format\nvoid print_byte(uint8_t byte)\n{\n    if (32 < byte and byte < 128)\n    {\n        std::cout << static_cast<char>(byte);\n    }\n    else\n    {\n        std::cout << static_cast<int>(byte);\n    }\n}\n\nint main()\n{\n    // create a JSON value\n    json j = R\"({\"compact\": true, \"schema\": false})\"_json;\n\n    // serialize it to BJData\n    std::vector<std::uint8_t> v = json::to_bjdata(j);\n\n    // print the vector content\n    for (auto& byte : v)\n    {\n        print_byte(byte);\n    }\n    std::cout << '\\n';\n\n    // create an array of numbers\n    json array = {1, 2, 3, 4, 5, 6, 7, 8};\n\n    // serialize it to BJData using default representation\n    std::vector<std::uint8_t> v_array = json::to_bjdata(array);\n    // serialize it to BJData using size optimization\n    std::vector<std::uint8_t> v_array_size = json::to_bjdata(array, true);\n    // serialize it to BJData using type optimization\n    std::vector<std::uint8_t> v_array_size_and_type = json::to_bjdata(array, true, true);\n\n    // print the vector contents\n    for (auto& byte : v_array)\n    {\n        print_byte(byte);\n    }\n    std::cout << '\\n';\n\n    for (auto& byte : v_array_size)\n    {\n        print_byte(byte);\n    }\n    std::cout << '\\n';\n\n    for (auto& byte : v_array_size_and_type)\n    {\n        print_byte(byte);\n    }\n    std::cout << '\\n';\n}\n

    Output:

    {i7compactTi6schemaF}\n[i1i2i3i4i5i6i7i8]\n[#i8i1i2i3i4i5i6i7i8\n[$i#i812345678\n
    "},{"location":"features/binary_formats/bjdata/#deserialization","title":"Deserialization","text":"

    The library maps BJData types to JSON value types as follows:

    BJData type JSON value type marker no-op no value, next value is read N null null Z false false F true true T float16 number_float h float32 number_float d float64 number_float D high-precision number number_integer, number_unsigned, or number_float H uint8 number_unsigned U int8 number_integer i uint16 number_unsigned u int16 number_integer I uint32 number_unsigned m int32 number_integer l uint64 number_unsigned M int64 number_integer L byte number_unsigned B string string S char string C array array (optimized values are supported) [ ND-array object (in JData annotated array format) [$.#[. object object (optimized values are supported) { binary binary (strongly-typed byte array) [$B

    Complete mapping

    The mapping is complete for the BJData types of Draft 2 and Draft 3 with one exception: column-major N-dimensional arrays are rejected with parse_error.113. The Draft 4 constructs (structure-of-arrays containers and the extension type E) are not supported either.

    The digits of an H value are parsed like a JSON number: integers that fit 64 bits become number_integer or number_unsigned, anything else a number_float; invalid text throws parse_error.115.

    Duplicate object keys

    If an object contains the same key more than once, from_bjdata accepts it and keeps the last value; with ordered_json, the key keeps the position of its first occurrence.

    Ill-formed UTF-8 in string values and object keys

    BJData strings must use UTF-8 encoding, but checking it on read is opt-in: with the error_handler parameter left at keep (the default), from_bjdata() accepts a string value or object key whose bytes are not valid UTF-8 and hands them back unchanged. Passing error_handler_t::strict makes from_bjdata() check and throw parse_error.113 for ill-formed UTF-8, and replace/ignore sanitize the string instead of keeping it. However, dump() still requires valid UTF-8 and throws type_error.316 for a value read with the default keep handler, unless an error handler is passed that replaces or ignores the ill-formed bytes. to_bjdata()'s own error_handler parameter defaults to keep (see above), so such a value is written back unchanged.

    Round trips

    A value returned by from_bjdata can be serialized with to_bjdata using any combination of options and parsed back into an equal value, and serializing that value again with the same options produces the same bytes. The exception is binary values: they are only written as an optimized binary array ([$B) if Draft 3 is enabled and both use_size and use_type are set. Otherwise, they are written as arrays of integers and parsed back as such (see the notes on binary values above), and serializing such an array again may choose different, but equally valid, type markers. The bytes can then differ, but parsing them again yields the same value.

    Example: deserialize a JSON value from BJData
    #include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create byte vector\n    std::vector<std::uint8_t> v = {0x7B, 0x69, 0x07, 0x63, 0x6F, 0x6D, 0x70, 0x61,\n                                   0x63, 0x74, 0x54, 0x69, 0x06, 0x73, 0x63, 0x68,\n                                   0x65, 0x6D, 0x61, 0x69, 0x00, 0x7D\n                                  };\n\n    // deserialize it with BJData\n    json j = json::from_bjdata(v);\n\n    // print the deserialized JSON value\n    std::cout << std::setw(2) << j << '\\n';\n}\n

    Output:

    {\n  \"compact\": true,\n  \"schema\": 0\n}\n
    "},{"location":"features/binary_formats/bjdata/#see-also","title":"See also","text":"
    • Binary formats - overview and comparison of the supported binary formats
    • Binary values - how binary values and subtypes map to BJData
    • to_bjdata - serialize a JSON value to BJData
    • from_bjdata - parse a JSON value from BJData
    • JSON_STRICT_BINARY_UTF8 - reject ill-formed UTF-8 in strings
    • SAX interface - decode binary formats without building a value
    "},{"location":"features/binary_formats/bon8/","title":"BON8","text":"

    BON8 (Binary Object Notation 8) is a compact binary serialization format for JSON values. It uses byte values that cannot begin a UTF-8 character as type markers, so strings are stored as plain UTF-8 without a length prefix: a string ends at the first byte that cannot continue it. Integers from -10 to 39, true, false, null, and the floating-point values -1.0, 0.0, and 1.0 take a single byte, and arrays and objects with up to four elements need no terminator.

    References

    • BON8 specification
    • Reference implementation in HikoGUI
    "},{"location":"features/binary_formats/bon8/#byte-layout","title":"Byte layout","text":"

    BON8 exploits the fact that some byte values can never start a UTF-8 character. These bytes serve as type markers, so strings can be stored as plain UTF-8 without a length prefix: a string ends at the first byte that cannot continue it: a marker byte, or a lead byte 0xC2..0xF7 followed by a byte outside 0x80..0xBF. The ending byte is often the marker of the next value. Small integers, true, false, null, and a few common floats are a single byte. Arrays and objects are introduced by a marker; those with up to four elements encode their size in the marker and need no terminator, while larger ones are closed by the end marker 0xFE.

    Consider the following JSON value (shown formatted for readability):

    {\n  \"id\": 300,\n  \"name\": \"json\",\n  \"pi\": 3.14,\n  \"tags\": [\n    \"a\",\n    \"b\"\n  ]\n}\n

    to_bon8 encodes it to 35 bytes (shown in hexadecimal; the encoding contains no whitespace). The colors mark the role of each byte: type/marker length/count/size data.

    JSONBytesMeaning {8Aobject with 4 members \"id\": 300,69 64 C4 04key: UTF-8 bytes; the string ends at 0xC4, because the byte after it (0x04) is not a UTF-8 continuation byte, so 0xC4 starts an integer; value: 2-byte positive integer (lead byte, then a byte below 0x80) \"name\": \"json\",6E 61 6D 65 FF 6A 73 6F 6E FFkey: UTF-8 bytes; 0xFF terminates the string as another string follows; value: UTF-8 bytes; terminated as a string key follows \"pi\": 3.14,70 69 8F 40 09 1E B8 51 EB 85 1Fkey: UTF-8 bytes; value: binary64 (IEEE 754, big-endian); its marker also ends \"pi\" \"tags\": [74 61 67 73 82key: UTF-8 bytes; value: array with 2 elements; its marker also ends \"tags\" \"a\",61 FFUTF-8 bytes; terminated as a string follows \"b\"62 FFUTF-8 bytes; terminated as nothing follows ]no end marker: the element count was given up front }no end marker: the member count was given up front"},{"location":"features/binary_formats/bon8/#serialization","title":"Serialization","text":"

    The library uses the following mapping from JSON values types to BON8 types according to the BON8 specification:

    JSON value type value/range BON8 type first byte null null null 0xFA boolean true true 0xF9 boolean false false 0xF8 number_integer -9223372036854775808..-2147483649 int64 0x8D number_integer -2147483648..-33818507 int32 0x8C number_integer -33818506..-264075 4-byte negative integer 0xF0..0xF7 number_integer -264074..-1931 3-byte negative integer 0xE0..0xEF number_integer -1930..-11 2-byte negative integer 0xC2..0xDF number_integer -10..-1 1-byte negative integer 0xB8..0xC1 number_integer 0..39 1-byte positive integer 0x90..0xB7 number_integer 40..3879 2-byte positive integer 0xC2..0xDF number_integer 3880..528167 3-byte positive integer 0xE0..0xEF number_integer 528168..67637031 4-byte positive integer 0xF0..0xF7 number_integer 67637032..2147483647 int32 0x8C number_integer 2147483648..9223372036854775807 int64 0x8D number_unsigned 0..39 1-byte positive integer 0x90..0xB7 number_unsigned 40..3879 2-byte positive integer 0xC2..0xDF number_unsigned 3880..528167 3-byte positive integer 0xE0..0xEF number_unsigned 528168..67637031 4-byte positive integer 0xF0..0xF7 number_unsigned 67637032..2147483647 int32 0x8C number_unsigned 2147483648..9223372036854775807 int64 0x8D number_float -1.0 -1.0 0xFB number_float 0.0 0.0 0xFC number_float 1.0 1.0 0xFD number_float any other value representable by a float binary32 0x8E number_float any value NOT representable by a float binary64 0x8F string empty end of string 0xFF string non-empty UTF-8 string 0x00..0x7F, 0xC2..0xF4 array size: 0..4 array with count 0x80..0x84 array size: 5 or more array (terminated by 0xFE) 0x85 object size: 0..4 object with count 0x86..0x8A object size: 5 or more object (terminated by 0xFE) 0x8B binary size: 0..4 array with count 0x80..0x84 binary size: 5 or more array (terminated by 0xFE) 0x85

    An integer that takes 2 to 4 bytes starts with a UTF-8 lead byte (0xC2..0xF7) that is followed by a byte that cannot continue a UTF-8 character: 0x00..0x7F for positive and 0xC0..0xFF for negative integers. A string is terminated by 0xFF only if it is empty, if another string follows it, or if nothing follows it in the message; otherwise, the byte after it ends it: the first byte of the next value, or the 0xFE that ends an array or object. For example, [\"e\"] is serialized as 0x81 0x65 0xFF, but [1,2,3,4,\"e\"] as 0x85 0x91 0x92 0x93 0x94 0x65 0xFE.

    Complete mapping

    Except for the values listed below, any JSON value can be converted to a BON8 value.

    Any BON8 output created by to_bon8 can be successfully parsed by from_bon8.

    Unsupported values

    The following values can not be converted to a BON8 value:

    • integers outside the int64 range (unsigned integers above 9223372036854775807 and, for number types wider than 64 bits, any larger or smaller integer), because BON8 integers are limited to int64 (out_of_range.407)
    • strings that are not valid UTF-8, because the end of a string is determined from its encoding (type_error.316)

    NaN/infinity handling

    -0.0, Infinity, and -Infinity are serialized as binary32 (type 0x8E, 5 bytes total). NaN is serialized as the binary32 value 0x7F800001 that the specification recommends. This is in contrast to the dump function which serializes NaN or Infinity to null.

    Binary values

    BON8 has no binary type. Binary values are serialized as arrays of integers (0..255), so they are read back as arrays. The subtype is not serialized.

    Canonical representation

    The output follows the specification's canonical representation rules: every value uses the shortest encoding, floating-point numbers use binary32 whenever that loses no precision, and object keys are sorted by their UTF-8 code units. There are two exceptions:

    • Strings are not normalized to Unicode Normalization Form C (NFC).
    • Object keys are written in the order of the object type, which is sorted for json, but not for ordered_json.
    Example: serialize a JSON value to BON8
    #include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\nusing namespace nlohmann::literals;\n\nint main()\n{\n    // create a JSON value\n    json j = R\"({\"compact\": true, \"format\": \"BON8\", \"schema\": 0})\"_json;\n\n    // serialize it to BON8\n    std::vector<std::uint8_t> v = json::to_bon8(j);\n\n    // print the vector content\n    for (auto& byte : v)\n    {\n        std::cout << \"0x\" << std::hex << std::setw(2) << std::setfill('0') << static_cast<int>(byte) << \" \";\n    }\n    std::cout << '\\n';\n}\n

    Output:

    0x89 0x63 0x6f 0x6d 0x70 0x61 0x63 0x74 0xf9 0x66 0x6f 0x72 0x6d 0x61 0x74 0xff 0x42 0x4f 0x4e 0x38 0xff 0x73 0x63 0x68 0x65 0x6d 0x61 0x90 \n
    "},{"location":"features/binary_formats/bon8/#deserialization","title":"Deserialization","text":"

    The library maps BON8 types to JSON value types as follows:

    BON8 type JSON value type first byte UTF-8 string string 0x00..0x7F array with count array 0x80..0x84 array (terminated by 0xFE) array 0x85 object with count object 0x86..0x8A object (terminated by 0xFE) object 0x8B int32 number_unsigned or number_integer 0x8C int64 number_unsigned or number_integer 0x8D binary32 number_float 0x8E binary64 number_float 0x8F 1-byte positive integer number_unsigned 0x90..0xB7 1-byte negative integer number_integer 0xB8..0xC1 UTF-8 string string 0xC2..0xF4, followed by 0x80..0xBF 2- to 4-byte positive integer number_unsigned 0xC2..0xF7, followed by 0x00..0x7F 2- to 4-byte negative integer number_integer 0xC2..0xF7, followed by 0xC0..0xFF false false 0xF8 true true 0xF9 null null 0xFA -1.0 number_float 0xFB 0.0 number_float 0xFC 1.0 number_float 0xFD empty string string 0xFF

    Non-negative integers are read as number_unsigned, negative integers as number_integer.

    A byte 0xF5..0xF7 followed by 0x80..0xBF is neither a string nor an integer and is rejected with parse_error.112 (invalid UTF-8 byte). The same error is reported for any other invalid byte (such as a stray 0xFE), for ill-formed UTF-8, and for an object key that is not a string. Input that ends prematurely, trailing data after the value, and a missing final 0xFF after a string at the end of the message are reported as parse_error.110.

    Non-canonical input

    Values that do not use the canonical representation, such as integers with a longer encoding than necessary, arrays and objects with up to four elements that are terminated by 0xFE, unsorted object keys, or a 0xFF after a string that would also end without it, are accepted. A second 0xFF is not a terminator but an empty string.

    Strings must be valid UTF-8, and a string at the very end of a message must be terminated by 0xFF.

    Duplicate object keys are accepted; the last value wins (ordered_json keeps the position of the first occurrence). The specification does not say how to treat them; the HikoGUI reference decoder keeps the first value.

    Round trips

    Any BON8 output created by to_bon8 can be successfully parsed by from_bon8.

    Example: deserialize a JSON value from BON8
    #include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create byte vector\n    std::vector<std::uint8_t> v = {0x89, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x63, 0x74,\n                                   0xf9, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0xff,\n                                   0x42, 0x4f, 0x4e, 0x38, 0xff, 0x73, 0x63, 0x68,\n                                   0x65, 0x6d, 0x61, 0x90\n                                  };\n\n    // deserialize it with BON8\n    json j = json::from_bon8(v);\n\n    // print the deserialized JSON value\n    std::cout << std::setw(2) << j << '\\n';\n}\n

    Output:

    {\n  \"compact\": true,\n  \"format\": \"BON8\",\n  \"schema\": 0\n}\n
    "},{"location":"features/binary_formats/bon8/#see-also","title":"See also","text":"
    • Binary formats - overview and comparison of the supported binary formats
    • Binary values - how binary values and subtypes map to BON8
    • to_bon8 - serialize a JSON value to BON8
    • from_bon8 - parse a JSON value from BON8
    • JSON_STRICT_BINARY_UTF8 - reject ill-formed UTF-8 in strings
    • SAX interface - decode binary formats without building a value
    "},{"location":"features/binary_formats/bson/","title":"BSON","text":"

    BSON, short for Binary JSON, is a binary-encoded serialization of JSON-like documents. Like JSON, BSON supports the embedding of documents and arrays within other documents and arrays. BSON also contains extensions that allow representation of data types that are not part of the JSON spec. For example, BSON has a Date type and a BinData type.

    References

    • BSON Website - the main source on BSON
    • BSON Specification - the specification
    "},{"location":"features/binary_formats/bson/#byte-layout","title":"Byte layout","text":"

    A BSON document is a length-prefixed sequence of elements. The first four bytes hold the total size of the document (little-endian int32), followed by the elements, and a final 0x00 byte ends the document. Each element starts with a one-byte type, followed by its key as a NUL-terminated string and the value, whose encoding depends on the type. Arrays are documents whose keys are the decimal indices \"0\", \"1\", ...; nesting is expressed by embedding documents. Because every document announces its size, a reader can skip over it without parsing its content. The top level of a BSON value is always a document, which is why only JSON objects can be serialized.

    Consider the following JSON value (shown formatted for readability):

    {\n  \"id\": 300,\n  \"name\": \"json\",\n  \"pi\": 3.14,\n  \"tags\": [\n    \"a\",\n    \"b\"\n  ]\n}\n

    to_bson encodes it to 69 bytes (shown in hexadecimal; the encoding contains no whitespace). The colors mark the role of each byte: type/marker length/count/size data.

    JSONBytesMeaning {45 00 00 00document size: 69 bytes (int32, little-endian) \"id\": 300,10 69 64 00 2C 01 00 00int32 element; key as NUL-terminated string; value (little-endian) \"name\": \"json\",02 6E 61 6D 65 00 05 00 00 00 6A 73 6F 6E 00string element; key; length incl. NUL (int32); NUL-terminated UTF-8 bytes \"pi\": 3.14,01 70 69 00 1F 85 EB 51 B8 1E 09 40double element; key; value (little-endian) \"tags\": [04 74 61 67 73 00 17 00 00 00array element; key; embedded document of 23 bytes (keys are the indices) \"a\",02 30 00 02 00 00 00 61 00string element; key \"0\"; length 2; a + NUL \"b\"02 31 00 02 00 00 00 62 00string element; key \"1\"; length 2; b + NUL ]00end of the array document }00end of the document"},{"location":"features/binary_formats/bson/#serialization","title":"Serialization","text":"

    The library uses the following mapping from JSON values types to BSON types:

    JSON value type value/range BSON type marker null null null 0x0A boolean true, false boolean 0x08 number_integer -9223372036854775808..-2147483649 int64 0x12 number_integer -2147483648..2147483647 int32 0x10 number_integer 2147483648..9223372036854775807 int64 0x12 number_unsigned 0..2147483647 int32 0x10 number_unsigned 2147483648..9223372036854775807 int64 0x12 number_unsigned 9223372036854775808..18446744073709551615 uint64 0x11 number_float any value double 0x01 string any value string 0x02 array any value document 0x04 object any value document 0x03 binary any value binary 0x05

    Incomplete mapping

    The mapping is incomplete, since only JSON-objects (and things contained therein) can be serialized to BSON. Also, keys may not contain U+0000, since they are serialized as zero-terminated C strings.

    Order of object members

    The members of an object are written in the order in which iteration visits them: sorted by key for json, in insertion order for ordered_json.

    BSON type 0x11 interoperability

    The BSON specification defines type 0x11 as a Timestamp. This library uses marker 0x11 when serializing number_unsigned values in the range 9223372036854775808..18446744073709551615. Other BSON implementations may therefore interpret these values as Timestamps instead of unsigned integers.

    Binary values without a subtype

    BSON requires every binary value to have a subtype. If a binary value has no subtype, this library serializes it with the generic subtype 0x00. After deserialization, has_subtype() returns true and subtype() returns 0. As a result, serializing and deserializing a JSON object containing such a value produces a different JSON object, even though the binary data is unchanged.

    Binary subtype 0x02 (old binary)

    The BSON specification defines the payload of the \"binary (old)\" subtype 0x02 as an int32 followed by that many bytes, so the value is preceded by two lengths: the length of the binary element and, as the first four bytes of the payload, the number of bytes that follow. A binary value with subtype 2 is therefore written with the outer length 4 bytes larger than its size and the size as inner length: binary({1, 2, 3}, 2) becomes 07 00 00 00 02 03 00 00 00 01 02 03. When reading, the inner length is checked and removed, so the value contains only the bytes that follow it. from_bson() throws parse_error.112 if the outer length is less than 4 or the inner length is not the outer length minus 4. Versions before 3.13.0 did not write the inner length and returned it as part of the payload; BSON data written by those versions with subtype 2 is not readable any more and must be written again.

    Example: serialize a JSON value to BSON
    #include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\nusing namespace nlohmann::literals;\n\nint main()\n{\n    // create a JSON value\n    json j = R\"({\"compact\": true, \"schema\": 0})\"_json;\n\n    // serialize it to BSON\n    std::vector<std::uint8_t> v = json::to_bson(j);\n\n    // print the vector content\n    for (auto& byte : v)\n    {\n        std::cout << \"0x\" << std::hex << std::setw(2) << std::setfill('0') << static_cast<int>(byte) << \" \";\n    }\n    std::cout << '\\n';\n}\n

    Output:

    0x1b 0x00 0x00 0x00 0x08 0x63 0x6f 0x6d 0x70 0x61 0x63 0x74 0x00 0x01 0x10 0x73 0x63 0x68 0x65 0x6d 0x61 0x00 0x00 0x00 0x00 0x00 0x00 \n
    "},{"location":"features/binary_formats/bson/#deserialization","title":"Deserialization","text":"

    The library maps BSON record types to JSON value types as follows:

    BSON type BSON marker byte JSON value type double 0x01 number_float string 0x02 string document 0x03 object array 0x04 array binary 0x05 binary undefined 0x06 unsupported ObjectId 0x07 unsupported boolean 0x08 boolean UTC Date-Time 0x09 unsupported null 0x0A null Regular Expr. 0x0B unsupported DB Pointer 0x0C unsupported JavaScript Code 0x0D unsupported Symbol 0x0E unsupported JavaScript Code w/ scope 0x0F unsupported int32 0x10 number_integer uint64(Timestamp) 0x11 number_unsigned int64 0x12 number_integer 128-bit decimal float 0x13 unsupported Max Key 0x7F unsupported Min Key 0xFF unsupported

    Incomplete mapping

    The mapping is incomplete. The unsupported mappings are indicated in the table above.

    Handling of BSON type 0x11

    This library deserializes BSON type 0x11 (Timestamp) as a number_unsigned value. The 64-bit value is preserved, but the Timestamp type information is not.

    Lenient BSON input handling

    The BSON reader is lenient in a few areas where the BSON specification is more restrictive:

    • array element keys are not checked against the required decimal sequence (0, 1, 2, ...),
    • any non-zero byte is accepted as true for the boolean type,
    • the payloads of the binary subtypes 0x03 (UUID, old), 0x04 (UUID), and 0x05 (MD5) are not checked to have 16 bytes,
    • duplicate keys within a document are accepted; the last value wins ({\"a\": 1, \"a\": 2} is read as {\"a\": 2}), while a SAX handler receives every occurrence,
    • a string value may contain embedded 0x00 bytes, and
    • with strict set to false, bytes after the end of the document are ignored.

    If BSON input must be validated for strict specification compliance, validate it separately before passing it to from_bson().

    Document size

    Every document starts with its size. from_bson() rejects a document with parse_error.112 if the size is less than 5 (the size prefix and the terminator), if an embedded document does not end before the end of the document that contains it, if the elements do not fit into the declared size, or if the size does not match the number of bytes read when the terminating 0x00 byte is reached. A size that is too small is detected before an element is read whose type byte and name no longer fit; an element that starts inside the declared size but extends past it is read, and reported to a SAX handler, before the mismatch is found at the terminator. A size that is too large is likewise found only at the terminator. Passing strict as false skips only the check for bytes after the end of the document (parse_error.110), not the document size checks.

    Ill-formed UTF-8 in string values

    The BSON specification requires string values (type 0x02) to be valid UTF-8, but this is not required of a decoder, so checking is opt-in: with the error_handler parameter left at keep (the default), from_bson() accepts a string value whose bytes are not valid UTF-8 and hands them back unchanged. Passing error_handler_t::strict makes from_bson() check and throw parse_error.113 for ill-formed UTF-8, and replace/ignore sanitize the string instead of keeping it. However, dump() still requires valid UTF-8 and throws type_error.316 for a value read with the default keep handler, unless an error handler is passed that replaces or ignores the ill-formed bytes. to_bson()'s own error_handler parameter defaults to keep, so such a string value or element (key) name is written unchanged; with strict (the default if JSON_STRICT_BINARY_UTF8 is enabled), it throws the same exception instead. Element (key) names are treated like string values: with keep they are read unchanged, with strict, replace, or ignore they are checked and handled in the same way. binary values (type 0x05) are unaffected, since they are not required to hold text.

    Example: deserialize a JSON value from BSON
    #include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create byte vector\n    std::vector<std::uint8_t> v = {0x1b, 0x00, 0x00, 0x00, 0x08, 0x63, 0x6f, 0x6d,\n                                   0x70, 0x61, 0x63, 0x74, 0x00, 0x01, 0x10, 0x73,\n                                   0x63, 0x68, 0x65, 0x6d, 0x61, 0x00, 0x00, 0x00,\n                                   0x00, 0x00, 0x00\n                                  };\n\n    // deserialize it with BSON\n    json j = json::from_bson(v);\n\n    // print the deserialized JSON value\n    std::cout << std::setw(2) << j << '\\n';\n}\n

    Output:

    {\n  \"compact\": true,\n  \"schema\": 0\n}\n
    "},{"location":"features/binary_formats/bson/#see-also","title":"See also","text":"
    • Binary formats - overview and comparison of the supported binary formats
    • Binary values - how binary values and subtypes map to BSON
    • to_bson - serialize a JSON value to BSON
    • from_bson - parse a JSON value from BSON
    • JSON_STRICT_BINARY_UTF8 - reject ill-formed UTF-8 in strings
    • SAX interface - decode binary formats without building a value
    "},{"location":"features/binary_formats/cbor/","title":"CBOR","text":"

    The Concise Binary Object Representation (CBOR) is a data format whose design goals include the possibility of extremely small code sizes, fairly small message size, and extensibility without the need for version negotiation.

    References

    • CBOR Website - the main source on CBOR
    • CBOR Playground - an interactive webpage to translate between JSON and CBOR
    • RFC 8949 - the CBOR specification
    "},{"location":"features/binary_formats/cbor/#byte-layout","title":"Byte layout","text":"

    CBOR encodes every data item as a head followed by optional content. The first byte of the head holds the major type in its upper three bits (unsigned integer, negative integer, byte string, text string, array, map, tag, or simple/float) and an additional information value in its lower five bits. Additional information below 24 is the argument itself (for example, a small integer or a short length); the values 24 to 27 announce that the argument follows in 1, 2, 4, or 8 big-endian bytes. Strings, arrays, and maps are prefixed with their length (or count of elements/pairs), and content follows directly. A reader of definite-length items knows how many items to expect without a terminator; indefinite-length items (additional information 31) are instead closed by the \"break\" byte 0xFF, which from_cbor reads but to_cbor never writes.

    Consider the following JSON value (shown formatted for readability):

    {\n  \"id\": 300,\n  \"name\": \"json\",\n  \"pi\": 3.14,\n  \"tags\": [\n    \"a\",\n    \"b\"\n  ]\n}\n

    to_cbor encodes it to 39 bytes (shown in hexadecimal; the encoding contains no whitespace). The colors mark the role of each byte: type/marker data.

    JSONBytesMeaning {A4map with 4 key/value pairs \"id\": 300,62 69 64 19 01 2Ckey: text string of length 2, then its UTF-8 bytes; value: unsigned integer, 2 bytes follow (big-endian) \"name\": \"json\",64 6E 61 6D 65 64 6A 73 6F 6Ekey: text string of length 4; value: text string of length 4 \"pi\": 3.14,62 70 69 FB 40 09 1E B8 51 EB 85 1Fkey: text string of length 2; value: double-precision float (IEEE 754, big-endian) \"tags\": [64 74 61 67 73 82key: text string of length 4; value: array with 2 elements \"a\",61 61text string of length 1 \"b\"61 62text string of length 1 ]no end marker: the element count was given up front }no end marker: the member count was given up front"},{"location":"features/binary_formats/cbor/#serialization","title":"Serialization","text":"

    The library uses the following mapping from JSON values types to CBOR types according to the CBOR specification (RFC 8949):

    JSON value type value/range CBOR type first byte null null Null 0xF6 boolean true True 0xF5 boolean false False 0xF4 number_integer -9223372036854775808..-4294967297 Negative integer (8 bytes follow) 0x3B number_integer -4294967296..-65537 Negative integer (4 bytes follow) 0x3A number_integer -65536..-257 Negative integer (2 bytes follow) 0x39 number_integer -256..-25 Negative integer (1 byte follow) 0x38 number_integer -24..-1 Negative integer 0x20..0x37 number_integer 0..23 Integer 0x00..0x17 number_integer 24..255 Unsigned integer (1 byte follow) 0x18 number_integer 256..65535 Unsigned integer (2 bytes follow) 0x19 number_integer 65536..4294967295 Unsigned integer (4 bytes follow) 0x1A number_integer 4294967296..9223372036854775807 Unsigned integer (8 bytes follow) 0x1B number_unsigned 0..23 Integer 0x00..0x17 number_unsigned 24..255 Unsigned integer (1 byte follow) 0x18 number_unsigned 256..65535 Unsigned integer (2 bytes follow) 0x19 number_unsigned 65536..4294967295 Unsigned integer (4 bytes follow) 0x1A number_unsigned 4294967296..18446744073709551615 Unsigned integer (8 bytes follow) 0x1B number_float any value representable by a float Single-Precision Float 0xFA number_float any value NOT representable by a float Double-Precision Float 0xFB string length: 0..23 UTF-8 string 0x60..0x77 string length: 24..255 UTF-8 string (1 byte follow) 0x78 string length: 256..65535 UTF-8 string (2 bytes follow) 0x79 string length: 65536..4294967295 UTF-8 string (4 bytes follow) 0x7A string length: 4294967296..18446744073709551615 UTF-8 string (8 bytes follow) 0x7B array size: 0..23 array 0x80..0x97 array size: 24..255 array (1 byte follow) 0x98 array size: 256..65535 array (2 bytes follow) 0x99 array size: 65536..4294967295 array (4 bytes follow) 0x9A array size: 4294967296..18446744073709551615 array (8 bytes follow) 0x9B object size: 0..23 map 0xA0..0xB7 object size: 24..255 map (1 byte follow) 0xB8 object size: 256..65535 map (2 bytes follow) 0xB9 object size: 65536..4294967295 map (4 bytes follow) 0xBA object size: 4294967296..18446744073709551615 map (8 bytes follow) 0xBB binary size: 0..23 byte string 0x40..0x57 binary size: 24..255 byte string (1 byte follow) 0x58 binary size: 256..65535 byte string (2 bytes follow) 0x59 binary size: 65536..4294967295 byte string (4 bytes follow) 0x5A binary size: 4294967296..18446744073709551615 byte string (8 bytes follow) 0x5B

    Binary values with subtype are mapped to tagged values (0xD8..0xDB) depending on the subtype, followed by a byte string, see \"binary\" cells in the table above.

    Complete mapping

    The mapping is complete in the sense that any JSON value type can be converted to a CBOR value, with one exception: an integer outside the range of CBOR integers (only possible with a number type wider than 64 bits) throws out_of_range.407.

    Not a deterministic encoding

    to_cbor does not produce the deterministic encoding of RFC 8949, Section 4.2.1, and not always the preferred serialization of Section 4.1:

    • floating-point numbers are written as single precision (0xFA) when that is exact and as double precision (0xFB) otherwise; half precision (0xF9) is used only for NaN and Infinity/-Infinity (1.0 is fa 3f 80 00 00);
    • a binary subtype 0..23 is written as d8 xx instead of the one-byte tag 0xC0..0xD7 (d8 01 41 01);
    • object members are written in the order of object_t (for the default std::map: sorted by the key string, not by the encoded key bytes).

    Integers and lengths use the shortest form, and indefinite-length items are never written. Decoders must accept all of this; the RFC does not require the preferred serialization.

    NaN/infinity handling

    NaN, Infinity, and -Infinity are serialized as a CBOR half-precision float (type 0xF9, 3 bytes total): NaN as 0xF9 0x7E 0x00, Infinity as 0xF9 0x7C 0x00, and -Infinity as 0xF9 0xFC 0x00. This behavior differs from the normal JSON serialization which serializes NaN or Infinity to null.

    Note

    Prior to version 3.8.0, NaN and Infinity were instead serialized as a CBOR double-precision float (type 0xFB, 9 bytes total).

    Unused CBOR types

    The following CBOR types are not used in the conversion:

    • UTF-8 strings terminated by \"break\" (0x7F)
    • arrays terminated by \"break\" (0x9F)
    • maps terminated by \"break\" (0xBF)
    • byte strings terminated by \"break\" (0x5F)
    • date/time (0xC0..0xC1)
    • bignum (0xC2..0xC3)
    • decimal fraction (0xC4)
    • bigfloat (0xC5)
    • expected conversions (0xD5..0xD7)
    • simple values (0xE0..0xF3, 0xF8)
    • undefined (0xF7)
    • break (0xFF)

    Tagged items

    Binary subtypes will be serialized as tagged items. See binary values for an example.

    Example: serialize a JSON value to CBOR
    #include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\nusing namespace nlohmann::literals;\n\nint main()\n{\n    // create a JSON value\n    json j = R\"({\"compact\": true, \"schema\": 0})\"_json;\n\n    // serialize it to CBOR\n    std::vector<std::uint8_t> v = json::to_cbor(j);\n\n    // print the vector content\n    for (auto& byte : v)\n    {\n        std::cout << \"0x\" << std::hex << std::setw(2) << std::setfill('0') << static_cast<int>(byte) << \" \";\n    }\n    std::cout << '\\n';\n}\n

    Output:

    0xa2 0x67 0x63 0x6f 0x6d 0x70 0x61 0x63 0x74 0xf5 0x66 0x73 0x63 0x68 0x65 0x6d 0x61 0x00 \n
    "},{"location":"features/binary_formats/cbor/#deserialization","title":"Deserialization","text":"

    The library maps CBOR types to JSON value types as follows:

    CBOR type JSON value type first byte Integer number_unsigned 0x00..0x17 Unsigned integer number_unsigned 0x18 Unsigned integer number_unsigned 0x19 Unsigned integer number_unsigned 0x1A Unsigned integer number_unsigned 0x1B Negative integer number_integer 0x20..0x37 Negative integer number_integer 0x38 Negative integer number_integer 0x39 Negative integer number_integer 0x3A Negative integer number_integer 0x3B Byte string binary 0x40..0x57 Byte string binary 0x58 Byte string binary 0x59 Byte string binary 0x5A Byte string binary 0x5B Byte string binary 0x5F UTF-8 string string 0x60..0x77 UTF-8 string string 0x78 UTF-8 string string 0x79 UTF-8 string string 0x7A UTF-8 string string 0x7B UTF-8 string string 0x7F array array 0x80..0x97 array array 0x98 array array 0x99 array array 0x9A array array 0x9B array array 0x9F map object 0xA0..0xB7 map object 0xB8 map object 0xB9 map object 0xBA map object 0xBB map object 0xBF False false 0xF4 True true 0xF5 Null null 0xF6 Half-Precision Float number_float 0xF9 Single-Precision Float number_float 0xFA Double-Precision Float number_float 0xFB

    Indefinite-length UTF-8 strings (0x7F) and byte strings (0x5F) are supported. Each chunk must be a definite-length string of the same major type, as required by RFC 8949, Section 3.2.3.

    Incomplete mapping

    The mapping is incomplete in the sense that not all CBOR types can be converted to a JSON value. The following CBOR types are not supported and will yield parse errors:

    • simple values (0xE0..0xF3, 0xF8)
    • undefined (0xF7)

    Tagged items (0xC0..0xDB) are not interpreted either; see the note on tagged items below.

    Negative integer overflow

    CBOR negative integers (major type 1) are decoded as -1 - n. If the encoded magnitude n is too large for the result to fit into number_integer_t (std::int64_t by default), the result is stored as number_float_t, like a too small integer in JSON text. For example, -18446744073709551616 (0x3B followed by eight 0xFF bytes) is stored as -1.8446744073709552e+19.

    Object keys

    CBOR allows map keys of any type, whereas JSON only allows strings as keys in object values. Therefore, CBOR maps with keys other than text strings (major type 3) are rejected with a parse_error.113 exception (or, with allow_exceptions set to false, a discarded value) naming the type of the key that was found, for instance:

    [json.exception.parse_error.113] parse error at byte 2: syntax error while parsing CBOR object key: only string keys are supported, but found an unsigned integer; last byte: 0x01\n

    This applies to the SAX interface as well, as the key is read before it is passed on. This is a deliberate restriction of the library's JSON value model, not an oversight: formats built on CBOR maps with integer keys, such as COSE (RFC 9052) or CWT (RFC 8392), cannot be read with this library and need a general-purpose CBOR library instead.

    A tag in front of a text string key is handled like a tag in front of a value: it is skipped with cbor_tag_handler_t::ignore or cbor_tag_handler_t::store and rejected with the default error. A tag does not turn a key of another type into a text string.

    A map with duplicate keys is well-formed, but invalid under RFC 8949, Section 5.3.1. from_cbor accepts it and the last value wins; the SAX interface reports every occurrence.

    Ill-formed UTF-8 in text strings

    RFC 8949, Section 3.1 requires CBOR text strings (major type 3) to be valid UTF-8 (a string with ill-formed UTF-8 is \"well-formed but invalid\"), and Section 5.3.1 leaves it up to the decoder whether to verify this, so checking is opt-in: with the error_handler parameter left at keep (the default), from_cbor() accepts a text string (object keys included) whose bytes are not valid UTF-8 and hands them back unchanged. Passing error_handler_t::strict makes from_cbor() check and throw parse_error.113 for ill-formed UTF-8, and replace/ignore sanitize the string instead of keeping it. However, dump() still requires valid UTF-8 and throws type_error.316 for a value read with the default keep handler, unless an error handler is passed that replaces or ignores the ill-formed bytes. to_cbor()'s own error_handler parameter defaults to keep, so such a value is written back unchanged; with strict (the default if JSON_STRICT_BINARY_UTF8 is enabled), it throws the same exception instead. Byte strings (major type 2) are unaffected, since they are not required to hold text.

    The chunks of an indefinite-length text string are checked one by one, as required by RFC 8949, Section 3.2.3: a code point cannot be spread over two chunks. With error_handler_t::strict such a string throws parse_error.113; replace and ignore sanitize each chunk on its own.

    Tagged items

    Tagged items (0xC0..0xDB) will throw a parse error by default. They can be ignored by passing cbor_tag_handler_t::ignore to function from_cbor, in which case the tag is skipped and the enclosed data item is parsed on its own. Passing cbor_tag_handler_t::store to function from_cbor stores tagged byte strings (for bytes 0xd8..0xdb) as binary values with the tag as subtype; other tagged values are read as if the tag were ignored. If several tags precede a byte string, only the tag directly in front of it is stored, and only when it has the form 0xD8..0xDB (a tag 0..23 written as 0xC0..0xD7 is skipped); for example, D8 05 C1 41 AA yields subtype null, whereas C1 D8 05 41 AA yields 5. Tags in front of a text string map key are skipped as well. Note that no tag is ever interpreted: for instance, a text string tagged with tag 0 (date/time) stays a string.

    Example: deserialize a JSON value from CBOR
    #include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create byte vector\n    std::vector<std::uint8_t> v = {0xa2, 0x67, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x63,\n                                   0x74, 0xf5, 0x66, 0x73, 0x63, 0x68, 0x65, 0x6d,\n                                   0x61, 0x00\n                                  };\n\n    // deserialize it with CBOR\n    json j = json::from_cbor(v);\n\n    // print the deserialized JSON value\n    std::cout << std::setw(2) << j << '\\n';\n}\n

    Output:

    {\n  \"compact\": true,\n  \"schema\": 0\n}\n
    "},{"location":"features/binary_formats/cbor/#see-also","title":"See also","text":"
    • Binary formats - overview and comparison of the supported binary formats
    • Binary values - how binary values and subtypes map to CBOR
    • to_cbor - serialize a JSON value to CBOR
    • from_cbor - parse a JSON value from CBOR
    • JSON_STRICT_BINARY_UTF8 - reject ill-formed UTF-8 in strings
    • SAX interface - decode binary formats without building a value
    • cbor_tag_handler_t - how CBOR tags are handled when parsing
    "},{"location":"features/binary_formats/messagepack/","title":"MessagePack","text":"

    MessagePack is an efficient binary serialization format. It lets you exchange data among multiple languages like JSON. But it's faster and smaller. Small integers are encoded into a single byte, and typical short strings require only one extra byte in addition to the strings themselves.

    References

    • MessagePack website
    • MessagePack specification
    "},{"location":"features/binary_formats/messagepack/#byte-layout","title":"Byte layout","text":"

    MessagePack encodes each value as a one-byte format marker, optionally followed by a length or the payload. The marker range is partitioned to keep common values small: small non-negative integers (0 to 127) and small negative integers (-32 to -1) are the marker byte itself; short strings, arrays, and maps (up to 31 bytes for strings and up to 15 elements for arrays and maps) hide their length in the marker's lower bits. Larger values use dedicated markers that announce the width (8, 16, 32, or 64 bits) of the length or number that follows, in big-endian byte order. Like CBOR, containers are length-prefixed, so no terminator is needed.

    Consider the following JSON value (shown formatted for readability):

    {\n  \"id\": 300,\n  \"name\": \"json\",\n  \"pi\": 3.14,\n  \"tags\": [\n    \"a\",\n    \"b\"\n  ]\n}\n

    to_msgpack encodes it to 39 bytes (shown in hexadecimal; the encoding contains no whitespace). The colors mark the role of each byte: type/marker data.

    JSONBytesMeaning {84map with 4 key/value pairs \"id\": 300,A2 69 64 CD 01 2Ckey: fixstr of length 2, then its UTF-8 bytes; value: uint 16 (big-endian) \"name\": \"json\",A4 6E 61 6D 65 A4 6A 73 6F 6Ekey: fixstr of length 4; value: fixstr of length 4 \"pi\": 3.14,A2 70 69 CB 40 09 1E B8 51 EB 85 1Fkey: fixstr of length 2; value: float 64 (IEEE 754, big-endian) \"tags\": [A4 74 61 67 73 92key: fixstr of length 4; value: fixarray with 2 elements \"a\",A1 61fixstr of length 1 \"b\"A1 62fixstr of length 1 ]no end marker: the element count was given up front }no end marker: the member count was given up front"},{"location":"features/binary_formats/messagepack/#serialization","title":"Serialization","text":"

    The library uses the following mapping from JSON values types to MessagePack types according to the MessagePack specification:

    JSON value type value/range MessagePack type first byte null null nil 0xC0 boolean true true 0xC3 boolean false false 0xC2 number_integer -9223372036854775808..-2147483649 int64 0xD3 number_integer -2147483648..-32769 int32 0xD2 number_integer -32768..-129 int16 0xD1 number_integer -128..-33 int8 0xD0 number_integer -32..-1 negative fixint 0xE0..0xFF number_integer 0..127 positive fixint 0x00..0x7F number_integer 128..255 uint 8 0xCC number_integer 256..65535 uint 16 0xCD number_integer 65536..4294967295 uint 32 0xCE number_integer 4294967296..18446744073709551615 uint 64 0xCF number_unsigned 0..127 positive fixint 0x00..0x7F number_unsigned 128..255 uint 8 0xCC number_unsigned 256..65535 uint 16 0xCD number_unsigned 65536..4294967295 uint 32 0xCE number_unsigned 4294967296..18446744073709551615 uint 64 0xCF number_float any value representable by a float float 32 0xCA number_float any value NOT representable by a float float 64 0xCB string length: 0..31 fixstr 0xA0..0xBF string length: 32..255 str 8 0xD9 string length: 256..65535 str 16 0xDA string length: 65536..4294967295 str 32 0xDB array size: 0..15 fixarray 0x90..0x9F array size: 16..65535 array 16 0xDC array size: 65536..4294967295 array 32 0xDD object size: 0..15 fix map 0x80..0x8F object size: 16..65535 map 16 0xDE object size: 65536..4294967295 map 32 0xDF binary size: 0..255 bin 8 0xC4 binary size: 256..65535 bin 16 0xC5 binary size: 65536..4294967295 bin 32 0xC6

    Complete mapping

    The mapping is complete in the sense that any JSON value type can be converted to a MessagePack value.

    Any MessagePack output created by to_msgpack can be successfully parsed by from_msgpack.

    Size constraints

    The following values can not be converted to a MessagePack value:

    • strings with more than 4294967295 bytes
    • byte strings with more than 4294967295 bytes
    • arrays with more than 4294967295 elements
    • objects with more than 4294967295 elements

    Serializing such a value throws out_of_range.412.

    NaN/infinity handling

    NaN, Infinity, and -Infinity are serialized as a MessagePack float 32 (type 0xCA, 5 bytes total), regardless of magnitude, in contrast to the dump function which serializes NaN or Infinity to null.

    Note

    Prior to version 3.13.0 unreleased, NaN and Infinity were instead serialized as a MessagePack float 64 (type 0xCB, 9 bytes total), because the check used to select the smaller float 32 encoding failed for NaN (all comparisons are false) and for Infinity and -Infinity (outside the float range checked against std::numeric_limits<float>::lowest() and max()), so the float 32 path was skipped.

    Example: serialize a JSON value to MessagePack
    #include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\nusing namespace nlohmann::literals;\n\nint main()\n{\n    // create a JSON value\n    json j = R\"({\"compact\": true, \"schema\": 0})\"_json;\n\n    // serialize it to MessagePack\n    std::vector<std::uint8_t> v = json::to_msgpack(j);\n\n    // print the vector content\n    for (auto& byte : v)\n    {\n        std::cout << \"0x\" << std::hex << std::setw(2) << std::setfill('0') << static_cast<int>(byte) << \" \";\n    }\n    std::cout << '\\n';\n}\n

    Output:

    0x82 0xa7 0x63 0x6f 0x6d 0x70 0x61 0x63 0x74 0xc3 0xa6 0x73 0x63 0x68 0x65 0x6d 0x61 0x00 \n
    "},{"location":"features/binary_formats/messagepack/#deserialization","title":"Deserialization","text":"

    The library maps MessagePack types to JSON value types as follows:

    MessagePack type JSON value type first byte positive fixint number_unsigned 0x00..0x7F fixmap object 0x80..0x8F fixarray array 0x90..0x9F fixstr string 0xA0..0xBF nil null 0xC0 (never used) \u2013 0xC1 false false 0xC2 true true 0xC3 float 32 number_float 0xCA float 64 number_float 0xCB uint 8 number_unsigned 0xCC uint 16 number_unsigned 0xCD uint 32 number_unsigned 0xCE uint 64 number_unsigned 0xCF int 8 number_integer 0xD0 int 16 number_integer 0xD1 int 32 number_integer 0xD2 int 64 number_integer 0xD3 str 8 string 0xD9 str 16 string 0xDA str 32 string 0xDB array 16 array 0xDC array 32 array 0xDD map 16 object 0xDE map 32 object 0xDF bin 8 binary 0xC4 bin 16 binary 0xC5 bin 32 binary 0xC6 ext 8 binary 0xC7 ext 16 binary 0xC8 ext 32 binary 0xC9 fixext 1 binary 0xD4 fixext 2 binary 0xD5 fixext 4 binary 0xD6 fixext 8 binary 0xD7 fixext 16 binary 0xD8 negative fixint number_integer 0xE0-0xFF

    The byte 0xC1 is reserved as \"never used\" by the specification. As a value it is rejected with parse_error.112 (invalid byte: 0xC1); as a map key it is rejected with parse_error.113 and the generic \"expected length specification\" message, because the key is read as a string.

    Duplicate keys in a map are accepted; the last value wins.

    "},{"location":"features/binary_formats/messagepack/#extension-types-ext-fixext","title":"Extension types (ext, fixext)","text":"

    MessagePack ext and fixext values are read as binary values, and the ext type byte is stored as the binary subtype. Although the specification defines the type as a signed 8-bit integer (0 to 127 for applications, -128 to -1 reserved, with -1 being the Timestamp extension), the library reads it as an unsigned byte: a negative ext type n becomes subtype 256+n, so ext type -1 is read as subtype 255 and -128 as subtype 128. The Timestamp extension is not interpreted; it is returned as binary with subtype 255. Use has_subtype() to tell a bin value (no subtype) from an ext value (subtype, even if it is 0).

    When serializing, a binary value with a subtype is always written as fixext (1, 2, 4, 8, or 16 bytes) or ext, even for subtype 0 (d6 00 01 02 03 04); a binary value without a subtype is written as bin. Subtypes 128 to 255 are written as the reserved negative ext types (255 as -1), so json::binary({1,2,3,4}, 255) becomes d6 ff 01 02 03 04, which other MessagePack libraries decode as a 32-bit timestamp. A subtype above 255 throws out_of_range.415. The payload length is limited to 4294967295 bytes like all other lengths.

    Info

    Any MessagePack output created by to_msgpack can be successfully parsed by from_msgpack.

    Object keys

    MessagePack allows map keys of any type, whereas JSON only allows strings as keys in object values. Like the JSON-compatible profile sketched in the MessagePack specification, this library restricts map keys to str values. Maps with keys of any other type are rejected with a parse_error.113 exception (or, with allow_exceptions set to false, a discarded value). For most key types the message names the type that was found, for instance:

    [json.exception.parse_error.113] parse error at byte 2: syntax error while parsing MessagePack object key: only string keys are supported, but found nil; last byte: 0xC0\n

    This applies to the SAX interface as well, as the key is read before it is passed on. Such input needs a general-purpose MessagePack library instead.

    Ill-formed UTF-8 in string values

    The MessagePack specification explicitly allows a str value (fixstr, str 8, str 16, str 32) to contain a byte sequence that is not valid UTF-8, and recommends that a deserializer provide a way to obtain the original bytes. This library follows that by default: with its error_handler parameter left at keep (the default), from_msgpack() reads str bytes (object keys included) as-is, without validating them, so such a value round-trips through from_msgpack(to_msgpack(j)) byte for byte. Passing error_handler_t::strict makes from_msgpack() check anyway and throw parse_error.113 for ill-formed UTF-8, and replace/ignore sanitize the string instead of keeping it. to_msgpack() also writes str bytes as-is by default, since the specification permits it; its error_handler parameter can be set to strict to throw type_error.316 instead, or to replace/ignore to sanitize the string, for instance for a decoder that rejects ill-formed UTF-8. However, dump() still requires valid UTF-8 and throws type_error.316 for a value read this way with the default keep handler, unless an error handler is passed that replaces or ignores the ill-formed bytes.

    Example: deserialize a JSON value from MessagePack
    #include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create byte vector\n    std::vector<std::uint8_t> v = {0x82, 0xa7, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x63,\n                                   0x74, 0xc3, 0xa6, 0x73, 0x63, 0x68, 0x65, 0x6d,\n                                   0x61, 0x00\n                                  };\n\n    // deserialize it with MessagePack\n    json j = json::from_msgpack(v);\n\n    // print the deserialized JSON value\n    std::cout << std::setw(2) << j << '\\n';\n}\n

    Output:

    {\n  \"compact\": true,\n  \"schema\": 0\n}\n
    "},{"location":"features/binary_formats/messagepack/#see-also","title":"See also","text":"
    • Binary formats - overview and comparison of the supported binary formats
    • Binary values - how binary values and subtypes map to MessagePack
    • to_msgpack - serialize a JSON value to MessagePack
    • from_msgpack - parse a JSON value from MessagePack
    • JSON_STRICT_BINARY_UTF8 - reject ill-formed UTF-8 in strings
    • SAX interface - decode binary formats without building a value
    "},{"location":"features/binary_formats/ubjson/","title":"UBJSON","text":"

    Universal Binary JSON (UBJSON) is a binary form directly imitating JSON, but requiring fewer bytes of data. It aims to achieve the generality of JSON, combined with being much easier to process than JSON.

    References

    • UBJSON Website
    "},{"location":"features/binary_formats/ubjson/#byte-layout","title":"Byte layout","text":"

    UBJSON is built from just a one-byte, human-readable ASCII type marker (for example, i for int8, S for string, [ for array) followed by the payload of that type. Strings and the like are prefixed with their length, which is itself a UBJSON integer value including its marker. Numbers are stored in big-endian byte order. Containers can be written in two ways: as an unoptimized container that is opened with [ or { and closed with ] or }, or as an optimized container that declares a count (#) after the opening marker, optionally preceded by an element type ($); an element type is only allowed together with a count. An optimized container saves the closing marker and, with a type, the per-element markers.

    Consider the following JSON value (shown formatted for readability):

    {\n  \"id\": 300,\n  \"name\": \"json\",\n  \"pi\": 3.14,\n  \"tags\": [\n    \"a\",\n    \"b\"\n  ]\n}\n

    to_ubjson encodes it to 51 bytes (shown in hexadecimal; the encoding contains no whitespace). The colors mark the role of each byte: type/marker length/count/size data.

    JSONBytesMeaning {7Bobject start ({) \"id\": 300,69 02 69 64 49 01 2Ckey: length 2 as int8 (i), then UTF-8 bytes; value: int16 (I), big-endian \"name\": \"json\",69 04 6E 61 6D 65 53 69 04 6A 73 6F 6Ekey: length 4; value: string (S), length 4 as int8, UTF-8 bytes \"pi\": 3.14,69 02 70 69 44 40 09 1E B8 51 EB 85 1Fkey: length 2; value: float64 (D), big-endian \"tags\": [69 04 74 61 67 73 5Bkey: length 4; value: array start ([) \"a\",53 69 01 61string, length 1 \"b\"53 69 01 62string, length 1 ]5Darray end (]) }7Dobject end (})"},{"location":"features/binary_formats/ubjson/#serialization","title":"Serialization","text":"

    The library uses the following mapping from JSON values types to UBJSON types according to the UBJSON specification:

    JSON value type value/range UBJSON type marker null null null Z boolean true true T boolean false false F number_integer -9223372036854775808..-2147483649 int64 L number_integer -2147483648..-32769 int32 l number_integer -32768..-129 int16 I number_integer -128..127 int8 i number_integer 128..255 uint8 U number_integer 256..32767 int16 I number_integer 32768..2147483647 int32 l number_integer 2147483648..9223372036854775807 int64 L number_unsigned 0..127 int8 i number_unsigned 128..255 uint8 U number_unsigned 256..32767 int16 I number_unsigned 32768..2147483647 int32 l number_unsigned 2147483648..9223372036854775807 int64 L number_unsigned 9223372036854775808..18446744073709551615 high-precision H number_float any value float64 (float32 if number_float_t is float) D (d) string with shortest length indicator string S array see notes on optimized format array [ object see notes on optimized format object {

    Complete mapping

    The mapping is complete in the sense that any JSON value type can be converted to a UBJSON value.

    Any UBJSON output created by to_ubjson can be successfully parsed by from_ubjson.

    Size constraints

    The following values can not be converted to a UBJSON value:

    • strings with more than 9223372036854775807 bytes (theoretical)

    UTF-8 validation of string values and object keys

    UBJSON's required string encoding is UTF-8. By default (the error_handler parameter left at keep), to_ubjson() writes the bytes of string values and object keys unchanged, even if they are not valid UTF-8. With error_handler_t::strict, it throws type_error.316 for ill-formed UTF-8 instead; replace/ignore sanitize the string. JSON_STRICT_BINARY_UTF8 makes strict the default.

    Unused UBJSON markers

    The following markers are not used in the conversion:

    • N: no-op values are never written (they are skipped when reading).
    • C: single-byte strings are serialized with S markers.

    NaN/infinity handling

    NaN and infinity are written as IEEE 754 float64 values (D) and read back unchanged. This differs from dump(), which serializes them to null, and from the UBJSON specification, which encodes infinity as null (it does not mention NaN); other UBJSON readers may therefore not accept these values.

    Optimized formats

    The optimized formats for containers are supported: Parameter use_size adds size information to the beginning of a container and removes the closing marker. Parameter use_type further checks whether all elements of a container have the same type and adds the type marker to the beginning of the container. The use_type parameter must only be used together with use_size = true: combining use_type with use_size = false throws other_error.502 if the value contains a non-empty array, object, or binary value.

    Two elements have the same type if they are written with the same type marker. For example, [1, 2] is written with the type i, but [1, 200] (i, U), [true, false] (T, F), and [1, 2.5] (i, D) are not; an empty container is never given a $ annotation of its own (an array of empty arrays is still typed [).

    Note that use_size = true alone may result in larger representations - the benefit of this parameter is that the receiving side is immediately informed on the number of elements of the container.

    An array whose type marker is Z (null), T (true) or F (false) stores no payload at all, because the marker already is the value. Its declared count is therefore the only thing that decides how much memory the receiving side allocates, and a handful of bytes can describe billions of elements. from_ubjson rejects such an array with out_of_range.408 when the count exceeds 1,048,576 (1 << 20), and to_ubjson writes longer arrays of these types in the counted but untyped form: the $ type marker is dropped, the # count is kept, and every element is written with its own marker ([#l 1048577 Z Z ...), so any value it produces can be read back. Objects and untyped counted arrays are not subject to this limit.

    Binary values

    If the JSON data contains the binary type, the value stored is a list of integers, as suggested by the UBJSON documentation. In particular, this means that serialization and the deserialization of a JSON containing binary values into UBJSON and back will result in a different JSON object.

    Example: serialize JSON values to UBJSON, with and without size/type optimization
    #include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\nusing namespace nlohmann::literals;\n\n// function to print UBJSON's diagnostic format\nvoid print_byte(uint8_t byte)\n{\n    if (32 < byte and byte < 128)\n    {\n        std::cout << static_cast<char>(byte);\n    }\n    else\n    {\n        std::cout << static_cast<int>(byte);\n    }\n}\n\nint main()\n{\n    // create a JSON value\n    json j = R\"({\"compact\": true, \"schema\": false})\"_json;\n\n    // serialize it to UBJSON\n    std::vector<std::uint8_t> v = json::to_ubjson(j);\n\n    // print the vector content\n    for (auto& byte : v)\n    {\n        print_byte(byte);\n    }\n    std::cout << '\\n';\n\n    // create an array of numbers\n    json array = {1, 2, 3, 4, 5, 6, 7, 8};\n\n    // serialize it to UBJSON using default representation\n    std::vector<std::uint8_t> v_array = json::to_ubjson(array);\n    // serialize it to UBJSON using size optimization\n    std::vector<std::uint8_t> v_array_size = json::to_ubjson(array, true);\n    // serialize it to UBJSON using type optimization\n    std::vector<std::uint8_t> v_array_size_and_type = json::to_ubjson(array, true, true);\n\n    // print the vector contents\n    for (auto& byte : v_array)\n    {\n        print_byte(byte);\n    }\n    std::cout << '\\n';\n\n    for (auto& byte : v_array_size)\n    {\n        print_byte(byte);\n    }\n    std::cout << '\\n';\n\n    for (auto& byte : v_array_size_and_type)\n    {\n        print_byte(byte);\n    }\n    std::cout << '\\n';\n}\n

    Output:

    {i7compactTi6schemaF}\n[i1i2i3i4i5i6i7i8]\n[#i8i1i2i3i4i5i6i7i8\n[$i#i812345678\n
    "},{"location":"features/binary_formats/ubjson/#deserialization","title":"Deserialization","text":"

    The library maps UBJSON types to JSON value types as follows:

    UBJSON type JSON value type marker no-op no value, next value is read N null null Z false false F true true T float32 number_float d float64 number_float D uint8 number_unsigned U int8 number_integer i int16 number_integer I int32 number_integer l int64 number_integer L string string S char string C high-precision number_unsigned, number_integer, or number_float H array array (optimized values are supported) [ object object (optimized values are supported) {

    High-precision numbers

    The payload of H is a length-prefixed string that is parsed as a JSON number (surrounding whitespace is ignored). Integer text in the range of number_unsigned_t (non-negative) or number_integer_t (negative) is stored as such; any other valid number text (larger or smaller integers, fractions, and exponents such as 1e2) is stored as number_float, so precision may be lost. Text that is not a valid JSON number raises parse_error.115, a number outside the range of number_float_t (1e999) raises out_of_range.406.

    Complete mapping

    Every well-formed UBJSON value can be converted to a JSON value, with these exceptions: a high-precision number outside the range of number_float_t (out_of_range.406), an optimized array of Z, T, or F with more than 1,048,576 elements, and a count that exceeds the capacity of the container (out_of_range.408). High-precision numbers that do not fit an integer type are stored as floating-point numbers and may lose precision. Ill-formed input is rejected with a parse error.

    Duplicate object keys

    If an object contains the same key more than once, the last value is kept (the UBJSON specification does not address duplicate keys).

    Type marker of optimized containers

    The type marker after $ must be one of Z, N, T, F, i, U, I, l, L, d, D, H, C, S, [, or {. It is checked even if the count is 0; any other marker raises parse_error.112. A counted object typed N ({$N#i1 ...) is not supported.

    Ill-formed UTF-8 in string values and object keys

    UBJSON's required string encoding is UTF-8, but checking it on read is opt-in: with the error_handler parameter left at keep (the default), from_ubjson() accepts a string value or object key whose bytes are not valid UTF-8 and hands them back unchanged. Passing error_handler_t::strict makes from_ubjson() check and throw parse_error.113 for ill-formed UTF-8, and replace/ignore sanitize the string instead of keeping it. However, dump() still requires valid UTF-8 and throws type_error.316 for a value read with the default keep handler, unless an error handler is passed that replaces or ignores the ill-formed bytes. to_ubjson()'s own error_handler parameter defaults to keep (see above), so such a value is written back unchanged.

    Example: deserialize a JSON value from UBJSON
    #include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // create byte vector\n    std::vector<std::uint8_t> v = {0x7B, 0x69, 0x07, 0x63, 0x6F, 0x6D, 0x70, 0x61,\n                                   0x63, 0x74, 0x54, 0x69, 0x06, 0x73, 0x63, 0x68,\n                                   0x65, 0x6D, 0x61, 0x69, 0x00, 0x7D\n                                  };\n\n    // deserialize it with UBJSON\n    json j = json::from_ubjson(v);\n\n    // print the deserialized JSON value\n    std::cout << std::setw(2) << j << '\\n';\n}\n

    Output:

    {\n  \"compact\": true,\n  \"schema\": 0\n}\n
    "},{"location":"features/binary_formats/ubjson/#see-also","title":"See also","text":"
    • Binary formats - overview and comparison of the supported binary formats
    • Binary values - how binary values and subtypes map to UBJSON
    • to_ubjson - serialize a JSON value to UBJSON
    • from_ubjson - parse a JSON value from UBJSON
    • JSON_STRICT_BINARY_UTF8 - reject ill-formed UTF-8 in strings
    • SAX interface - decode binary formats without building a value
    "},{"location":"features/element_access/","title":"Element Access","text":"

    There are many ways elements in a JSON value can be accessed:

    • unchecked access via operator[]
    • checked access via at
    • access with default value via value
    • iterators
    • JSON pointers

    Testing whether a key or index exists before accessing it is also possible, with contains or find (which returns an iterator to the value, or end() if it is not found).

    How do I get a value out? Start at the top and follow the first question that applies:

    flowchart TD\n    A[\"getting a value out\"] --> P{{\"nested path such as /server/port?\"}}\n    P -->|\"yes\"| JP[\"JSON Pointer: at(ptr), value(ptr, default), contains(ptr)\"]\n    P -->|\"no, one key or index\"| T{{\"only testing whether it exists?\"}}\n    T -->|\"yes\"| CF[\"contains() / find()\"]\n    T -->|\"no\"| M{{\"may it be missing?\"}}\n    M -->|\"yes, a fallback is fine\"| V[\"value(key, default)\"]\n    M -->|\"yes, and missing is an error\"| AT[\"at(): throws out_of_range\"]\n    M -->|\"no, it exists and its type is known\"| OP[\"operator[] and get#lt;T#gt;()\"]\n    OP -.- W[\"non-const operator[] inserts null for a missing key\"]

    Decision tree for reading a value: the labels on the arrows are the answers to the questions, and the boxes name the functions to use. The dashed line marks a side effect of the non-const operator[].

    "},{"location":"features/element_access/#does-this-key-exist","title":"Does this key exist?","text":"

    Use contains to test for a key; it does not modify the value and does not throw:

    json j = {{\"name\", \"Mary\"}, {\"address\", {{\"city\", \"Berlin\"}}}};\n\nj.contains(\"name\");                   // true\nj.contains(\"age\");                    // false\nj.contains(\"city\");                   // false: contains() only looks at the top level\nj[\"address\"].contains(\"city\");        // true\nj.contains(json::json_pointer(\"/address/city\"));  // true: a JSON pointer tests a nested path in one call\n

    If the value is needed afterwards, find tests and accesses with a single lookup:

    if (auto it = j.find(\"name\"); it != j.end())\n{\n    std::cout << *it << '\\n';\n}\n

    contains also returns true for a key whose value is null; use j.contains(\"k\") && !j[\"k\"].is_null() if a null should count as missing. To read a value with a fallback instead, see value.

    operator[] inserts missing keys

    Like std::map::operator[], the non-const operator[] adds a null value if the key is missing. Testing a key with it therefore changes the object:

    json j = {{\"foo\", 1}};\nbool absent = j[\"bar\"].is_null();   // true, but j is now {\"bar\": null, \"foo\": 1}\n

    Use contains/find to test, and at to access a value that must exist (it throws an out_of_range exception otherwise).

    "},{"location":"features/element_access/#see-also","title":"See also","text":"
    • operator[] - unchecked access
    • at - checked access
    • value - access with default value
    • contains - and find - test for existence
    • front - and back - first and last element
    • items - iterate over keys and values
    • Checked access: at - access with range checking
    • Unchecked access: operator[] - access without range checking
    • Access with default value: value - fall back to a default instead of throwing
    • Iterators - visit all elements of arrays and objects
    • JSON Pointer - address nested values with a single string
    • Modifying values - add, merge and remove elements
    • basic_json - all member functions
    "},{"location":"features/element_access/checked_access/","title":"Checked access: at","text":""},{"location":"features/element_access/checked_access/#overview","title":"Overview","text":"

    The at member function performs checked access; that is, it returns a reference to the desired value if it exists and throws a basic_json::out_of_range exception otherwise.

    Example: read access

    Consider the following JSON value:

    {\n    \"name\": \"Mary Smith\",\n    \"age\": 42,\n    \"hobbies\": [\"hiking\", \"reading\"]\n}\n

    Assume the value is parsed to a json variable j.

    expression value j {\"name\": \"Mary Smith\", \"age\": 42, \"hobbies\": [\"hiking\", \"reading\"]} j.at(\"name\") \"Mary Smith\" j.at(\"age\") 42 j.at(\"hobbies\") [\"hiking\", \"reading\"] j.at(\"hobbies\").at(0) \"hiking\" j.at(\"hobbies\").at(1) \"reading\"

    The return value is a reference, so it can be used to modify the original value.

    Example: write access
    j.at(\"name\") = \"John Smith\";\n

    This code produces the following JSON value:

    {\n    \"name\": \"John Smith\",\n    \"age\": 42,\n    \"hobbies\": [\"hiking\", \"reading\"]\n}\n

    When accessing an invalid index (i.e., an index greater than or equal to the array size) or the passed object key is non-existing, an exception is thrown.

    Example: access via invalid index or missing key
    j.at(\"hobbies\").at(3) = \"cooking\";\n

    This code produces the following exception:

    [json.exception.out_of_range.401] array index 3 is out of range\n

    When extended diagnostic messages are enabled by defining JSON_DIAGNOSTICS, the exception further gives information where the key or index is missing or out of range.

    [json.exception.out_of_range.401] (/hobbies) array index 3 is out of range\n
    "},{"location":"features/element_access/checked_access/#notes","title":"Notes","text":"

    Exceptions

    • at can only be used with objects (with a string argument) or with arrays (with a numeric argument). For other types, a basic_json::type_error is thrown.
    • basic_json::out_of_range exception exceptions are thrown if the provided key is not found in an object or the provided index is invalid.
    "},{"location":"features/element_access/checked_access/#summary","title":"Summary","text":"scenario non-const value const value access to existing object key reference to existing value is returned const reference to existing value is returned access to valid array index reference to existing value is returned const reference to existing value is returned access to non-existing object key basic_json::out_of_range exception is thrown basic_json::out_of_range exception is thrown access to invalid array index basic_json::out_of_range exception is thrown basic_json::out_of_range exception is thrown

    Result of at in each scenario, for a non-const and a const value.

    "},{"location":"features/element_access/checked_access/#see-also","title":"See also","text":"
    • Element Access - overview of all ways to access elements
    • Unchecked access: operator[] - access without range checking
    • Access with default value: value - fall back to a default instead of throwing
    • at - checked access by reference
    • JSON Pointer - access nested values with at and a pointer
    "},{"location":"features/element_access/default_value/","title":"Access with default value: value","text":""},{"location":"features/element_access/default_value/#overview","title":"Overview","text":"

    In many situations, such as configuration files, missing values are not exceptional, but may be treated as if a default value was present. For this case, use value(key, default_value) which takes the key you want to access and a default value in case there is no value stored with that key. This is equivalent to Python's dict.get(key, default).

    "},{"location":"features/element_access/default_value/#example","title":"Example","text":"Example

    Consider the following JSON value:

    {\n    \"logOutput\": \"result.log\",\n    \"append\": true\n}\n

    Assume the value is parsed to a json variable j.

    expression value j {\"logOutput\": \"result.log\", \"append\": true} j.value(\"logOutput\", \"logfile.log\") \"result.log\" j.value(\"append\", true) true j.value(\"append\", false) true j.value(\"logLevel\", \"verbose\") \"verbose\""},{"location":"features/element_access/default_value/#nested-values","title":"Nested values","text":"

    To read a value deep inside a document, pass a JSON Pointer instead of a key. The default value is returned if the value at the pointer does not exist, including the case that an intermediate key is missing. There is no need to check each level with contains first.

    json j = {{\"server\", {{\"port\", 8080}}}, {\"list\", {10, 20}}};\n\nint port = j.value(\"/server/port\"_json_pointer, 80);        // 8080\nint timeout = j.value(\"/server/limits/timeout\"_json_pointer, 30); // 30 (missing intermediate key)\nint second = j.value(\"/list/1\"_json_pointer, 0);            // 20 (numeric tokens index arrays)\nint third = j.value(\"/list/5\"_json_pointer, 0);             // 0 (index out of range)\n\nbool has_port = j.contains(\"/server/port\"_json_pointer);    // true\nbool has_host = j.contains(\"/server/host/name\"_json_pointer); // false\n

    If the path is only available as a dotted string such as \"server.port\", do not build the pointer by concatenating \"/\" and the parts: keys containing / or ~ would be misinterpreted. Append each part as a reference token with operator/= instead. It escapes the token for you.

    json::json_pointer to_pointer(const std::string& dotted)\n{\n    json::json_pointer ptr;\n    std::istringstream in(dotted);\n    for (std::string token; std::getline(in, token, '.');)\n    {\n        ptr /= token;\n    }\n    return ptr;\n}\n\nint port = j.value(to_pointer(\"server.port\"), 80);          // 8080\nint first = j.value(to_pointer(\"list.0\"), 0);               // 10\n

    The key \"a/b\" yields the pointer \"/a~1b\"; the dot-splitting itself is up to the caller, so keys containing . need a different separator.

    "},{"location":"features/element_access/default_value/#notes","title":"Notes","text":"

    Exceptions

    • With string keys, value can only be used with objects. For other types, a basic_json::type_error is thrown.
    • With JSON Pointers, value can be used with both objects and arrays. For other types (null, boolean, number, string), a basic_json::type_error is thrown.

    null and mistyped members are not missing

    value returns the default value only if the key is absent. If the member exists, it is converted to the type of the default value, even if it is null. For {\"k\": null}, the call j.value(\"k\", 0) throws a basic_json::type_error, and so does a member of another type such as a string where a number is expected. The same holds for JSON Pointers.

    To treat null like a missing value, check for it explicitly:

    int n = (j.contains(\"k\") && !j[\"k\"].is_null()) ? j[\"k\"].get<int>() : 0;\n

    With C++17, get<std::optional<T>>() maps null to an empty optional. As at throws out_of_range for an absent key, use find to cover both cases:

    std::optional<int> n;                        // empty if \"k\" is absent or null\nif (const auto it = j.find(\"k\"); it != j.end())\n{\n    n = it->get<std::optional<int>>();       // still throws for a non-number such as \"text\"\n}\n

    Return type

    The value function is a template, and the return type of the function is determined by the type of the provided default value unless otherwise specified. This can have unexpected effects. In the example below, we store a 64-bit unsigned integer. We get exactly that value when using operator[]. However, when we call value and provide 0 as default value, then -1 is returned. This occurs, because 0 has type int which overflows when handling the value 18446744073709551615.

    To address this issue, either provide a correctly typed default value or use the template parameter to specify the desired return type. Note that this issue occurs even when a value is stored at the provided key, and the default value is not used as the return value.

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    json j = json::parse(R\"({\"uint64\": 18446744073709551615})\");\n\n    std::cout << \"operator[]:                \" << j[\"uint64\"] << '\\n'\n              << \"default value (int):       \" << j.value(\"uint64\", 0) << '\\n'\n              << \"default value (uint64_t):  \" << j.value(\"uint64\", static_cast<std::uint64_t>(0)) << '\\n'\n              << \"explicit return value type: \" << j.value<std::uint64_t>(\"uint64\", 0) << '\\n';\n}\n

    Output:

    operator[]:                18446744073709551615\ndefault value (int):       -1\ndefault value (uint64_t):  18446744073709551615\nexplicit return value type: 18446744073709551615\n
    "},{"location":"features/element_access/default_value/#see-also","title":"See also","text":"
    • value - for access with default value
    • Checked access: at - access with bounds checking
    • JSON Pointer - addressing values by path
    • contains - to check whether a key or JSON Pointer exists
    • json_pointer::operator/= - to build a pointer token by token
    • Unchecked access: operator[] - access without range checking
    • Element Access - overview of all ways to access elements
    "},{"location":"features/element_access/unchecked_access/","title":"Unchecked access: operator[]","text":""},{"location":"features/element_access/unchecked_access/#overview","title":"Overview","text":"

    Elements in a JSON object and a JSON array can be accessed via operator[] similar to a std::map and a std::vector, respectively.

    Example: read access

    Consider the following JSON value:

    {\n    \"name\": \"Mary Smith\",\n    \"age\": 42,\n    \"hobbies\": [\"hiking\", \"reading\"]\n}\n

    Assume the value is parsed to a json variable j.

    expression value j {\"name\": \"Mary Smith\", \"age\": 42, \"hobbies\": [\"hiking\", \"reading\"]} j[\"name\"] \"Mary Smith\" j[\"age\"] 42 j[\"hobbies\"] [\"hiking\", \"reading\"] j[\"hobbies\"][0] \"hiking\" j[\"hobbies\"][1] \"reading\"

    The return value is a reference, so it can modify the original value. In case the passed object key is non-existing, a null value is inserted which can immediately be overwritten.

    Example: write access
    j[\"name\"] = \"John Smith\";\nj[\"maidenName\"] = \"Jones\";\n

    This code produces the following JSON value:

    {\n    \"name\": \"John Smith\",\n    \"maidenName\": \"Jones\",\n    \"age\": 42,\n    \"hobbies\": [\"hiking\", \"reading\"]\n}\n

    When accessing an invalid index (i.e., an index greater than or equal to the array size), the JSON array is resized such that the passed index is the new maximal index. Intermediate values are filled with null.

    Example: filling up arrays with null values
    j[\"hobbies\"][0] = \"running\";\nj[\"hobbies\"][3] = \"cooking\";\n

    This code produces the following JSON value:

    {\n    \"name\": \"John Smith\",\n    \"maidenName\": \"Jones\",\n    \"age\": 42,\n    \"hobbies\": [\"running\", \"reading\", null, \"cooking\"]\n}\n
    "},{"location":"features/element_access/unchecked_access/#notes","title":"Notes","text":"

    Design rationale

    The library behaves differently to std::vector and std::map:

    • std::vector::operator[] never inserts a new element.
    • std::map::operator[] is not available for const values.

    The type json wraps all JSON value types. It would be impossible to remove operator[] for const objects. At the same time, inserting elements for non-const objects is really convenient as it avoids awkward insert calls. To this end, we decided to have an inserting non-const behavior for both arrays and objects.

    Info

    The access is unchecked. In case the passed object key does not exist or the passed array index is invalid, no exception is thrown.

    Danger

    • It is undefined behavior to access a const object with a non-existing key.
    • It is undefined behavior to access a const array with an invalid index.
    • In debug mode, an assertion will fire in both cases. You can disable assertions by defining the preprocessor symbol NDEBUG or redefine the macro JSON_ASSERT(x). See the documentation on runtime assertions for more information.

    Exceptions

    operator[] can only be used with objects (with a string argument) or with arrays (with a numeric argument). For other types, a basic_json::type_error is thrown.

    "},{"location":"features/element_access/unchecked_access/#performance-reserving-array-capacity","title":"Performance: reserving array capacity","text":"

    There is no public reserve(count) member on basic_json for pre-allocating array capacity. If you are building a large array incrementally (e.g., via repeated push_back()) and know its final size ahead of time, you can reserve capacity via get_ref() to access the underlying array_t directly:

    json j = json::array();\nj.get_ref<json::array_t&>().reserve(1000);\nfor (int i = 0; i < 1000; ++i) {\n    j.push_back(i);\n}\n
    "},{"location":"features/element_access/unchecked_access/#summary","title":"Summary","text":"scenario non-const value const value access to existing object key reference to existing value is returned const reference to existing value is returned access to valid array index reference to existing value is returned const reference to existing value is returned access to non-existing object key reference to newly inserted null value is returned undefined behavior; runtime assertion in debug mode access to invalid array index reference to newly inserted null value is returned; any index between previous maximal index and passed index are filled with null undefined behavior; runtime assertion in debug mode

    Result of operator[] in each scenario, for a non-const and a const value.

    "},{"location":"features/element_access/unchecked_access/#see-also","title":"See also","text":"
    • Element Access - overview of all ways to access elements
    • Checked access: at - access with range checking
    • Access with default value: value - fall back to a default instead of throwing
    • operator[] - unchecked access by reference
    • Runtime assertions - assertions that guard operator[] misuse
    "},{"location":"features/parsing/","title":"Parsing","text":"

    This library can create a JSON value from a wide range of inputs. This page gives an overview of the available parsing functions and how they behave; the linked pages go into more detail.

    flowchart LR\n    I[\"JSON input\"] --> P[\"parse()\"]\n    I --> S[\"sax_parse()\"]\n    I --> A[\"accept()\"]\n    P -->|\"optional parser callback filters values\"| D[\"basic_json value (DOM)\"]\n    S --> H[\"events delivered to a user SAX handler\"]\n    A --> V[\"bool: is the input valid JSON?\"]

    The three entry points for parsing: parse() builds a basic_json value, optionally filtered by a parser callback, sax_parse() delivers events to a SAX handler, and accept() only checks whether the input is valid.

    "},{"location":"features/parsing/#input","title":"Input","text":"

    The parse function reads a JSON value from an input. The input can be

    • a string (std::string, C string, or string literal),
    • a wide string (std::u16string, std::u32string, or std::wstring, or a wide string literal),
    • a std::istream (e.g., an std::ifstream reading from a file),
    • a FILE* pointer,
    • a pair of iterators over a contiguous range (e.g., a std::vector<std::uint8_t>), or
    • a contiguous container.
    // parse from a string\njson j = json::parse(R\"({\"happy\": true, \"pi\": 3.141})\");\n\n// parse from a file\nstd::ifstream f(\"example.json\");\njson data = json::parse(f);\n

    The input must be encoded in UTF-8; other encodings are not supported. The exception is wide-character input, which is read as UTF-16 or UTF-32 \u2014 depending on the character type \u2014 and converted to UTF-8; see the parse page for an example. A single input may contain only one JSON value. Inputs consisting of multiple values separated by newlines are handled by the JSON Lines format; input that arrives in chunks or contains several values is covered in Large, streamed, and partial input.

    By default, the library rejects comments and trailing commas. Both can be enabled with parameters of the parse function \u2014 see comments and trailing commas.

    basic_json_document::parse accepts the same inputs with the same options, but keeps the result in a document rather than in a basic_json value; see Documents and views below.

    "},{"location":"features/parsing/#strictness-and-trailing-data","title":"Strictness and trailing data","text":"

    parse reads a single JSON value and requires the whole input to be consumed: any non-whitespace data after the value is reported as a parse error. Use it when you want to guarantee that an input is exactly one complete JSON document.

    operator>> follows relaxed std::istream semantics instead: it parses one JSON value and leaves the stream positioned right after it, without requiring the rest of the stream to be consumed. This is what makes it possible to read several concatenated values from the same stream, but it also means that \"a valid document followed by trailing bytes\" is accepted rather than rejected. If you are validating conformance, or need to reject any input that is not exactly one JSON document, prefer parse.

    When using operator>> to read several concatenated values this way, a value that is a number must be followed by whitespace, because operator>> consumes the character that terminates a number, unless JSON_PRECISE_STREAM_POSITION is defined to 1 \u2014 see the operator>> notes for details and examples.

    "},{"location":"features/parsing/#input-sources-and-performance","title":"Input sources and performance","text":"

    All inputs produce the same values and the same exceptions, but they are read in different ways, which makes some of them faster than others:

    input how it is read strings, string views, string literals, contiguous containers, pointer or iterator ranges over contiguous memory the whole input is scanned in bulk: runs of string characters, numbers, and indentation are recognized several bytes at a time std::istream (std::ifstream, std::istringstream, ...) the characters the stream buffer holds are scanned in bulk like a string; the stream buffer is asked for more when they are used up FILE* one character at a time, with the file locked once for the whole parse other iterator ranges (e.g., std::list<char>, std::istreambuf_iterator<char>), wide strings one character at a time

    Parsing a file from a std::ifstream is therefore only about 10 to 20 % slower than reading the whole file into a std::string first and parsing that, and it needs no memory for a copy of the file. The stream is never read ahead: after parsing, it is positioned exactly as if every character had been read one at a time, so operator>> can still read several values from one stream (see also JSON Lines).

    Two macros switch these optimizations off without changing any result: JSON_DISABLE_STREAM_BULK_SCAN for stream buffers that do not follow the usual std::streambuf contract, and JSON_DISABLE_UNLOCKED_FILE_IO for programs in which another thread must use the same FILE object while it is parsed.

    Where the target has them, strings are scanned with vector instructions: SSE2 on x86-64 (and SSSE3 for UTF-8 text, when the CPU has it) and NEON on AArch64. JSON_NO_SIMD selects portable code instead, again without changing any result.

    "},{"location":"features/parsing/#sax-vs-dom-parsing","title":"SAX vs. DOM parsing","text":"

    The library offers two parsing models, and a third, read-only alternative:

    • DOM parsing (the default): the complete input is read and stored as an in-memory basic_json value that can be traversed and modified freely. This is what parse does, and it is the right choice for most use cases.
    • SAX parsing: instead of building a value, the parser reports events (such as \"a string was read\" or \"an object started\") to a handler that you implement. This avoids building the full value in memory and is useful for very large inputs or when you only need to extract parts of the input. See the SAX interface for details and sax_parse for the API.

    • Document and views (<nlohmann/json_view.hpp>, added in version 3.13.0 unreleased): json_document::parse reads the same JSON grammar but builds a flat, read-only index of the values instead of a basic_json tree. Strings and floating-point numbers are read from the text on demand, and only the parts you materialize() become basic_json values. This avoids most of the work when you need only a few values from a large or frequently parsed text; see Zero-copy JSON views. It is read-only, so use parse when you need to modify the value.

    You can influence a DOM parse without switching to the SAX interface by passing a parser callback, which is called during parsing and can, for example, discard parts of the input.

    "},{"location":"features/parsing/#documents-and-views","title":"Documents and views","text":"

    A third model sits between DOM and SAX: basic_json_document::parse parses the input into a document that keeps the text and a flat index of the values in it, and basic_json_view gives read-only access to the values through that index. The whole input is validated during parsing, but only integers and strings that contain escape sequences are converted right away (the strings into a buffer owned by the document). Floating-point numbers and all other strings stay in the source text and are only converted when they are read, which is faster and uses less memory than building a tree of basic_json values when only parts of the document are needed. A document can also be modified in place, and it can be saved and loaded again without parsing it.

    #include <nlohmann/json_view.hpp>\n\njson_document doc = json_document::parse(R\"({\"happy\": true, \"pi\": 3.141})\");\nstd::cout << doc.root()[\"happy\"].get<bool>() << '\\n';\n

    See Zero-copy JSON views for the concept and the trade-offs.

    "},{"location":"features/parsing/#exceptions","title":"Exceptions","text":"

    When the input is not valid JSON, the parse function throws an exception by default. If exceptions are undesired or unavailable, the parser can instead return a discarded value, or accept can be used to only check whether an input is valid JSON. See parsing and exceptions for the available options.

    "},{"location":"features/parsing/#see-also","title":"See also","text":"
    • parse - deserialize from a compatible input
    • basic_json_document::parse - deserialize into a document instead of a value
    • accept - check if the input is valid JSON
    • sax_parse - generate SAX events
    • JSON Lines - parse newline-delimited JSON
    • Large, streamed, and partial input - chunked, concatenated, and very large input
    • parser callbacks - influence the parsing by a callback function
    • SAX interface - implement a custom SAX handler
    • Zero-copy JSON views - parse into a read-only document and read it through views
    • parsing and exceptions - control error handling
    • parsing untrusted input - what to consider when parsing input from untrusted sources
    • operator>> - deserialize from stream
    • json_sax - documentation of the SAX interface
    • parse_error - exception thrown on a parse error
    • Comments - ignore // and /* */ comments while parsing
    • Trailing Commas - accept trailing commas in arrays and objects
    • Serialization - pretty-printing, UTF-8 handling, and number output
    • Working Without Exceptions - error handling when exceptions are disabled
    • Exceptions - list of exceptions and error codes
    "},{"location":"features/parsing/json_lines/","title":"JSON Lines","text":"

    The JSON Lines format is a text format of newline-delimited JSON. In particular:

    1. The input must be UTF-8 encoded.
    2. Every line must be a valid JSON value.
    3. The line separator must be \\n. As \\r is silently ignored, \\r\\n is also supported.
    4. The final character may be \\n, but is not required to be one.

    JSON Text example

    {\"name\": \"Gilbert\", \"wins\": [[\"straight\", \"7\u2663\"], [\"one pair\", \"10\u2665\"]]}\n{\"name\": \"Alexa\", \"wins\": [[\"two pair\", \"4\u2660\"], [\"two pair\", \"9\u2660\"]]}\n{\"name\": \"May\", \"wins\": []}\n{\"name\": \"Deloise\", \"wins\": [[\"three of a kind\", \"5\u2663\"]]}\n

    JSON Lines input with more than one value is treated as invalid JSON by the parse or accept functions. To process it line by line, functions like std::getline can be used:

    Example: Parse JSON Text input line by line

    The example below demonstrates how JSON Lines can be processed.

    #include <sstream>\n#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // JSON Lines (see https://jsonlines.org)\n    std::stringstream input;\n    input << R\"({\"name\": \"Gilbert\", \"wins\": [[\"straight\", \"7\u2663\"], [\"one pair\", \"10\u2665\"]]}\n{\"name\": \"Alexa\", \"wins\": [[\"two pair\", \"4\u2660\"], [\"two pair\", \"9\u2660\"]]}\n{\"name\": \"May\", \"wins\": []}\n{\"name\": \"Deloise\", \"wins\": [[\"three of a kind\", \"5\u2663\"]]}\n)\";\n\n    std::string line;\n    while (std::getline(input, line))\n    {\n        std::cout << json::parse(line) << '\\n';\n    }\n}\n

    Output:

    {\"name\":\"Gilbert\",\"wins\":[[\"straight\",\"7\u2663\"],[\"one pair\",\"10\u2665\"]]}\n{\"name\":\"Alexa\",\"wins\":[[\"two pair\",\"4\u2660\"],[\"two pair\",\"9\u2660\"]]}\n{\"name\":\"May\",\"wins\":[]}\n{\"name\":\"Deloise\",\"wins\":[[\"three of a kind\",\"5\u2663\"]]}\n

    Note

    Using operator>> like

    json j;\nwhile (input >> j)\n{\n    std::cout << j << std::endl;\n}\n

    with a JSON Lines input does not work, because the parser will try to parse one value after the last one and throw a parse_error.101 exception. The same happens for a stream of concatenated (non-newline-delimited) JSON values: operator>> reads them one at a time, but the loop above throws after the last value. To read either format with operator>>, check for the end of the stream before each read:

    json j;\nwhile (input >> std::ws && input.peek() != std::char_traits<char>::eof())\n{\n    input >> j;\n    std::cout << j << std::endl;\n}\n

    A value that is a number must be followed by whitespace \u2014 see the notes of operator>> for details.

    "},{"location":"features/parsing/json_lines/#see-also","title":"See also","text":"
    • Parsing - overview of the parsing functions
    • Large, Streamed, and Partial Input - chunked, concatenated, and very large input
    • parse - deserialize from a compatible input
    • operator>> - deserialize from stream
    "},{"location":"features/parsing/large_and_partial_input/","title":"Large, Streamed, and Partial Input","text":"

    parse reads exactly one complete JSON value and builds it in memory. It cannot be paused and resumed, and it does not hand back a half-parsed value when the input ends early. This page shows what to do when the input does not fit that model: it arrives in pieces, it contains several values, or it is too large to hold as a json value.

    flowchart TD\n    A[\"my input is...\"] --> B{\"several JSON values in one stream?\"}\n    B -->|\"yes\"| C[\"read them one at a time\"]\n    A --> D{\"arriving in chunks (socket, pipe)?\"}\n    D -->|\"yes\"| E[\"frame the messages, or buffer until complete\"]\n    A --> F{\"too large to keep in memory?\"}\n    F -->|\"yes\"| G[\"discard parts with a callback, or use SAX\"]\n    A --> H{\"only a small part is needed?\"}\n    H -->|\"yes\"| I[\"stop early with SAX, or read through a view\"]

    Questions about the input and the approach this page describes for each; an input can match more than one question.

    "},{"location":"features/parsing/large_and_partial_input/#several-values-in-one-stream","title":"Several values in one stream","text":"

    For newline-delimited input, read line by line and parse each line, as described in JSON Lines. For values that are simply concatenated, operator>> reads one value and leaves the stream positioned after it. Check for the end of the stream before each read, because a read at the end throws:

    Example: read concatenated values
    #include <iostream>\n#include <sstream>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    std::istringstream input(R\"({\"a\":1} [2,3] 4 \"s\")\");\n\n    // check for the end of the stream before each read, because a read at the end throws\n    json j;\n    while (input >> std::ws && input.peek() != std::char_traits<char>::eof())\n    {\n        input >> j;\n        std::cout << j << '\\n';\n    }\n}\n

    Output:

    {\"a\":1}\n[2,3]\n4\n\"s\"\n

    The same works for binary formats. from_cbor and its relatives accept strict = false to stop after the first value and leave the rest of the stream untouched; tellg() then reports how many bytes the value took:

    Example: read one CBOR value and find out how many bytes it used
    #include <iostream>\n#include <sstream>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n    // a CBOR value followed by other data\n    const std::vector<std::uint8_t> cbor = json::to_cbor(json{1, 2, 3});\n    std::string data(cbor.begin(), cbor.end());\n    data += \"TRAILING\";\n\n    std::istringstream input(data);\n    json j = json::from_cbor(input, false); // strict = false: stop after the first value\n\n    std::cout << \"value: \" << j << '\\n';\n    std::cout << \"bytes used: \" << input.tellg() << '\\n';\n\n    std::string rest;\n    input >> rest;\n    std::cout << \"remaining input: \" << rest << '\\n';\n}\n

    Output:

    value: [1,2,3]\nbytes used: 4\nremaining input: TRAILING\n
    "},{"location":"features/parsing/large_and_partial_input/#input-arriving-in-chunks","title":"Input arriving in chunks","text":"

    A socket, pipe, or HTTP body hands over data in pieces of arbitrary size, and a piece can end in the middle of a number, a string, or an object. The parser does not keep state between calls, so there are two ways to deal with this.

    Frame the messages. The most robust approach is a protocol that says where a value ends: one value per line (JSON Lines), a length prefix, or a delimiter. Collect the bytes of one message and parse them when the frame is complete. Prefer this whenever you control the protocol.

    Buffer until the value is complete. If the data has no framing, append every chunk to a buffer and try to parse it. A parse error at the very end of the buffer means that the input ended prematurely, while an error anywhere else is a real syntax error. The member byte of the parse_error exception is one past the buffer size in the first case:

    Example: buffer chunks until the value is complete
    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nstd::string buffer;\n\n// call for every chunk; returns true and sets `value` once the buffer holds one complete JSON value\nbool push(const std::string& chunk, json& value)\n{\n    buffer += chunk;\n    try\n    {\n        value = json::parse(buffer);\n        buffer.clear();\n        return true;\n    }\n    catch (const json::parse_error& e)\n    {\n        if (e.byte == buffer.size() + 1)\n        {\n            return false; // the input ends prematurely: wait for more data\n        }\n        throw; // a real syntax error\n    }\n}\n\nint main()\n{\n    json value;\n    const auto chunks = {\"{\\\"na\", \"me\\\": \\\"Ma\", \"ry\\\", \\\"l\", \"ist\\\": [1, 2\", \", 3]}\"};\n    for (const std::string chunk : chunks)\n    {\n        std::cout << \"chunk \" << chunk << \" -> \" << (push(chunk, value) ? \"complete\" : \"incomplete\") << '\\n';\n    }\n    std::cout << value << '\\n';\n\n    // a syntax error in the middle is not mistaken for missing data\n    try\n    {\n        push(\"[1, ]\", value);\n    }\n    catch (const json::parse_error& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n}\n

    Output:

    chunk {\"na -> incomplete\nchunk me\": \"Ma -> incomplete\nchunk ry\", \"l -> incomplete\nchunk ist\": [1, 2 -> incomplete\nchunk , 3]} -> complete\n{\"list\":[1,2,3],\"name\":\"Mary\"}\n[json.exception.parse_error.101] parse error at line 1, column 5: syntax error while parsing value - unexpected ']'; expected '[', '{', or a literal\n

    The example feeds a document in five chunks. The first four are reported as incomplete, and a syntax error is reported as such, not as missing data.

    The chunks of the example, and the bytes each attempt parses again:

    Buffering chunks until the value is complete: five chunks of {\"name\": \"Mary\", \"list\": [1, 2, 3]} appended to a buffer. After chunks 1 to 4 the buffer has 4, 12, 19, and 30 bytes, and parsing it fails at byte 5, 13, 20, and 31: one past the end, so the input is incomplete and the program waits for more. After chunk 5 the buffer of 35 bytes parses as one complete value. For the input [1, ] of 5 bytes the error is at byte 5, before the end, so it is a real syntax error. Every attempt parses the buffer from byte 1, so 4 + 12 + 19 + 30 + 35 = 100 bytes are parsed for a 35-byte value, and the work grows quadratically. chunk buffer, parsed from byte 1 each time result chunk 1 {\"na error at byte 5 = size + 1 incomplete: wait for more chunk 2 {\"name\": \"Ma error at byte 13 = size + 1 incomplete: wait for more chunk 3 {\"name\": \"Mary\", \"l error at byte 20 = size + 1 incomplete: wait for more chunk 4 {\"name\": \"Mary\", \"list\": [1, 2 error at byte 31 = size + 1 incomplete: wait for more chunk 5 {\"name\": \"Mary\", \"list\": [1, 2, 3]} parsed, size 35 complete: one value other input [1, ] error at byte 5, size 5 before the end: a real error Bytes parsed: 4 + 12 + 19 + 30 + 35 = 100 for a value of 35 bytes. Every attempt starts again at byte 1, so the total work grows quadratically with the size of the value.

    Each row is one parse attempt on the growing buffer: an error at the byte after the end of the buffer means the value is incomplete, an error before the end is a real syntax error. The last line adds up the bytes parsed over all attempts.

    Limits of buffering

    • The buffer must contain exactly one value. Data that belongs to the next value is a syntax error. Use framing if values follow each other without a separator.
    • A number at the end of the buffer is a complete value, even if more digits are still to come (12 may be the start of 123). Buffering cannot detect this; use framing for top-level numbers.
    • Every attempt parses the buffer from the beginning, so the total work grows quadratically with the size of the value. Limit the size of the buffer for input you do not trust (see untrusted input).
    "},{"location":"features/parsing/large_and_partial_input/#input-too-large-for-memory","title":"Input too large for memory","text":"

    The input does not have to become one huge json value. The two tools below process it piece by piece.

    How the memory use develops while a large array of records is parsed (illustrative, not a measurement):

    Illustrative memory use over time while a large array of records is parsed, not a measurement. Four curves. D\u200bOM, parse(): rises steadily until the whole tree is in memory. json_document: starts at about the size of the text, which it keeps, and grows a little while its index is built. Parser callback that discards every record: stays flat at the size of one record. S\u200bAX: stays flat and lowest, because no value is built and only what the handler keeps is in memory. memory time: records parsed illustrative, not a measurement D\u200bOM: parse() the whole tree json_document the text plus its index callback, discard one record at a time S\u200bAX only what the handler keeps

    Memory use over the number of records parsed: parse() keeps the whole tree, json_document the text plus its index, a discarding callback one record at a time, and SAX only what the handler keeps.

    "},{"location":"features/parsing/large_and_partial_input/#handle-and-discard-elements-with-a-callback","title":"Handle and discard elements with a callback","text":"

    A parser callback is called for every finished value. If it returns false, the value is discarded and its memory is released at once. For a file that consists of one huge array (or one huge object) of records, handle each record at depth 1 and discard it:

    Example: handle and discard each record of a large array
    #include <iostream>\n#include <sstream>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nvoid handle(const json& record)\n{\n    std::cout << \"handling \" << record << '\\n';\n}\n\nint main()\n{\n    std::istringstream file(R\"([{\"id\": 1}, {\"id\": 2}, {\"id\": 3}])\");\n\n    json result = json::parse(file, [](int depth, json::parse_event_t event, json & record)\n    {\n        if (depth == 1 && event == json::parse_event_t::object_end)\n        {\n            handle(record);\n            return false; // discard the record\n        }\n        return true;\n    });\n\n    std::cout << \"result: \" << result << '\\n';\n}\n

    Output:

    handling {\"id\":1}\nhandling {\"id\":2}\nhandling {\"id\":3}\nresult: []\n

    Only one record is in memory at any time. The same recipe, with more detail, is in the parser callbacks page. To skip entire members you do not need, discard them when their key is read; see the example for parse_event_t::key.

    "},{"location":"features/parsing/large_and_partial_input/#extract-a-few-values-and-stop-with-sax","title":"Extract a few values and stop with SAX","text":"

    With the SAX interface, no value is built at all, and returning false from any handler function stops the parser. sax_parse then returns false, and the rest of the input is not read. The example finds the first id in a document without parsing the remainder:

    Example: stop parsing as soon as a value is found
    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nstruct find_id : nlohmann::json_sax<json>\n{\n    bool next_is_id = false;\n    json::number_unsigned_t id = 0;\n\n    bool key(std::string& name) override\n    {\n        next_is_id = (name == \"id\");\n        return true;\n    }\n\n    bool number_unsigned(json::number_unsigned_t value) override\n    {\n        if (next_is_id)\n        {\n            id = value;\n            return false; // found: stop parsing\n        }\n        return true;\n    }\n\n    bool null() override\n    {\n        return true;\n    }\n    bool boolean(bool /*val*/) override\n    {\n        return true;\n    }\n    bool number_integer(json::number_integer_t /*val*/) override\n    {\n        return true;\n    }\n    bool number_float(json::number_float_t /*val*/, const std::string& /*s*/) override\n    {\n        return true;\n    }\n    bool string(std::string& /*val*/) override\n    {\n        return true;\n    }\n    bool binary(json::binary_t& /*val*/) override\n    {\n        return true;\n    }\n    bool start_object(std::size_t /*elements*/) override\n    {\n        return true;\n    }\n    bool end_object() override\n    {\n        return true;\n    }\n    bool start_array(std::size_t /*elements*/) override\n    {\n        return true;\n    }\n    bool end_array() override\n    {\n        return true;\n    }\n    bool parse_error(std::size_t /*position*/, const std::string& /*last_token*/, const json::exception& /*ex*/) override\n    {\n        return false;\n    }\n};\n\nint main()\n{\n    find_id handler;\n    const bool completed = json::sax_parse(R\"({\"x\": [1, 2, 3], \"id\": 42, \"rest\": [4, 5, 6]})\", &handler);\n\n    std::cout << std::boolalpha;\n    std::cout << \"parse completed: \" << completed << '\\n';\n    std::cout << \"id: \" << handler.id << '\\n';\n}\n

    Output:

    parse completed: false\nid: 42\n

    Note that sax_parse returns false both when a handler stopped the parse and when the input is invalid, so record the reason in the handler (here: id) if you need to tell the two apart.

    "},{"location":"features/parsing/large_and_partial_input/#read-parts-of-a-large-document-with-a-view","title":"Read parts of a large document with a view","text":"

    If the whole text is available and you only need to read some of it, a json_document from <nlohmann/json_view.hpp> (added in version 3.13.0 unreleased) avoids the basic_json tree altogether: it keeps the text, builds a flat index of the values, and gives read-only views of the parts you look at. Only what you materialize() becomes a basic_json value. See Zero-copy JSON views for details and for the lifetime rules.

    "},{"location":"features/parsing/large_and_partial_input/#see-also","title":"See also","text":"
    • Parsing - overview of the parsing functions
    • JSON Lines - newline-delimited JSON
    • Parser callbacks - discard values while parsing
    • SAX interface - event-based parsing
    • Zero-copy JSON views - read parts of a large document without building a tree
    • Untrusted input - limits for input you do not control
    • operator>> - deserialize from stream
    • parse - deserialize from a compatible input
    • sax_parse - generate SAX events
    • JSON_PRECISE_STREAM_POSITION - leave the stream positioned right after a parsed number
    • JSON_DISABLE_STREAM_BULK_SCAN - read a std::istream one character at a time
    "},{"location":"features/parsing/parse_exceptions/","title":"Parsing and Exceptions","text":"

    When the input is not valid JSON, an exception of type parse_error is thrown. This exception contains the position in the input where the error occurred, together with a diagnostic message and the last read input token. The exceptions page contains a list of examples for parse error exceptions. In case you process untrusted input, always enclose your code with a try/catch block, like

    json j;\ntry\n{\n    j = json::parse(my_input);\n}\ncatch (json::parse_error& ex)\n{\n    std::cerr << \"parse error at byte \" << ex.byte << std::endl;\n}\n

    In case exceptions are undesired or not supported by the environment, there are different ways to proceed:

    Tip

    Working without exceptions also covers accessing values and converting to your own types.

    "},{"location":"features/parsing/parse_exceptions/#switch-off-exceptions","title":"Switch off exceptions","text":"

    The parse() function accepts a bool parameter allow_exceptions which controls whether an exception is thrown when a parse error occurs (true, default) or whether a discarded value should be returned (false).

    json j = json::parse(my_input, nullptr, false);\nif (j.is_discarded())\n{\n    std::cerr << \"parse error\" << std::endl;\n}\n

    Note there is no diagnostic information available in this scenario.

    "},{"location":"features/parsing/parse_exceptions/#use-accept-function","title":"Use accept() function","text":"

    Alternatively, function accept() can be used which does not return a json value, but a bool indicating whether the input is valid JSON.

    if (!json::accept(my_input))\n{\n    std::cerr << \"parse error\" << std::endl;\n}\n

    Again, there is no diagnostic information available.

    "},{"location":"features/parsing/parse_exceptions/#user-defined-sax-interface","title":"User-defined SAX interface","text":"

    Finally, you can implement the SAX interface and decide what should happen in case of a parse error.

    This function has the following interface:

    bool parse_error(std::size_t position,\n                 const std::string& last_token,\n                 const json::exception& ex);\n

    The return value indicates whether the parsing should continue, so the function should usually return false.

    Example: report parse errors without exceptions

    The example derives from the library's DOM parser and overrides parse_error to print the error instead of throwing. Note the DOM parser is an implementation detail (nlohmann::detail) and may change between releases; see Do not use the detail namespace.

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\n// a DOM parser that reports parse errors instead of throwing\nclass sax_no_exception : public nlohmann::detail::json_sax_dom_parser<json, nlohmann::detail::string_input_adapter_type>\n{\n  public:\n    explicit sax_no_exception(json& j)\n        : nlohmann::detail::json_sax_dom_parser<json, nlohmann::detail::string_input_adapter_type>(j, false)\n    {}\n\n    bool parse_error(std::size_t position,\n                     const std::string& last_token,\n                     const json::exception& ex)\n    {\n        std::cout << \"parse error at input byte \" << position << \"\\n\"\n                  << ex.what() << \"\\n\"\n                  << \"last read: \\\"\" << last_token << \"\\\"\"\n                  << '\\n';\n        return false;\n    }\n};\n\nint main()\n{\n    std::string myinput = \"[1,2,3,]\";\n\n    json result;\n    sax_no_exception sax(result);\n\n    bool parse_result = json::sax_parse(myinput, &sax);\n    if (!parse_result)\n    {\n        std::cout << \"parsing unsuccessful!\" << '\\n';\n    }\n\n    std::cout << \"parsed value: \" << result << '\\n';\n}\n

    Output:

    parse error at input byte 8\n[json.exception.parse_error.101] parse error at line 1, column 8: syntax error while parsing value - unexpected ']'; expected '[', '{', or a literal\nlast read: \"3,]\"\nparsing unsuccessful!\nparsed value: [1,2,3]\n
    "},{"location":"features/parsing/parse_exceptions/#where-did-the-error-occur","title":"Where did the error occur?","text":"

    The message of a parse_error for JSON text contains the line and column of the error:

    [json.exception.parse_error.101] parse error at line 3, column 8: syntax error while parsing value - unexpected ']'; expected '[', '{', or a literal\n

    The exception object itself only stores the byte index of the last read character in the member byte (the first byte of the input has index 1). The same index is passed to parse_error in the SAX interface. If you need the line and column as numbers, for example to show them in an editor, compute them from the input:

    Example: compute line and column of a parse error
    #include <iostream>\n#include <utility>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\n// line and column (both starting at 1) of a byte index in a text\nstd::pair<std::size_t, std::size_t> line_column(const std::string& input, std::size_t byte)\n{\n    std::size_t line = 1;\n    std::size_t column = 1;\n    for (std::size_t i = 0; i + 1 < byte && i < input.size(); ++i)\n    {\n        if (input[i] == '\\n')\n        {\n            ++line;\n            column = 1;\n        }\n        else\n        {\n            ++column;\n        }\n    }\n    return {line, column};\n}\n\nint main()\n{\n    const std::string input = \"{\\n  \\\"a\\\": 1,\\n  \\\"b\\\": ]\\n}\";\n\n    try\n    {\n        const json j = json::parse(input);\n        std::cout << j << '\\n';\n    }\n    catch (const json::parse_error& e)\n    {\n        const auto position = line_column(input, e.byte);\n        std::cout << e.what() << '\\n';\n        std::cout << \"byte \" << e.byte << \" = line \" << position.first << \", column \" << position.second << '\\n';\n    }\n}\n

    Output:

    [json.exception.parse_error.101] parse error at line 3, column 8: syntax error while parsing value - unexpected ']'; expected '[', '{', or a literal\nbyte 20 = line 3, column 8\n

    Columns count bytes, so a line with multi-byte UTF-8 characters before the error may differ from the column your editor shows.

    "},{"location":"features/parsing/parse_exceptions/#where-is-the-value-that-caused-a-later-error","title":"Where is the value that caused a later error?","text":"

    A parse_error is raised while the text is read. Many mistakes show up later: the text is valid JSON, but a value has the wrong type when you convert it (type_error.302), or a key is missing (out_of_range.403). The exception then says what is wrong, but not where in the input the value was. Define JSON_DIAGNOSTIC_POSITIONS before including the library to add the byte range of the offending value to such messages (since version 3.12.0), and to query the range of any value with start_pos() and end_pos():

    Example: locate a value with diagnostic positions
    #define JSON_DIAGNOSTIC_POSITIONS 1\n#include <iostream>\n#include <utility>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\n// line and column (both starting at 1) of a byte index in a text\nstd::pair<std::size_t, std::size_t> line_column(const std::string& input, std::size_t byte)\n{\n    std::size_t line = 1;\n    std::size_t column = 1;\n    for (std::size_t i = 0; i + 1 < byte && i < input.size(); ++i)\n    {\n        if (input[i] == '\\n')\n        {\n            ++line;\n            column = 1;\n        }\n        else\n        {\n            ++column;\n        }\n    }\n    return {line, column};\n}\n\nint main()\n{\n    const std::string input = \"{\\n  \\\"name\\\": \\\"Mary\\\",\\n  \\\"age\\\": \\\"forty-two\\\"\\n}\";\n    const json j = json::parse(input); // the input is valid JSON ...\n\n    try\n    {\n        const int age = j[\"age\"]; // ... but the value has the wrong type\n        std::cout << age << '\\n';\n    }\n    catch (const json::exception& e)\n    {\n        std::cout << e.what() << '\\n';\n\n        // start_pos() is a 0-based index into the input; the helper expects a 1-based byte index\n        const auto position = line_column(input, j[\"age\"].start_pos() + 1);\n        std::cout << \"the value starts at line \" << position.first << \", column \" << position.second << '\\n';\n    }\n}\n

    Output:

    [json.exception.type_error.302] (bytes 29-40) type must be number, but is string\nthe value starts at line 3, column 10\n

    Positions are only available for values created by parse, they are not updated when a value is changed, and the macro makes every value 16 bytes larger on 64-bit platforms, so use it where the cost is acceptable, for example for configuration files. Note that start_pos() is a 0-based index into the input, whereas byte of a parse_error starts at 1.

    For binary formats such as CBOR, there are no lines; byte is the position in the byte sequence. To find out how many bytes a successfully parsed value used, see Several values in one stream.

    "},{"location":"features/parsing/parse_exceptions/#see-also","title":"See also","text":"
    • parse - deserialize from a compatible input
    • accept - check if the input is valid JSON
    • sax_parse - generate SAX events
    • parse_error - exception thrown on a parse error
    • JSON_DIAGNOSTIC_POSITIONS - record start and end positions of parsed values
    • Working Without Exceptions - error handling when exceptions are disabled
    • Exceptions - list of exceptions and error codes
    • Parsing Untrusted Input - limits and checks for input you do not control
    "},{"location":"features/parsing/parser_callbacks/","title":"Parser Callbacks","text":""},{"location":"features/parsing/parser_callbacks/#overview","title":"Overview","text":"

    With a parser callback function, the result of parsing a JSON text can be influenced. When passed to parse, it is called on certain events (passed as parse_event_t via parameter event) with a set recursion depth depth and context JSON value parsed. The return value of the callback function is a boolean indicating whether the element that emitted the callback shall be kept or not.

    The type of the callback function is:

    template<typename BasicJsonType>\nusing parser_callback_t =\n    std::function<bool(int depth, parse_event_t event, BasicJsonType& parsed)>;\n
    "},{"location":"features/parsing/parser_callbacks/#callback-event-types","title":"Callback event types","text":"

    We distinguish six scenarios (determined by the event type) in which the callback function can be called. The following table describes the values of the parameters depth, event, and parsed.

    parameter event description parameter depth parameter parsed parse_event_t::object_start the parser read { and started to process a JSON object depth of the parent of the JSON object a JSON value with type discarded parse_event_t::key the parser read a key of a value in an object depth of the currently parsed JSON object a JSON string containing the key parse_event_t::object_end the parser read } and finished processing a JSON object depth of the parent of the JSON object the parsed JSON object parse_event_t::array_start the parser read [ and started to process a JSON array depth of the parent of the JSON array a JSON value with type discarded parse_event_t::array_end the parser read ] and finished processing a JSON array depth of the parent of the JSON array the parsed JSON array parse_event_t::value the parser finished reading a JSON value depth of the value the parsed JSON value

    Example of the parse events a callback sees for the J\u200bSON text {\"name\": \"Berlin\", \"location\": [52.519444, 13.406667]}: object_start after the opening brace, key after each key, array_start after the opening bracket, value after each value, array_end after the closing bracket, and object_end after the closing brace. Every array and object also produces a value event when it is complete. J\u200bSON to parse callback events { \"name\" : \"Berlin\" , \"location\" : [ 52.519444 , 13.406667 ] } object_start key object_end array_start array_end value

    Each coloured dot marks where the parser reports a parse_event_t event while reading the JSON text on the left; the legend on the right names the event per colour.

    Example: sequence of callback events

    When parsing the following JSON text,

    {\n    \"name\": \"Berlin\",\n    \"location\": [\n        52.519444,\n        13.406667\n    ]\n}\n

    these calls are made to the callback function:

    event depth parsed object_start 0 discarded key 1 \"name\" value 1 \"Berlin\" key 1 \"location\" array_start 1 discarded value 2 52.519444 value 2 13.406667 array_end 1 [52.519444,13.406667] object_end 0 {\"location\":[52.519444,13.406667],\"name\":\"Berlin\"}

    No built-in nesting depth limit

    The library has no built-in limit on recursion/nesting depth while parsing. A parser callback can only discard content it has already parsed (by returning false); it cannot make parsing fail once a nesting limit is exceeded partway through reading a deeply nested value. If you need to reject over-deep untrusted input outright, track depth in a callback and throw from it once your limit is exceeded (a thrown exception propagates out of parse() as usual).

    "},{"location":"features/parsing/parser_callbacks/#return-value","title":"Return value","text":"

    Discarding a value (i.e., returning false) has different effects depending on the context in which the function was called:

    • Discarded values in structured types are skipped. That is, the parser will behave as if the discarded value was never read.
    • In case a value outside a structured type is skipped, it is replaced with null. This case happens if the top-level element is skipped.
    Example: skip an object key while parsing

    The example below demonstrates the parse() function with and without callback function.

    #include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    // a JSON text\n    const auto* text = R\"(\n    {\n        \"Image\": {\n            \"Width\":  800,\n            \"Height\": 600,\n            \"Title\":  \"View from 15th Floor\",\n            \"Thumbnail\": {\n                \"Url\":    \"http://www.example.com/image/481989943\",\n                \"Height\": 125,\n                \"Width\":  100\n            },\n            \"Animated\" : false,\n            \"IDs\": [116, 943, 234, 38793]\n        }\n    }\n    )\";\n\n    // parse and serialize JSON\n    json j_complete = json::parse(text);\n    std::cout << std::setw(4) << j_complete << \"\\n\\n\";\n\n    // define parser callback\n    json::parser_callback_t cb = [](int depth, json::parse_event_t event, json & parsed)\n    {\n        // skip object elements with key \"Thumbnail\"\n        if (event == json::parse_event_t::key and parsed == json(\"Thumbnail\"))\n        {\n            return false;\n        }\n        else\n        {\n            return true;\n        }\n    };\n\n    // parse (with callback) and serialize JSON\n    json j_filtered = json::parse(text, cb);\n    std::cout << std::setw(4) << j_filtered << '\\n';\n}\n

    Output:

    {\n    \"Image\": {\n        \"Animated\": false,\n        \"Height\": 600,\n        \"IDs\": [\n            116,\n            943,\n            234,\n            38793\n        ],\n        \"Thumbnail\": {\n            \"Height\": 125,\n            \"Url\": \"http://www.example.com/image/481989943\",\n            \"Width\": 100\n        },\n        \"Title\": \"View from 15th Floor\",\n        \"Width\": 800\n    }\n}\n\n{\n    \"Image\": {\n        \"Animated\": false,\n        \"Height\": 600,\n        \"IDs\": [\n            116,\n            943,\n            234,\n            38793\n        ],\n        \"Title\": \"View from 15th Floor\",\n        \"Width\": 800\n    }\n}\n
    "},{"location":"features/parsing/parser_callbacks/#recipe-rejecting-duplicate-object-keys","title":"Recipe: rejecting duplicate object keys","text":"

    The JSON specification leaves the handling of objects with repeated keys up to the implementation. As described in object_t, it is unspecified which value for a repeated key ends up in the resulting json value \u2014 once parsing has produced that value, the duplicate is already gone, because object storage maps each key to a single value. If duplicate keys should instead be treated as an error, a parser callback can detect them while the object is still being read, before that ambiguity ever applies.

    Example: reject duplicate object keys
    #include <iostream>\n#include <nlohmann/json.hpp>\n#include <stdexcept>\n#include <string>\n#include <unordered_set>\n#include <vector>\n\nusing nlohmann::json;\n\njson parse_strict(const std::string& input)\n{\n    // one key set per nesting depth, reused across sibling objects\n    std::vector<std::unordered_set<std::string>> keys;\n\n    auto reject_duplicate_keys = [&](int depth, json::parse_event_t event, json & parsed)\n    {\n        if (event == json::parse_event_t::object_start)\n        {\n            // keys of this object are reported at depth+1 (see the event table above)\n            const auto child_depth = static_cast<std::size_t>(depth) + 1;\n            if (keys.size() <= child_depth)\n            {\n                keys.resize(child_depth + 1);\n            }\n            keys[child_depth].clear();\n            return true;\n        }\n\n        if (event == json::parse_event_t::key)\n        {\n            auto& seen = keys[static_cast<std::size_t>(depth)];\n            const auto& key = parsed.get_ref<const std::string&>();\n            if (!seen.insert(key).second)\n            {\n                throw std::runtime_error(\"duplicate JSON object key: \" + key);\n            }\n            return true;\n        }\n\n        return true;\n    };\n\n    return json::parse(input, reject_duplicate_keys);\n}\n\nint main()\n{\n    // parsing succeeds when all keys are unique\n    json j = parse_strict(R\"({\"one\": 1, \"two\": 2})\");\n    std::cout << j << '\\n';\n\n    // parsing throws when a key is repeated\n    try\n    {\n        parse_strict(R\"({\"one\": 1, \"one\": 2})\");\n    }\n    catch (const std::exception& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n}\n

    Output:

    {\"one\":1,\"two\":2}\nduplicate JSON object key: one\n

    This approach has three limitations:

    • The depth-indexed bookkeeping must account for the fact that object_start reports the depth of the parent of the object, while the key events inside that object are reported one depth deeper (see the event table above); it is easy to get this off by one for nested objects.
    • The thrown exception cannot carry a parse_error-style byte offset, because position tracking only exists inside the parser and lexer, not at the callback layer.
    • The exception only names the repeated key, not where it occurs in the document. Reporting its full path requires maintaining a stack of the enclosing keys and array indices in the callback as well.

    A SAX interface does not lift the position limitation: its key function receives no position either \u2014 only parse_error is passed the byte position.

    "},{"location":"features/parsing/parser_callbacks/#recipe-streaming-a-large-homogeneous-array","title":"Recipe: streaming a large homogeneous array","text":"

    A common use case is a huge top-level array of many similarly-shaped objects, too large to hold entirely in memory as a json value. A parser callback can hand off each completed element to a user function and then discard it, so memory usage stays bounded by a single element (plus the not-yet-parsed tail of the input) rather than the whole document. Since the top-level array's array_start/array_end are reported at depth == 0 (its parent is the document root), the object elements it contains are reported at depth == 1:

    Example: stream a large top-level array
    std::ifstream input(\"large_array.json\");\n\nauto callback = [](int depth, json::parse_event_t event, json& parsed) -> bool {\n    if (depth == 1 && event == json::parse_event_t::object_end) {\n        handle_element(parsed); // process the element, e.g. write it elsewhere\n        return false;           // discard it -- frees its memory before the next one is parsed\n    }\n    return true; // keep everything else, including the (by then empty) top-level array\n};\n\njson::parse(input, callback);\n

    If the array's elements are scalars or nested arrays instead of objects, check for parse_event_t::value or parse_event_t::array_end at depth == 1 instead. The same approach works for a top-level object of many homogeneous values by checking object_end/value events at depth == 1 there too.

    "},{"location":"features/parsing/parser_callbacks/#recipe-max-nesting-depth-via-a-callback","title":"Recipe: max nesting depth via a callback","text":"

    Since there is no built-in nesting-depth limit (see the note above), a callback can enforce one manually by tracking the maximum depth seen and throwing once it is exceeded:

    Example: limit the nesting depth
    constexpr int max_depth = 32;\n\nauto callback = [](int depth, json::parse_event_t /*event*/, json& /*parsed*/) -> bool {\n    if (depth > max_depth) {\n        throw std::runtime_error(\"maximum nesting depth exceeded\");\n    }\n    return true;\n};\n\njson::parse(input, callback);\n
    "},{"location":"features/parsing/parser_callbacks/#see-also","title":"See also","text":"
    • Parsing - overview of the parsing functions
    • SAX Interface - guide to event-based parsing
    • parse - deserialize from a compatible input
    • parser_callback_t - callback function type for the parser
    • parse_event_t - enumeration of parser events
    "},{"location":"features/parsing/sax_interface/","title":"SAX Interface","text":"

    The library uses a SAX-like interface with the following functions:

    classDiagram\n\nclass sax_t [\"json::sax_t\"] {\n    <<interface>>\n    +bool null()*\n\n    +bool boolean(bool val)*\n\n    +bool number_integer(number_integer_t val)*\n    +bool number_unsigned(number_unsigned_t val)*\n\n    +bool number_float(number_float_t val, const string_t& s)*\n\n    +bool string(string_t& val)*\n    +bool binary(binary_t& val)*\n\n    +bool start_object(std::size_t elements)*\n    +bool end_object()*\n    +bool start_array(std::size_t elements)*\n    +bool end_array()*\n    +bool key(string_t& val)*\n\n    +bool parse_error(std::size_t position, const std::string& last_token, const json::exception& ex)*\n}

    The interface json::sax_t: one function per event, each returning bool; the functions marked with * are pure virtual.

    // called when null is parsed\nbool null();\n\n// called when a boolean is parsed; value is passed\nbool boolean(bool val);\n\n// called when a signed or unsigned integer number is parsed; value is passed\nbool number_integer(number_integer_t val);\nbool number_unsigned(number_unsigned_t val);\n\n// called when a floating-point number is parsed; value and original string is passed\nbool number_float(number_float_t val, const string_t& s);\n\n// called when a string is parsed; value is passed and can be safely moved away\nbool string(string_t& val);\n// called when a binary value is parsed; value is passed and can be safely moved away\nbool binary(binary_t& val);\n\n// called when an object or array begins or ends, resp. The number of elements is passed (or -1 if not known)\nbool start_object(std::size_t elements);\nbool end_object();\nbool start_array(std::size_t elements);\nbool end_array();\n// called when an object key is parsed; value is passed and can be safely moved away\nbool key(string_t& val);\n\n// called when a parse error occurs; byte position, the last token, and an exception is passed\nbool parse_error(std::size_t position, const std::string& last_token, const json::exception& ex);\n

    The return value of each function determines whether parsing should proceed.

    "},{"location":"features/parsing/sax_interface/#stepping-through-the-events","title":"Stepping through the events","text":"

    The events for a small input, step by step, and what two different handlers do with them. Press Play or step with Next:

    input

    {\"a\":[1,true],\"b\":\"x\"}

    events, in the order the parser calls them

    1. start_object(-1)
    2. key(\"a\")
    3. start_array(-1)
    4. number_unsigned(1)
    5. boolean(true)
    6. end_array()
    7. key(\"b\")
    8. string(\"x\")
    9. end_object()

    handler: build a value tree, as parse does

    {\n  \"a\": [\n    1,\n    true\n  ],\n  \"b\": \"x\"\n}

    After end_object() the tree is complete and no container is open. The number of elements is passed as -1: the parser does not know it in advance.

    The three lanes show the input consumed so far, the events called so far, and the state of the selected handler (build a tree or keep only /b). Check return false at this event to stop the parse at the current event and see which events are no longer called.

    To implement your own SAX handler, proceed as follows:

    1. Implement the SAX interface in a class. You can use class nlohmann::json_sax<json> as base class, but you can also use any class where the functions described above are implemented and public.
    2. Create an object of your SAX interface class, e.g. my_sax.
    3. Call bool json::sax_parse(input, &my_sax); where the first parameter can be any input like a string or an input stream and the second parameter is a pointer to your SAX interface.

    Note the sax_parse function only returns a bool indicating the result of the last executed SAX event. It does not return json value - it is up to you to decide what to do with the SAX events. Furthermore, no exceptions are thrown in case of a parse error - it is up to you what to do with the exception object passed to your parse_error implementation. Internally, the SAX interface is used for the DOM parser (class json_sax_dom_parser) as well as the acceptor (json_sax_acceptor), see file json_sax.hpp.

    "},{"location":"features/parsing/sax_interface/#see-also","title":"See also","text":"
    • json_sax - documentation of the SAX interface
    • sax_parse - SAX parser
    • Parsing - overview of the parsing functions
    • Parsing and Exceptions - handling parse errors and locating them in the input
    • parse - deserialize from a compatible input
    • Binary Formats - CBOR, MessagePack, BSON, and other formats
    "},{"location":"features/parsing/untrusted_input/","title":"Parsing Untrusted Input","text":"

    This page is for applications that parse JSON \u2014 or one of the supported binary formats (BJData, BON8, BSON, CBOR, MessagePack, UBJSON) \u2014 from a source they do not fully control, such as a network connection, an uploaded file, or another process. It summarizes what the library already does for such input and what remains the caller's responsibility, linking to the pages that cover each aspect in detail rather than repeating them.

    For the project's threat model and the countermeasures behind these behaviors, see the assurance case; to report a vulnerability, see the security policy.

    "},{"location":"features/parsing/untrusted_input/#errors-without-exceptions","title":"Errors without exceptions","text":"

    By default, parse() throws a parse_error (for instance parse_error.101 for a syntax error) when the input is not valid. If your environment cannot use exceptions for untrusted input, the library offers several alternatives; see Parsing and exceptions for the full comparison:

    • Pass false as the third argument to parse() to get a discarded value (checked with is_discarded()) instead of a thrown exception, with no diagnostic information.
    • Use accept() to only check whether the input is valid JSON, without building a value.
    • Implement the SAX interface and override parse_error() to react to an error yourself, with the byte position and the exception that would otherwise have been thrown; see the example that overrides it to print instead of throw.

    If exceptions are unavailable entirely (-fno-exceptions, or JSON_NOEXCEPTION defined), every throw in the library becomes a call to std::abort(). The alternatives above do not throw, so parse() with allow_exceptions set to false (and likewise accept() and the from_* functions with allow_exceptions set to false) can still reject invalid input in that configuration; a plain parse() call aborts on invalid input. See Working without exceptions and Switch off exceptions for the details and for overriding the abort with JSON_THROW_USER.

    "},{"location":"features/parsing/untrusted_input/#nesting-depth","title":"Nesting depth","text":"

    The JSON parser and the binary readers are iterative: they keep the containers they are currently inside of on a heap-allocated stack instead of calling themselves once per nesting level, so the native call stack does not grow with the nesting depth of the input. A deeply nested document is therefore bounded by available memory, not by the call stack, however deeply it is nested.

    No built-in depth limit while parsing

    Neither the parser nor the binary readers impose a limit on how deep the input may nest. An attacker can still exhaust memory (though not the call stack) with a sufficiently deep document. If you need to reject over-deep untrusted input outright, track the depth yourself, either with a parser callback for the JSON parser, or by counting start_object/start_array and end_object/end_array calls in a SAX handler (for the JSON parser or a binary format alike) and throwing once your limit is exceeded.

    Once a value has been parsed, operations that walk it recursively \u2014 serializing it with dump, hashing it, copying it, comparing two values with ==, <, or (in C++20) <=>, merging with update, applying a merge_patch, creating a patch with diff or merge_diff, flatten, and the binary writers (to_cbor, to_msgpack, ...) \u2014 descend at most 128 levels on the call stack and continue below that with an explicit stack instead, so none of them can exhaust the stack either, however deeply the value is nested. Destroying a value (its destructor) never recurses at all, regardless of nesting depth, for the same reason.

    "},{"location":"features/parsing/untrusted_input/#input-size","title":"Input size","text":"

    The library does not limit the overall size of a JSON text; a value nested or wide enough will use memory proportional to the input. If you parse untrusted input of unbounded size, check the size of the file or stream yourself before \u2014 or while \u2014 handing it to parse().

    For the binary formats, an announced size is never trusted outright:

    • Reading a string or binary value copies the input in bounded 4096-byte chunks and grows the result as bytes are actually consumed, rather than allocating the announced length up front \u2014 a truncated input runs out of bytes (reported as a parse error) instead of triggering an oversized allocation.
    • When an array announces its number of elements and the array container supports reserve() (as std::vector, the default, does), the library reserves storage for at most 16384 of them upfront, regardless of how large the announced count is; further elements still grow the container normally as they are read.
    • An announced array or object size that exceeds what the target container could ever hold (its max_size()) is rejected immediately as out_of_range.408, without attempting to allocate anything.
    "},{"location":"features/parsing/untrusted_input/#strings","title":"Strings","text":"

    Invalid UTF-8 is rejected while parsing, not just while serializing:

    • In JSON text, an ill-formed UTF-8 byte in a string is a parse_error.101 (\"invalid string: ill-formed UTF-8 byte\").
    • In UTF-16 or UTF-32 input, an ill-formed sequence is a parse_error.101 as well: a lone surrogate, a high surrogate that is not followed by its low surrogate, and a code point above U+10FFFF are all rejected.
    • In a binary format, a string that is not valid UTF-8 is a parse_error.113.

    A '\\0' (NUL) byte inside a quoted JSON string is always rejected (it must be escaped as \\u0000). A NUL byte outside of a string is different: by default it is silently treated as the end of the input, so trailing bytes after it \u2014 including further, otherwise well-formed JSON \u2014 are silently ignored rather than rejected. Since untrusted input that happens to embed a NUL is a way to make part of it disappear without a parse error, see the FAQ entry and consider defining JSON_STRICT_NUL_HANDLING to 1 to reject a NUL byte like any other unexpected byte instead.

    Parsing is not the only place invalid UTF-8 matters: a string that reached a json value some other way (for example, constructed by application code, or, before JSON_STRICT_NUL_HANDLING existed, read from a binary format that does not validate strings) still has to round-trip back to JSON text. By default, dump() throws type_error.316 if the string is not valid UTF-8; passing error_handler_t::replace or error_handler_t::ignore avoids the exception instead of crashing an application that forgot to catch it. See Handling invalid UTF-8 for the options and an example.

    "},{"location":"features/parsing/untrusted_input/#duplicate-object-keys","title":"Duplicate object keys","text":"

    The JSON specification leaves the handling of repeated keys in an object up to the implementation, and this library does too: as described in object_t, it is unspecified which of the values for a repeated key ends up in the parsed object. If your application must reject duplicate keys instead of silently resolving them one way or another, see the parser callback recipe for rejecting duplicate keys.

    "},{"location":"features/parsing/untrusted_input/#numbers","title":"Numbers","text":"

    A number whose value cannot be represented \u2014 for instance 1E1000, which overflows double \u2014 is rejected while parsing as out_of_range.406 rather than silently becoming infinity. An integer that is syntactically valid but does not fit the 64-bit integer types is not rejected; it is instead stored as a double, which may lose precision for very large values. See number limits for the exact ranges and an example.

    "},{"location":"features/parsing/untrusted_input/#comments-and-trailing-commas","title":"Comments and trailing commas","text":"

    Both comments and trailing commas are rejected by default, matching the JSON specification; they must be explicitly enabled per call with the ignore_comments and ignore_trailing_commas parameters of parse() or accept(). Do not enable either for input whose conformance you cannot otherwise control, since interoperability with strictly conforming JSON consumers is exactly what the default rejects.

    "},{"location":"features/parsing/untrusted_input/#json-pointers-and-flattened-keys","title":"JSON Pointers and flattened keys","text":"

    A JSON Pointer can come from untrusted input as well, for instance as a path in a request or as a key of a flattened object. The non-const operator[] with a JSON Pointer and unflatten create missing values, and when an array index lies beyond the end of an array, they fill the array with null values up to that index. The memory used therefore grows with the index, not with the size of the pointer: on a 64-bit platform, the index 10000000 allocates about 160 MB, the index 100000000 about 1.6 GB. The library does not limit the index. For pointers from untrusted input, check the array indices (or the pointer as a whole) before using them, or use at or contains, which never add values.

    "},{"location":"features/parsing/untrusted_input/#checklist","title":"Checklist","text":"
    • Wrap parsing in a try/catch block, or use allow_exceptions=false/accept() if your environment cannot use exceptions; never let JSON_NOEXCEPTION's abort() be the first time you think about error handling.
    • If the input's nesting depth matters to you, enforce your own limit with a parser callback or a SAX handler; the library bounds the call stack but not memory use.
    • Bound the size of the input itself before parsing, independent of the library's own bounded allocations for binary format lengths.
    • Decide up front how you want a string with invalid UTF-8 \u2014 from any source, not only parsing \u2014 to be serialized (strict, replace, or ignore), rather than discovering it from an uncaught type_error.316.
    • If a stray NUL byte silently truncating trailing input is a problem for your input format, define JSON_STRICT_NUL_HANDLING.
    • Decide whether duplicate object keys should be an error for your application, and add a callback if so.
    • Do not enable ignore_comments or ignore_trailing_commas for input that must be strictly conforming JSON.
    • Check the array indices of untrusted JSON Pointers and flattened keys before passing them to the non-const operator[] or unflatten(), which fill arrays with null values up to the index.

    For the broader design rationale and how it is tested (fuzzing, sanitizers, static analysis), see the assurance case and quality assurance. To report a security issue in the library itself, follow the security policy.

    "},{"location":"features/parsing/untrusted_input/#see-also","title":"See also","text":"
    • Parsing - overview of the parsing functions
    • Parsing and exceptions - error handling without exceptions
    • Parser callbacks - depth limits, duplicate-key rejection, and streaming recipes
    • SAX interface - implement a custom handler with access to parse errors and positions
    • Serialization - handling invalid UTF-8 when dumping
    • Number handling - number ranges and overflow behavior
    • Assurance case - the library's threat model and countermeasures
    • Security policy - how to report a vulnerability
    • parse - deserialize from a compatible input
    • accept - check if the input is valid JSON
    • sax_parse - generate SAX events
    • parser_callback_t - callback function type for the parser
    • JSON_STRICT_NUL_HANDLING - opt in to rejecting a NUL byte in the input
    • JSON_DIAGNOSTIC_POSITIONS - record start and end positions of parsed values
    "},{"location":"features/types/","title":"Types","text":"

    This page gives an overview of how JSON values are stored and how this can be configured.

    "},{"location":"features/types/#overview","title":"Overview","text":"

    By default, JSON values are stored as follows:

    JSON type C++ type object std::map<std::string, basic_json> array std::vector<basic_json> null std::nullptr_t string std::string boolean bool number std::int64_t, std::uint64_t, and double

    Note there are three different types for numbers - when parsing JSON text, the best fitting type is chosen.

    "},{"location":"features/types/#storage","title":"Storage","text":"
    classDiagram\n\nclass value_t {\n    <<enumeration>>\n    null\n    object\n    array\n    string\n    boolean\n    number_integer\n    number_unsigned\n    number_float\n    binary\n    discarded\n}\n\nclass json_value {\n    <<union>>\n    object_t* object\n    array_t* array\n    string_t* string\n    binary_t* binary\n    boolean_t boolean\n    number_integer_t number_integer\n    number_unsigned_t number_unsigned\n    number_float_t number_float\n}\n\nclass basic_json {\n    -value_t m_type\n    -json_value m_value\n    +typedef object_t\n    +typedef array_t\n    +typedef binary_t\n    +typedef boolean_t\n    +typedef number_integer_t\n    +typedef number_unsigned_t\n    +typedef number_float_t\n}\n\nbasic_json .. json_value\nbasic_json .. value_t

    Storage of a basic_json value: the enumeration value_t holds the type, and the union json_value holds the value, as a pointer for objects, arrays, strings, and binary values and directly for booleans and numbers.

    "},{"location":"features/types/#template-arguments","title":"Template arguments","text":"

    The data types to store a JSON value are derived from the template arguments passed to class basic_json:

    template<\n    template<typename U, typename V, typename... Args> class ObjectType = std::map,\n    template<typename U, typename... Args> class ArrayType = std::vector,\n    class StringType = std::string,\n    class BooleanType = bool,\n    class NumberIntegerType = std::int64_t,\n    class NumberUnsignedType = std::uint64_t,\n    class NumberFloatType = double,\n    template<typename U> class AllocatorType = std::allocator,\n    template<typename T, typename SFINAE = void> class JSONSerializer = adl_serializer,\n    class BinaryType = std::vector<std::uint8_t>,\n    class CustomBaseClass = void\n>\nclass basic_json;\n

    Type json is an alias for basic_json<> and uses the default types.

    From the template arguments, the following types are derived:

    using object_comparator_t = std::less<>;\nusing object_t = ObjectType<StringType, basic_json, object_comparator_t,\n                   AllocatorType<std::pair<const StringType, basic_json>>>;\n\nusing array_t = ArrayType<basic_json, AllocatorType<basic_json>>;\n\nusing string_t = StringType;\n\nusing boolean_t = BooleanType;\n\nusing number_integer_t = NumberIntegerType;\nusing number_unsigned_t = NumberUnsignedType;\nusing number_float_t = NumberFloatType;\n\nusing binary_t = nlohmann::byte_container_with_subtype<BinaryType>;\n

    Not every type can be passed for these template arguments: the library uses the resulting types in ways that imply a number of requirements, for instance that StringType is char-based or that ArrayType is vector-like. These requirements are collected in Template Parameter Requirements.

    "},{"location":"features/types/#objects","title":"Objects","text":"

    RFC 8259 describes JSON objects as follows:

    An object is an unordered collection of zero or more name/value pairs, where a name is a string and a value is a string, number, boolean, null, object, or array.

    "},{"location":"features/types/#default-type","title":"Default type","text":"

    With the default values for ObjectType (std::map), StringType (std::string), and AllocatorType (std::allocator), the default type for object_t is:

    std::map<\n  std::string, // key_type\n  basic_json, // value_type\n  std::less<>, // key_compare\n  std::allocator<std::pair<const std::string, basic_json>> // allocator_type\n>\n
    "},{"location":"features/types/#behavior","title":"Behavior","text":"

    The choice of object_t influences the behavior of the JSON class. With the default type, objects have the following behavior:

    • When all names are unique, objects will be interoperable in the sense that all software implementations receiving that object will agree on the name-value mappings.
    • When the names within an object are not unique, it is unspecified which one of the values for a given key will be chosen. For instance, {\"key\": 2, \"key\": 1} could be equal to either {\"key\": 1} or {\"key\": 2}. To reject duplicate keys instead of silently resolving them one way or another, see this parsing recipe.
    • Internally, name/value pairs are stored in lexicographical order of the names. Objects will also be serialized (see dump) in this order. For instance, both {\"b\": 1, \"a\": 2} and {\"a\": 2, \"b\": 1} will be stored and serialized as {\"a\": 2, \"b\": 1}.
    • When comparing objects, the order of the name/value pairs is irrelevant. This makes objects interoperable in the sense that they will not be affected by these differences. For instance, {\"b\": 1, \"a\": 2} and {\"a\": 2, \"b\": 1} will be treated as equal.
    "},{"location":"features/types/#key-order","title":"Key order","text":"

    The order in which name/value pairs are added to the object is 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 alphabetical order as std::map with std::less is used by default. Please note this behavior conforms to RFC 8259, because any order implements the specified \"unordered\" nature of JSON objects.

    "},{"location":"features/types/#limits","title":"Limits","text":"

    RFC 8259 specifies:

    An implementation may set limits on the maximum depth of nesting.

    In this class, the object's limit of nesting is not explicitly constrained. However, a maximum depth of nesting may be introduced by the compiler or runtime environment. A theoretical limit can be queried by calling the max_size function of a JSON object.

    "},{"location":"features/types/#storage_1","title":"Storage","text":"

    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.

    "},{"location":"features/types/#converting-maps-with-non-string-keys","title":"Converting maps with non-string keys","text":"

    A std::map/std::unordered_map whose key type is not string-like (e.g., std::map<int, std::string>) is converted to a JSON array of 2-element [key, value] arrays rather than a JSON object, because JSON object keys must be strings:

    std::map<int, std::string> m{{1, \"one\"}, {2, \"two\"}};\njson j = m;\n// j is [[1,\"one\"],[2,\"two\"]], not {\"1\":\"one\",\"2\":\"two\"}\n
    "},{"location":"features/types/#arrays","title":"Arrays","text":"

    RFC 8259 describes JSON arrays as follows:

    An array is an ordered sequence of zero or more values.

    "},{"location":"features/types/#default-type_1","title":"Default type","text":"

    With the default values for ArrayType (std::vector) and AllocatorType (std::allocator), the default type for array_t is:

    std::vector<\n  basic_json, // value_type\n  std::allocator<basic_json> // allocator_type\n>\n
    "},{"location":"features/types/#limits_1","title":"Limits","text":"

    RFC 8259 specifies:

    An implementation may set limits on the maximum depth of nesting.

    In this class, the array's limit of nesting is not explicitly constrained. However, a maximum depth of nesting may be introduced by the compiler or runtime environment. A theoretical limit can be queried by calling the max_size function of a JSON array.

    "},{"location":"features/types/#storage_2","title":"Storage","text":"

    Arrays are stored as pointers in a basic_json type. That is, for any access to array values, a pointer of type array_t* must be dereferenced.

    "},{"location":"features/types/#strings","title":"Strings","text":"

    RFC 8259 describes JSON strings as follows:

    A string is a sequence of zero or more Unicode characters.

    Unicode values are split by the JSON class into byte-sized characters during deserialization.

    "},{"location":"features/types/#default-type_2","title":"Default type","text":"

    With the default values for StringType (std::string), the default type for string_t is std::string.

    "},{"location":"features/types/#encoding","title":"Encoding","text":"

    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.

    "},{"location":"features/types/#string-comparison","title":"String comparison","text":"

    RFC 8259 states:

    Software implementations are typically required to test names of object members for equality. Implementations that transform the textual representation into sequences of Unicode code units and then perform the comparison numerically, code unit by code unit are interoperable in the sense that implementations will agree in all cases on equality or inequality of two strings. For example, implementations that compare strings with escaped characters unconverted may incorrectly find that \"a\\\\b\" and \"a\\u005Cb\" are not equal.

    This implementation is interoperable as it does compare strings code unit by code unit.

    "},{"location":"features/types/#storage_3","title":"Storage","text":"

    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.

    "},{"location":"features/types/#booleans","title":"Booleans","text":"

    RFC 8259 implicitly describes a boolean as a type which differentiates the two literals true and false.

    "},{"location":"features/types/#default-type_3","title":"Default type","text":"

    With the default values for BooleanType (bool), the default type for boolean_t is bool.

    "},{"location":"features/types/#storage_4","title":"Storage","text":"

    Boolean values are stored directly inside a basic_json type.

    "},{"location":"features/types/#numbers","title":"Numbers","text":"

    See the number handling article for a detailed discussion on how numbers are handled by this library.

    RFC 8259 describes numbers as follows:

    The representation of numbers is similar to that used in most programming languages. A number is represented in base 10 using decimal digits. It contains an integer component that may be prefixed with an optional minus sign, which may be followed by a fraction part and/or an exponent part. Leading zeros are not allowed. (...) Numeric values that cannot be represented in the grammar below (such as Infinity and NaN) are not permitted.

    This description includes both integer and floating-point numbers. However, C++ allows more precise storage if it is known whether the number is a signed integer, an unsigned integer, or a floating-point number. Therefore, three different types, number_integer_t, number_unsigned_t, and number_float_t are used.

    "},{"location":"features/types/#default-types","title":"Default types","text":"

    With the default values for NumberIntegerType (std::int64_t), the default type for number_integer_t is std::int64_t. With the default values for NumberUnsignedType (std::uint64_t), the default type for number_unsigned_t is std::uint64_t. With the default values for NumberFloatType (double), the default type for number_float_t is double.

    "},{"location":"features/types/#default-behavior","title":"Default behavior","text":"
    • 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.
    • Not-a-number (NaN) values will be serialized to null.
    "},{"location":"features/types/#limits_2","title":"Limits","text":"

    RFC 8259 specifies:

    An implementation may set limits on the range and precision of numbers.

    When the default type is used, the maximal integer number that can be stored is 9223372036854775807 (INT64_MAX) and the minimal integer number that can be stored is -9223372036854775808 (INT64_MIN). Integer numbers that are out of range will yield over/underflow when used in a constructor. During deserialization, too large or small integer numbers will automatically be stored as number_unsigned_t or number_float_t.

    When the default type is used, the maximal unsigned integer number that can be stored is 18446744073709551615 (UINT64_MAX) and the minimal integer number that can be stored is 0. Integer numbers that are out of range will yield over/underflow when used in a constructor. During deserialization, too large or small integer numbers will automatically be stored as number_integer_t or number_float_t.

    RFC 8259 further states:

    Note that when such software is used, numbers that are integers and are in the range [-253+1, 253-1] are interoperable in the sense that implementations will agree exactly on their numeric values.

    As this range is a subrange of the exactly supported range [INT64_MIN, INT64_MAX], this class's integer type is interoperable.

    RFC 8259 states:

    This specification allows implementations to set limits on the range and precision of numbers accepted. Since software that implements IEEE 754-2008 binary64 (double precision) numbers is generally available and widely used, good interoperability can be achieved by implementations that expect no more precision or range than these provide, in the sense that implementations will approximate JSON numbers within the expected precision.

    This implementation does exactly follow this approach, as it uses double precision floating-point numbers by default (see NumberFloatType above). Note that with the default double, numbers smaller than -1.79769313486232e+308 or greater than 1.79769313486232e+308 are rejected during parsing with out_of_range.406. Non-finite values (NaN and infinity) can only be stored by assigning them directly and are serialized to null.

    "},{"location":"features/types/#storage_5","title":"Storage","text":"

    Integer number values, unsigned integer number values, and floating-point number values are stored directly inside a basic_json type.

    "},{"location":"features/types/#see-also","title":"See also","text":"
    • Number handling - how numbers are stored and converted
    • Template parameter requirements - what the template parameters of basic_json must provide
    • basic_json - the class template and its member types
    • type - and value_t - query the type of a value
    • object_t, array_t, string_t, number_integer_t, number_float_t - the underlying types
    • Object order - how object keys are ordered
    • json - the default JSON type
    • boolean_t - the underlying boolean type
    • number_unsigned_t - the underlying unsigned integer type
    • is_primitive - and the other is_* functions query the type
    • is_structured - true for objects and arrays
    • Converting values - convert JSON values to and from C++ types
    • Creating JSON values - build JSON values
    "},{"location":"features/types/number_handling/","title":"Number Handling","text":"

    This document describes how the library is handling numbers.

    "},{"location":"features/types/number_handling/#background","title":"Background","text":"

    This section briefly summarizes how the JSON specification describes how numbers should be handled.

    "},{"location":"features/types/number_handling/#json-number-syntax","title":"JSON number syntax","text":"

    JSON defines the syntax of numbers as follows:

    RFC 8259, Section 6

    The representation of numbers is similar to that used in most programming languages. A number is represented in base 10 using decimal digits. It contains an integer component that may be prefixed with an optional minus sign, which may be followed by a fraction part and/or an exponent part. Leading zeros are not allowed.

    A fraction part is a decimal point followed by one or more digits.

    An exponent part begins with the letter E in uppercase or lowercase, which may be followed by a plus or minus sign. The E and optional sign are followed by one or more digits.

    The following railroad diagram from json.org visualizes the number syntax:

    Railroad diagram of the J\u200bSON number syntax: optional minus, then 0 or a digit from 1 to 9 followed by digits, then an optional fraction (a dot and digits) and an optional exponent (e or E, an optional sign, and digits). \u2212 0 digit 1\u20139 digit . digit e E \u2212 + digit number fraction exponent

    Read the diagram from left to right: every path along the lines spells a valid number, made of an optional minus sign, an integer part, an optional fraction, and an optional exponent.

    "},{"location":"features/types/number_handling/#number-interoperability","title":"Number interoperability","text":"

    On number interoperability, the following remarks are made:

    RFC 8259, Section 6

    This specification allows implementations to set limits on the range and precision of numbers accepted. Since software that implements IEEE 754 binary64 (double precision) numbers [IEEE754] is generally available and widely used, good interoperability can be achieved by implementations that expect no more precision or range than these provide, in the sense that implementations will approximate JSON numbers within the expected precision. A JSON number such as 1E400 or 3.141592653589793238462643383279 may indicate potential interoperability problems, since it suggests that the software that created it expects receiving software to have greater capabilities for numeric magnitude and precision than is widely available.

    Note that when such software is used, numbers that are integers and are in the range [-253+1, 253-1] are interoperable in the sense that implementations will agree exactly on their numeric values.

    "},{"location":"features/types/number_handling/#library-implementation","title":"Library implementation","text":"

    This section describes how this library implements the above number specification.

    "},{"location":"features/types/number_handling/#number-storage","title":"Number storage","text":"

    In the default json type, numbers are stored as std::uint64_t, std::int64_t, and double, respectively. Thereby, std::uint64_t and std::int64_t are used only if they can store the number without loss of precision. If this is impossible (e.g., if the number is too large), the number is stored as double.

    Positive integers are stored as std::uint64_t, while negative integers are stored as std::int64_t. This distinction is determined at parse time: if the JSON number has a leading minus sign, it uses signed integer storage; otherwise, it uses unsigned integer storage.

    flowchart TD\n    A[\"number literal\"] --> B{{\"has a fraction (.) or exponent (e/E)?\"}}\n    B -->|\"yes\"| F[\"number_float_t\"]\n    B -->|\"no\"| C{{\"has a leading minus sign?\"}}\n    C -->|\"yes\"| D[\"try number_integer_t\"]\n    C -->|\"no\"| E[\"try number_unsigned_t\"]\n    D -->|\"overflow\"| F\n    E -->|\"overflow\"| F

    How the parser picks the storage type of a number literal: a fraction or exponent always gives number_float_t; otherwise the sign selects the signed or unsigned integer type, and a value that overflows it is stored as number_float_t.

    Notes

    • Numbers with a decimal digit or scientific notation are always stored as double.
    • The number types can be changed, see Template number types.
    • The library converts integers and floating-point numbers itself, independent of the locale. Floating-point numbers are correctly rounded (to nearest, ties to even). Only a long double that is not IEEE 754 binary64 (e.g., the 80-bit x87 format) is converted with std::from_chars where available, or else with std::strtold. For that call, the library temporarily replaces the . with the decimal point of the current locale (which may be longer than one byte, e.g., in fa_IR.UTF-8), so the result does not depend on the locale either. Changing the locale in another thread during parsing is undefined behavior of the C library, though. Before version 3.13.0 unreleased, the conversion was realized by std::strtoull, std::strtoll, and std::strtod, respectively.

    Examples

    • Integer -12345678912345789123456789 is smaller than INT64_MIN and will be stored as floating-point number -1.2345678912345788e+25.
    • Integer 1E3 will be stored as floating-point number 1000.0.
    "},{"location":"features/types/number_handling/#number-limits","title":"Number limits","text":"
    • Any 64-bit signed or unsigned integer can be stored without loss of precision.
    • Numbers exceeding the limits of double (i.e., numbers whose rounded value is not satisfying std::isfinite such as 1E400) will throw exception json.exception.out_of_range.406 during parsing. Numbers too small for double (such as 1E-400) become zero, with the sign of the number.
    • Floating-point numbers are rounded to the next number representable as double. For instance 3.141592653589793238462643383279 is stored as 0x400921fb54442d18. This is the same behavior as the code double x = 3.141592653589793238462643383279;.

    Interoperability

    • The library is interoperable with respect to the specification, because its supported range [-263, 264-1] is larger than the described range [-253+1, 253-1].
    • All integers outside the range [-263, 264-1], as well as floating-point numbers are stored as double. This also concurs with the specification above.
    "},{"location":"features/types/number_handling/#zeros","title":"Zeros","text":"

    The JSON number grammar allows for different ways to express zero, and this library will store zeros differently:

    Literal Stored value and type Serialization 0 std::uint64_t(0) 0 -0 std::int64_t(0) 0 0.0 double(0.0) 0.0 -0.0 double(-0.0) -0.0 0E0 double(0.0) 0.0 -0E0 double(-0.0) -0.0

    That is, -0 is stored as a signed integer, but the serialization does not reproduce the -.

    The literals mentioned on this page, parsed with json::parse and serialized with dump() (checked against the library; pick one or type it to see the row):

    Literal Stored as (type()) dump() 0 number_unsigned (std::uint64_t) 0 -0 number_integer (std::int64_t) 0 -0.0 number_float (double) -0.0 1E3 number_float (double) 1000.0 -12345678912345789123456789 number_float (double) -1.2345678912345788e+25 18446744073709551615 number_unsigned (std::uint64_t) 18446744073709551615 18446744073709551616 number_float (double) 1.8446744073709552e+19 -9223372036854775808 number_integer (std::int64_t) -9223372036854775808 1E400 exception out_of_range.406 (nothing, parsing fails) 1E-400 number_float (double) 0.0 3.141592653589793238462643383279 number_float (double) 3.141592653589793 2555.5599999999999 number_float (double) 2555.56 0.0000972439793401814 number_float (double) 9.72439793401814e-05 12345E-5 number_float (double) 0.12345

    Each row shows how a literal is stored and how dump() writes it back. The explorer only knows the literals in this list; other input is reported as not in the verified list.

    "},{"location":"features/types/number_handling/#number-serialization","title":"Number serialization","text":"
    • Integer numbers are serialized as is; that is, no scientific notation is used.
    • Floating-point numbers are serialized with the fewest digits that read back as the same value (the closest such digits if there are several), in the layout of the %g printf modifier: 1.5, 100.0, 1e+100. Doubles are converted with the algorithm of \u017bmij, floats with Grisu2, which can write more digits than necessary.

    Notes regarding precision of floating-point numbers

    As described above, floating-point numbers are rounded to the nearest double and serialized with the shortest representation to allow round-tripping. This can yield confusing examples:

    • The serialization can have fewer decimal places than the input: 2555.5599999999999 will be serialized as 2555.56. The reverse can also be true.
    • The serialization can be in scientific notation even if the input is not: 0.0000972439793401814 will be serialized as 9.72439793401814e-05. The reverse can also be true: 12345E-5 will be serialized as 0.12345.
    • Conversions from float to double can also introduce rounding errors:
      float f = 0.3;\njson j = f;\nstd::cout << j << '\\n';\n
      yields 0.30000001192092896.

    All examples here can be reproduced by passing the original double value to

    std::printf(\"%.*g\\n\", std::numeric_limits<double>::max_digits10, double_value);\n
    "},{"location":"features/types/number_handling/#nan-handling","title":"NaN handling","text":"

    NaN (not-a-number) cannot be expressed with the number syntax described above and are in fact explicitly excluded:

    RFC 8259, Section 6

    Numeric values that cannot be represented in the grammar below (such as Infinity and NaN) are not permitted.

    That is, there is no way to parse a NaN value. However, assignments can store NaN values in a JSON value.

    This library serializes NaN values as null. This corresponds to the behavior of JavaScript's JSON.stringify function.

    Example

    The following example shows how a NaN value is stored in a json value.

    int main()\n{\n    double val = std::numeric_limits<double>::quiet_NaN();\n    std::cout << \"val=\" << val << std::endl;\n    json j = val;\n    std::cout << \"j=\" << j.dump() << std::endl;\n    val = j;\n    std::cout << \"val=\" << val << std::endl;\n}\n

    output:

    val=nan\nj=null\nval=nan\n
    "},{"location":"features/types/number_handling/#number-comparison","title":"Number comparison","text":"

    Floating-point numbers inside JSON values are compared with json::number_float_t::operator== which is double::operator== by default.

    Alternative comparison functions

    To compare floating-point while respecting an epsilon, an alternative comparison function could be used, for instance

    template<typename T, typename = typename std::enable_if<std::is_floating_point<T>::value, T>::type>\ninline bool is_same(T a, T b, T epsilon = std::numeric_limits<T>::epsilon()) noexcept\n{\n    return std::abs(a - b) <= epsilon;\n}\n
    Or you can self-define an operator equal function like this:

    bool my_equal(const_reference lhs, const_reference rhs)\n{\n    const auto lhs_type = lhs.type();\n    const auto rhs_type = rhs.type();\n    if (lhs_type == rhs_type)\n    {\n        switch(lhs_type)\n        {\n            // self_defined case\n            case value_t::number_float:\n                return std::abs(lhs - rhs) <= std::numeric_limits<float>::epsilon();\n\n            // other cases remain the same with the original\n            ...\n        }\n    }\n    ...\n}\n

    (see #703 for more information.)

    Note

    NaN values never compare equal to themselves or to other NaN values. See #514.

    "},{"location":"features/types/number_handling/#number-conversion","title":"Number conversion","text":"

    Just like the C++ language itself, the get family of functions allows conversions between unsigned and signed integers, and between integers and floating-point values. This behavior may be surprising.

    Unconditional number conversions

    double d = 42.3;                          // non-integer double value 42.3\njson jd = d;                              // stores double value 42.3\nstd::int64_t i = jd.get<std::int64_t>();  // now i==42; no warning or error is produced\n

    Note the last line with throw a json.exception.type_error.302 exception if jd is not a numerical type, for instance a string.

    Numeric conversions are performed according to the corresponding C++ conversion rules. The library does not perform range checks when converting between numeric types.

    In particular, conversions from floating-point values to integer types, or conversions to integer types with a smaller range than the stored value, may produce implementation-defined or undefined behavior if the source value cannot be represented by the target type.

    Applications requiring checked conversions should inspect the stored number type with is_number_float(), is_number_integer(), is_number_unsigned(), or type(), and perform explicit range checks before converting to a narrower type.

    The rationale is twofold:

    1. JSON does not define a number type or precision (see above).
    2. C++ also allows silently converting between number types.

    Conditional number conversion

    The code above can be solved by explicitly checking the nature of the value with members such as is_number_integer() or is_number_unsigned():

    // check if jd is really integer-valued\nif (jd.is_number_integer())\n{\n    // if so, do the conversion and use i\n    std::int64_t i = jd.get<std::int64_t>();\n    // ...\n}\nelse\n{\n    // otherwise, take appropriate action\n    // ...\n}\n

    Note this approach also has the advantage that it can react on non-numerical JSON value types such as strings.

    (Example taken from #777.)

    "},{"location":"features/types/number_handling/#determine-number-types","title":"Determine number types","text":"

    As the example in Number conversion shows, there are different functions to determine the type of the stored number:

    • is_number() returns true for any number type
    • is_number_integer() returns true for signed and unsigned integers
    • is_number_unsigned() returns true for unsigned integers only
    • is_number_float() returns true for floating-point numbers
    • type_name() returns \"number\" for any number type
    • type() returns a different enumerator of value_t for all number types
    function unsigned integer signed integer floating-point string is_number() true true true false is_number_integer() true true false false is_number_unsigned() true false false false is_number_float() false false true false type_name() \"number\" \"number\" \"number\" \"string\" type() number_unsigned number_integer number_float string

    Return value of each function for a value that stores an unsigned integer, a signed integer, or a floating-point number, and for a string for comparison.

    "},{"location":"features/types/number_handling/#template-number-types","title":"Template number types","text":"

    The number types can be changed with template parameters.

    position number type default type possible values 5 signed integers std::int64_t std::int32_t, std::int16_t, etc. 6 unsigned integers std::uint64_t std::uint32_t, std::uint16_t, etc. 7 floating-point double float, long double

    Constraints on number types

    • The type for signed integers must be convertible from long long. The type for floating-point numbers is used in case of overflow.
    • The type for unsigned integers must be convertible from unsigned long long. The type for floating-point numbers is used in case of overflow.
    • The type for unsigned integers can also be the same signed type as the type for signed integers (e.g., std::int64_t for both). Then every integer is stored as a signed integer, and is_number_unsigned() is always false, see Template Parameter Requirements.
    • The type for floating-point numbers must be distinct from the integer types.
    • Only double, float, and long double are supported for floating-point numbers.

    Example

    A basic_json type that uses long double as floating-point type.

    using json_ld = nlohmann::json::with_float_t<long double>;\n

    Note values should then be parsed with json_ld::parse rather than json::parse as the latter would parse floating-point values to double before then converting them to long double.

    "},{"location":"features/types/number_handling/#see-also","title":"See also","text":"
    • Types - how all value types are stored
    • Converting values - convert numbers to C++ types
    • number_integer_t - the signed integer type
    • number_unsigned_t - the unsigned integer type
    • number_float_t - the floating-point type
    • is_number - check for a number of any kind
    "},{"location":"features/types/template_parameters/","title":"Template Parameter Requirements","text":"

    Class basic_json is configurable through eleven template parameters. The library never formally states what a type passed for one of these parameters has to provide \u2014 the requirements are implied by the way the library uses the resulting object_t, array_t, string_t, etc. This page collects these requirements so they do not have to be discovered by trial and error. Each section lists the concrete types that are known to work for that parameter and the ones that do not, checked against Boost 1.83, Abseil 20250127.0, Folly, EASTL 3.21, ankerl::unordered_dense, phmap, gtl, robin_hood, tsl::ordered_map, and Qt 6.

    To change a single template parameter and keep the others, use the member alias templates with_*_t; for instance, nlohmann::json::with_float_t<long double> is json with long double as number_float_t.

    "},{"location":"features/types/template_parameters/#how-to-read-this-page","title":"How to read this page","text":"

    Requirements are split into two groups:

    • Always required \u2014 needed to instantiate basic_json at all, or needed by functions that virtually every program uses (construction, element access, dump).
    • Required for ... \u2014 only needed when a particular part of the API is instantiated. Member function templates are only instantiated when they are used, so a type may be perfectly usable even though it does not satisfy these requirements, as long as the corresponding functions are never called.

    Requirements are not checked

    Three requirements are checked with a static_assert: the array iterator category, the width of BinaryType's value_type, and NumberUnsignedType being at least as wide as NumberIntegerType. The rest are not diagnosed with dedicated error messages, and violating most of them results in a compiler error somewhere inside the library. Four violations are not caught at compile time at all:

    • A StringType whose data() is not null-terminated compiles and silently misparses numbers stored as a long double that is not IEEE 754 binary64 (e.g., the 80-bit x87 format), because the lexer hands the buffer to std::strtold.
    • A stateful AllocatorType compiles and silently ignores its state: allocation, deallocation, and get_allocator() each use a different default-constructed instance.
    • The two cross-specialization conversions below. These abort on an assertion in a normal build, and only fail silently under NDEBUG.
    "},{"location":"features/types/template_parameters/#overview","title":"Overview","text":"Template parameter Default Notable substitutes ObjectType std::map nlohmann::ordered_map, Abseil hash maps ArrayType std::vector std::deque StringType std::string std::string-like types over char BooleanType bool none worth using NumberIntegerType std::int64_t any signed integer type NumberUnsignedType std::uint64_t any unsigned integer type at least as wide as NumberIntegerType, or NumberIntegerType itself NumberFloatType double float (long double: no binary formats) AllocatorType std::allocator stateless allocators JSONSerializer adl_serializer serializers with the same interface BinaryType std::vector<std::uint8_t> std::vector<char> CustomBaseClass void any default-constructible class

    Third-party containers and incomplete types

    object_t is instantiated inside the definition of basic_json \u2014 it is probed for a key_compare member to form object_comparator_t \u2014 i.e. while basic_json is still an incomplete type. std::map is required by the standard to support incomplete mapped types; most third-party maps are not, and inspecting the mapped type at class scope (for instance with std::is_trivially_move_assignable) makes them unusable as ObjectType, no matter how their template arguments are adapted. This rules out absl::btree_map, phmap::btree_map, gtl::btree_map, robin_hood::unordered_node_map, folly::F14FastMap, and eastl::hash_map.

    array_t is only named in the class definition and is not instantiated until basic_json is complete, so an ArrayType that inspects its value type at class scope is generally fine \u2014 boost::container::small_vector and static_vector both reject incomplete value types yet work here. absl::InlinedVector is the exception: the std::is_trivially_move_assignable<basic_json> it evaluates while instantiating itself re-enters the library's own trait machinery mid-instantiation.

    Folly requires C++20

    Folly's headers use consteval and std::type_identity, so any basic_json specialization that names a Folly type has to be compiled as C++20 or later, whatever the rest of the library supports.

    "},{"location":"features/types/template_parameters/#objecttype","title":"ObjectType","text":"

    ObjectType is instantiated as

    using object_t = ObjectType<StringType,                                    // key_type\n                            basic_json,                                    // mapped_type\n                            default_object_comparator_t,                   // key_compare\n                            AllocatorType<std::pair<const StringType,\n                                                    basic_json>>>;         // allocator_type\n

    i.e., the template arguments follow the order and meaning of std::map.

    "},{"location":"features/types/template_parameters/#always-required","title":"Always required","text":"
    • The template must be usable with four type arguments in the order shown above. The third argument is a comparator; containers that expect something else in this position (e.g., a hash function) need an alias template or wrapper \u2014 see Notes.
    • An optional member type key_compare. If it is present it becomes object_comparator_t; otherwise default_object_comparator_t is used.
    • Member types key_type, mapped_type, value_type, and iterator.
    • value_type must behave like std::pair<const key_type, mapped_type>; the library accesses .first and .second on it.
    • iterator must be default-constructible and satisfy LegacyBidirectionalIterator. The type returned by cbegin()/cend() must satisfy the same requirements.
    • Constructors: default, copy, move, and from an iterator range (first, last).
    • Member functions begin(), end(), cbegin(), cend(), empty(), size(), max_size(), clear(), find(key), count(key), emplace(key, value), insert(value_type), insert(first, last), operator[](key), erase(iterator), and erase(first, last). erase(iterator) may return the following iterator or void; in the latter case the library computes the successor itself, before erasing.
    • erase(key) is optional: if the container does not provide one, the library falls back to find(key) followed by erase(iterator).
    • at(key) is required only by to_ubjson and to_bjdata, but every container tried here provides it.
    • emplace and insert(value_type) must return std::pair<iterator, bool> and must have unique-key semantics; multimaps cannot be used.
    • The type must be swappable (via std::swap or an ADL swap).
    • The comparison operators == and <; !=, <=, >, and >= are derived from them. Where the library uses three-way comparison (C++20), == and <=> are required instead \u2014 the six two-way operators do not satisfy it. They implement basic_json's comparison operators.
    "},{"location":"features/types/template_parameters/#required-for-heterogeneous-key-lookup","title":"Required for heterogeneous key lookup","text":"

    The overloads of at, operator[], find, contains, count, erase, and value that accept a key type other than object_t::key_type require

    • a transparent comparator, i.e. object_comparator_t has a member type is_transparent (this is why the default comparator is std::less<> since C++14), and
    • corresponding heterogeneous find, count, erase, and operator[] overloads on the container.
    "},{"location":"features/types/template_parameters/#notes","title":"Notes","text":""},{"location":"features/types/template_parameters/#stdunordered_map-needs-an-adapter","title":"std::unordered_map needs an adapter","text":"

    std::unordered_map cannot be passed directly: its third template parameter is a hash function, but basic_json passes a comparator in that position. An alias template or wrapper that restores the expected argument order makes it usable:

    template<class Key, class T, class IgnoredCompare, class Allocator>\nstruct unordered_map_object\n    : std::unordered_map<Key, T, std::hash<Key>, std::equal_to<Key>, Allocator>\n{\n    using base_t = std::unordered_map<Key, T, std::hash<Key>, std::equal_to<Key>, Allocator>;\n    using base_t::base_t;\n};\n\nusing unordered_json = nlohmann::json::with_object_t<unordered_map_object>;\n

    Whether std::unordered_map can be instantiated at all depends on the standard library: object_t is formed while basic_json is still incomplete (see the warning above), and libstdc++ 9 needs the size of the mapped type to instantiate the hash map's node type, so the adapter does not compile there. Newer libstdc++ versions, and the hash maps listed below, do not have that problem.

    The adapter above works verbatim for Abseil's, Boost's, phmap's and gtl's hash maps, which all place the hash function third and take a std::pair<const Key, T> allocator fifth. Two need a different adapter:

    • ankerl::unordered_dense expects an allocator over std::pair<Key, T> (non-const key), so the allocator has to be rebound to that or dropped.
    • robin_hood's fifth parameter is the non-type MaxLoadFactor100, so its adapter must drop the allocator entirely.

    None of these hash maps defines key_compare, so all of them additionally rely on object_comparator_t falling back to default_object_comparator_t; see object_comparator_t.

    "},{"location":"features/types/template_parameters/#abseil-hash-maps","title":"Abseil hash maps","text":"

    absl::flat_hash_map and absl::node_hash_map tolerate an incomplete value type, but they take a hash function as their third template argument. The same adapter as for std::unordered_map makes them usable:

    template<class Key, class T, class IgnoredCompare, class Allocator>\nstruct flat_hash_object\n    : absl::flat_hash_map<Key, T, absl::Hash<Key>, std::equal_to<Key>, Allocator>\n{\n    using base_t = absl::flat_hash_map<Key, T, absl::Hash<Key>, std::equal_to<Key>, Allocator>;\n    using base_t::base_t;\n};\n\nusing flat_hash_json = nlohmann::json::with_object_t<flat_hash_object>;\n

    absl::node_hash_map keeps references to the mapped values valid across insertions; absl::flat_hash_map does not, which makes it behave like ordered_json with respect to iterator invalidation. Both expose a capacity() member function, so JSON_DIAGNOSTICS treats them conservatively and keeps the parent pointers correct either way.

    "},{"location":"features/types/template_parameters/#iteration-order","title":"Iteration order","text":"

    The library never relies on the container's iteration order for correctness; it does determine the order in which object keys are serialized by dump and visited by items. See Object Order.

    "},{"location":"features/types/template_parameters/#capacity-marks-a-container-as-insertion-ordered","title":"capacity() marks a container as insertion-ordered","text":"

    With JSON_DIAGNOSTICS enabled, the library detects insertion-ordered maps by probing for a capacity() member function (nlohmann::ordered_map inherits it from std::vector) and refreshes all parent pointers after every insertion. An ObjectType that happens to have a capacity() member is therefore treated conservatively \u2014 this is correct, but slower.

    "},{"location":"features/types/template_parameters/#key-order-and-duplicate-keys","title":"Key order and duplicate keys","text":"

    The library does not sort or de-duplicate keys itself; the behavior described in object_t is entirely the behavior of the chosen container.

    Reference implementation

    docs/mkdocs/docs/examples/custom_object_type.hpp wraps a private std::map and satisfies every requirement above. It does not define key_compare, so object_comparator_t falls back to default_object_comparator_t \u2014 a good starting point for a custom ObjectType.

    #pragma once\n\n#include <map>\n#include <utility>\n\n// A minimal, self-contained ObjectType built around a private std::map.\n// key_compare is deliberately not exposed: when an ObjectType has no\n// key_compare member, the library falls back to its own default comparator.\n// See https://json.nlohmann.me/features/types/template_parameters/#objecttype\ntemplate<class Key, class T, class Compare, class Allocator>\nclass custom_object_type\n{\n    using map_t = std::map<Key, T, Compare, Allocator>;\n    map_t data_;\n\n  public:\n    using key_type = typename map_t::key_type;\n    using mapped_type = typename map_t::mapped_type;\n    using value_type = typename map_t::value_type;\n    using size_type = typename map_t::size_type;\n    using iterator = typename map_t::iterator;\n    using const_iterator = typename map_t::const_iterator;\n\n    custom_object_type() = default;\n    custom_object_type(const custom_object_type&) = default;\n    custom_object_type(custom_object_type&&) = default;\n    custom_object_type& operator=(const custom_object_type&) = default;\n    custom_object_type& operator=(custom_object_type&&) = default;\n\n    template<class InputIt>\n    custom_object_type(InputIt first, InputIt last) : data_(first, last) {}\n\n    iterator begin()\n    {\n        return data_.begin();\n    }\n    iterator end()\n    {\n        return data_.end();\n    }\n    const_iterator begin() const\n    {\n        return data_.begin();\n    }\n    const_iterator end() const\n    {\n        return data_.end();\n    }\n    const_iterator cbegin() const\n    {\n        return data_.cbegin();\n    }\n    const_iterator cend() const\n    {\n        return data_.cend();\n    }\n\n    bool empty() const\n    {\n        return data_.empty();\n    }\n    size_type size() const\n    {\n        return data_.size();\n    }\n    size_type max_size() const\n    {\n        return data_.max_size();\n    }\n    void clear()\n    {\n        data_.clear();\n    }\n\n    iterator find(const key_type& key)\n    {\n        return data_.find(key);\n    }\n    const_iterator find(const key_type& key) const\n    {\n        return data_.find(key);\n    }\n    size_type count(const key_type& key) const\n    {\n        return data_.count(key);\n    }\n\n    std::pair<iterator, bool> emplace(const key_type& key, const mapped_type& value)\n    {\n        return data_.emplace(key, value);\n    }\n\n    std::pair<iterator, bool> insert(const value_type& value)\n    {\n        return data_.insert(value);\n    }\n\n    template<class InputIt>\n    void insert(InputIt first, InputIt last)\n    {\n        data_.insert(first, last);\n    }\n\n    mapped_type& operator[](const key_type& key)\n    {\n        return data_[key];\n    }\n\n    mapped_type& at(const key_type& key)\n    {\n        return data_.at(key);\n    }\n    const mapped_type& at(const key_type& key) const\n    {\n        return data_.at(key);\n    }\n\n    iterator erase(iterator pos)\n    {\n        return data_.erase(pos);\n    }\n    iterator erase(iterator first, iterator last)\n    {\n        return data_.erase(first, last);\n    }\n    size_type erase(const key_type& key)\n    {\n        return data_.erase(key);\n    }\n\n    void swap(custom_object_type& other)\n    {\n        data_.swap(other.data_);\n    }\n\n    friend bool operator==(const custom_object_type& lhs, const custom_object_type& rhs)\n    {\n        return lhs.data_ == rhs.data_;\n    }\n    friend bool operator<(const custom_object_type& lhs, const custom_object_type& rhs)\n    {\n        return lhs.data_ < rhs.data_;\n    }\n};\n
    Example: use the custom ObjectType
    #include <iostream>\n#include <type_traits>\n\n#include <nlohmann/json.hpp>\n\n#include \"custom_object_type.hpp\"\n\nusing custom_json = nlohmann::json::with_object_t<custom_object_type>;\n\nint main()\n{\n    custom_json j;\n    j[\"pi\"] = 3.141;\n    j[\"happy\"] = true;\n    j[\"list\"] = {1, 2, 3};\n\n    std::cout << j.dump(2) << '\\n';\n    std::cout << std::boolalpha << (custom_json::parse(j.dump()) == j) << '\\n';\n\n    // custom_object_type has no key_compare member, so object_comparator_t\n    // falls back to its default\n    std::cout << std::boolalpha\n              << std::is_same<custom_json::object_comparator_t, custom_json::default_object_comparator_t>::value\n              << '\\n';\n}\n

    Output:

    {\n  \"happy\": true,\n  \"list\": [\n    1,\n    2,\n    3\n  ],\n  \"pi\": 3.141\n}\ntrue\ntrue\n
    "},{"location":"features/types/template_parameters/#compatible-containers","title":"Compatible containers","text":"Container Notes std::map (default) nlohmann::ordered_map used by ordered_json; keeps insertion order nlohmann::fifo_map keeps insertion order; adapter puts fifo_map_compare in the comparator slot boost::container::map, boost::container::flat_map no adapter needed std::unordered_map through the adapter above; not with libstdc++ 9, see the note boost::unordered_map, boost::unordered_flat_map, boost::unordered_node_map through the adapter above absl::flat_hash_map, absl::node_hash_map through the adapter above; flat_hash_map moves mapped values on rehash phmap::flat_hash_map, phmap::node_hash_map, gtl::flat_hash_map through the adapter above ankerl::unordered_dense::map and segmented_map adapter must rebind or drop the allocator robin_hood::unordered_flat_map adapter must drop the allocator folly::F14NodeMap through the adapter above; requires C++20, see the note above folly::sorted_vector_map alias must drop the allocator, whose value type it disagrees on"},{"location":"features/types/template_parameters/#containers-that-cannot-be-used","title":"Containers that cannot be used","text":"Container Reason absl::btree_map, phmap::btree_map, gtl::btree_map require a complete mapped type robin_hood::unordered_node_map, folly::F14FastMap, eastl::hash_map require a complete mapped type eastl::map EASTL iterators do not work with std::iterator_traits tsl::ordered_map its iterators expose the mapped value as const QMap no value_type member type QHash its value_type is the mapped type rather than a key/value pair, and its iterators dereference to the mapped value std::multimap, std::unordered_multimap emplace does not return std::pair<iterator, bool>"},{"location":"features/types/template_parameters/#arraytype","title":"ArrayType","text":"

    ArrayType is instantiated as

    using array_t = ArrayType<basic_json, AllocatorType<basic_json>>;\n
    "},{"location":"features/types/template_parameters/#always-required_1","title":"Always required","text":"
    • The template must be usable with two type arguments (value type and allocator).
    • Member types value_type and iterator.
    • Constructors: default, copy, and move; and from an iterator range (first, last).
    • Member functions begin(), end(), cbegin(), cend(), empty(), size(), max_size(), clear(), operator[](size_type), back(), push_back(), emplace_back(), pop_back(), resize(), insert() (single element, count, and range), erase(pos), and erase(first, last). basic_json::insert(pos, initializer_list) goes through the range overload, so no initializer-list insert is needed. at(size_type) is not required: basic_json::at(size_type) checks the index itself and then uses operator[].
    • iterator must be default-constructible, and it as well as the type returned by cbegin()/cend() must satisfy LegacyRandomAccessIterator. A static_assert only checks for LegacyBidirectionalIterator, but dump (cend() - 1), erase(idx) (begin() + idx), and the random-access operations of basic_json::iterator require random access.
    • The comparison operators, as for ObjectType: == and <, or == and <=> under C++20.
    "},{"location":"features/types/template_parameters/#required-for-individual-functions","title":"Required for individual functions","text":"
    • A member type value_type, for to_bson of an array.
    • A constructor from (count, value), for basic_json(size_type, const basic_json&).
    • Swappability, via std::swap or an ADL swap, for swap(array_t&).

    capacity() is optional

    With JSON_DIAGNOSTICS enabled, the library reads array_t::capacity() to find out whether adding an element reallocated the array and moved its elements, which would invalidate the parent pointers. An array type without a capacity() member function is handled conservatively: the parent pointers of all elements are refreshed after every insertion, which makes adding n elements cost O(*n*\u00b2). Only diagnostics builds pay this; without them capacity() is never called.

    Reference implementation

    docs/mkdocs/docs/examples/custom_array_type.hpp wraps a private std::vector and satisfies every requirement above \u2014 a good starting point for a custom ArrayType.

    #pragma once\n\n#include <memory>\n#include <utility>\n#include <vector>\n\n// A minimal, self-contained ArrayType built around a private std::vector.\n// See https://json.nlohmann.me/features/types/template_parameters/#arraytype\ntemplate<class T, class Allocator = std::allocator<T>>\nclass custom_array_type\n{\n    using vector_t = std::vector<T, Allocator>;\n    vector_t data_;\n\n  public:\n    using value_type = typename vector_t::value_type;\n    using size_type = typename vector_t::size_type;\n    using iterator = typename vector_t::iterator;\n    using const_iterator = typename vector_t::const_iterator;\n\n    custom_array_type() = default;\n    custom_array_type(const custom_array_type&) = default;\n    custom_array_type(custom_array_type&&) = default;\n    custom_array_type& operator=(const custom_array_type&) = default;\n    custom_array_type& operator=(custom_array_type&&) = default;\n\n    template<class InputIt>\n    custom_array_type(InputIt first, InputIt last) : data_(first, last) {}\n\n    custom_array_type(size_type count, const T& value) : data_(count, value) {}\n\n    iterator begin()\n    {\n        return data_.begin();\n    }\n    iterator end()\n    {\n        return data_.end();\n    }\n    const_iterator begin() const\n    {\n        return data_.begin();\n    }\n    const_iterator end() const\n    {\n        return data_.end();\n    }\n    const_iterator cbegin() const\n    {\n        return data_.cbegin();\n    }\n    const_iterator cend() const\n    {\n        return data_.cend();\n    }\n\n    bool empty() const\n    {\n        return data_.empty();\n    }\n    size_type size() const\n    {\n        return data_.size();\n    }\n    size_type max_size() const\n    {\n        return data_.max_size();\n    }\n    void clear()\n    {\n        data_.clear();\n    }\n    void resize(size_type n)\n    {\n        data_.resize(n);\n    }\n\n    T& operator[](size_type pos)\n    {\n        return data_[pos];\n    }\n    const T& operator[](size_type pos) const\n    {\n        return data_[pos];\n    }\n\n    T& back()\n    {\n        return data_.back();\n    }\n    const T& back() const\n    {\n        return data_.back();\n    }\n\n    void push_back(const T& value)\n    {\n        data_.push_back(value);\n    }\n    void push_back(T&& value)\n    {\n        data_.push_back(std::move(value));\n    }\n\n    template<class... Args>\n    void emplace_back(Args&& ... args)\n    {\n        data_.emplace_back(std::forward<Args>(args)...);\n    }\n\n    void pop_back()\n    {\n        data_.pop_back();\n    }\n\n    iterator insert(const_iterator pos, const T& value)\n    {\n        return data_.insert(pos, value);\n    }\n    iterator insert(const_iterator pos, size_type count, const T& value)\n    {\n        return data_.insert(pos, count, value);\n    }\n    template<class InputIt>\n    iterator insert(const_iterator pos, InputIt first, InputIt last)\n    {\n        return data_.insert(pos, first, last);\n    }\n\n    iterator erase(const_iterator pos)\n    {\n        return data_.erase(pos);\n    }\n    iterator erase(const_iterator first, const_iterator last)\n    {\n        return data_.erase(first, last);\n    }\n\n    void swap(custom_array_type& other)\n    {\n        data_.swap(other.data_);\n    }\n\n    friend bool operator==(const custom_array_type& lhs, const custom_array_type& rhs)\n    {\n        return lhs.data_ == rhs.data_;\n    }\n    friend bool operator<(const custom_array_type& lhs, const custom_array_type& rhs)\n    {\n        return lhs.data_ < rhs.data_;\n    }\n};\n
    Example: use the custom ArrayType
    #include <iostream>\n\n#include <nlohmann/json.hpp>\n\n#include \"custom_array_type.hpp\"\n\nusing custom_json = nlohmann::json::with_array_t<custom_array_type>;\n\nint main()\n{\n    custom_json j = custom_json::array();\n    j.push_back(1);\n    j.push_back(2);\n    j.push_back(3);\n\n    std::cout << j.dump() << '\\n';\n    std::cout << std::boolalpha << (custom_json::parse(j.dump()) == j) << '\\n';\n}\n

    Output:

    [1,2,3]\ntrue\n
    "},{"location":"features/types/template_parameters/#compatible-containers_1","title":"Compatible containers","text":"Container Notes std::vector (default) std::deque references survive appends, but not insertions elsewhere; see the capacity() note above std::pmr::vector through an alias, as the allocator comes from AllocatorType instead boost::container::vector, deque, devector boost::container::stable_vector the only one tried that keeps references valid across every insertion boost::container::small_vector, folly::small_vector through an alias that fixes the inline capacity boost::container::static_vector through the same kind of alias, for arrays that stay within the fixed capacity folly::fbvector requires C++20, see the note above"},{"location":"features/types/template_parameters/#containers-that-cannot-be-used_1","title":"Containers that cannot be used","text":"Container Reason std::list no operator[], and no random-access iterators eastl::vector, QList, QVector no max_size(); they handle the incomplete value type fine absl::InlinedVector requires a complete value type, see the note above absl::FixedArray the size is fixed at construction, so resize, push_back, insert and erase are missing"},{"location":"features/types/template_parameters/#stringtype","title":"StringType","text":"

    StringType is used both for JSON string values and for the keys of JSON objects (string_t and object_t::key_type).

    "},{"location":"features/types/template_parameters/#always-required_2","title":"Always required","text":"
    • A member type value_type that is one byte wide and char-compatible. The library stores and processes UTF-8 encoded char data and passes data() to functions that take a const char*, such as std::strtold (only used to parse a long double that is not IEEE 754 binary64, see NumberFloatType). std::wstring, std::u16string, and std::u32string are not valid choices; see the FAQ on wide string handling.
    • Constructors: default, copy, move, from const char* (which must not be explicit), from (const char*, size_type), and from (size_type, char); and copy or move assignment.
    • Member functions size(), clear(), resize(n, c), data(), push_back(char), and operator[] (const and non-const, returning references). c_str() and back() are not required.
    • data() must return a pointer to a contiguous, null-terminated buffer. float, double, and a long double that is IEEE 754 binary64 are converted by the library itself and do not depend on this. For any other NumberFloatType (a long double of another format), the parser falls back to std::strtold when std::from_chars is not available or declines the token, and std::strtold reads up to the null character. A type whose data() is not null-terminated does not fail to compile; with such a NumberFloatType it can silently misparse floating-point numbers.
    • append(const char*, size_type), used by dump and by the binary readers. The library's internal string concatenation additionally has to append a char and a const char*; for each it selects between append(arg), operator+=, append(first, last), and append(data, size).
    • The comparison operator == against another StringType, and < for use as a key of the chosen ObjectType (with the default comparator, std::less<> must be able to compare two StringType values, and a StringType with the key types used for lookup). != is never applied to a StringType, and == against const char* is resolved by the implicit const char* constructor.
    "},{"location":"features/types/template_parameters/#required-for-the-binary-formats","title":"Required for the binary formats","text":"
    • resize(n), used by the readers to make room for a block of bytes.
    • Non-const operator[], into which the readers std::memcpy those bytes. A non-const data() would serve just as well, but std::string has only had one since C++17, and the library still supports C++11.
    "},{"location":"features/types/template_parameters/#required-for-json-pointer-flatten-and-diff","title":"Required for JSON Pointer, flatten, and diff","text":"
    • A static member npos and the member function find_first_of(char, size_type) \u2014 together with data(), reserve(n), and append(const char*, size_type) they implement the escaping and unescaping of reference tokens described in RFC 6901. Neither find(const StringType&, size_type), nor substr(pos, count), nor replace(pos, count, const StringType&) is required.
    • empty().
    • resize(n) (one argument) \u2014 used by to_string to size the result before the reference tokens are copied into it.
    • begin() and end() \u2014 used by operator[](const json_pointer&) to decide whether a reference token denotes an array index.
    "},{"location":"features/types/template_parameters/#required-for-other-functionality","title":"Required for other functionality","text":"Functionality Additional requirement diff, items, std::hash conversion of a std::size_t to StringType: either assignability from the result of std::to_string, or an ADL overload void int_to_string(StringType&, std::size_t) operator/(std::size_t) the same conversion of a std::size_t to StringType as diff, items, and std::hash above std::hash<basic_json> additionally a specialization of std::hash<StringType> to_bson find(value_type) and npos parse from a string_t the input adapters must accept it; otherwise pass a character range operator<<(std::ostream&, const json_pointer&) streamability to std::ostream to_string conversion of StringType to std::string (the function returns a std::string) exception messages data() and size(), or begin() and end()"},{"location":"features/types/template_parameters/#compatible-types","title":"Compatible types","text":"Type Notes std::string (default) std::basic_string with a custom stateless allocator std::pmr::string see the warning below before relying on the memory resource boost::container::string needs a user-supplied std::hash specialization (Boost provides boost::hash instead) folly::fbstring requires C++20, see the note above eastl::string needs a user-supplied std::hash and an ADL int_to_string (it is not assignable from a std::string); parse does not accept it directly \u2014 pass a character range or a std::string a custom string class in a user-defined namespace if the requirements above are met"},{"location":"features/types/template_parameters/#types-that-cannot-be-used","title":"Types that cannot be used","text":"Type Reason std::wstring, std::u16string, std::u32string the character type is not one byte wide std::u8string one byte wide, but char8_t is not char-compatible absl::Cord no value_type, and the storage is not contiguous QString no append(const char*, size_type); its QChar is also two bytes wide, though that is never diagnosed

    A std::pmr::string mostly does not use the memory resource you choose

    basic_json cannot be given an allocator or a memory resource. AllocatorType is default-constructed at every allocation and has to be stateless (see AllocatorType), and string values the library creates are constructed with their own default allocator. So:

    • Every string the library itself produces \u2014 from parse, from dump, or by default construction \u2014 allocates from std::pmr::get_default_resource().
    • Copying an arena-backed string into a value silently drops its memory resource: the copy lands on the default resource, because std::pmr::polymorphic_allocator does not propagate on copy construction. Nothing warns about this.
    • Moving one in does keep it, and later growth still allocates from that arena \u2014 but it does not survive a copy of the enclosing basic_json.
    • Passing std::pmr::polymorphic_allocator as AllocatorType does not work around any of this; it does not compile.

    Apart from moving a string in, the only way to redirect these allocations is the process-global std::pmr::set_default_resource().

    Reference implementation

    docs/mkdocs/docs/examples/custom_string_type.hpp wraps a private std::string and satisfies every requirement above \u2014 a good starting point for a custom StringType. The unit test tests/src/unit-alt-string.cpp contains a more thorough variant, alt_string, exercised against a larger part of the API.

    #pragma once\n\n#include <cstddef>\n#include <ostream>\n#include <string>\n\n// A minimal, self-contained StringType built around a private std::string.\n// Wraps rather than inherits, so it exposes exactly what the library needs\n// and nothing more of std::string's interface.\n//\n// Covers the \"Always required\" members, the extras needed for the binary\n// formats, JSON Pointer / flatten / unflatten, and the int_to_string overload\n// needed for diff and items. Extending it further (e.g. for\n// std::hash<basic_json> or to_bson) is a matter of adding the extra members\n// listed in the \"Required for other functionality\" table.\n//\n// See https://json.nlohmann.me/features/types/template_parameters/#stringtype\nclass custom_string_type\n{\n    std::string data_;\n\n  public:\n    using value_type = char;\n    using size_type = std::string::size_type;\n    using iterator = std::string::iterator;\n    using const_iterator = std::string::const_iterator;\n\n    static constexpr size_type npos = std::string::npos;\n\n    custom_string_type() = default;\n    custom_string_type(const custom_string_type&) = default;\n    custom_string_type(custom_string_type&&) = default;\n    custom_string_type& operator=(const custom_string_type&) = default;\n    custom_string_type& operator=(custom_string_type&&) = default;\n\n    // not explicit: the library relies on being able to hand it a string literal\n    custom_string_type(const char* s) : data_(s) {}\n    custom_string_type(const char* s, size_type count) : data_(s, count) {}\n    custom_string_type(size_type count, char ch) : data_(count, ch) {}\n\n    size_type size() const\n    {\n        return data_.size();\n    }\n    bool empty() const\n    {\n        return data_.empty();\n    }\n    void clear()\n    {\n        data_.clear();\n    }\n    void resize(size_type n)\n    {\n        data_.resize(n);\n    }\n    void resize(size_type n, char c)\n    {\n        data_.resize(n, c);\n    }\n    void reserve(size_type n)\n    {\n        data_.reserve(n);\n    }\n\n    // must stay null-terminated -- the parser hands this to std::strtoull &\n    // friends; std::string::data() has guaranteed that since C++11\n    const char* data() const\n    {\n        return data_.data();\n    }\n\n    void push_back(char c)\n    {\n        data_.push_back(c);\n    }\n\n    char& operator[](size_type pos)\n    {\n        return data_[pos];\n    }\n    char operator[](size_type pos) const\n    {\n        return data_[pos];\n    }\n\n    custom_string_type& append(const char* s, size_type count)\n    {\n        data_.append(s, count);\n        return *this;\n    }\n    custom_string_type& append(const custom_string_type& other)\n    {\n        data_.append(other.data_);\n        return *this;\n    }\n    custom_string_type& operator+=(char c)\n    {\n        data_.push_back(c);\n        return *this;\n    }\n\n    size_type find_first_of(char c, size_type pos = 0) const\n    {\n        return data_.find_first_of(c, pos);\n    }\n\n    iterator begin()\n    {\n        return data_.begin();\n    }\n    iterator end()\n    {\n        return data_.end();\n    }\n    const_iterator begin() const\n    {\n        return data_.begin();\n    }\n    const_iterator end() const\n    {\n        return data_.end();\n    }\n\n    // found by ADL; converts array indices to keys in diff and items\n    friend void int_to_string(custom_string_type& target, std::size_t value)\n    {\n        target.data_ = std::to_string(value);\n    }\n\n    friend bool operator==(const custom_string_type& lhs, const custom_string_type& rhs)\n    {\n        return lhs.data_ == rhs.data_;\n    }\n    friend bool operator<(const custom_string_type& lhs, const custom_string_type& rhs)\n    {\n        return lhs.data_ < rhs.data_;\n    }\n\n    // not required by the library itself, but dump() returns a custom_string_type\n    // and this makes `std::cout << j.dump()` work as expected\n    friend std::ostream& operator<<(std::ostream& os, const custom_string_type& s)\n    {\n        return os << s.data_;\n    }\n};\n
    Example: use the custom StringType
    #include <iostream>\n\n#include <nlohmann/json.hpp>\n\n#include \"custom_string_type.hpp\"\n\nusing custom_json = nlohmann::json::with_string_t<custom_string_type>;\n\nint main()\n{\n    custom_json j;\n    j[\"pi\"] = 3.141;\n    j[\"happy\"] = true;\n    j[\"list\"] = {1, 2, 3};\n\n    std::cout << j.dump(2) << '\\n';\n    std::cout << std::boolalpha << (custom_json::parse(j.dump()) == j) << '\\n';\n}\n

    Output:

    {\n  \"happy\": true,\n  \"list\": [\n    1,\n    2,\n    3\n  ],\n  \"pi\": 3.141\n}\ntrue\n
    "},{"location":"features/types/template_parameters/#booleantype","title":"BooleanType","text":"

    boolean_t is stored directly inside basic_json, as a member of an anonymous union.

    "},{"location":"features/types/template_parameters/#always-required_3","title":"Always required","text":"
    • A literal type that is trivially default-constructible, trivially copyable, and trivially destructible; otherwise the union's special member functions are deleted.
    • Implicitly convertible from bool \u2014 an explicit constructor is not enough, because the to_json overload for a custom BooleanType is constrained on std::is_convertible \u2014 and contextually convertible to bool (here an explicit operator bool is fine).
    • Comparison operators ==, !=, <, <=, >, >= (or <=>).
    • Convertible from and to bool through the serializer, because get<bool>() is used internally.

    There is little reason to use anything other than bool here.

    "},{"location":"features/types/template_parameters/#compatible-types_1","title":"Compatible types","text":"

    bool is the only usable choice. Another trivially copyable type that is implicitly convertible to and from bool \u2014 std::uint8_t, say \u2014 does compile, and JSON booleans still round-trip, but the type then serves as both boolean_t and an ordinary integer: basic_json can no longer be constructed or assigned from a std::uint8_t at all (the boolean and unsigned-integer to_json overloads become ambiguous), and get<std::uint8_t>() on a number throws type_error.302 instead of returning the value.

    "},{"location":"features/types/template_parameters/#numberintegertype-and-numberunsignedtype","title":"NumberIntegerType and NumberUnsignedType","text":"

    Both types are stored directly inside basic_json's union.

    "},{"location":"features/types/template_parameters/#always-required_4","title":"Always required","text":"
    • std::is_integral must be satisfied: NumberIntegerType must be a signed integer type, NumberUnsignedType an unsigned integer type or the same type as NumberIntegerType (see below). Class types are not supported \u2014 among others, the constructors taking integer values are constrained on std::is_integral.
    • Trivially default-constructible, trivially copyable, and trivially destructible (union member).
    • std::numeric_limits must be specialized for both types.
    • An unsigned NumberUnsignedType must be able to represent the absolute value of every NumberIntegerType value; serialization of negative numbers converts the value to NumberUnsignedType. A static_assert requires it to be at least as wide as NumberIntegerType, which is what that amounts to for the standard integer types.
    • Both types must fit into the internal 64-character number buffer used by dump, which is the case for all standard integer types.
    • std::hash<basic_json> additionally requires std::hash specializations.
    "},{"location":"features/types/template_parameters/#notes_1","title":"Notes","text":"

    The number types influence what the parser accepts: an integer literal that does not round-trip through the chosen type is stored as number_float_t instead. Choosing types narrower than 64 bits therefore silently changes parse results rather than raising an error. See Number Handling for details.

    "},{"location":"features/types/template_parameters/#same-type-for-both","title":"Same type for both","text":"

    NumberUnsignedType may be the same type as NumberIntegerType, e.g. nlohmann::json::with_integers_t<std::int64_t, std::int64_t> (see with_integers_t), for code that only wants to handle one integer type. Such a basic_json stores every integer as number_integer_t:

    • is_number_unsigned() is always false, and type() never returns value_t::number_unsigned. Constructing a value from value_t::number_unsigned gives a value_t::number_integer value.
    • Values of unsigned C++ types (e.g., 5u) are converted to NumberIntegerType, so values above its maximum wrap around, as values outside the range of a narrower NumberIntegerType already do.
    • The parsers store a non-negative integer above the maximum of NumberIntegerType (e.g., 18446744073709551615 for std::int64_t) as number_float_t, like any other integer that does not fit.
    • Converting from a basic_json with distinct types turns its unsigned values into number_integer_t values.
    "},{"location":"features/types/template_parameters/#compatible-types_2","title":"Compatible types","text":"Type pair Support std::int64_t / std::uint64_t (default) full std::int32_t / std::uint32_t, long long / unsigned long long full; narrower types change which literals the parser can represent any other pair of standard signed/unsigned integer types full the same signed integer type for both, e.g. std::int64_t / std::int64_t full; every integer is stored as number_integer_t, see above class types, enumerations not usable; std::is_integral must hold bool, number_float_t, or the type of another member of the union not usable; std::is_integral<bool> is in fact true, but the get_impl_ptr overloads for boolean_t, number_integer_t, number_unsigned_t and number_float_t would collide"},{"location":"features/types/template_parameters/#numberfloattype","title":"NumberFloatType","text":"

    number_float_t is stored directly inside basic_json's union.

    "},{"location":"features/types/template_parameters/#always-required_5","title":"Always required","text":"
    • Trivially default-constructible, trivially copyable, and trivially destructible (union member).
    • std::numeric_limits must be specialized; max_digits10 is used to size the conversion.
    • std::isfinite must be applicable to the type.
    "},{"location":"features/types/template_parameters/#required-for-parsing-and-serialization","title":"Required for parsing and serialization","text":"

    NumberFloatType must be one of float, double, or long double:

    • The parser converts number literals to float, double, and a long double that is IEEE 754 binary64 itself; other long double formats are converted with std::from_chars where available, or with std::strtold. The library provides overloads for exactly these three types.
    • dump falls back to std::snprintf with the %g and %Lg conversion specifiers, for which the library likewise provides only double and long double overloads (float is promoted to double).

    If std::numeric_limits<NumberFloatType> describes an IEEE 754 binary64 number, dump uses the algorithm of \u017bmij, which produces the shortest representation that round-trips. For IEEE 754 binary32 numbers, it uses Grisu2, which produces a short representation that round-trips. Otherwise the snprintf fallback with max_digits10 digits is used.

    "},{"location":"features/types/template_parameters/#required-for-the-binary-formats_1","title":"Required for the binary formats","text":"

    NumberFloatType must be float or double. The writers for CBOR, MessagePack, UBJSON, BJData, BON8, and BSON map a floating-point value onto an IEEE 754 binary32 or binary64 field and have no encoding for long double.

    "},{"location":"features/types/template_parameters/#compatible-types_3","title":"Compatible types","text":"Type Support double (default) full; shortest round-trip output through \u017bmij float full; short round-trip output through Grisu2 long double dump and parse only; the binary format writers do not compile, as they only handle IEEE 754 binary32 and binary64 any other type not usable"},{"location":"features/types/template_parameters/#allocatortype","title":"AllocatorType","text":"

    AllocatorType is instantiated with one argument, for each of object_t, array_t, string_t, binary_t, basic_json, std::pair<const StringType, basic_json>, and std::pair<StringType, basic_json>.

    AllocatorType is not the only allocator a basic_json uses. It allocates the JSON values themselves, but most temporary storage is allocated with std::allocator. This includes the parser's stacks and the stacks that process deeply nested values without recursion.

    "},{"location":"features/types/template_parameters/#always-required_6","title":"Always required","text":"
    • The template must be usable with exactly one type argument. The library instantiates AllocatorType<T> directly and never uses std::allocator_traits<...>::rebind_alloc.
    • It must satisfy the Allocator named requirement so that std::allocator_traits can be used with it.
    • It must be default-constructible and stateless. Objects are allocated with a default-constructed allocator and deallocated with a different default-constructed allocator, and get_allocator() returns a default-constructed instance. Allocators carrying state are not supported, so there is no way to tell a basic_json where to allocate from; see the note under StringType for what that means in practice. A stateful allocator is not diagnosed: it compiles and silently ignores the state.
    • It must support incomplete types: AllocatorType<basic_json> is instantiated inside the definition of basic_json itself.
    • std::allocator_traits<AllocatorType<basic_json>>::pointer becomes basic_json::pointer, and iterators are constructed from raw basic_json* values. The pointer type must therefore be a plain pointer; fancy pointers are not supported.
    "},{"location":"features/types/template_parameters/#compatible-types_4","title":"Compatible types","text":"Type Support std::allocator (default) full a custom stateless allocator template full stateful allocators, e.g. std::pmr::polymorphic_allocator not usable; see the requirements above"},{"location":"features/types/template_parameters/#jsonserializer","title":"JSONSerializer","text":"

    JSONSerializer is instantiated as JSONSerializer<T, void> and defaults to adl_serializer.

    "},{"location":"features/types/template_parameters/#always-required_7","title":"Always required","text":"
    • The template must accept two type arguments. It does not have to give the second one a default \u2014 basic_json declares the parameter as template<typename T, typename SFINAE = void> class JSONSerializer, so uses such as JSONSerializer<T> inside the library supply void themselves. The second parameter exists so that partial specializations can be constrained by SFINAE.
    • For every type T that is converted to a JSON value, a static member function static void to_json(basic_json&, T) must exist.
    • For every type T that is converted from a JSON value, either static void from_json(const basic_json&, T&) or static T from_json(const basic_json&) must exist. The latter form is required for types that are not default-constructible; see Arbitrary Types Conversions.
    • To support the converting constructor between different basic_json specializations, to_json must be available for boolean_t, number_integer_t, number_unsigned_t, number_float_t, string_t, object_t, array_t, and binary_t of the source specialization.
    "},{"location":"features/types/template_parameters/#compatible-types_5","title":"Compatible types","text":"Type Support nlohmann::adl_serializer (default) full a class template deriving from adl_serializer full; the usual way to change behavior while keeping the defaults an unrelated template with the same interface full, but it has to handle every type the library converts"},{"location":"features/types/template_parameters/#binarytype","title":"BinaryType","text":"

    BinaryType is not a JSON type; it is used for the byte strings of the binary formats. It is wrapped as

    using binary_t = nlohmann::byte_container_with_subtype<BinaryType>;\n
    "},{"location":"features/types/template_parameters/#always-required_8","title":"Always required","text":"
    • A non-final class type \u2014 byte_container_with_subtype derives from it publicly.
    • A member type value_type that is exactly one byte wide (e.g., std::uint8_t, char, or std::byte). Readers and writers reinterpret the container's storage as raw bytes, so a wider value_type is rejected with a static_assert.
    • Contiguous storage: the binary readers std::memcpy into &binary[n], the writers reinterpret_cast data(). data() + n would do for the readers too, but they share one helper with StringType, whose non-const data() is C++17 and later only.
    • Default-constructible, copy-constructible, and move-constructible.
    • Member functions size(), empty(), data(), resize(), operator[], back(), begin(), end(), cbegin(), and cend() with random-access iterators. push_back() is not required.
    • Comparison operators: == is used by byte_container_with_subtype, the relational operators by basic_json's comparison operators.
    "},{"location":"features/types/template_parameters/#required-for-individual-functions_1","title":"Required for individual functions","text":"
    • clear(), for basic_json::clear().

    max_size(), at(), reserve(), erase(), pop_back(), and emplace_back() are not used at all.

    See binary_t for how a non-default BinaryType changes the meaning of assigning such a container to a basic_json value.

    Reference implementation

    docs/mkdocs/docs/examples/custom_binary_type.hpp wraps a private std::vector<std::uint8_t> and satisfies every requirement above \u2014 a good starting point for a custom BinaryType.

    #pragma once\n\n#include <cstdint>\n#include <initializer_list>\n#include <vector>\n\n// A minimal, self-contained BinaryType built around a private std::vector.\n// See https://json.nlohmann.me/features/types/template_parameters/#binarytype\nclass custom_binary_type\n{\n    using vector_t = std::vector<std::uint8_t>;\n    vector_t data_;\n\n  public:\n    using value_type = vector_t::value_type;\n    using size_type = vector_t::size_type;\n    using iterator = vector_t::iterator;\n    using const_iterator = vector_t::const_iterator;\n\n    custom_binary_type() = default;\n    custom_binary_type(const custom_binary_type&) = default;\n    custom_binary_type(custom_binary_type&&) = default;\n    custom_binary_type& operator=(const custom_binary_type&) = default;\n    custom_binary_type& operator=(custom_binary_type&&) = default;\n\n    template<class InputIt>\n    custom_binary_type(InputIt first, InputIt last) : data_(first, last) {}\n\n    // so basic_json::binary({0x01, 0x02}) can build one directly\n    custom_binary_type(std::initializer_list<std::uint8_t> init) : data_(init) {}\n\n    size_type size() const\n    {\n        return data_.size();\n    }\n    bool empty() const\n    {\n        return data_.empty();\n    }\n    void clear()\n    {\n        data_.clear();\n    }\n    void resize(size_type n)\n    {\n        data_.resize(n);\n    }\n\n    // read-only is enough: the writers only ever read from a binary value\n    const std::uint8_t* data() const\n    {\n        return data_.data();\n    }\n\n    std::uint8_t& operator[](size_type pos)\n    {\n        return data_[pos];\n    }\n    std::uint8_t operator[](size_type pos) const\n    {\n        return data_[pos];\n    }\n\n    std::uint8_t& back()\n    {\n        return data_.back();\n    }\n    std::uint8_t back() const\n    {\n        return data_.back();\n    }\n\n    iterator begin()\n    {\n        return data_.begin();\n    }\n    iterator end()\n    {\n        return data_.end();\n    }\n    const_iterator begin() const\n    {\n        return data_.begin();\n    }\n    const_iterator end() const\n    {\n        return data_.end();\n    }\n    const_iterator cbegin() const\n    {\n        return data_.cbegin();\n    }\n    const_iterator cend() const\n    {\n        return data_.cend();\n    }\n\n    template<class InputIt>\n    iterator insert(const_iterator pos, InputIt first, InputIt last)\n    {\n        return data_.insert(pos, first, last);\n    }\n\n    friend bool operator==(const custom_binary_type& lhs, const custom_binary_type& rhs)\n    {\n        return lhs.data_ == rhs.data_;\n    }\n    friend bool operator<(const custom_binary_type& lhs, const custom_binary_type& rhs)\n    {\n        return lhs.data_ < rhs.data_;\n    }\n};\n
    Example: use the custom BinaryType
    #include <iostream>\n\n#include <nlohmann/json.hpp>\n\n#include \"custom_binary_type.hpp\"\n\nusing custom_json = nlohmann::json::with_binary_t<custom_binary_type>;\n\nint main()\n{\n    const auto j = custom_json::binary({0x01, 0x02, 0x03});\n\n    std::cout << j.dump() << '\\n';\n    std::cout << std::boolalpha << (custom_json::from_cbor(custom_json::to_cbor(j)) == j) << '\\n';\n}\n

    Output:

    {\"bytes\":[1,2,3],\"subtype\":null}\ntrue\n
    "},{"location":"features/types/template_parameters/#compatible-containers_2","title":"Compatible containers","text":"Container Notes std::vector<std::uint8_t> (default) std::vector<char>, std::vector<std::byte> dump() writes the bytes as 0..255 whichever is used boost::container::vector<std::uint8_t>, boost::container::small_vector<std::uint8_t, N> absl::InlinedVector<std::uint8_t, N> usable here, unlike as an ArrayType, because the value type is complete eastl::vector<std::uint8_t> usable here, unlike as an ArrayType, because max_size() is not needed folly::fbvector<std::uint8_t> requires C++20, see the note above"},{"location":"features/types/template_parameters/#containers-that-cannot-be-used_2","title":"Containers that cannot be used","text":"Container Reason QByteArray no empty() (it spells that isEmpty()); its insert takes an index rather than an iterator; and it converts to string_t, which makes to_json ambiguous between a string and a binary value std::string binary_t::container_type and string_t would be the same type, so the two swap overloads collide and basic_json cannot be instantiated at all std::deque<std::uint8_t> storage is not contiguous, so there is no data() containers whose value_type is wider than one byte see above \u2014 accepted by the compiler, wrong at runtime"},{"location":"features/types/template_parameters/#custombaseclass","title":"CustomBaseClass","text":"

    CustomBaseClass is an extension point: unless it is void (the default, which selects the empty nlohmann::json_default_base), basic_json publicly derives from it.

    "},{"location":"features/types/template_parameters/#always-required_9","title":"Always required","text":"
    • A non-final, default-constructible class type.
    • basic_json is copy-/move-constructible and copy-/move-assignable only if CustomBaseClass is.
    "},{"location":"features/types/template_parameters/#notes_2","title":"Notes","text":"

    basic_json is documented to be a StandardLayoutType. Because basic_json has non-static data members of its own, a CustomBaseClass with non-static data members forfeits this guarantee.

    Note the namespace of CustomBaseClass becomes an associated namespace of basic_json for the purpose of argument-dependent lookup.

    See json_base_class_t for an example.

    "},{"location":"features/types/template_parameters/#compatible-types_6","title":"Compatible types","text":"Type Support void (default) an empty base class is used; no effect on basic_json any default-constructible, non-final class full; see json_base_class_t"},{"location":"features/types/template_parameters/#cross-specialization-conversions","title":"Cross-specialization conversions","text":"

    Converting a value from one basic_json specialization into another (see the converting constructor) imposes two additional requirements that are not diagnosed at compile time. With assertions enabled they abort on the JSON_ASSERT at the end of the converting constructor; under NDEBUG they fail silently at runtime:

    • The target string_t must be directly constructible from the source string_t. Otherwise the string is converted to an array of character codes.
    • The target object_t::key_type must be directly constructible from the source object's key type. Otherwise the object is converted to an array of key/value pairs.

    See issue #3425, string_t, and object_t.

    "},{"location":"features/types/template_parameters/#see-also","title":"See also","text":"
    • Types - overview of how JSON values are stored
    • Number Handling - how the number types affect parsing and serialization
    • Object Order - using an insertion-ordered ObjectType
    • basic_json - API documentation of the class template
    • object_t - the ObjectType in use
    • array_t - the ArrayType in use
    • string_t - the StringType in use
    • json_serializer - the JSONSerializer in use
    • json_base_class_t - the CustomBaseClass in use
    • with_t - derive a specialization with one parameter replaced
    • get_allocator - the allocator in use
    "},{"location":"home/architecture/","title":"Architecture","text":"

    This page gives a high-level overview of the library's architecture. It should help new contributors to get an idea of the used concepts and where to make changes.

    "},{"location":"home/architecture/#overview","title":"Overview","text":"

    The library is built around a single class template, nlohmann::basic_json. A basic_json value is a node in a tree of JSON values. All other components either create such a tree from an input (parsing), write a tree to an output (serialization), or give access to it (iterators, JSON Pointer, conversions).

    flowchart LR\n    input[/\"input<br>(string, stream,<br>iterator range, file)\"/]\n    ia[\"input adapter\"]\n    lexer[\"lexer\"]\n    parser[\"parser\"]\n    breader[\"binary_reader\"]\n    sax[\"SAX interface\"]\n    value[(\"basic_json<br>value tree\")]\n    serializer[\"serializer\"]\n    bwriter[\"binary_writer\"]\n    oa[\"output adapter\"]\n    output[/\"output<br>(string, stream,<br>vector)\"/]\n\n    input --> ia\n    ia --> lexer --> parser --> sax\n    ia --> breader --> sax\n    sax --> value\n    value --> serializer --> oa\n    value --> bwriter --> oa\n    oa --> output

    Data flow through the library: input runs left to right through an input adapter and the lexer and parser (JSON text) or the binary_reader (binary formats) into SAX events, which build the value tree; the serializer or the binary_writer writes the tree to an output adapter.

    • JSON text is read by an input adapter, tokenized by the lexer, and turned into SAX events by the parser.
    • Binary formats (BJData, BON8, BSON, CBOR, MessagePack, UBJSON) are read by an input adapter and turned into the same SAX events by the binary_reader.
    • A SAX consumer receives the events. The one used by parse builds a basic_json value tree.
    • The serializer (JSON text) or the binary_writer (binary formats) writes a value tree to an output adapter.
    "},{"location":"home/architecture/#source-layout","title":"Source layout","text":"

    The public headers are in include/nlohmann:

    • json.hpp defines class basic_json.
    • json_fwd.hpp contains forward declarations.
    • adl_serializer.hpp, byte_container_with_subtype.hpp, and ordered_map.hpp define adl_serializer, byte_container_with_subtype, and ordered_map.
    • json_view.hpp is a separate, optional header that defines basic_json_document and basic_json_view, a flat-index, read-only, non-owning way to look at a parsed JSON text; see Zero-copy JSON views. It builds on json.hpp internals (it requires the same library version) and has its own detail/view/ subdirectory.

    Everything else lives in detail/ and namespace nlohmann::detail, which is not part of the public API. Paths below are relative to include/nlohmann.

    Component Location Value type enumeration detail/value_t.hpp Input adapters detail/input/input_adapters.hpp Lexer detail/input/lexer.hpp, detail/input/number_parse.hpp, detail/input/string_scan.hpp, detail/input/simd_scan.hpp Parser detail/input/parser.hpp SAX interface and DOM builders detail/input/json_sax.hpp Binary format readers detail/input/binary_reader.hpp JSON serializer detail/output/serializer.hpp, detail/conversions/to_chars.hpp Binary format writers detail/output/binary_writer.hpp Output adapters detail/output/output_adapters.hpp Iterators detail/iterators/ Conversions from/to arbitrary types detail/conversions/from_json.hpp, detail/conversions/to_json.hpp JSON Pointer detail/json_pointer.hpp Exceptions detail/exceptions.hpp Type traits and C++ feature backports detail/meta/ Macros detail/macro_scope.hpp, detail/macro_unscope.hpp, detail/abi_macros.hpp

    The single-header version single_include/nlohmann/json.hpp is generated from these files with make amalgamate and must not be edited by hand. The same command also generates single_include/nlohmann/json_view.hpp from json_view.hpp and detail/view/.

    "},{"location":"home/architecture/#template-parameters","title":"Template parameters","text":"

    basic_json is parameterized by the types it uses to store values and to convert from and to other types:

    Template parameter Default Used for ObjectType std::map objects, see object_t ArrayType std::vector arrays, see array_t StringType std::string strings and object keys, see string_t BooleanType bool Booleans, see boolean_t NumberIntegerType std::int64_t signed integers, see number_integer_t NumberUnsignedType std::uint64_t unsigned integers, see number_unsigned_t NumberFloatType double floating-point numbers, see number_float_t AllocatorType std::allocator allocating objects, arrays, strings, and binary values JSONSerializer adl_serializer conversions from/to other types, see adl_serializer BinaryType std::vector<std::uint8_t> binary values, see binary_t CustomBaseClass void an optional base class, see json_base_class_t

    The library provides two specializations:

    • json uses all default template arguments.
    • ordered_json uses ordered_map as ObjectType to keep the insertion order of object keys.

    The requirements on the template arguments are listed in Template Parameter Requirements.

    "},{"location":"home/architecture/#value-storage","title":"Value storage","text":"

    Each basic_json value stores its content as a tagged union: an enumeration value_t names the type of the value, and a union json_value holds the value itself. Both are members of the nested struct data, which is the only data member m_data of basic_json:

    struct data\n{\n    /// the type of the current element\n    value_t m_type = value_t::null;\n\n    /// the value of the current element\n    json_value m_value = {};\n};\n\ndata m_data = {};\n

    with

    enum class value_t : std::uint8_t\n{\n    null,             ///< null value\n    object,           ///< object (unordered set of name/value pairs)\n    array,            ///< array (ordered collection of values)\n    string,           ///< string value\n    boolean,          ///< boolean value\n    number_integer,   ///< number value (signed integer)\n    number_unsigned,  ///< number value (unsigned integer)\n    number_float,     ///< number value (floating-point)\n    binary,           ///< binary array (ordered collection of bytes)\n    discarded         ///< discarded by the parser callback function\n};\n\nunion json_value {\n  /// object (stored with pointer to save storage)\n  object_t *object;\n  /// array (stored with pointer to save storage)\n  array_t *array;\n  /// string (stored with pointer to save storage)\n  string_t *string;\n  /// binary (stored with pointer to save storage)\n  binary_t *binary;\n  /// boolean\n  boolean_t boolean;\n  /// number (integer)\n  number_integer_t number_integer;\n  /// number (unsigned integer)\n  number_unsigned_t number_unsigned;\n  /// number (floating-point)\n  number_float_t number_float;\n};\n

    Objects, arrays, strings, and binary values are allocated on the heap with AllocatorType, and the union only stores a pointer to them. This keeps a basic_json value small: one pointer-sized union and one byte for the type. The class maintains the invariant that the pointer matching m_type is never null; assert_invariant() checks it with runtime assertions.

    "},{"location":"home/architecture/#node-index-of-json-views","title":"Node index of JSON views","text":"

    A basic_json_document (see Zero-copy JSON views) does not build a tree of values. Its parser (detail/view/builder.hpp) writes a flat array of 16-byte nodes, one per value and one per object key, in document order. A basic_json_view is a pointer to the document and a pointer to one node. The layout is struct node in detail/view/node.hpp (the numbers are bit offsets, 32 bits per row):

    packet-beta\n  0-7: \"kind\"\n  8-15: \"flags\"\n  16-31: \"extra\"\n  32-63: \"off\"\n  64-95: \"len\"\n  96-127: \"next\"

    Layout of one 16-byte node of a JSON view index. Each row is 32 bits wide, and the numbers are the bit offsets of the fields kind, flags, extra, off, len, and next.

    Bytes Field Type Contents 0 kind uint8_t the type, numbered as value_t: 0 null, 1 object, 2 array, 3 string, 4 boolean, 5 signed integer, 6 unsigned integer, 7 float; 10 for a link (see below). There is no node for a discarded value: a discarded view has none 1 flags uint8_t bits 0-1: where a string's bytes (or a number's token) are (0: the source text, 1: the buffer of decoded strings, for strings with escapes, 2: the edit buffer); bit 2: the value of a boolean; bit 3: moved, bit 4: new, bit 5: linked (see below) 2-3 extra uint16_t numbers: the number of integer digits (low byte) and fraction digits (high byte), 255 for more; objects: the number of their key hash index (1-based), or 0; otherwise 0 4-7 off uint32_t where the value starts: the first byte after a string's opening quote (or its position in the buffer of decoded strings), the first byte of a number or literal, the bracket of an array or object 8-11 len uint32_t strings: the length after decoding; floats and literals: the length of the token; arrays and objects: the number of elements 12-15 next uint32_t arrays and objects: the number of nodes of the subtree, including the node itself; strings with escapes: the position of the opening quote in the source plus one if the document was parsed with JSON_DIAGNOSTIC_POSITIONS, or 0 if it was not; all other values: 0

    Fields of a node, by their byte offset within the 16-byte node. Integers use bytes 8-15 differently, see below.

    • Integers keep their converted value in bytes 8-15 instead of len and next; the length of their token follows from the number of digits in extra (and the sign). Non-negative integers are unsigned integers, as with parse.
    • Floats keep only their token. The digit layout in extra lets the conversion read the digits without scanning the token again, and only when the value is read.
    • Object members are the node of the key (a string) followed by the nodes of the value.
    • Navigation needs no pointers: the elements of an array or object follow its node, and the node after a value's subtree is next nodes further for an array or object, and the next node otherwise (document_data::after). Views step from element to element this way and skip whole subtrees in constant time.
    • Offsets are 32 bits wide, so a document is limited to 4294967279 bytes, 4 GiB minus 16 bytes (a margin below 2^32 for positions one scanner step past the end of the text; out_of_range.416).
    • Source positions (JSON_DIAGNOSTIC_POSITIONS) are derived by materialize() and cost almost nothing while parsing: the only work is storing the offset of the opening quote of a string with escapes in its next, which is otherwise unused. A scalar's range follows from off and its length, a string with escapes is scanned from its opening quote (next) to the closing one, and the end of an array or object is found by scanning from the end of its last element over whitespace, comments, and a trailing comma. materialize() hands these positions to the SAX builder of parse() in place of its lexer.
    • Large objects (128 members or more) get a hash index for their keys after parsing (detail/view/object_index.hpp): an open-addressing table whose slots hold the distance from the object's node to a key's node, so that a lookup does not compare every key. Of duplicate keys the table leads to the first, as a linear search does. The object's extra holds the number of its table. Only 65,535 tables fit into extra; objects beyond them are searched linearly.

    For example, {\"a\": [1, 2.5]} becomes five nodes. Each node's elements follow it, and next leads from an array or object past its subtree:

    flowchart LR\n    n0[\"0: object<br>len 1, next 5\"]\n    n1[\"1: key a\"]\n    n2[\"2: array<br>len 2, next 3\"]\n    n3[\"3: unsigned integer 1\"]\n    n4[\"4: float 2.5\"]\n    e([\"end\"])\n    n0 --> n1 --> n2 --> n3 --> n4 --> e\n    n0 -. next .-> e\n    n2 -. next .-> e

    The five nodes of {\"a\": [1, 2.5]} in document order. Solid arrows lead from each node to the one after it; dotted arrows show where next leads from the object and the array, past their subtrees.

    Node kind extra off len next 0 1 (object) 0 0 1 5 1 3 (string) 0 2 1 0 2 2 (array) 0 6 2 3 3 6 (unsigned integer) 0x0001 7 - - 4 7 (float) 0x0101 10 3 0

    Fields of the five nodes of {\"a\": [1, 2.5]}. off is the byte offset in the text, and - marks the bytes 8-15 that hold the integer's value instead of len and next.

    All flags are 0. The integer's bytes 8-15 hold its value, 1; its extra says it has one digit. The float's extra says it has one integer and one fraction digit, and its len is that of the token 2.5.

    Editable documents (json_editable_document, detail/view/edit.hpp and detail/view/edit_storage.hpp) never write the source text and never move or resize the parsed index, so views stay valid while the document is edited:

    • A new scalar is written over its node. Its text (a string, or the token of a number as dump() writes it) goes to the edit buffer, which flags bits 0-1 then name.
    • An array or object whose elements change gets the flag moved (bit 3): its elements then live in a separate sequence (a header node, then the entries), whose number is in off. The entries are links (kind 10), whose bytes 8-15 hold the address of the value's node, so values never move.
    • A node written by an edit gets the flag new (bit 4): it has no position in the source text.
    • A value that an entry of such a sequence links to gets the flag linked (bit 5): its extent in the parsed layout (next) no longer matters, so a scalar can replace an array or object there in place.
    • Views of read-only documents compile without any of this: how views walk the index is a template parameter (navigation<Editable>).

    Images (save and load, detail/view/image.hpp) store the nodes as they are: a 64-byte header (the magic bytes NJVI, a format version, the sizes, and reserved bytes that must be zero), the nodes, the text, and the decoded strings. An edited document is first written in document order, as the parser would have written it (without links), and the numbers of the hash indexes are cleared, since load rebuilds the indexes. The flag new is kept, as these values have no position in the text. So a change of the node layout is a change of the image format: it must raise image_version, and load then rejects images of other versions (parse_error.116) instead of misreading them.

    "},{"location":"home/architecture/#input-adapters","title":"Input adapters","text":"

    Input is read via input adapters that abstract a source. Every input adapter provides this interface:

    /// the type of the characters in the input\nusing char_type = ...;\n\n/// read a single character; returns std::char_traits<char_type>::eof() at the end of the input\ntypename std::char_traits<char_type>::int_type get_character();\n\n/// read up to count * sizeof(T) bytes into dest and return the number of bytes read\n/// (used by the binary readers)\ntemplate<class T>\nstd::size_t get_elements(T* dest, std::size_t count = 1);\n

    The lexer detects two optional extensions at compile time. iterator_input_adapter provides both, and only for random-access input of single-byte characters. input_stream_adapter provides the second one (as a window onto the streambuf's buffer) unless JSON_DISABLE_STREAM_BULK_SCAN is defined:

    • supports_seek, get_consumed_count(), and copy_consumed_range() let the lexer reconstruct already consumed input for error messages instead of copying every character it reads. With get_read_count() and count_consumed_lines(), the lexer also derives the read position from the adapter and counts lines only when an error needs them, instead of counting characters and lines on every read.
    • supports_bulk_scan, bulk_data(), bulk_remaining(), and bulk_skip() let the lexer scan strings directly in contiguous memory, several bytes at a time, and skip the spaces that indent a line in 8-byte steps.

    The function input_adapter picks the right adapter for the argument passed to parse, accept, sax_parse, or the from_* functions:

    • iterator_input_adapter reads from an iterator range, which also covers strings, containers, and pointers.
    • wide_string_input_adapter reads from ranges of wchar_t, char16_t, or char32_t and converts them to UTF-8. It cannot be used for binary formats; its get_elements() throws.
    • input_stream_adapter reads from a std::istream.
    • file_input_adapter reads from a std::FILE*.

    The adapters have no common base class: the lexer and the parser are templates on the adapter type, and wide_string_input_adapter wraps an iterator_input_adapter:

    classDiagram\n    class input_adapter [\"input adapter\"] {\n        <<concept>>\n        +char_type\n        +get_character() int_type\n        +get_elements(T* dest, size_t count) size_t\n    }\n    class iterator_input_adapter {\n        -IteratorType current\n        -SentinelType end\n    }\n    class wide_string_input_adapter {\n        -BaseInputAdapter base_adapter\n    }\n    class input_stream_adapter {\n        -std::istream* is\n        -std::streambuf* sb\n    }\n    class file_input_adapter {\n        -std::FILE* m_file\n    }\n    input_adapter <|.. iterator_input_adapter\n    input_adapter <|.. wide_string_input_adapter\n    input_adapter <|.. input_stream_adapter\n    input_adapter <|.. file_input_adapter\n    wide_string_input_adapter o-- iterator_input_adapter : converts to UTF-8

    The input adapters as a class diagram. The dotted arrows mean that each adapter implements the input adapter concept; the diamond shows that wide_string_input_adapter holds an iterator_input_adapter.

    "},{"location":"home/architecture/#sax-interface","title":"SAX interface","text":"

    The parser does not build values itself. It reports what it reads as events to a SAX consumer, which implements the interface json_sax: null, boolean, number_integer, number_unsigned, number_float, string, binary, start_object, key, end_object, start_array, end_array, and parse_error.

    The library comes with two consumers in detail/input/json_sax.hpp:

    • json_sax_dom_parser builds a basic_json value tree. parse uses it.
    • json_sax_dom_callback_parser does the same, but calls a parser callback for each event, which can skip values. parse uses it when a callback is given.

    The binary_reader emits the same events for binary formats, so sax_parse works with a user-defined consumer for JSON and for all binary formats alike. The SAX event stepper shows the events for a small input.

    "},{"location":"home/architecture/#output-adapters","title":"Output adapters","text":"

    Output is written via output adapters:

    void write_character(CharType c);\n\nvoid write_characters(const CharType* s, std::size_t length);\n

    The serializer (used by dump and operator<<) and the binary_writer (used by the to_* functions) write to one of these adapters:

    • output_vector_adapter appends to a std::vector.
    • output_stream_adapter writes to a std::ostream.
    • output_string_adapter appends to a string.

    They implement the abstract class output_adapter_protocol. The class output_adapter creates the one that matches its argument and holds it in a std::shared_ptr (output_adapter_t):

    classDiagram\n    class output_adapter_protocol~CharType~ {\n        <<interface>>\n        +write_character(CharType c)*\n        +write_characters(const CharType* s, size_t length)*\n    }\n    class output_vector_adapter {\n        -std::vector& v\n    }\n    class output_stream_adapter {\n        -std::basic_ostream& stream\n    }\n    class output_string_adapter {\n        -StringType& str\n    }\n    class output_adapter {\n        -output_adapter_t oa\n    }\n    output_adapter_protocol <|-- output_vector_adapter\n    output_adapter_protocol <|-- output_stream_adapter\n    output_adapter_protocol <|-- output_string_adapter\n    output_adapter o-- output_adapter_protocol : shared_ptr

    The output adapters as a class diagram. The three adapters derive from output_adapter_protocol (solid arrows), and output_adapter holds one of them through a shared_ptr (diamond).

    The binary_writer does not call an adapter for every byte. The to_* functions that return a std::vector write into the vector through a sink (output_vector_sink) that is not virtual. The functions that take an output adapter write through a sink (output_adapter_sink) that collects the output in a buffer of one kibibyte and passes it to the adapter in blocks, so that the adapter is called (and a stream locked) once per block instead of once per value.

    "},{"location":"home/architecture/#value-conversion","title":"Value conversion","text":"

    Values are converted from and to other types with the JSONSerializer template parameter. The default, adl_serializer, calls the free functions

    template<class T>\nvoid to_json(basic_json& j, const T& t);\n\ntemplate<class T>\nvoid from_json(const basic_json& j, T& t);\n

    found by argument-dependent lookup. The library defines them for standard types in detail/conversions; users add them for their own types, see Arbitrary Type Conversions. The serialization macros generate these functions.

    "},{"location":"home/architecture/#additional-features","title":"Additional features","text":"
    • JSON Pointer (class json_pointer) addresses values inside a tree. It is also the basis of JSON Patch.
    • Binary formats are read by binary_reader and written by binary_writer.
    • A custom base class can add members to every basic_json value.
    • Serialization macros generate to_json and from_json functions for user-defined types.
    "},{"location":"home/architecture/#details-namespace","title":"Details namespace","text":"

    Namespace nlohmann::detail contains all implementation details. It is not part of the public API and may change in any release. Besides the components above, it contains:

    • type traits to detect the capabilities of user-defined types (detail/meta/type_traits.hpp),
    • backports of C++14/17 features to C++11 (detail/meta/cpp_future.hpp), and
    • helpers such as string_concat and string_escape.
    "},{"location":"home/architecture/#see-also","title":"See also","text":"
    • basic_json - the main class and all its member functions
    • adl_serializer - customization point for type conversions
    • json_sax - interface of the SAX parser events
    • SAX Interface - how to consume parser events without building a DOM
    • Zero-copy JSON views - the flat node index that backs views and documents
    • Template Parameter Requirements - the template parameters of basic_json
    • Serialization - the output side of the library
    • nlohmann Namespace - how the library namespace is structured
    "},{"location":"home/customers/","title":"Customers","text":"

    The library is used in multiple projects, applications, operating systems, etc. The list below is not exhaustive, but the result of an internet search. If you know further customers of the library, please let me know.

    "},{"location":"home/customers/#space-exploration","title":"Space Exploration","text":"
    • Peregrine Lunar Lander Flight 01 - The library was used for payload management in the Peregrine Moon Lander, developed by Astrobotic Technology and launched as part of NASA's Commercial Lunar Payload Services (CLPS) program. After six days in orbit, the spacecraft was intentionally redirected into Earth's atmosphere, where it burned up over the Pacific Ocean on January 18, 2024.
    • NASA Unsteady Pressure-Sensitive Paint Processing, NASA software for processing high-speed video recordings of wind tunnel tests on launch vehicle and aircraft models
    • Terma TEMU, an emulator of spacecraft on-board computers used to develop and validate flight software for European space missions
    "},{"location":"home/customers/#automotive","title":"Automotive","text":"
    • Alexa Auto SDK, a software development kit enabling the integration of Alexa into automotive systems
    • Apollo, a framework for building autonomous driving systems
    • Automotive Grade Linux (AGL), a collaborative open-source platform for automotive software development
    • Autoware, an open-source software stack for autonomous driving built on ROS 2
    • Eclipse S-CORE, an open-source software platform for the software-defined vehicle backed by major automotive manufacturers and suppliers
    • Genesis Motor (infotainment), a luxury automotive brand
    • Hyundai (infotainment), a global automotive brand
    • Kia (infotainment), a global automotive brand
    • Mercedes-Benz Operating System (MB.OS), a core component of the vehicle software ecosystem from Mercedes-Benz
    • NVIDIA DRIVE OS, the operating system and DriveWorks SDK powering NVIDIA's platform for autonomous vehicles
    • Rivian (infotainment), an electric vehicle manufacturer
    • Suzuki (infotainment), a global automotive and motorcycle manufacturer
    "},{"location":"home/customers/#gaming-and-entertainment","title":"Gaming and Entertainment","text":"
    • Anno 117: Pax Romana, a city-building strategy game set in the Roman Empire
    • Assassin's Creed: Mirage, a stealth-action game set in the Middle East, focusing on the journey of a young assassin with classic parkour and stealth mechanics
    • Battlefield 6, a military first-person shooter known for its large-scale multiplayer battles
    • Battlefield: REDSEC, a free-to-play battle royale experience set in the Battlefield universe
    • BioMenace: Remastered, a remaster of the classic side-scrolling platform shooter
    • Chasm: The Rift, a first-person shooter blending horror and adventure, where players navigate dark realms and battle monsters
    • College Football 25, a college football simulation game featuring gameplay that mimics real-life college teams and competitions
    • College Football 26, a college football simulation game featuring licensed teams and stadiums
    • College Football 27, the latest installment of the college football simulation series
    • Concepts, a digital sketching app designed for creative professionals, offering flexible drawing tools for illustration, design, and brainstorming
    • Depthkit, a tool for creating and capturing volumetric video, enabling immersive 3D experiences and interactive content
    • Dune: Awakening, an open-world survival MMO set on the desert planet Arrakis
    • EA Sports FC 25, an association football simulation with club, career, and online modes
    • EA Sports FC 26, the latest installment of the association football simulation series
    • EA Sports UFC 6, a mixed martial arts fighting simulation
    • FiveM, a modification framework for Grand Theft Auto V that powers custom multiplayer servers
    • FLUX:: Immersive, a suite of professional audio processing and immersive mixing plugins used in music and post-production
    • IMG.LY, a platform offering creative tools and SDKs for integrating advanced image and video editing in applications
    • immersivetech, a technology company focused on immersive experiences, providing tools and solutions for virtual and augmented reality applications
    • Kodi, a home theater and media center application
    • LOOT, a tool for optimizing the load order of game plugins, commonly used in The Elder Scrolls and Fallout series
    • LunaTranslator, a real-time translation tool for visual novels
    • MaaAssistantArknights, an automation assistant for the mobile game Arknights
    • Madden NFL 25, a sports simulation game capturing the excitement of American football with realistic gameplay and team management features
    • Madden NFL 26, an American football simulation with franchise and team management modes
    • Madden NFL 27, the latest installment of the American football simulation series
    • Marne, an unofficial private server platform for hosting custom Battlefield 1 game experiences
    • Minecraft, a popular sandbox video game
    • Mumble, a low-latency, open-source voice chat application widely used by gaming communities
    • NHL 22, a hockey simulation game offering realistic gameplay, team management, and various modes to enhance the hockey experience
    • OBS Studio, a free and open-source suite for video recording and live streaming
    • OpenRCT2, an open source re-implementation of RollerCoaster Tycoon 2
    • Pixelpart, a 2D animation and video compositing software that allows users to create animated graphics and visual effects with a focus on simplicity and ease of use
    • Razer Cortex, a gaming performance optimizer and system booster designed to enhance the gaming experience
    • Red Dead Redemption II, an open-world action-adventure game following an outlaw's story in the late 1800s, emphasizing deep storytelling and immersive gameplay
    • RetroArch, a frontend for emulators, game engines, and media players built on the libretro API
    • shadPS4, a PlayStation 4 emulator for Windows, Linux and macOS
    • skate., a free-to-play skateboarding game set in an open world
    • Snapchat, a multimedia messaging and augmented reality app for communication and entertainment
    • Steel Century Groove, an action game released in 2026
    • Sunshine, a self-hosted game streaming host compatible with Moonlight clients
    • Tactics Ogre: Reborn, a tactical role-playing game featuring strategic battles and deep storytelling elements
    • Throne and Liberty, an MMORPG that offers an expansive fantasy world with dynamic gameplay and immersive storytelling
    • Unity Vivox, a communication service that enables voice and text chat functionality in multiplayer games developed with Unity
    • xemu, an emulator of the original Xbox console
    • Zool: Redimensioned, a modern reimagining of the classic platformer featuring fast-paced gameplay and vibrant environments
    "},{"location":"home/customers/#consumer-electronics","title":"Consumer Electronics","text":"
    • Audinate, a provider of networked audio solutions specializing in Dante technology, which facilitates high-quality digital audio transport over IP networks
    • Canon CanoScan LIDE, a series of flatbed scanners offering high-resolution image scanning for home and office use
    • Canon PIXMA Printers, a line of all-in-one inkjet printers known for high-quality printing and wireless connectivity
    • Cisco Webex Desk Camera, a video camera designed for professional-quality video conferencing and remote collaboration
    • DJI Edge SDK, the reference applications for DJI's Edge SDK, used to build edge computing services on DJI drone docks
    • Elgato Stream Deck, a family of programmable control surfaces for content creators and their plugin ecosystem
    • Instagrid, a manufacturer of portable, high-performance battery systems for professional mobile power supply
    • iRobot, a manufacturer of autonomous home robots including the Roomba vacuum cleaner range
    • Logitech Logi Bolt, the management application for Logitech's secure wireless connectivity technology
    • Novitus, a manufacturer of fiscal cash registers and point-of-sale devices
    • Philips Hue Personal Wireless Lighting, a smart lighting system for customizable and wireless home illumination
    • Ray-Ban Meta Smart glasses, a pair of smart glasses designed for capturing photos and videos with integrated connectivity and social features
    • Razer Synapse, a unified configuration software enabling hardware customization for Razer devices
    • Sharp Professional Displays, a range of large-format interactive displays for business and education
    • Siemens SINEMA Remote Connect, a remote connectivity solution for monitoring and managing industrial networks and devices securely
    • Skydio, a manufacturer of autonomous drones for inspection, public safety, and defense applications
    • Sony PlayStation 4, a gaming console developed by Sony that offers a wide range of games and multimedia entertainment features
    • Sony Spatial Reality Display, a glasses-free stereoscopic 3D display and its plugins for Blender, 3ds Max, and ZBrush
    • Sony Virtual Webcam Driver for Remote Camera, a software driver that enables the use of Sony cameras as virtual webcams for video conferencing and streaming
    • Yamaha Clavinova, a series of digital pianos combining acoustic piano feel with digital sound technology
    "},{"location":"home/customers/#operating-systems-and-platforms","title":"Operating Systems and Platforms","text":"
    • Apple iOS and macOS, a family of operating systems developed by Apple, including iOS for mobile devices and macOS for desktop computers
    • Chromium, the open-source browser project that Google Chrome, Microsoft Edge, and many other browsers are built on, where the library is used as data container for on-device model execution
    • Google Fuchsia, an open-source operating system developed by Google, designed to be secure, updatable, and adaptable across various devices
    • LG webOS, a Linux-based operating system used in LG smart TVs, signage, and embedded devices
    • Microsoft Azure Linux, a Linux distribution developed by Microsoft for Azure infrastructure and edge workloads
    • OpenHarmony, an open-source operating system for smart devices and the foundation of HarmonyOS
    • SerenityOS, an open-source operating system that aims to provide a simple and beautiful user experience with a focus on simplicity and elegance
    • Windows Subsystem for Linux, a compatibility layer that runs Linux environments natively on Windows
    • Yocto, a Linux-based build system for creating custom operating systems and software distributions, tailored for embedded devices and IoT applications
    "},{"location":"home/customers/#development-tools-and-ides","title":"Development Tools and IDEs","text":"
    • Accentize SpectralBalance, an adaptive speech analysis tool designed to enhance audio quality by optimizing frequency balance in recordings
    • Airbus Ghidralligator, a Ghidra-based emulator from Airbus CyberSecurity used to fuzz and analyse embedded firmware
    • Apache brpc, an industrial-grade remote procedure call framework for C++
    • Arm Compiler for Linux, a software development toolchain for compiling and optimizing applications on Arm-based Linux systems
    • BBEdit, a professional text and code editor for macOS
    • CoderPad, a collaborative coding platform that enables real-time code interviews and assessments for developers; the library is included in every CoderPad instance and can be accessed with a simple #include \"json.hpp\"
    • Codon, an ahead-of-time compiler for a Python-like language
    • Compiler Explorer, a web-based tool that allows users to write, compile, and visualize the assembly output of code in various programming languages; the library is readily available and accessible with the directive #include <nlohmann/json.hpp>.
    • Flutter, a UI toolkit for building natively compiled applications for mobile, web, and desktop from a single codebase
    • Fraunhofer VVenC, a fast and efficient encoder for the Versatile Video Coding (H.266/VVC) standard
    • GitHub CodeQL, a code analysis tool used for identifying security vulnerabilities and bugs in software through semantic queries
    • GoPro ngfx, a low-level graphics abstraction and profiling framework developed by GoPro
    • gRPC, a high-performance universal remote procedure call framework
    • Hex-Rays, a reverse engineering toolset for analyzing and decompiling binaries, primarily used for security research and vulnerability analysis
    • ImHex, a hex editor designed for reverse engineering, providing advanced features for data analysis and manipulation
    • Intel GITS, a tool for capturing and replaying graphics API calls for debugging and performance analysis
    • Intel GPA Framework, a suite of cross-platform tools for capturing, analyzing, and optimizing graphics applications across different APIs
    • Intopix, a provider of advanced image processing and compression solutions used in software development and AV workflows
    • Java SE, the core Java platform that provides the libraries and runtime needed to build and run general-purpose Java applications
    • Meta Yoga, a layout engine that facilitates flexible and efficient user interface design across multiple platforms
    • MKVToolNix, a set of tools for creating, editing, and inspecting MKV (Matroska) multimedia container files
    • MRTech IFF SDK, an image processing SDK for machine vision applications with GPU-accelerated pipelines
    • Nix, a purely functional package manager
    • Notepad++, a free source code editor that supports various programming languages
    • NVIDIA Nsight Compute, a performance analysis tool for CUDA applications that provides detailed insights into GPU performance metrics
    • openFrameworks, a community-developed C++ toolkit for creative coding
    • OpenRGB, an open source RGB lighting control that doesn't depend on manufacturer software
    • OpenTelemetry C++, a library for collecting and exporting observability data in C++, enabling developers to implement distributed tracing and metrics in their application
    • Oracle GraalVM, a high-performance JDK distribution with ahead-of-time compilation and polyglot runtime support
    • Philips amp-cucumber-cpp-runner, a behaviour-driven development test runner for embedded C++ software developed at Philips
    • Qt Creator, an IDE for developing applications using the Qt application framework
    • Qt for MCUs, a graphics framework for building fluid user interfaces on microcontrollers
    • React Native, a framework for building native mobile applications using React
    • Scanbot SDK, a software development kit (SDK) that provides tools for integrating advanced document scanning and barcode scanning capabilities into applications
    • STMicroelectronics TouchGFX, a graphical user interface framework shipped with STM32 microcontrollers for building embedded HMIs
    • swagger-codegen, a template-driven engine that generates API clients and server stubs from an OpenAPI specification
    • Swoole, a coroutine-based concurrency engine for PHP
    • Tracy Profiler, a real-time frame profiler for games and other applications
    • WasmEdge, a lightweight WebAssembly runtime for edge and cloud workloads
    • x64dbg, an open source user mode debugger for Windows, aimed at reverse engineering and malware analysis
    "},{"location":"home/customers/#machine-learning-and-ai","title":"Machine Learning and AI","text":"
    • Alibaba MNN, a lightweight deep learning inference engine for mobile and embedded devices
    • AMD Gaia, an open-source framework for running generative AI applications locally on AMD hardware
    • AMD Vitis AI (VAIP), the execution provider stack that runs AI models on AMD Ryzen AI and adaptive computing devices
    • Apple Core ML Tools, a set of tools for converting and configuring machine learning models for deployment in Apple's Core ML framework
    • Avular Mobile Robotics, a platform for developing and deploying mobile robotics solutions
    • FunASR, a speech recognition toolkit for training and deploying end-to-end models
    • Google gemma.cpp, a lightweight C++ inference engine designed for running AI models from the Gemma family
    • Google Magenta The Infinite Crate, an open-source generative AI plugin for digital audio workstations from Google's Magenta research team
    • GPT4All, a desktop application for running local large language models on consumer hardware
    • Huawei MindSpore, a deep learning framework for training and inference across device, edge, and cloud
    • KTransformers, a framework for heterogeneous large language model inference
    • llama.cpp, a C++ library designed for efficient inference of large language models (LLMs), enabling streamlined integration into applications
    • LocalAI, a self-hosted inference engine that exposes local models through an OpenAI-compatible API
    • MLX, an array framework for machine learning on Apple Silicon
    • Mozilla llamafile, a tool designed for distributing and executing large language models (LLMs) efficiently using a single file format
    • NVIDIA ACE, a suite of real-time AI solutions designed for the development of interactive avatars and digital human applications, enabling scalable and sophisticated user interactions
    • NVIDIA Instant NGP, an implementation of instant neural graphics primitives for rapid scene reconstruction
    • NVIDIA TensorRT, an SDK for high-performance deep learning inference, including its TensorRT-LLM extension for large language models
    • NVIDIA TensorRT-LLM, a toolkit for optimizing and serving large language model inference on GPUs
    • ONNX Runtime, a cross-platform inference and training accelerator for machine learning models
    • OpenVINO, Intel's toolkit for optimizing and deploying deep learning inference across CPUs, GPUs, and NPUs
    • PaddleOCR, an optical character recognition toolkit that turns documents and images into structured data
    • PaddlePaddle, a deep learning framework for distributed training and inference
    • Peer, a platform offering personalized AI assistants for interactive learning and creative collaboration
    • PyTorch, a machine learning framework for building and training neural networks, widely used in research and production
    • Qualcomm AI Engine Direct, a toolchain for building and running generative AI applications on Snapdragon devices
    • sherpa-onnx, a speech toolkit for on-device recognition, synthesis and speaker diarization
    • stable-diffusion.cpp, a C++ implementation of the Stable Diffusion image generation model
    • TanvasTouch, a software development kit (SDK) that enables developers to create tactile experiences on touchscreens, allowing users to feel textures and physical sensations in a digital environment
    • TensorFlow, a machine learning framework that facilitates the development and training of models, supporting data serialization and efficient data exchange between components
    • whisper.cpp, a C++ implementation of OpenAI's Whisper automatic speech recognition model
    "},{"location":"home/customers/#scientific-research-and-analysis","title":"Scientific Research and Analysis","text":"
    • BLACK, a bounded linear temporal logic (LTL) satisfiability checker
    • CERN ALICE O2, the online-offline computing framework of the ALICE heavy-ion experiment at the Large Hadron Collider
    • CERN Atlas Athena, a software framework used in the ATLAS experiment at the Large Hadron Collider (LHC) for performance monitoring
    • CERN CMSSW, the offline software framework of the CMS experiment at the Large Hadron Collider
    • CERN Gaudi, the event-processing framework used by the LHCb and ATLAS experiments at the Large Hadron Collider
    • ICU, the International Components for Unicode, a mature library for software globalization and multilingual support
    • KAMERA, a platform for synchronized data collection and real-time deep learning to map marine species like polar bears and seals, aiding Arctic ecosystem research
    • KiCad, a free and open-source software suite for electronic design automation
    • LLNL ROSE, a compiler infrastructure from Lawrence Livermore National Laboratory for building source-to-source program analysis and transformation tools
    • Maple, a symbolic and numeric computing environment for advanced mathematical modeling and analysis
    • MeVisLab, a software framework for medical image processing and visualization.
    • MITK, the Medical Imaging Interaction Toolkit, a framework for developing interactive medical image processing software
    • OpenPMD API, a versatile programming interface for accessing and managing scientific data, designed to facilitate the efficient storage, retrieval, and sharing of simulation data across various applications and platforms
    • ORNL DataFed, a federated scientific data management system developed at Oak Ridge National Laboratory
    • ParaView, an open-source tool for large-scale data visualization and analysis across various scientific domains
    • QGIS, a free and open-source geographic information system (GIS) application that allows users to create, edit, visualize, and analyze geospatial data across a variety of formats
    • Sandia InterSpec, spectral radiation analysis software from Sandia National Laboratories for identifying radioactive isotopes
    • VolView, a lightweight application for interactive visualization and analysis of 3D medical imaging data.
    • VTK, a software library for 3D computer graphics, image processing, and visualization
    "},{"location":"home/customers/#business-and-productivity-software","title":"Business and Productivity Software","text":"
    • ArcGIS PRO, a desktop geographic information system (GIS) application developed by Esri for mapping and spatial analysis
    • Autodesk Desktop, a software platform developed by Autodesk for creating and managing desktop applications and services
    • Check Point, a cybersecurity company specializing in threat prevention and network security solutions, offering a range of products designed to protect enterprises from cyber threats and ensure data integrity
    • EasyEffects, an audio effects processor for PipeWire offering limiting, compression and equalization
    • espanso, a cross-platform text expander
    • Karabiner-Elements, a keyboard customizer for macOS
    • MacType, a font rendering engine for Windows
    • magicplan, a mobile application for creating floor plans and interior designs using augmented reality
    • Microsoft Office for Mac, a suite of productivity applications developed by Microsoft for macOS, including tools for word processing, spreadsheets, and presentations
    • Microsoft Teams, a team collaboration application offering workspace chat and video conferencing, file storage, and integration of proprietary and third-party applications and services
    • MuseScore, a free and open-source music notation and composition application
    • NanaZip, a 7-Zip derivative built for modern Windows
    • Nexthink Infinity, a digital employee experience management platform for monitoring and improving IT performance
    • Sophos Connect Client, a secure VPN client from Sophos that allows remote users to connect to their corporate network, ensuring secure access to resources and data
    • Stonebranch, a cloud-based cybersecurity solution that integrates backup, disaster recovery, and cybersecurity features to protect data and ensure business continuity for organizations
    • Tablecruncher, a data analysis tool that allows users to import, analyze, and visualize spreadsheet data, offering interactive features for better insights and decision-making
    • VNote, a Markdown-based note-taking application written in C++
    "},{"location":"home/customers/#databases-and-big-data","title":"Databases and Big Data","text":"
    • ADIOS2, a data management framework designed for high-performance input and output operations
    • Apache Doris, a real-time analytical database for high-concurrency queries
    • Claris FileMaker Server, the server platform hosting FileMaker custom apps and databases, developed by Apple subsidiary Claris
    • ClickHouse, a column-oriented database management system for real-time analytical queries
    • Cribl Stream, a real-time data processing platform that enables organizations to collect, route, and transform observability data, enhancing visibility and insights into their systems
    • DB Browser for SQLite, a visual open-source tool for creating, designing, and editing SQLite database files
    • Manticore Search, a database for search, offering full-text and vector queries
    • Milvus, a cloud-native vector database built for embedding similarity search
    • MongoDB, a general-purpose document database
    • MySQL Connector/C++, a C++ library for connecting and interacting with MySQL databases
    • MySQL NDB Cluster, a distributed database system that provides high availability and scalability for MySQL databases
    • MySQL Shell, an advanced client and code editor for interacting with MySQL servers, supporting SQL, Python, and JavaScript
    • PrestoDB, a distributed SQL query engine designed for large-scale data analytics, originally developed by Facebook
    • ROOT Data Analysis Framework, an open-source data analysis framework widely used in high-energy physics and other fields for data processing and visualization
    • Typesense, an open source typo-tolerant search engine
    • Vearch, a distributed vector database developed at JD.com for similarity search and retrieval-augmented generation
    • WiredTiger, a high-performance storage engine for databases, offering support for compression, concurrency, and checkpointing
    "},{"location":"home/customers/#simulation-and-modeling","title":"Simulation and Modeling","text":"
    • Adobe Lagrange, a geometry processing library developed by Adobe for mesh manipulation and analysis
    • Arcturus HoloSuite, a software toolset for capturing, editing, and streaming volumetric video, featuring advanced compression technologies for high-quality 3D content creation
    • azul, a fast and efficient 3D city model viewer designed for visualizing urban environments and spatial data
    • Bambu Studio, a slicing and print management application for Bambu Lab 3D printers
    • Blender, a free and open-source 3D creation suite for modeling, animation, rendering, and more
    • cpplot, a library for creating interactive graphs and charts in C++, which can be viewed in web browsers
    • Foundry Nuke, a powerful node-based digital compositing and visual effects application used in film and television post-production
    • FreeCAD, a free and open-source parametric 3D CAD modeler for product design and engineering
    • GAMS, a high-performance mathematical modeling system for optimization and decision support
    • Keysight WirelessPro, a simulation platform for 5G, 5G-Advanced, and 6G cellular network research
    • Kitware SMTK, a software toolkit for managing simulation models and workflows in scientific and engineering applications
    • M-Star, a computational fluid dynamics software for simulating and analyzing fluid flow
    • MapleSim CAD Toolbox, a software extension for MapleSim that integrates CAD models, allowing users to import, manipulate, and analyze 3D CAD data within the MapleSim environment for enhanced modeling and simulation
    • Microsoft AirSim, a simulator for autonomous vehicles and drones built on Unreal Engine
    • NVIDIA Omniverse, a platform for 3D content creation and collaboration that enables real-time simulations and interactive experiences across various industries
    • OpenSCAD, a script-driven solid 3D CAD modeller
    • OrcaSlicer, an open-source slicer supporting a wide range of consumer 3D printers
    • Pixar Renderman, a photorealistic 3D rendering software developed by Pixar, widely used in the film industry for creating high-quality visual effects and animations
    • PrusaSlicer, the slicing software developed by Prusa Research for its 3D printers
    • ROS - Robot Operating System, a set of software libraries and tools that assist in developing robot applications
    • UBS, a multinational financial services and banking company
    "},{"location":"home/customers/#enterprise-and-cloud-applications","title":"Enterprise and Cloud Applications","text":"
    • Acronis Cyber Protect Cloud, an all-in-one data protection solution that combines backup, disaster recovery, and cybersecurity to safeguard business data from threats like ransomware
    • Baereos, a backup solution that provides data protection and recovery options for various environments, including physical and virtual systems
    • Bitdefender Home Scanner, a tool from Bitdefender that scans devices for malware and security threats, providing a safeguard against potential online dangers
    • Cisco MLS++, an implementation of the Messaging Layer Security protocol for end-to-end encrypted group messaging
    • Citrix Provisioning, a solution that streamlines the delivery of virtual desktops and applications by allowing administrators to manage and provision resources efficiently across multiple environments
    • Citrix Virtual Apps and Desktops, a solution from Citrix that delivers virtual apps and desktops
    • CyberArk, a security solution that specializes in privileged access management, enabling organizations to control and monitor access to critical systems and data, thereby enhancing overall cybersecurity posture
    • Deutsche Telekom sysrepo-plugins, a collection of YANG datastore plugins used to manage network devices
    • Egnyte Desktop, a secure cloud storage solution designed for businesses, enabling file sharing, collaboration, and data management across teams while ensuring compliance and data protection
    • Elster, a digital platform developed by German tax authorities for secure and efficient electronic tax filing and management using secunet protect4use
    • Envoy, a cloud-native edge and service proxy that forms the data plane of many service meshes
    • Ethereum Solidity, a high-level, object-oriented programming language designed for implementing smart contracts on the Ethereum platform
    • gVisor, an application kernel that provides a secure sandbox for running untrusted containers
    • IBM Storage Virtualize, the software powering IBM FlashSystem enterprise storage arrays
    • Inciga, a monitoring tool for IT infrastructure, designed to provide insights into system performance and availability through customizable dashboards and alerts
    • Intel Accelerator Management Daemon for VMware ESXi, a management tool designed for monitoring and controlling Intel hardware accelerators within VMware ESXi environments, optimizing performance and resource allocation
    • Juniper Identity Management Service
    • Meta FBOSS, the software stack that controls the network switches in Meta's data centers
    • Microsoft Azure IoT SDK, a collection of tools and libraries to help developers connect, build, and deploy Internet of Things (IoT) solutions on the Azure cloud platform
    • Microsoft Confidential Consortium Framework, a framework for building secure, highly available applications on trusted execution environments
    • Microsoft WinGet, a command-line utility included in the Windows Package Manager
    • Mitsubishi Electric SECS/GEM, the semiconductor equipment communication software running on Mitsubishi Electric C Controller and C intelligent function modules
    • Moxa, a provider of industrial networking, computing, and automation infrastructure
    • plexusAV, a high-performance AV-over-IP transceiver device capable of video encoding and decoding using the IPMX standard
    • Pointr, a platform for indoor positioning and navigation solutions, offering tools and SDKs for developers to create location-based applications
    • secunet protect4use, a secure, passwordless multifactor authentication solution that transforms smartphones into digital keyrings, ensuring high security for online services and digital identities
    • Sencore MRD 7000, a professional multi-channel receiver and decoder supporting UHD and HD stream decoding
    • Siemens SINEC, a family of network management and infrastructure services for industrial networks
    • Toshiba Industrial Servers, the FS20000R series of industrial servers for factory automation and control systems
    • Wazuh, a security platform for threat detection, integrity monitoring and incident response
    • ZeroTier, a software-defined networking service that creates virtual Ethernet networks
    "},{"location":"home/debugging/","title":"Debugging","text":"

    This page collects the library's built-in debugger integrations and other debugging-related features. They are not covered by any single page elsewhere in the docs, so they are collected here.

    "},{"location":"home/debugging/#visual-studio-natvis","title":"Visual Studio (natvis)","text":"

    The repository ships nlohmann_json.natvis at its root, a Natvis file that gives json/ordered_json values a friendly, key/value debugger view instead of showing raw internal fields, when debugging with the MSVC debug engine (cppvsdbg) in Visual Studio or VS Code.

    The checked-in visualizers cover namespace variants with zero, one, or two ABI tags. Configurations with three or more ABI tags are not covered and may show raw internal fields instead. To generate a Natvis file for such a configuration:

    1. Check out the release tag of the library version you use.
    2. List the ABI tags and the macros that enable them:

      make natvis NATVIS_ARGS=\"--list-tags\"\n
    3. Generate a Natvis file with the tags of your configuration, for example for JSON_DIAGNOSTICS, JSON_DIAGNOSTIC_POSITIONS, and JSON_NO_SIMD:

      make natvis NATVIS_ARGS=\"--abi-tags _diag,_dp,_ns --output my_nlohmann_json.natvis\"\n
    4. Use the generated file instead of nlohmann_json.natvis.

    --abi-tags can be repeated for several configurations, and --all generates every combination (about 60 MB for 12 ABI tags, doubling with each further tag). See tools/generate_natvis for all options.

    Debug engines that wrap LLDB instead of the MSVC debug engine (for example, codelldb in VS Code) only have partial/experimental Natvis support, and commonly fall back to showing raw internal fields even with the .natvis file present. Switching to cppvsdbg where available, or checking your debug extension's own Natvis support/version, are the next things to try if this happens. There is currently no bundled LLDB-native pretty-printer script in this repository.

    "},{"location":"home/debugging/#gdb","title":"GDB","text":"

    The repository ships a GDB Python pretty printer under tools/gdb_pretty_printer, with its own usage instructions in that directory's README.md.

    "},{"location":"home/debugging/#extended-exception-diagnostics","title":"Extended exception diagnostics","text":"

    Defining JSON_DIAGNOSTICS before including the library augments type_error/out_of_range-style exceptions with a JSON Pointer to the offending value, which can help pinpoint where in a large document a runtime error occurred. This only applies to exceptions thrown after a value exists (e.g. during element access); parse errors, which happen before any value exists to point at, are not covered by this mechanism \u2014 see Parsing and exceptions for how parse errors report their own location instead.

    "},{"location":"home/debugging/#see-also","title":"See also","text":"
    • JSON_DIAGNOSTICS - extended exception messages with the path of the failing value
    • JSON_DIAGNOSTIC_POSITIONS - record byte positions of values for error messages
    • Exceptions - all exceptions and their error codes
    • exception - base class of all exceptions thrown by the library
    "},{"location":"home/design_goals/","title":"Design goals","text":"

    There are myriads of JSON libraries out there, and each may even have its reason to exist. Our class had these design goals:

    • Intuitive syntax. In languages such as Python, JSON feels like a first-class data type. We used all the operator magic of modern C++ to achieve the same feeling in your code.

    • Trivial integration. Our whole code consists of a single header file json.hpp. That's it. No library, no subproject, no dependencies, no complex build system. The class is written in vanilla C++11. All in all, everything should require no adjustment of your compiler flags or project settings.

    • Serious testing. Our class is heavily unit-tested and covers 100% of the code, including all exceptional behavior. Furthermore, we checked with Valgrind and the Clang Sanitizers that there are no memory leaks. Google OSS-Fuzz additionally runs fuzz tests against all parsers 24/7, effectively executing billions of tests so far. To maintain high quality, the project is following the OpenSSF Best Practices.

    Other aspects were not so important to us:

    • Memory efficiency. Each JSON object has an overhead of one pointer (the maximal size of a union) and one enumeration element (1 byte). The default generalization uses the following C++ data types: std::string for strings, int64_t, uint64_t or double for numbers, std::map for objects, std::vector for arrays, and bool for Booleans. However, you can template the generalized class basic_json to your needs.

    • Speed. There are certainly faster JSON libraries out there. However, if your goal is to speed up your development by adding JSON support with a single header, then this library is the way to go. If you know how to use a std::vector or std::map, you are already set.

    See the contribution guidelines for more information.

    "},{"location":"home/design_goals/#see-also","title":"See also","text":"
    • basic_json - the main class and all its member functions
    • Macros - reference of all macros
    • Performance - how the library performs and what is not optimized
    • Architecture - how the library is put together
    "},{"location":"home/exceptions/","title":"Exceptions","text":""},{"location":"home/exceptions/#overview","title":"Overview","text":""},{"location":"home/exceptions/#base-type","title":"Base type","text":"

    All exceptions inherit from class json::exception (which in turn inherits from std::exception). It is used as the base class for all exceptions thrown by the basic_json class. This class can hence be used as \"wildcard\" to catch exceptions.

    The map shows the class tree and every exception id documented on this page; click an id to jump to its section.

    Exception id map Class tree: std::exception is the base of json::exception, which is the base of the five exception families parse_error (ids 1xx), invalid_iterator (2xx), type_error (3xx), out_of_range (4xx) and other_error (5xx). Each family lists the ids documented on this page, 68 in total; every id links to its section. std::exceptionC++ standard library base json::exceptionid, what() \u00b7 catch-all json::parse_error1xx \u00b7 15 ids \u00b7 adds member byte 101 102 103 104 105 106 107 108 109 110 112 113 114 115 116 json::invalid_iterator2xx \u00b7 14 ids 201 202 203 204 205 206 207 208 209 210 211 212 213 214 json::type_error3xx \u00b7 21 ids 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 json::out_of_range4xx \u00b7 16 ids 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 json::other_error5xx \u00b7 2 ids 501 502 Exception id map Class tree: std::exception is the base of json::exception, which is the base of the five exception families parse_error (ids 1xx), invalid_iterator (2xx), type_error (3xx), out_of_range (4xx) and other_error (5xx). Each family lists the ids documented on this page, 68 in total; every id links to its section. std::exceptionC++ standard library base json::exceptionid, what() \u00b7 catch-all json::parse_error1xx \u00b7 15 ids \u00b7 adds member byte 101 102 103 104 105 106 107 108 109 110 112 113 114 115 116 json::invalid_iterator2xx \u00b7 14 ids 201 202 203 204 205 206 207 208 209 210 211 212 213 214 json::type_error3xx \u00b7 21 ids 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 json::out_of_range4xx \u00b7 16 ids 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 json::other_error5xx \u00b7 2 ids 501 502

    The exception classes from std::exception down to the five families, each with the ids it can throw. Every id chip links to the section that describes it.

    Which exception an element access throws depends on the function and on the type of the value:

    flowchart LR\n    S{{\"which call?\"}} -->|\"at(key)\"| A{{\"j is\"}}\n    A -->|\"object, key missing\"| A1[\"out_of_range.403\"]\n    A -->|\"array or null\"| A2[\"type_error.304\"]\n    S -->|\"at(index)\"| B{{\"j is\"}}\n    B -->|\"array, index >= size()\"| B1[\"out_of_range.401\"]\n    B -->|\"object or null\"| B2[\"type_error.304\"]\n    S -->|\"non-const operator[](key)\"| C{{\"j is\"}}\n    C -->|\"object or null\"| C1[\"no exception: a missing key is inserted as null\"]\n    C -->|\"array\"| C2[\"type_error.305\"]\n    S -->|\"value(key, default)\"| D{{\"j is\"}}\n    D -->|\"object, key missing\"| D1[\"no exception: returns the default\"]\n    D -->|\"object, incompatible value type\"| D2[\"type_error.302\"]\n    D -->|\"array or null\"| D3[\"type_error.306\"]

    Exceptions thrown by element access. Start at the call on the left, follow the edge that matches the type of j, and read the exception id (or \"no exception\") in the box at the end.

    "},{"location":"home/exceptions/#switch-off-exceptions","title":"Switch off exceptions","text":"

    Exceptions are used widely within the library. They can, however, be switched off with either using the compiler flag -fno-exceptions or by defining the symbol JSON_NOEXCEPTION. In this case, exceptions are replaced by abort() calls. You can further control this behavior by defining JSON_THROW_USER (overriding throw), JSON_TRY_USER (overriding try), and JSON_CATCH_USER (overriding catch).

    See Working without exceptions for the functions that report errors without throwing.

    Note that JSON_THROW_USER should leave the current scope (e.g., by throwing or aborting), as continuing after it may yield undefined behavior.

    Example: switch off exceptions and log errors before aborting

    The code below switches off exceptions and creates a log entry with a detailed error message in case of errors.

    #include <iostream>\n\n#define JSON_TRY_USER if(true)\n#define JSON_CATCH_USER(exception) if(false)\n#define JSON_THROW_USER(exception)                           \\\n    {std::clog << \"Error in \" << __FILE__ << \":\" << __LINE__ \\\n               << \" (function \" << __FUNCTION__ << \") - \"    \\\n               << (exception).what() << std::endl;           \\\n     std::abort();}\n\n#include <nlohmann/json.hpp>\n

    Note the explanatory what() string of exceptions is not available for MSVC if exceptions are disabled, see #2824.

    See documentation of JSON_TRY_USER, JSON_CATCH_USER and JSON_THROW_USER for more information.

    "},{"location":"home/exceptions/#extended-diagnostic-messages","title":"Extended diagnostic messages","text":"

    Exceptions in the library are thrown in the local context of the JSON value they are detected. This makes detailed diagnostics messages, and hence debugging, difficult.

    Example: standard diagnostic message
    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    json j;\n    j[\"address\"][\"street\"] = \"Fake Street\";\n    j[\"address\"][\"housenumber\"] = \"12\";\n\n    try\n    {\n        int housenumber = j[\"address\"][\"housenumber\"];\n    }\n    catch (const json::exception& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n}\n

    Output:

    [json.exception.type_error.302] type must be number, but is string\n

    This exception can be hard to debug if storing the value \"12\" and accessing it is further apart.

    To create better diagnostics messages, each JSON value needs a pointer to its parent value such that a global context (i.e., a path from the root value to the value that led to the exception) can be created. That global context is provided as JSON Pointer.

    As this global context comes at the price of storing one additional pointer per JSON value and runtime overhead to maintain the parent relation, extended diagnostics are disabled by default. They can, however, be enabled by defining the preprocessor symbol JSON_DIAGNOSTICS to 1 before including json.hpp.

    Example: extended diagnostic message with JSON_DIAGNOSTICS
    #include <iostream>\n\n# define JSON_DIAGNOSTICS 1\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    json j;\n    j[\"address\"][\"street\"] = \"Fake Street\";\n    j[\"address\"][\"housenumber\"] = \"12\";\n\n    try\n    {\n        int housenumber = j[\"address\"][\"housenumber\"];\n    }\n    catch (const json::exception& e)\n    {\n        std::cout << e.what() << '\\n';\n    }\n}\n

    Output:

    [json.exception.type_error.302] (/address/housenumber) type must be number, but is string\n

    Now the exception message contains a JSON Pointer /address/housenumber that indicates which value has the wrong type.

    See documentation of JSON_DIAGNOSTICS for more information, and Debugging for the debugger integrations of the library.

    "},{"location":"home/exceptions/#parse-errors","title":"Parse errors","text":"

    The library throws this exception when a parse error occurs. Parse errors can occur during the deserialization of JSON text or of one of the binary formats (BJData, BON8, BSON, CBOR, MessagePack, UBJSON), as well as when using JSON Patch.

    Exceptions have ids 1xx.

    Byte index

    Member byte holds the byte index of the last read character in the input file.

    For an input with n bytes, 1 is the index of the first character and n+1 is the index of the terminating null byte or the end of file. This also holds true when reading a byte vector (CBOR or MessagePack).

    Example: catch a parse_error exception

    The following code shows how a parse_error exception can be caught.

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    try\n    {\n        // parsing input with a syntax error\n        json j = json::parse(\"[1,2,3,]\");\n    }\n    catch (const json::parse_error& e)\n    {\n        // output exception information\n        std::cout << \"message: \" << e.what() << '\\n'\n                  << \"exception id: \" << e.id << '\\n'\n                  << \"byte position of error: \" << e.byte << '\\n';\n    }\n}\n

    Output:

    message: [json.exception.parse_error.101] parse error at line 1, column 8: syntax error while parsing value - unexpected ']'; expected '[', '{', or a literal\nexception id: 101\nbyte position of error: 8\n
    "},{"location":"home/exceptions/#jsonexceptionparse_error101","title":"json.exception.parse_error.101","text":"

    This error indicates a syntax error while deserializing a JSON text. The error message describes that an unexpected token (character) was encountered, and the member byte indicates the error position.

    Example message

    Input ended prematurely:

    [json.exception.parse_error.101] parse error at 2: unexpected end of input; expected string literal\n

    No input:

    [json.exception.parse_error.101] parse error at line 1, column 1: attempting to parse an empty input; check that your input string or stream contains the expected JSON\n

    Control character was not escaped:

    [json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: control character U+0009 (HT) must be escaped to \\u0009 or \\\\; last read: '\"<U+0009>'\"\n

    String was not closed:

    [json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: missing closing quote; last read: '\"'\n

    Invalid number format:

    [json.exception.parse_error.101] parse error at line 1, column 3: syntax error while parsing value - invalid number; expected '+', '-', or digit after exponent; last read: '1E'\n

    \\u was not be followed by four hex digits:

    [json.exception.parse_error.101] parse error at line 1, column 6: syntax error while parsing value - invalid string: '\\u' must be followed by 4 hex digits; last read: '\"\\u01\"'\n

    Invalid UTF-8 surrogate pair:

    [json.exception.parse_error.101] parse error at line 1, column 13: syntax error while parsing value - invalid string: surrogate U+DC00..U+DFFF must follow U+D800..U+DBFF; last read: '\"\\uD7FF\\uDC00'\"\n

    Invalid UTF-8 byte:

    [json.exception.parse_error.101] parse error at line 3, column 24: syntax error while parsing value - invalid string: ill-formed UTF-8 byte; last read: '\"vous \\352t'\n

    Tip

    • Make sure the input is correctly read. Try to write the input to standard output to check if, for instance, the input file was successfully opened.
    • Paste the input to a JSON validator like https://jsonlint.com or a tool like jq.
    Parsing a file fails at line 1, column 1 (unexpected end of input)

    The messages attempting to parse an empty input (since version 3.11.3) and unexpected end of input (also the message of earlier versions for an empty input) at the very start of the input mean that the parser did not see a single character. The library only reads from the stream it is given: it does not open files and cannot tell a missing file from an empty one. The usual causes are:

    • The file was not opened. A relative path is resolved against the working directory of the running program, not against the source file or the project. IDEs and build tools often start the program in a build directory (for example build/ or cmake-build-debug/), so \"example.json\" may need to be \"../example.json\". Use an absolute path to rule this out.
    • The file is empty, or a previous run truncated it (for example when it was opened for writing).
    • The stream was already read. A stream whose content has been consumed (by printing it with std::cout << file.rdbuf(), or by an earlier accept/parse/>>) is at its end. Parse it once, or rewind it with seekg(0) after clearing the state with clear().

    Check the stream before parsing it:

    std::ifstream f(\"example.json\");\nif (!f.is_open())\n{\n    std::cerr << \"cannot open example.json\\n\";\n    return 1;\n}\njson data = json::parse(f);\n
    "},{"location":"home/exceptions/#jsonexceptionparse_error102","title":"json.exception.parse_error.102","text":"

    JSON uses the \\uxxxx format to describe Unicode characters. Code points above 0xFFFF are split into two \\uxxxx entries (\"surrogate pairs\"). This error indicates that the surrogate pair is incomplete or contains an invalid code point.

    Example message

    [json.exception.parse_error.102] parse error at 14: missing or wrong low surrogate\n

    Note

    This exception is not used any more. Instead json.exception.parse_error.101 with a more detailed description is used.

    "},{"location":"home/exceptions/#jsonexceptionparse_error103","title":"json.exception.parse_error.103","text":"

    Unicode supports code points up to 0x10FFFF. Code points above 0x10FFFF are invalid.

    Example message

    [json.exception.parse_error.103] parse error: code points above 0x10FFFF are invalid\n

    Note

    This exception is not used any more. Instead json.exception.parse_error.101 with a more detailed description is used.

    "},{"location":"home/exceptions/#jsonexceptionparse_error104","title":"json.exception.parse_error.104","text":"

    RFC 6902 requires a JSON Patch document to be a JSON document that represents an array of objects.

    Example message

    [json.exception.parse_error.104] parse error: JSON patch must be an array of objects\n
    "},{"location":"home/exceptions/#jsonexceptionparse_error105","title":"json.exception.parse_error.105","text":"

    An operation of a JSON Patch document must contain exactly one \"op\" member, whose value indicates the operation to perform. Its value must be one of \"add\", \"remove\", \"replace\", \"move\", \"copy\", or \"test\"; other values are errors.

    Example message

    [json.exception.parse_error.105] parse error: operation 'add' must have member 'value'\n
    [json.exception.parse_error.105] parse error: operation 'copy' must have string member 'from'\n
    [json.exception.parse_error.105] parse error: operation value 'foo' is invalid\n

    "},{"location":"home/exceptions/#jsonexceptionparse_error106","title":"json.exception.parse_error.106","text":"

    An array index in a JSON Pointer (RFC 6901) may be 0 or any number without a leading 0.

    Example message

    [json.exception.parse_error.106] parse error: array index '01' must not begin with '0'\n
    "},{"location":"home/exceptions/#jsonexceptionparse_error107","title":"json.exception.parse_error.107","text":"

    A JSON Pointer must be a Unicode string containing a sequence of zero or more reference tokens, each prefixed by a / character.

    Example message

    [json.exception.parse_error.107] parse error at byte 1: JSON pointer must be empty or begin with '/' - was: 'foo'\n
    "},{"location":"home/exceptions/#jsonexceptionparse_error108","title":"json.exception.parse_error.108","text":"

    In a JSON Pointer, only ~0 and ~1 are valid escape sequences.

    Example message

    [json.exception.parse_error.108] parse error: escape character '~' must be followed with '0' or '1'\n
    "},{"location":"home/exceptions/#jsonexceptionparse_error109","title":"json.exception.parse_error.109","text":"

    A JSON Pointer array index must be a number. This exception is thrown for an array index that does not begin with a digit, except for - and the empty reference token, which throw out_of_range.404 where they cannot be resolved.

    Example messages

    [json.exception.parse_error.109] parse error: array index 'one' is not a number\n
    [json.exception.parse_error.109] parse error: array index '+1' is not a number\n

    Note

    Before version 3.13.0 unreleased, a one-character array index that is not a digit (e.g., x) threw out_of_range.404 instead.

    "},{"location":"home/exceptions/#jsonexceptionparse_error110","title":"json.exception.parse_error.110","text":"

    When parsing a binary format, the byte vector ends before the complete value has been read, or (with strict = true) further bytes follow the value.

    Example messages

    [json.exception.parse_error.110] parse error at byte 5: syntax error while parsing CBOR string: unexpected end of input\n
    [json.exception.parse_error.110] parse error at byte 2: syntax error while parsing UBJSON value: expected end of input; last byte: 0x5A\n
    [json.exception.parse_error.110] parse error at byte 8: syntax error while parsing BSON number: unexpected end of input\n

    "},{"location":"home/exceptions/#jsonexceptionparse_error112","title":"json.exception.parse_error.112","text":"

    An unexpected byte was read in a binary format or length information is invalid (BSON). In BON8, this exception is also thrown for a key that is not a string and for ill-formed UTF-8.

    Example messages

    [json.exception.parse_error.112] parse error at byte 1: syntax error while parsing CBOR value: invalid byte: 0x1C\n
    [json.exception.parse_error.112] parse error at byte 1: syntax error while parsing MessagePack value: invalid byte: 0xC1\n
    [json.exception.parse_error.112] parse error at byte 4: syntax error while parsing BJData size: expected '#' after type information; last byte: 0x02\n
    [json.exception.parse_error.112] parse error at byte 4: syntax error while parsing UBJSON size: expected '#' after type information; last byte: 0x02\n
    [json.exception.parse_error.112] parse error at byte 10: syntax error while parsing BSON string: string length must be at least 1, is -2147483648\n
    [json.exception.parse_error.112] parse error at byte 15: syntax error while parsing BSON binary: byte array length cannot be negative, is -1\n
    [json.exception.parse_error.112] parse error at byte 5: syntax error while parsing BSON document: document size 6 does not match the number of bytes read (5)\n
    [json.exception.parse_error.112] parse error at byte 2: syntax error while parsing BON8 string: invalid UTF-8 byte: 0x80\n

    "},{"location":"home/exceptions/#jsonexceptionparse_error113","title":"json.exception.parse_error.113","text":"

    A string could not be read from a binary format: either a value that is not a string was read where one was required (for instance as a map key), the string's length specification is invalid, or the string's bytes are not valid UTF-8 and the error_handler parameter of the corresponding from_* function is set to strict. By default (error_handler_t::keep), the bytes of a string are not checked for valid UTF-8 on read. This applies to the from_* functions that have an error_handler parameter; from_bon8 does not have one. See the ill-formed UTF-8 notes on the individual binary format pages for how such a string is handled depending on error_handler. from_bon8() never throws this exception: BON8 non-string keys and ill-formed UTF-8 are reported as parse_error.112.

    CBOR and MessagePack allow map keys of any type, but JSON object keys are always strings. Maps with keys of any other type (for instance integers or null) are therefore not supported; see the notes on CBOR and MessagePack.

    Example messages

    [json.exception.parse_error.113] parse error at byte 2: syntax error while parsing CBOR object key: only string keys are supported, but found an unsigned integer; last byte: 0x01\n
    [json.exception.parse_error.113] parse error at byte 2: syntax error while parsing MessagePack object key: only string keys are supported, but found nil; last byte: 0xC0\n
    [json.exception.parse_error.113] parse error at byte 2: syntax error while parsing CBOR string: expected length specification (0x60-0x7B) or indefinite string type (0x7F); last byte: 0x7C\n
    [json.exception.parse_error.113] parse error at byte 2: syntax error while parsing UBJSON char: byte after 'C' must be in range 0x00..0x7F; last byte: 0x82\n
    [json.exception.parse_error.113] parse error at byte 3: syntax error while parsing BJData string: string length must not be negative\n
    [json.exception.parse_error.113] parse error at byte 3: syntax error while parsing CBOR string: invalid string: ill-formed UTF-8 byte\n

    "},{"location":"home/exceptions/#jsonexceptionparse_error114","title":"json.exception.parse_error.114","text":"

    The parsing of the corresponding BSON record type is not implemented (yet).

    Example message

    [json.exception.parse_error.114] parse error at byte 5: Unsupported BSON record type 0xFF\n
    "},{"location":"home/exceptions/#jsonexceptionparse_error115","title":"json.exception.parse_error.115","text":"

    A UBJSON or BJData high-precision number could not be parsed.

    Example messages

    [json.exception.parse_error.115] parse error at byte 5: syntax error while parsing UBJSON high-precision number: invalid number text: 1A\n
    [json.exception.parse_error.115] parse error at byte 5: syntax error while parsing BJData high-precision number: invalid number text: 1A\n

    "},{"location":"home/exceptions/#jsonexceptionparse_error116","title":"json.exception.parse_error.116","text":"

    basic_json_document::load() rejected an image: either the bytes are not one save() could have written (too short, an unknown magic number or format version, or sizes that do not fit the buffer), or they are, but fail the requested image_check.

    Example message

    [json.exception.parse_error.116] parse error: invalid json_document image: the check failed\n

    Note

    This exception was added in version 3.13.0 unreleased, together with images.

    "},{"location":"home/exceptions/#iterator-errors","title":"Iterator errors","text":"

    This exception is thrown if iterators passed to a library function do not match the expected semantics.

    Exceptions have ids 2xx.

    Example: catch an invalid_iterator exception

    The following code shows how an invalid_iterator exception can be caught.

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    try\n    {\n        // calling iterator::key() on non-object iterator\n        json j = \"string\";\n        json::iterator it = j.begin();\n        auto k = it.key();\n    }\n    catch (const json::invalid_iterator& e)\n    {\n        // output exception information\n        std::cout << \"message: \" << e.what() << '\\n'\n                  << \"exception id: \" << e.id << '\\n';\n    }\n}\n

    Output:

    message: [json.exception.invalid_iterator.207] cannot use key() for non-object iterators\nexception id: 207\n
    "},{"location":"home/exceptions/#jsonexceptioninvalid_iterator201","title":"json.exception.invalid_iterator.201","text":"

    The iterators passed to constructor basic_json(InputIT first, InputIT last) are not compatible, meaning they do not belong to the same container. Therefore, the range (first, last) is invalid.

    Example message

    [json.exception.invalid_iterator.201] iterators are not compatible\n
    "},{"location":"home/exceptions/#jsonexceptioninvalid_iterator202","title":"json.exception.invalid_iterator.202","text":"

    In the erase or insert function, the passed iterator pos does not belong to the JSON value for which the function was called. It hence does not define a valid position for the deletion/insertion.

    Example messages

    [json.exception.invalid_iterator.202] iterator does not fit current value\n
    [json.exception.invalid_iterator.202] iterators first and last must point to objects\n

    "},{"location":"home/exceptions/#jsonexceptioninvalid_iterator203","title":"json.exception.invalid_iterator.203","text":"

    Either iterator passed to function erase(IteratorType first, IteratorType last) does not belong to the JSON value from which values shall be erased. It hence does not define a valid range to delete values from.

    Example message

    [json.exception.invalid_iterator.203] iterators do not fit current value\n
    "},{"location":"home/exceptions/#jsonexceptioninvalid_iterator204","title":"json.exception.invalid_iterator.204","text":"

    When an iterator range for a primitive type (number, boolean, or string) is passed to a constructor or an erase function, this range has to be exactly (begin(), end()), because this is the only way the single stored value is expressed. All other ranges are invalid.

    Example message

    [json.exception.invalid_iterator.204] iterators out of range\n
    "},{"location":"home/exceptions/#jsonexceptioninvalid_iterator205","title":"json.exception.invalid_iterator.205","text":"

    When an iterator for a primitive type (number, boolean, or string) is passed to an erase function, the iterator has to be the begin() iterator, because it is the only way to address the stored value. All other iterators are invalid.

    Example message

    [json.exception.invalid_iterator.205] iterator out of range\n
    "},{"location":"home/exceptions/#jsonexceptioninvalid_iterator206","title":"json.exception.invalid_iterator.206","text":"

    The iterators passed to constructor basic_json(InputIT first, InputIT last) belong to a JSON null value and hence to not define a valid range.

    Example message

    [json.exception.invalid_iterator.206] cannot construct with iterators from null\n
    "},{"location":"home/exceptions/#jsonexceptioninvalid_iterator207","title":"json.exception.invalid_iterator.207","text":"

    The key() member function can only be used on iterators belonging to a JSON object, because other types do not have a concept of a key.

    Example message

    [json.exception.invalid_iterator.207] cannot use key() for non-object iterators\n
    "},{"location":"home/exceptions/#jsonexceptioninvalid_iterator208","title":"json.exception.invalid_iterator.208","text":"

    The operator[] to specify a concrete offset cannot be used on iterators belonging to a JSON object, because JSON objects are unordered.

    Example message

    [json.exception.invalid_iterator.208] cannot use operator[] for object iterators\n
    "},{"location":"home/exceptions/#jsonexceptioninvalid_iterator209","title":"json.exception.invalid_iterator.209","text":"

    The offset operators (+, -, +=, -=) cannot be used on iterators belonging to a JSON object, because JSON objects are unordered.

    Example message

    [json.exception.invalid_iterator.209] cannot use offsets with object iterators\n
    "},{"location":"home/exceptions/#jsonexceptioninvalid_iterator210","title":"json.exception.invalid_iterator.210","text":"

    The iterator range passed to the insert function is not compatible, meaning they do not belong to the same container. Therefore, the range (first, last) is invalid.

    Example message

    [json.exception.invalid_iterator.210] iterators do not fit\n
    "},{"location":"home/exceptions/#jsonexceptioninvalid_iterator211","title":"json.exception.invalid_iterator.211","text":"

    The iterator range passed to the insert function must not be a subrange of the container to insert to.

    Example message

    [json.exception.invalid_iterator.211] passed iterators may not belong to container\n
    "},{"location":"home/exceptions/#jsonexceptioninvalid_iterator212","title":"json.exception.invalid_iterator.212","text":"

    When two iterators are compared, they must belong to the same container.

    Example message

    [json.exception.invalid_iterator.212] cannot compare iterators of different containers\n
    "},{"location":"home/exceptions/#jsonexceptioninvalid_iterator213","title":"json.exception.invalid_iterator.213","text":"

    The order of object iterators cannot be compared, because JSON objects are unordered.

    Example message

    [json.exception.invalid_iterator.213] cannot compare order of object iterators\n
    "},{"location":"home/exceptions/#jsonexceptioninvalid_iterator214","title":"json.exception.invalid_iterator.214","text":"

    Cannot retrieve value from iterator: The iterator either refers to a null value, or it refers to a primitive type (number, boolean, or string), but does not match the iterator returned by begin().

    Example message

    [json.exception.invalid_iterator.214] cannot get value\n
    "},{"location":"home/exceptions/#type-errors","title":"Type errors","text":"

    This exception is thrown in case of a type error; that is, a library function is executed on a JSON value whose type does not match the expected semantics.

    Exceptions have ids 3xx.

    Example: catch a type_error exception

    The following code shows how a type_error exception can be caught.

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    try\n    {\n        // calling push_back() on a string value\n        json j = \"string\";\n        j.push_back(\"another string\");\n    }\n    catch (const json::type_error& e)\n    {\n        // output exception information\n        std::cout << \"message: \" << e.what() << '\\n'\n                  << \"exception id: \" << e.id << '\\n';\n    }\n}\n

    Output:

    message: [json.exception.type_error.308] cannot use push_back() with string\nexception id: 308\n
    "},{"location":"home/exceptions/#jsonexceptiontype_error301","title":"json.exception.type_error.301","text":"

    To create an object from an initializer list, the initializer list must consist only of a list of pairs whose first element is a string. When this constraint is violated, an array is created instead.

    Example message

    [json.exception.type_error.301] cannot create object from initializer list\n
    "},{"location":"home/exceptions/#jsonexceptiontype_error302","title":"json.exception.type_error.302","text":"

    During implicit or explicit value conversion, the JSON type must be compatible with the target type. For instance, a JSON string can only be converted into string types, but not into numbers or boolean types.

    Example messages

    [json.exception.type_error.302] type must be object, but is null\n
    [json.exception.type_error.302] type must be string, but is object\n

    This exception is also thrown with JSON_USE_OBJECTS_FOR_ENUM_KEYED_MAPS if a key of a map with enum keys is not converted to a string, for instance, because the enum is stored as an integer.

    "},{"location":"home/exceptions/#jsonexceptiontype_error303","title":"json.exception.type_error.303","text":"

    To retrieve a reference to a value stored in a basic_json object with get_ref, the type of the reference must match the value type. For instance, for a JSON array, the ReferenceType must be array_t &.

    Example messages

    [json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is object\n
    [json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is number\"\n

    "},{"location":"home/exceptions/#jsonexceptiontype_error304","title":"json.exception.type_error.304","text":"

    The at() member functions can only be executed for certain JSON types.

    Example messages

    [json.exception.type_error.304] cannot use at() with string\n
    [json.exception.type_error.304] cannot use at() with number\n

    "},{"location":"home/exceptions/#jsonexceptiontype_error305","title":"json.exception.type_error.305","text":"

    The operator[] member functions can only be executed for certain JSON types.

    Example messages

    [json.exception.type_error.305] cannot use operator[] with a string argument with array\n
    [json.exception.type_error.305] cannot use operator[] with a numeric argument with object\n

    "},{"location":"home/exceptions/#jsonexceptiontype_error306","title":"json.exception.type_error.306","text":"

    The value() member functions can only be executed for certain JSON types.

    Example message

    [json.exception.type_error.306] cannot use value() with number\n
    "},{"location":"home/exceptions/#jsonexceptiontype_error307","title":"json.exception.type_error.307","text":"

    The erase() member functions can only be executed for certain JSON types.

    Example message

    [json.exception.type_error.307] cannot use erase() with string\n
    "},{"location":"home/exceptions/#jsonexceptiontype_error308","title":"json.exception.type_error.308","text":"

    The push_back() and operator+= member functions can only be executed for certain JSON types.

    Example message

    [json.exception.type_error.308] cannot use push_back() with string\n
    "},{"location":"home/exceptions/#jsonexceptiontype_error309","title":"json.exception.type_error.309","text":"

    The insert() member functions can only be executed for certain JSON types.

    Example messages

    [json.exception.type_error.309] cannot use insert() with array\n
    [json.exception.type_error.309] cannot use insert() with number\n

    "},{"location":"home/exceptions/#jsonexceptiontype_error310","title":"json.exception.type_error.310","text":"

    The swap() member functions can only be executed for certain JSON types.

    Example message

    [json.exception.type_error.310] cannot use swap() with number\n
    "},{"location":"home/exceptions/#jsonexceptiontype_error311","title":"json.exception.type_error.311","text":"

    The emplace() and emplace_back() member functions can only be executed for certain JSON types.

    Example messages

    [json.exception.type_error.311] cannot use emplace() with number\n
    [json.exception.type_error.311] cannot use emplace_back() with number\n

    "},{"location":"home/exceptions/#jsonexceptiontype_error312","title":"json.exception.type_error.312","text":"

    The update() member functions can only be executed for certain JSON types.

    Example message

    [json.exception.type_error.312] cannot use update() with array\n
    "},{"location":"home/exceptions/#jsonexceptiontype_error313","title":"json.exception.type_error.313","text":"

    The unflatten() function converts an object whose keys are JSON Pointers back into an arbitrary nested JSON value. The JSON Pointers must not overlap, because then the resulting value would not be well-defined.

    Example message

    [json.exception.type_error.313] invalid value to unflatten\n
    "},{"location":"home/exceptions/#jsonexceptiontype_error314","title":"json.exception.type_error.314","text":"

    The unflatten() function only works for an object whose keys are JSON Pointers.

    Example message

    Calling unflatten() on an array [1,2,3]:

    [json.exception.type_error.314] only objects can be unflattened\n
    "},{"location":"home/exceptions/#jsonexceptiontype_error315","title":"json.exception.type_error.315","text":"

    The unflatten() function only works for an object whose keys are JSON Pointers and whose values are primitive.

    Example message

    Calling unflatten() on an object {\"/1\", [1,2,3]}:

    [json.exception.type_error.315] values in object must be primitive\n
    "},{"location":"home/exceptions/#jsonexceptiontype_error316","title":"json.exception.type_error.316","text":"

    The dump() function only works with UTF-8 encoded strings; that is, if you assign a std::string to a JSON value, make sure it is UTF-8 encoded. See the FAQ entry on serializing untrusted or invalid UTF-8 for background and the recommended fix.

    The binary writers to_cbor(), to_ubjson(), to_bjdata(), and to_bson() throw this exception as well for a string value or object key that is not valid UTF-8 if their error_handler is strict (the default if JSON_STRICT_BINARY_UTF8 is enabled). So does to_msgpack() if error_handler_t::strict is passed. to_bon8() always throws this exception for such a string or key, regardless of JSON_STRICT_BINARY_UTF8, because the end of a BON8 string is determined from its UTF-8 encoding.

    Example message

    Calling dump() on a JSON value containing an ISO 8859-1 encoded string:

    [json.exception.type_error.316] invalid UTF-8 byte at index 15: 0x6F\n

    Tip

    • Store the source file with UTF-8 encoding.
    • Pass an error handler as last parameter to the dump() function to avoid this exception:
      • json::error_handler_t::replace will replace invalid bytes sequences with U+FFFD
      • json::error_handler_t::ignore will silently ignore invalid byte sequences
      • json::error_handler_t::keep will copy invalid byte sequences to the output unchanged
    "},{"location":"home/exceptions/#jsonexceptiontype_error317","title":"json.exception.type_error.317","text":"

    The dynamic type of the object cannot be represented in the requested serialization format (e.g., a raw true or null JSON object cannot be serialized to BSON)

    Example messages

    Serializing null to BSON:

    [json.exception.type_error.317] to serialize to BSON, top-level type must be object, but is null\n
    Serializing [1,2,3] to BSON:
    [json.exception.type_error.317] to serialize to BSON, top-level type must be object, but is array\n

    Tip

    Encapsulate the JSON value in an object. That is, instead of serializing true, serialize {\"value\": true}

    "},{"location":"home/exceptions/#jsonexceptiontype_error318","title":"json.exception.type_error.318","text":"

    With JSON_USE_OBJECTS_FOR_ENUM_KEYED_MAPS, a map with enum keys is stored as an object. This exception is thrown if two of its keys are converted to the same string, so one of the entries would be lost. This happens, for instance, if NLOHMANN_JSON_SERIALIZE_ENUM does not list an enumerator and it is therefore converted like the first listed one.

    Example message

    [json.exception.type_error.318] duplicate object key 'red'\n
    "},{"location":"home/exceptions/#jsonexceptiontype_error319","title":"json.exception.type_error.319","text":"

    basic_json_document::set, basic_json_document::push_back, and basic_json_document::insert can store any basic_json value except a binary one: a json_document has no representation for binary values, which only ever arise from parsing a binary format or from an explicit json::binary value, not from JSON text.

    Example message

    [json.exception.type_error.319] cannot store a binary value in a json_document\n

    Note

    This exception was added in version 3.13.0 unreleased, together with editable json_documents.

    "},{"location":"home/exceptions/#jsonexceptiontype_error320","title":"json.exception.type_error.320","text":"

    basic_json_document::save() cannot write an image of a discarded document.

    Example messages

    [json.exception.type_error.320] cannot save a discarded json_document\n

    Note

    This exception was added in version 3.13.0 unreleased, together with images.

    "},{"location":"home/exceptions/#jsonexceptiontype_error321","title":"json.exception.type_error.321","text":"

    A discarded value (one created by parse() with a callback that returns false for the value, or by default-constructing a basic_json with value_t::discarded) was passed to a binary serialization function, either directly or nested in an array or object. There is no way to represent a discarded value in CBOR, MessagePack, UBJSON, BJData, BSON, or BON8.

    Example message

    Serializing [1, 2] to CBOR, where the second element was discarded by a parser callback:

    [json.exception.type_error.321] cannot serialize discarded value to CBOR\n

    "},{"location":"home/exceptions/#out-of-range","title":"Out of range","text":"

    This exception is thrown in case a library function is called on an input parameter that exceeds the expected range, for instance, in the case of array indices or nonexisting object keys.

    Exceptions have ids 4xx.

    Example: catch an out_of_range exception

    The following code shows how an out_of_range exception can be caught.

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\n\nint main()\n{\n    try\n    {\n        // calling at() for an invalid index\n        json j = {1, 2, 3, 4};\n        j.at(4) = 10;\n    }\n    catch (const json::out_of_range& e)\n    {\n        // output exception information\n        std::cout << \"message: \" << e.what() << '\\n'\n                  << \"exception id: \" << e.id << '\\n';\n    }\n}\n

    Output:

    message: [json.exception.out_of_range.401] array index 4 is out of range\nexception id: 401\n
    "},{"location":"home/exceptions/#jsonexceptionout_of_range401","title":"json.exception.out_of_range.401","text":"

    The provided array index i is larger than size-1.

    Example message

    [json.exception.out_of_range.401] array index 3 is out of range\n
    "},{"location":"home/exceptions/#jsonexceptionout_of_range402","title":"json.exception.out_of_range.402","text":"

    The special array index - in a JSON Pointer never describes a valid element of the array, but the index past the end. That is, it can only be used to add elements at this position, but not to read it.

    Example message

    [json.exception.out_of_range.402] array index '-' (3) is out of range\n
    "},{"location":"home/exceptions/#jsonexceptionout_of_range403","title":"json.exception.out_of_range.403","text":"

    The provided key was not found in the JSON object.

    Example message

    [json.exception.out_of_range.403] key 'foo' not found\n
    "},{"location":"home/exceptions/#jsonexceptionout_of_range404","title":"json.exception.out_of_range.404","text":"

    A reference token in a JSON Pointer could not be resolved, for instance an array index that begins with a digit but contains other characters (e.g., 1a), or - where it cannot be used.

    Example message

    [json.exception.out_of_range.404] unresolved reference token 'foo'\n
    "},{"location":"home/exceptions/#jsonexceptionout_of_range405","title":"json.exception.out_of_range.405","text":"

    The JSON Patch operations 'remove' and 'move' cannot be applied to the root element of the JSON value. The exception is also thrown when the parent or a reference token of an empty JSON Pointer is requested, for instance by back or pop_back.

    Example message

    [json.exception.out_of_range.405] JSON pointer has no parent\n
    "},{"location":"home/exceptions/#jsonexceptionout_of_range406","title":"json.exception.out_of_range.406","text":"

    A parsed number could not be stored without changing it to NaN or INF. For the binary formats, this happens when a finite floating-point number does not fit into number_float_t, for example a double-precision number when number_float_t is float.

    Example messages

    [json.exception.out_of_range.406] number overflow parsing '10E1000'\n
    [json.exception.out_of_range.406] syntax error while parsing CBOR value: number overflow\n

    "},{"location":"home/exceptions/#jsonexceptionout_of_range407","title":"json.exception.out_of_range.407","text":"

    An integer number cannot be represented by the binary format it is serialized to:

    • BON8 only stores integers that fit into int64, so to_bon8 throws for unsigned integers greater than 9223372036854775807 and, with a number type wider than 64 bits, for any integer outside the int64 range.
    • CBOR, MessagePack, and BSON store integers in at most 64 bits. With the default number types, every integer fits, but a number_integer_t or number_unsigned_t wider than 64 bits (e.g., __int128) can hold values outside the range of the format: [-2^64, 2^64-1] for CBOR, [-2^63, 2^64-1] for MessagePack, and the range of int64 (signed integers) or uint64 (unsigned integers) for BSON.

    UBJSON and BJData never throw this exception, because they serialize integers beyond 64 bits as high-precision numbers.

    Former occurrences

    The UBJSON and BSON writers used to throw this exception as well:

    • Since version 3.9.0, integer numbers beyond int64 are serialized as high-precision UBJSON numbers.
    • Since version 3.12.0, integer numbers beyond int64 are serialized as uint64 BSON numbers.

    Before version 3.13.0 unreleased, CBOR, MessagePack, and BSON silently truncated integers wider than 64 bits, and BJData truncated unsigned integers wider than 64 bits that were elements of ND-arrays with \"_ArrayType_\": \"uint64\".

    Example messages

    [json.exception.out_of_range.407] integer number 18446744073709551615 cannot be represented by BON8 as it does not fit int64\n
    [json.exception.out_of_range.407] integer number 1267650600228229401496703205376 cannot be represented by CBOR as it does not fit [-2^64, 2^64-1]\n

    "},{"location":"home/exceptions/#jsonexceptionout_of_range408","title":"json.exception.out_of_range.408","text":"

    The size of an array or object in a binary format exceeds the maximal capacity: the size following # for UBJSON/BJData, or the encoded length for CBOR.

    The exception is also thrown for a UBJSON array of a type that is encoded by its marker alone (Z, T or F) whose declared count exceeds 1,048,576 (1 << 20). Such an array has no payload, so its count alone decides how much memory is allocated, and a handful of bytes would otherwise describe billions of values. to_ubjson writes longer arrays of these types without the $ type annotation (the # count and one marker per element are kept), so any value it produces can still be read back.

    Example messages

    [json.exception.out_of_range.408] excessive array size: 8658170730974374167\n
    [json.exception.out_of_range.408] syntax error while parsing CBOR size: excessive array size\n
    [json.exception.out_of_range.408] syntax error while parsing CBOR size: excessive map size\n
    [json.exception.out_of_range.408] syntax error while parsing UBJSON size: excessive array size\n

    "},{"location":"home/exceptions/#jsonexceptionout_of_range409","title":"json.exception.out_of_range.409","text":"

    Key identifiers to be serialized to BSON cannot contain code point U+0000, since the key is stored as zero-terminated c-string.

    Example message

    [json.exception.out_of_range.409] BSON key cannot contain code point U+0000 (at byte 2)\n
    "},{"location":"home/exceptions/#jsonexceptionout_of_range410","title":"json.exception.out_of_range.410","text":"

    This exception is thrown when an undefined value is used with NLOHMANN_JSON_SERIALIZE_ENUM_STRICT, or when an array index in a JSON pointer exceeds the range of size_type (e.g., on 32-bit platforms).

    Example message

    [json.exception.out_of_range.410] enum value out of range\n[json.exception.out_of_range.410] array index 18446744073709551615 exceeds size_type\n

    The second message is thrown, for instance, by json::parse(\"[1, 2]\").at(\"/18446744073709551615\"_json_pointer) on a 64-bit platform, where size_type is std::size_t and this index is SIZE_MAX. An index that does not fit into 64 bits (such as 18446744073709551616) is not reported as 410 but as out_of_range.404.

    "},{"location":"home/exceptions/#jsonexceptionout_of_range411","title":"json.exception.out_of_range.411","text":"

    A JSON Patch add operation cannot be applied because the target location's parent is neither an object nor an array. Per RFC 6902, an add target must reference a member of an existing object or an element of an existing array; a primitive value (string, number, boolean, etc.) cannot receive a new member or element.

    Example message

    [json.exception.out_of_range.411] cannot add value: the JSON Patch 'add' target's parent is of type string, but must be an object or array\n

    Note

    This exception was added in version 3.13.0 unreleased. Before that, this situation hit an internal assertion (aborting the program in debug builds) or was silently ignored when assertions were disabled.

    A null parent is rejected as well. Before version 3.13.0 unreleased, an add into a null parent silently converted it to an object (e.g., add at /foo/bar turned {\"foo\":null} into {\"foo\":{\"bar\":1}}).

    "},{"location":"home/exceptions/#jsonexceptionout_of_range412","title":"json.exception.out_of_range.412","text":"

    BSON stores the length of documents, arrays, strings, and binary values in a signed 32-bit integer, and MessagePack stores the length of strings, binary values, arrays, and objects in at most an unsigned 32-bit integer. This exception is thrown when a value is too large to be described by such a length field.

    Example messages

    [json.exception.out_of_range.412] BSON length 2147483661 exceeds maximum of 2147483647\n
    [json.exception.out_of_range.412] MessagePack length 4294967296 exceeds maximum of 4294967295\n

    Note

    This exception was added in version 3.13.0 unreleased. Before that, the BSON length was silently truncated, and to_bson produced documents with negative length prefixes that from_bson rejected; to_msgpack wrote such a value without any length, producing output that could not be read back.

    "},{"location":"home/exceptions/#jsonexceptionout_of_range413","title":"json.exception.out_of_range.413","text":"

    A JSON Patch remove operation cannot be applied because the target location's parent is neither an object nor an array. Per RFC 6902, a remove target must reference a member of an existing object or an element of an existing array; a primitive value (string, number, boolean, etc.) or null has no members or elements to remove.

    Example message

    [json.exception.out_of_range.413] cannot remove value: the JSON Patch 'remove' target's parent is of type number, but must be an object or array\n

    Note

    This exception was added in version 3.13.0 unreleased. Before that, this situation was silently ignored (the remove operation had no effect).

    "},{"location":"home/exceptions/#jsonexceptionout_of_range414","title":"json.exception.out_of_range.414","text":"

    A JSON Patch move operation's \"from\" location is a proper prefix of its \"path\" location. Per RFC 6902 (section 4.4), a location cannot be moved into one of its own children.

    Example message

    [json.exception.out_of_range.414] cannot move value: 'from' path '/0' is a proper prefix of 'path' '/0/0'\n

    Note

    This exception was added in version 3.13.0 unreleased. Before that, this situation could succeed with a corrupted result: for an array target, removing the \"from\" element before the \"add\" step shifted subsequent indices, so \"path\" silently re-resolved to a different element than intended.

    "},{"location":"home/exceptions/#jsonexceptionout_of_range415","title":"json.exception.out_of_range.415","text":"

    MessagePack's ext type and BSON's binary subtype are each stored in a single byte. This exception is thrown when serializing a byte_container_with_subtype whose subtype exceeds 255, the largest value the library can store in that byte.

    Example messages

    [json.exception.out_of_range.415] subtype 70000 is too large for the MessagePack ext type (max 255)\n
    [json.exception.out_of_range.415] subtype 70000 is too large for the BSON binary subtype (max 255)\n

    Note

    This exception was added in version 3.13.0 unreleased. Before that, subtypes above 255 were silently truncated modulo 256 instead of raising an error.

    "},{"location":"home/exceptions/#jsonexceptionout_of_range416","title":"json.exception.out_of_range.416","text":"

    basic_json_document::parse() and the other parsing functions of basic_json_document index a value's position in the source text in 32 bits, so they do not support an input of 4294967280 bytes (4 GiB minus 16 bytes) or more. The same 32-bit limit applies to an editable document's own storage: set and push_back throw this exception once the strings and number tokens written by edits reach 4 GiB in total, or once more than 4294967295 arrays/objects have had an element set or appended to them. The same limit applies to an image: save() throws it if the node count, the text, or the decoded strings it would write would individually reach 4 GiB.

    Example messages

    [json.exception.out_of_range.416] input of 4294967280 bytes or more is not supported by json_document\n
    [json.exception.out_of_range.416] edits of 4 GiB or more are not supported by json_document\n
    [json.exception.out_of_range.416] images of 4 GiB or more are not supported by json_document\n

    Note

    This exception was added in version 3.13.0 unreleased, together with <nlohmann/json_view.hpp>. basic_json::parse() has no such limit.

    "},{"location":"home/exceptions/#further-exceptions","title":"Further exceptions","text":"

    This exception is thrown in case of errors that cannot be classified with the other exception types.

    Exceptions have ids 5xx.

    Example: catch an other_error exception

    The following code shows how an other_error exception can be caught.

    #include <iostream>\n#include <nlohmann/json.hpp>\n\nusing nlohmann::json;\nusing namespace nlohmann::literals;\n\nint main()\n{\n    try\n    {\n        // executing a failing JSON Patch operation\n        json value = R\"({\n            \"best_biscuit\": {\n                \"name\": \"Oreo\"\n            }\n        })\"_json;\n        json patch = R\"([{\n            \"op\": \"test\",\n            \"path\": \"/best_biscuit/name\",\n            \"value\": \"Choco Leibniz\"\n        }])\"_json;\n        value.patch(patch);\n    }\n    catch (const json::other_error& e)\n    {\n        // output exception information\n        std::cout << \"message: \" << e.what() << '\\n'\n                  << \"exception id: \" << e.id << '\\n';\n    }\n}\n

    Output:

    message: [json.exception.other_error.501] unsuccessful: {\"op\":\"test\",\"path\":\"/best_biscuit/name\",\"value\":\"Choco Leibniz\"}\nexception id: 501\n
    "},{"location":"home/exceptions/#jsonexceptionother_error501","title":"json.exception.other_error.501","text":"

    A JSON Patch operation 'test' failed. The unsuccessful operation is also printed.

    Example message

    Executing {\"op\":\"test\", \"path\":\"/baz\", \"value\":\"bar\"} on {\"baz\": \"qux\"}:

    [json.exception.other_error.501] unsuccessful: {\"op\":\"test\",\"path\":\"/baz\",\"value\":\"bar\"}\n
    "},{"location":"home/exceptions/#jsonexceptionother_error502","title":"json.exception.other_error.502","text":"

    to_ubjson and to_bjdata were called with use_type = true but use_size = false, and the value contains a non-empty array or object (or, with BJData Draft 3, any binary value). UBJSON requires a size marker (#) after a type marker ($); scalars and empty arrays or objects do not throw.

    Example message

    [json.exception.other_error.502] use_type requires use_size = true\n

    Note

    This exception was added in version 3.13.0 unreleased. Before that, debug builds aborted on an assertion and release builds wrote a $ marker without #, which from_ubjson then rejected.

    "},{"location":"home/exceptions/#see-also","title":"See also","text":"
    • exception - base class of all exceptions thrown by the library
    • parse_error - exceptions indicating a parse error
    • invalid_iterator - exceptions indicating errors with iterators
    • type_error - exceptions indicating a wrong type
    • out_of_range - exceptions indicating access out of range
    • other_error - exceptions indicating other library errors
    • JSON_NOEXCEPTION - switch off exceptions
    • JSON_DIAGNOSTICS - extended exception messages with the path of the failing value
    • Working Without Exceptions - use the library without exceptions
    "},{"location":"home/faq/","title":"Frequently Asked Questions (FAQ)","text":""},{"location":"home/faq/#known-bugs","title":"Known bugs","text":""},{"location":"home/faq/#brace-initialization-yields-arrays","title":"Brace initialization yields arrays","text":"

    Question

    Why does

    json j{true};\n

    and

    json j(true);\n

    yield different results ([true] vs. true)?

    This is a known issue, and \u2014 even worse \u2014 the behavior differs between GCC and Clang. The \"culprit\" for this is the library's constructor overloads for initializer lists to allow syntax like

    json array = {1, 2, 3, 4};\n

    for arrays and

    json object = {{\"one\", 1}, {\"two\", 2}}; \n

    for objects.

    Tip

    To avoid any confusion and ensure portable code, do not use brace initialization with the types basic_json, json, or ordered_json unless you want to create an object or array as shown in the examples above.

    To explicitly create a single-element array, use json::array({value}):

    json j = json::array({true});  // [true]\n

    Opt-in copy semantics (since version 3.13.0 unreleased)

    If you define JSON_BRACE_INIT_COPY_SEMANTICS to 1 before including the library, single-element brace initialization is treated as copy/move instead of creating a single-element array:

    #define JSON_BRACE_INIT_COPY_SEMANTICS 1\n#include <nlohmann/json.hpp>\n\njson obj = {{\"key\", \"value\"}};\njson j{obj};   // -> {\"key\":\"value\"}  (copy, not array)\n

    Without the macro (default behavior), json j{obj} creates [{\"key\":\"value\"}]. This opt-in macro fixes issue #5074 while preserving backwards compatibility for existing code.

    "},{"location":"home/faq/#getting-started","title":"Getting started","text":""},{"location":"home/faq/#which-file-do-i-need","title":"Which file do I need?","text":"

    Question

    Do I have to clone the repository or build the library?

    No. The library is header-only: the single file json.hpp from the releases page is all you need, including the _json literals. Put it in a directory nlohmann on your include path. Companion headers (json_fwd.hpp, json_view.hpp, json_literals.hpp) are only needed if you use them. See Integration.

    "},{"location":"home/faq/#using-cmake-or-a-package-manager","title":"Using CMake or a package manager","text":"

    Question

    How do I add the library with CMake, Conan, vcpkg, Homebrew, or another tool?

    See CMake for find_package, add_subdirectory, and FetchContent, and Package managers for the list of supported package managers.

    "},{"location":"home/faq/#the-ide-cannot-open-the-header","title":"The IDE cannot open the header","text":"

    Question

    The compiler finds nlohmann/json.hpp, but my IDE reports \"cannot open source file\". Why?

    The compiler's include path is set correctly, but the IDE's is not. Add the same directory to the include paths of the IDE (or of its language server); the build itself is not affected.

    "},{"location":"home/faq/#compile-times","title":"Compile times","text":"

    Question

    Including the library slows down my build. What can I do?

    Include json_fwd.hpp in headers and json.hpp only in the source files that need it, instantiate basic_json once, and consider precompiled headers or C++20 modules. See Compile times.

    "},{"location":"home/faq/#parsing","title":"Parsing","text":""},{"location":"home/faq/#parsing-a-file-fails-with-unexpected-end-of-input","title":"Parsing a file fails with \"unexpected end of input\"","text":"

    Question

    json::parse(file) throws parse_error.101 at line 1, column 1 for a file that is valid JSON. Why?

    The parser did not see any character: the file was most likely not opened. A relative path is resolved against the working directory of the running program, which is often the build directory of your IDE, not the source directory. Check is_open() and try an absolute path. Other causes are an empty file and a stream that was already read. See parse_error.101.

    "},{"location":"home/faq/#input-that-arrives-in-chunks","title":"Input that arrives in chunks","text":"

    Question

    My data comes from a socket in pieces. How do I parse it?

    The parser cannot be resumed. Frame the messages (one value per line, a length prefix) and parse each complete frame, or buffer the chunks until the value is complete; a parse_error at the end of the buffer means the input ended prematurely. See Large, streamed, and partial input.

    "},{"location":"home/faq/#several-values-in-one-stream","title":"Several values in one stream","text":"

    Question

    How do I read concatenated JSON values or one value per line?

    Read newline-delimited input line by line (JSON Lines). For concatenated values, use operator>> and check for the end of the stream before each read, as shown in Several values in one stream.

    "},{"location":"home/faq/#files-that-are-too-large-for-memory","title":"Files that are too large for memory","text":"

    Question

    How do I process a huge JSON file?

    Handle and discard the records of a large array with a parser callback, stop early with the SAX interface, or read parts of the text through a json_document (added in version 3.13.0 unreleased). See Input too large for memory.

    "},{"location":"home/faq/#position-of-a-parse-error","title":"Position of a parse error","text":"

    Question

    How do I get the line and column of a parse error?

    The message contains them. The exception stores the byte index in byte, from which you can compute both; see Where did the error occur?. To locate a value that causes a later error, such as a type_error, use JSON_DIAGNOSTIC_POSITIONS.

    "},{"location":"home/faq/#comments-and-trailing-commas","title":"Comments and trailing commas","text":"

    Question

    Can the parser read JSON with comments or trailing commas?

    Yes, when asked to: see Comments and Trailing commas. Both are rejected by default.

    "},{"location":"home/faq/#accessing-and-creating-values","title":"Accessing and creating values","text":""},{"location":"home/faq/#reading-a-value-into-a-variable","title":"Reading a value into a variable","text":"

    Question

    How do I get a C++ value out of a json value?

    Use get<T>(), for example int age = j[\"age\"].get<int>();, or an implicit conversion. auto x = j[\"age\"]; is not a conversion: it copies the json value. See Converting values.

    "},{"location":"home/faq/#strings-are-printed-with-quotes","title":"Strings are printed with quotes","text":"

    Question

    std::cout << j[\"name\"] prints \"Mary\" with quotes. How do I get the string?

    The value is a json, and printing it produces JSON text. Convert it first: j[\"name\"].get<std::string>(). See Getting a string without quotes.

    "},{"location":"home/faq/#testing-whether-a-key-exists","title":"Testing whether a key exists","text":"

    Question

    How do I check if a key exists, without changing the object?

    Use contains or find. Do not test with the non-const operator[]: like std::map::operator[], it inserts a null value for a missing key. See Does this key exist?. For choosing between value, contains/find, at, operator[], and JSON Pointer, see the decision flow in Element access.

    "},{"location":"home/faq/#reading-a-value-with-a-fallback","title":"Reading a value with a fallback","text":"

    Question

    How do I read a value that may be missing?

    Use value, which returns a default for a missing key. It still throws if the key exists with a different type; see Working without exceptions.

    "},{"location":"home/faq/#iterating-and-nested-values","title":"Iterating and nested values","text":"

    Question

    How do I loop over an array or object, or reach a nested value?

    See Iterators and items() for loops, and JSON Pointer to address or test a nested value by path.

    "},{"location":"home/faq/#unexpected-arrays-when-creating-values","title":"Unexpected arrays when creating values","text":"

    Question

    Why does json j{x} or {{\"a\", 1}, {\"b\"}} produce an array instead of what I expected?

    Braces create arrays and objects based on their content, and single-element braces create a one-element array. See Brace initialization yields arrays and the table in Creating values.

    "},{"location":"home/faq/#keeping-the-order-of-object-keys","title":"Keeping the order of object keys","text":"

    Question

    The keys of my object come out sorted. How do I keep the insertion order?

    Use ordered_json, and call ordered_json::parse when reading. See Object order.

    "},{"location":"home/faq/#converting-your-own-types","title":"Converting your own types","text":""},{"location":"home/faq/#structs-enums-and-optional-fields","title":"Structs, enums, and optional fields","text":"

    Question

    How do I convert my own types to and from JSON?

    Write to_json/from_json functions or use the NLOHMANN_DEFINE_TYPE_* macros; see Arbitrary type conversions. Enums can be mapped to strings (Enum conversion), and an empty std::optional can be omitted (Omitting a field).

    "},{"location":"home/faq/#smart-pointers-variants-chrono-and-class-hierarchies","title":"Smart pointers, variants, chrono, and class hierarchies","text":"

    Question

    Why can't I convert std::shared_ptr, std::variant, std::chrono types, or a pointer to a base class?

    There is more than one sensible JSON representation for them, so the library leaves the choice to you. Recipes for common types shows one for each.

    "},{"location":"home/faq/#my-to_json-is-not-found","title":"My to_json is not found","text":"

    Question

    I wrote to_json/from_json, but the compiler does not find them. Why?

    Typical causes are a type alias of a standard type, a function in the wrong namespace, or a declaration that comes too late. See Why isn't my to_json found?.

    "},{"location":"home/faq/#limitations","title":"Limitations","text":""},{"location":"home/faq/#relaxed-parsing","title":"Relaxed parsing","text":"

    Question

    Can you add an option to ignore trailing commas?

    Yes, trailing commas in arrays and objects can be allowed by setting parameter ignore_trailing_commas of parse to true; see trailing commas. They are rejected by default, and the library never adds them when serializing.

    "},{"location":"home/faq/#parse-errors-reading-non-ascii-characters","title":"Parse errors reading non-ASCII characters","text":"

    Questions

    • Why is the parser complaining about a Chinese character?
    • Does the library support Unicode?
    • I get an exception [json.exception.parse_error.101] parse error at line 1, column 53: syntax error while parsing value - invalid string: ill-formed UTF-8 byte; last read: '\"Test\u00e9$')\"

    The library supports Unicode input as follows:

    • UTF-8 encoded input is supported, which is the default encoding for JSON, according to RFC 8259.
    • std::u16string and std::u32string can be parsed, assuming UTF-16 and UTF-32 encoding, respectively; std::wstring works as well and is interpreted as UTF-16 or UTF-32, depending on the width of the platform's wchar_t. These encodings cannot be read from a FILE* or a std::istream, which carry bytes only.
    • Ill-formed UTF-16 or UTF-32 input is rejected: a lone surrogate, a high surrogate that is not followed by its low surrogate, and a code point above U+10FFFF all yield a parse error. The same holds for iterators over 2- or 4-byte characters.
    • Other encodings such as Latin-1 or ISO 8859-1 are not supported and will yield parse or serialization errors.
    • The library will not replace Unicode noncharacters.
    • Invalid surrogates (e.g., incomplete pairs such as \\uDEAD) will yield parse errors.
    • The strings stored in the library are UTF-8 encoded. When using the default string type (std::string), note that its length/size functions return the number of stored bytes rather than the number of characters or glyphs.
    • When you store strings with different encodings in the library, calling dump() may throw an exception unless json::error_handler_t::replace, json::error_handler_t::ignore, or json::error_handler_t::keep are used as error handlers.

    In most cases, the parser is right to complain, because the input is not UTF-8 encoded. This is especially true for Microsoft Windows, where Latin-1 or ISO 8859-1 is often the standard encoding.

    "},{"location":"home/faq/#nul-bytes-in-the-input","title":"NUL bytes in the input","text":"

    Questions

    • Why does json::parse() silently ignore part of my input?
    • Why does a std::string/buffer with extra data after the JSON text parse without error, while a similar-looking string with extra text does not?

    A '\\0' (NUL) byte anywhere in the input is treated the same as the real end of the input, rather than as an ordinary (and, outside of a string, invalid) byte. Everything from that byte onward is silently ignored, without a parse error \u2014 including further, otherwise well-formed JSON:

    json::parse(std::string(\"123\") + '\\0');          // == 123, no error\njson::parse(std::string(\"123\") + '\\0' + \"true\"); // == 123, the \"true\" is silently ignored too\n

    This is different from any other unexpected trailing byte, which does raise parse_error.101:

    json::parse(\"123x\"); // throws parse_error.101: unexpected additional data\n

    This falls out of the same convention used when no explicit input length is given at all: json::parse(const char*) already stops at the first NUL byte via strlen(), since a bare pointer has no length of its own. The library applies that same NUL-terminated-C-string convention uniformly, rather than only when a length is genuinely unavailable \u2014 so a std::string, iterator range, or container whose content happens to include a NUL byte is affected the same way a raw const char* would be.

    If your input may contain a trailing or embedded NUL that is not meant to signal the end of the JSON text \u2014 for instance, a fixed-size, zero-padded buffer \u2014 trim it yourself before calling parse(), since the library will otherwise silently stop there instead of raising an error:

    s.resize(s.find('\\0')); // drop everything from the first NUL onward, if any\njson::parse(s);\n

    Opt-in strict handling (since version 3.13.0 unreleased)

    Manually trimming every input is easy to forget. If you define JSON_STRICT_NUL_HANDLING to 1 before including the library, a '\\0' byte is instead rejected like any other unexpected byte and raises parse_error.101, instead of being treated as end of input:

    #define JSON_STRICT_NUL_HANDLING 1\n#include <nlohmann/json.hpp>\n\njson::parse(std::string(\"123\") + '\\0'); // throws parse_error.101 instead of silently returning 123\n

    This macro defaults to 0 (disabled, preserving the behavior described above) to avoid breaking existing code that may depend on it, even unknowingly; it is planned to become the default in version 4.0.0. See its documentation for details, including how it also affects char arrays such as string literals.

    Note that this is unrelated to an unescaped NUL byte occurring inside a quoted JSON string, which is a different, already-invalid case and is correctly rejected either way:

    json::parse(std::string(\"\\\"\") + '\\0' + \"\\\"\"); // throws parse_error.101: control character U+0000 (NUL) must be escaped to \\u0000\n
    "},{"location":"home/faq/#wide-string-handling","title":"Wide string handling","text":"

    Question

    Why are wide strings (e.g., std::wstring) dumped as arrays of numbers?

    As described above, the library stores its strings as UTF-8. To store a wide string as a string, convert it to a UTF-8 encoded std::string first, as in the example below.

    Example

    #include <codecvt> // codecvt_utf8\n#include <locale>  // wstring_convert\n\n// encoding function\nstd::string to_utf8(std::wstring& wide_string)\n{\n    static std::wstring_convert<std::codecvt_utf8<wchar_t>> utf8_conv;\n    return utf8_conv.to_bytes(wide_string);\n}\n\njson j;\nstd::wstring ws = L\"\u8ecaB1234 \u3053\u3093\u306b\u3061\u306f\";\n\nj[\"original\"] = ws;\nj[\"encoded\"] = to_utf8(ws);\n\nstd::cout << j << std::endl;\n

    The result is:

    {\n  \"encoded\": \"\u8ecaB1234 \u3053\u3093\u306b\u3061\u306f\",\n  \"original\": [36554, 66, 49, 50, 51, 52, 32, 12371, 12435, 12395, 12385, 12399]\n}\n
    "},{"location":"home/faq/#usage","title":"Usage","text":""},{"location":"home/faq/#thread-safety","title":"Thread safety","text":"

    Question

    Is basic_json thread-safe?

    No. basic_json provides no built-in synchronization, the same as std::map or std::vector. Concurrent reads of the same value from multiple threads are safe, as are concurrent (non-overlapping) accesses to independent json objects. However, any concurrent write to a json object \u2014 or a concurrent read while another thread writes to the same object \u2014 is a data race and requires external synchronization (e.g., a std::mutex) by the caller.

    "},{"location":"home/faq/#schema-validation","title":"Schema validation","text":"

    Question

    Does this library support JSON Schema validation?

    Not directly, but the companion project json-schema-validator builds JSON Schema (draft 7; draft 4 in its older, now-superseded 1.x releases) validation on top of this library and is a common recommendation for this use case.

    "},{"location":"home/faq/#memory-use","title":"Memory use","text":"

    Question

    Does the library leak memory? My process stays large after I free a json value.

    Destroying a value frees everything it owns. Freed memory is returned to the allocator, which does not necessarily give it back to the operating system, so a high resident size alone is not a leak. Copies are deep, and clear() keeps the capacity of an array. See Memory, and use Valgrind or the sanitizers to tell a leak from retained memory.

    "},{"location":"home/faq/#reproducible-builds","title":"Reproducible builds","text":"

    Question

    The header path ends up in my binary. How do I get path-independent builds?

    The runtime assertions embed __FILE__. Define NDEBUG (the default for release builds) or map the path prefix; see Notes for builds and distribution.

    "},{"location":"home/faq/#slow-debug-builds","title":"Slow debug builds","text":"

    Question

    Parsing a large file is very slow in my debug build. Can I compile the library with optimizations?

    The library is header-only, so there is no separate source file. Keep the code that uses json in its own source file and compile that file with optimizations; see Notes for builds and distribution.

    "},{"location":"home/faq/#exceptions","title":"Exceptions","text":""},{"location":"home/faq/#parsing-without-exceptions","title":"Parsing without exceptions","text":"

    Question

    Is it possible to indicate a parse error without throwing an exception?

    Yes, see Parsing and exceptions and Working without exceptions.

    "},{"location":"home/faq/#key-name-in-exceptions","title":"Key name in exceptions","text":"

    Question

    Can I get the key of the object item that caused an exception?

    Yes, you can. Please define the symbol JSON_DIAGNOSTICS to get extended diagnostics messages.

    "},{"location":"home/faq/#serialization-issues","title":"Serialization issues","text":""},{"location":"home/faq/#number-precision","title":"Number precision","text":"

    Question

    • It seems that precision is lost when serializing a double.
    • Can I change the precision for floating-point serialization?

    The library serializes floating-point numbers with the shortest representation that parses back to the same value, using at most std::numeric_limits<number_float_t>::max_digits10 (17 for IEEE doubles) significant digits. This guarantees that value -> string -> value round-trips. The reverse direction, string -> value -> string, is only guaranteed for numbers with at most std::numeric_limits<number_float_t>::digits10 (15 for IEEE doubles) significant digits; a number with more digits may not be representable exactly and is then serialized as the closest double.

    cppreference.com

    The value of std::numeric_limits<T>::max_digits10 is the number of base-10 digits that are necessary to uniquely represent all distinct values of the type T, such as necessary for serialization/deserialization to text.

    Tip

    The website https://float.exposed gives a good insight into the internal storage of floating-point numbers.

    See this section on the library's number handling for more information.

    "},{"location":"home/faq/#serializing-untrusted-or-invalid-utf-8","title":"Serializing untrusted or invalid UTF-8","text":"

    Questions

    • Why does dump() throw when I serialize data that came from the network?
    • Is CVE-2024-34363 a vulnerability in this library?

    Crashes reported against this library that stem from an uncaught type_error.316 while serializing unvalidated input (e.g., CVE-2024-34363) are a usage issue, not a library vulnerability: dump() throws in its default strict mode because RFC 8259 requires JSON text to be valid UTF-8.

    The recommended pattern is to pass a non-strict error_handler or to handle the exception:

    // replace invalid sequences with U+FFFD instead of throwing\nconst auto s = j.dump(-1, ' ', false, json::error_handler_t::replace);\n
    "},{"location":"home/faq/#using-json-values-with-stdformat-or-fmt","title":"Using JSON values with std::format or fmt","text":"

    Question

    • Can I use std::format(\"{}\", j) on a JSON value?
    • Can I use fmt::format(\"{}\", j) or fmt::print(\"{}\", j) (the {fmt} library) on a JSON value?

    std::format works out of the box since version 3.13.0 unreleased, as long as the standard library provides <format> (see JSON_HAS_STD_FORMAT); see std::formatter<basic_json> for details, including the \"{:#}\" pretty-print spec, indent widths (\"{:2}\"), and custom indent characters (\"{:.>#}\").

    For fmt, the library ships format_as, a small customization point fmt looks for via argument-dependent lookup. It only has an effect on fmt 10.0.0 through 11.0.2 \u2014 from fmt 11.1.0 onwards, fmt no longer picks up a format_as overload that returns a std::string. On such versions (or any version, if you also want the same \"{:#}\"/width/fill-and-align spec support that std::formatter<basic_json> has), define your own fmt::formatter specialization; see format_as for a recipe that mirrors it.

    If you get ambiguous-overload errors when passing a JSON value to fmt::format/fmt::print without any fmt::formatter<json> specialization in scope, that's fmt picking up basic_json's implicit operator ValueType() conversion operator (see #964 and #958); disabling it via JSON_USE_IMPLICIT_CONVERSIONS 0 avoids the ambiguity.

    "},{"location":"home/faq/#compilation-issues","title":"Compilation issues","text":""},{"location":"home/faq/#android-sdk","title":"Android SDK","text":"

    Question

    Why does the code not compile with Android SDK?

    Since NDK r18 (2018), GCC and the gnustl/stlport C++ libraries have been removed from the Android NDK; Clang and libc++ are now the only compiler and C++ library, and they support C++11 and later out of the box. With a current NDK, no special configuration is needed to use this library.

    Only very old NDKs (before r18), which defaulted to GCC and gnustl, lacked C++11 library features such as std::to_string. If you run into this, update to a current NDK.

    "},{"location":"home/faq/#incomplete-detector-type-with-gcc-11","title":"Incomplete detector type with GCC < 11","text":"

    Question

    Why does GCC 10 or older fail with invalid use of incomplete type 'struct nlohmann::detail::detector<..., to_json_function, ...>' for a type that holds an optional member?

    This happens with GCC 10 and older in C++11/C++14 mode when all of these hold:

    • a class Holder has an optional<Dummy> member (e.g., boost::optional),
    • Dummy has a constructor taking a json value, and
    • to_json for Holder is a free function in the namespace of Dummy.
    class Dummy {\n  public:\n    explicit Dummy(const nlohmann::json& j);\n};\n\nclass Holder {\n    boost::optional<Dummy> d;\n};\n\nvoid to_json(nlohmann::json& j, const Holder& h);  // triggers the error\n

    To decide whether Dummy is copyable, the compiler checks whether a Dummy can be converted to json. That check looks up to_json via argument-dependent lookup, finds the unrelated to_json for Holder, and eventually asks again whether Dummy is copyable. GCC before version 11 turns this cycle into a hard error; GCC 11 and later, Clang, and C++17 mode compile the code. The same error shows up without this library whenever a constrained converting constructor is involved, so the library can't avoid it.

    To work around this, define to_json (and from_json) as a hidden friend inside the class. That way, argument-dependent lookup only finds it for Holder:

    class Holder {\n    boost::optional<Dummy> d;\n\n    friend void to_json(nlohmann::json& j, const Holder& h) { /* ... */ }\n};\n

    The NLOHMANN_DEFINE_TYPE_INTRUSIVE macros define hidden friends as well. See #3669 for details.

    "},{"location":"home/faq/#missing-stl-function","title":"Missing STL function","text":"

    Questions

    • Why do I get a compilation error 'to_string' is not a member of 'std' (or similarly, for strtod or strtof)?
    • Why does the code not compile with MinGW or Android SDK?

    This is not an issue with the code, but rather with the compiler itself. On Android, use a current NDK (see above). For MinGW, please refer to this site and this discussion for information on how to fix this bug.

    "},{"location":"home/faq/#see-also","title":"See also","text":"
    • basic_json - the main class and all its member functions
    • Macros - reference of all macros
    • Exceptions - all exceptions and their error codes
    • Features - overview of all features
    "},{"location":"home/license/","title":"License","text":"

    The class is licensed under the MIT License:

    Copyright \u00a9 2013-2026 Niels Lohmann

    Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \u201cSoftware\u201d), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

    The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

    THE SOFTWARE IS PROVIDED \u201cAS IS\u201d, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

    The class contains the UTF-8 Decoder from Bjoern Hoehrmann which is licensed under the MIT License (see above). Copyright \u00a9 2008-2009 Bj\u00f6rn Hoehrmann bjoern@hoehrmann.de

    The class contains a slightly modified version of the Grisu2 algorithm from Florian Loitsch which is licensed under the MIT License (see above). Copyright \u00a9 2009 Florian Loitsch

    The class contains a port of the shortest double-to-decimal conversion of \u017bmij by Victor Zverovich, including the conversion of the digits to text by Xiang JunBo and the SIMD instruction sequence of Dougall Johnson, which is licensed under the MIT License (see above). Copyright \u00a9 2025 Victor Zverovich

    The class contains a copy of Hedley from Evan Nemerson which is licensed as CC0-1.0.

    The class contains an adapted version of the Eisel-Lemire algorithm, its table of powers of five, and its digit comparison for long numbers from fast_float by Daniel Lemire and contributors, which is available under the MIT License (used here), the Apache 2.0 License, and the Boost Software License. Copyright \u00a9 2021 The fast_float authors

    The view's parser (<nlohmann/json_view.hpp>) contains techniques and code adapted from yyjson by YaoYuan, which is licensed under the MIT License (see above): table-driven decoding of \\u escapes and fixed-offset unrolled checks.

    The view's parser (<nlohmann/json_view.hpp>) validates non-ASCII strings with the vector UTF-8 check of simdjson by Daniel Lemire, Geoff Langdale, John Keiser, and contributors (its \"lookup4\" algorithm and tables, after J. Keiser and D. Lemire, \"Validating UTF-8 In Less Than One Instruction Per Byte\", 2021), which is available under the MIT License (used here) and the Apache 2.0 License. Copyright \u00a9 2018-2025 The simdjson authors

    "},{"location":"home/sponsors/","title":"Sponsors","text":"

    You can sponsor this library at GitHub Sponsors. Thanks to everyone who supports the project!

    "},{"location":"home/sponsors/#priority-sponsors","title":"Priority Sponsors","text":"
    • Mercedes-Benz
    • FastNetMon
    "},{"location":"home/sponsors/#named-sponsors","title":"Named Sponsors","text":"
    • Paul Harrington
    • Steve Wagner
    • mccaffers
    • jambolo
    "},{"location":"home/sponsors/#further-sponsors","title":"Further Sponsors","text":"
    • Grisha Kirilin
    • zimmerman-dev
    • WAAutoMaton
    • F3D
    • David Alvarez Rosa
    • Alex Kong
    • Mark Oates
    • Martti Laine
    • Michael Hartmann
    • Stefan Hagen
    • Steve Sperandeo
    • Robert Jefe Lindst\u00e4dt
    "},{"location":"home/releases/","title":"Releases","text":"

    This section summarizes the notable changes of every release and links to the relevant documentation. The complete release notes \u2014 including all changes, the download files, and their checksums \u2014 are published on the GitHub releases page.

    Unreleased changes

    This documentation is built from the develop branch and may describe changes that are not part of a release yet. Their version numbers are followed by an unreleased badge.

    Every release has its own page with a summary of its notable changes and an overview of the API that was added or changed in it. The API overview is generated from the \"Version history\" section of the API pages; it is not a change log, but helps to see whether a feature is available in the version you use.

    All releases at a glance (hover a marker for its version and date):

    Timeline from the first commit (2013-07-04) and the 44 releases from v1.0.0 (2015-12-28) to v3.12.0 (2025-04-11): 17 minor or major releases, drawn as filled dots with their version above the axis, and 27 patch releases, drawn as rings. The first commit is drawn as a diamond. 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 1.x 2.x 3.x first commit 1.0 1.1 2.0 2.1 3.0 3.1 3.2 3.3 3.4 3.5 3.6 3.7 3.8 3.9 3.10 3.11 3.12 First commit 2013-07-04 v2.0.1 released 2016-06-28 v2.0.2 released 2016-07-31 v2.0.3 released 2016-08-31 v2.0.4 released 2016-09-11 v2.0.5 released 2016-09-14 v2.0.6 released 2016-10-15 v2.0.7 released 2016-11-02 v2.0.8 released 2016-12-02 v2.0.9 released 2016-12-16 v2.0.10 released 2017-01-02 v2.1.1 released 2017-02-25 v3.0.1 released 2017-12-29 v3.1.1 released 2018-02-13 v3.1.2 released 2018-03-14 v3.7.1 released 2019-11-06 v3.7.2 released 2019-11-10 v3.7.3 released 2019-11-17 v3.9.1 released 2020-08-06 v3.10.1 released 2021-08-24 v3.10.2 released 2021-08-26 v3.10.3 released 2021-10-08 v3.10.4 released 2021-10-16 v3.10.5 released 2022-01-03 v3.11.2 released 2022-08-12 v3.11.3 released 2023-11-28 v1.0.0 released 2015-12-28 v1.1.0 released 2016-01-24 v2.0.0 released 2016-06-24 v2.1.0 released 2017-01-28 v3.0.0 released 2017-12-17 v3.1.0 released 2018-02-01 v3.2.0 released 2018-08-20 v3.3.0 released 2018-10-05 v3.4.0 released 2018-10-30 v3.5.0 released 2018-12-22 v3.6.0, v3.6.1 released 2019-03-20 v3.7.0 released 2019-07-28 v3.8.0 released 2020-06-14 v3.9.0 released 2020-07-27 v3.10.0 released 2021-08-17 v3.11.0, v3.11.1 released 2022-08-01 v3.12.0 released 2025-04-11

    From the first commit (diamond) in 2013 to the latest release, on a time axis by year. Filled dots with a version label are minor or major releases, rings are patch releases.

    "},{"location":"home/releases/#unreleased","title":"Unreleased","text":"Release Date Summary Unreleased Changes on the develop branch that are not part of a release yet."},{"location":"home/releases/#version-312x","title":"Version 3.12.x","text":"Release Date Summary v3.12.0 2025-04-11 Fixes bugs found in 3.11.3 and adds several features. No public API was removed or renamed. Highlights: diagnostic byte positions (start_pos/end_pos); templated conversion macros and NLOHMANN_DEFINE_DERIVED_TYPE; std::optional support."},{"location":"home/releases/#version-311x","title":"Version 3.11.x","text":"Release Date Summary v3.11.3 2023-11-28 Adds features and fixes bugs found in 3.11.2. All changes are backward-compatible. Highlights: custom base class for basic_json; serialization-only conversion macros; Bazel and Swift Package Manager support. v3.11.2 2022-08-12 Fixes bugs found in 3.11.1 and restructures the namespace. All changes are backward-compatible. Highlights: fixes value for strings and size types; restores json_pointer as associative-container key; restructured inline namespace. v3.11.1 2022-08-01 Fixes a regression from 3.11.0. All changes are backward-compatible. Highlights: restores the global _json and _json_pointer literals. v3.11.0 2022-08-01 One of the largest releases ever. All changes are backward-compatible. Highlights: std::string_view keys; BJData binary format; C++20 support including operator<=>."},{"location":"home/releases/#version-310x","title":"Version 3.10.x","text":"Release Date Summary v3.10.5 2022-01-03 Bug-fix release. All changes are backward-compatible. Highlights: guards the std::filesystem conversions with JSON_HAS_FILESYSTEM. v3.10.4 2021-10-16 Fixes regressions introduced in 3.10.0. All changes are backward-compatible. Highlights: fixes the std::filesystem::path conversion; fixes types with explicit defaulted constructors; fixes std::find/std::remove return values. v3.10.3 2021-10-08 Fixes more regressions from 3.10.0. All changes are backward-compatible. Highlights: fixes extended-diagnostics assertions in update and array insertion; custom allocators for binary output; conversion from begin()/end()-only types. v3.10.2 2021-08-26 Re-release of 3.10.1, whose Git tag pointed at the wrong commit due to a bug in the release script. All changes are backward-compatible. Highlights: re-release of 3.10.1 with the correct Git tag. v3.10.1 2021-08-24 Fixes a regression from 3.10.0. All changes are backward-compatible. Highlights: fixes an extended-diagnostics assertion with ordered_json; hardens the GDB pretty-printer. v3.10.0 2021-08-17 Feature release. All changes are backward-compatible. Highlights: extended diagnostic messages (JSON_DIAGNOSTICS); GDB pretty-printer; CBOR tag storage."},{"location":"home/releases/#version-39x","title":"Version 3.9.x","text":"Release Date Summary v3.9.1 2020-08-06 Fixes two regressions from 3.9.0. All changes are backward-compatible. Highlights: accepts consecutive comments; completes the ordered_json interface. v3.9.0 2020-07-27 Feature release adding four long-requested features. All changes are backward-compatible. Highlights: comment parsing; ordered_json; switch to disable implicit conversions."},{"location":"home/releases/#version-38x","title":"Version 3.8.x","text":"Release Date Summary v3.8.0 2020-06-14 Feature release. All changes are backward-compatible. Highlights: binary value type for CBOR, BSON, and MessagePack; input adapters for any LegacyInputIterator container; fixes contains for JSON pointers."},{"location":"home/releases/#version-37x","title":"Version 3.7.x","text":"Release Date Summary v3.7.3 2019-11-17 Fixes a regression from 3.7.2 that could yield quadratic complexity in destructor calls. All changes are backward-compatible. Highlights: fixes quadratic complexity in destructor calls. v3.7.2 2019-11-10 Fixes a stack overflow for deeply nested input by making the destructor iterative; parsing of JSON text is now bounded only by available memory (the binary-format parsers still recurse). All changes are backward-compatible. Highlights: iterative destructor fixes a stack overflow on deeply nested input. v3.7.1 2019-11-06 Bug-fix release. All changes are backward-compatible. Highlights: fixes a crash when serializing the minimum std::int64_t; fixes contains for JSON pointers; items with custom string types. v3.7.0 2019-07-28 Convenience features and house-keeping. All changes are backward-compatible. Highlights: contains overload for JSON pointers; generic to_string; return value for emplace_back."},{"location":"home/releases/#version-36x","title":"Version 3.6.x","text":"Release Date Summary v3.6.1 2019-03-20 Fixes a regression (GCC 7/8 compilation) and a <Windows.h> build error introduced in 3.6.0. All changes are backward-compatible. Highlights: fixes a GCC 7/8 compilation regression; fixes a <Windows.h> build error. v3.6.0 2019-03-20 Feature release. All changes are backward-compatible. Highlights: reworked JSON pointer interface; contains function; faster integer serialization."},{"location":"home/releases/#version-35x","title":"Version 3.5.x","text":"Release Date Summary v3.5.0 2018-12-22 Feature release. All changes are backward-compatible. Highlights: structured bindings via items; reading from FILE*; fixes eofbit handling on streams."},{"location":"home/releases/#version-34x","title":"Version 3.4.x","text":"Release Date Summary v3.4.0 2018-10-30 Feature release. All changes are backward-compatible. Highlights: BSON support; Unicode error handlers for dump; NLOHMANN_JSON_SERIALIZE_ENUM."},{"location":"home/releases/#version-33x","title":"Version 3.3.x","text":"Release Date Summary v3.3.0 2018-10-05 Feature release. All changes are backward-compatible. Highlights: GCC 4.8 support; get_to; overhauled CMake integration."},{"location":"home/releases/#version-32x","title":"Version 3.2.x","text":"Release Date Summary v3.2.0 2018-08-20 Feature release. All changes are backward-compatible. Highlights: SAX interface and non-recursive parser; parsing from wide strings; conversion to std::string_view."},{"location":"home/releases/#version-31x","title":"Version 3.1.x","text":"Release Date Summary v3.1.2 2018-03-14 Bug-fix release. All changes are backward-compatible. Highlights: fixes a memory leak in the parser callback; user-defined string types in parser and serializer. v3.1.1 2018-02-13 Bug-fix release. All changes are backward-compatible. Highlights: fixes parsing of indefinite-length CBOR strings; fixes a user-defined conversion to vector types; fixes UBJSON overflow detection. v3.1.0 2018-02-01 Feature release. All changes are backward-compatible. Highlights: UBJSON support; JSON Merge Patch; Grisu2 floating-point output."},{"location":"home/releases/#version-30x","title":"Version 3.0.x","text":"Release Date Summary v3.0.1 2017-12-29 Fixes small issues in the JSON Pointer and JSON Patch implementations (invalid \"copy\" targets and non-integer array indices). All changes are backward-compatible. Highlights: fixes invalid JSON Patch \"copy\" targets; fixes non-integer array indices in JSON Pointer. v3.0.0 2017-12-17 First 3.x release \u2014 a major release with breaking changes (see the migration guide). Highlights: user-defined exceptions with identifiers; non-throwing accept and allow_exceptions; update to merge objects."},{"location":"home/releases/#version-21x","title":"Version 2.1.x","text":"Release Date Summary v2.1.1 2017-02-25 Bug-fix release. All changes are backward-compatible. Highlights: locale-independent number parsing and serialization; correct floating-point round-tripping; GPG-signed commits and files. v2.1.0 2017-01-28 Feature release. All changes are backward-compatible. Highlights: conversions from and to arbitrary user-defined types; meta function; JSON_NOEXCEPTION."},{"location":"home/releases/#version-20x","title":"Version 2.0.x","text":"Release Date Summary v2.0.10 2017-01-02 Fixes several security-relevant bugs in the CBOR and MessagePack parsers found by OSS-Fuzz. All changes are backward-compatible. Highlights: fixes security-relevant bugs in the CBOR parser; fixes security-relevant bugs in the MessagePack parser. v2.0.9 2016-12-16 Adds the CBOR and MessagePack binary formats. All changes are backward-compatible. Highlights: CBOR support; MessagePack support. v2.0.8 2016-12-02 Adds the emplace and emplace_back functions and improves parsing and serialization performance. All changes are backward-compatible. Highlights: emplace and emplace_back; faster parsing; faster serialization. v2.0.7 2016-11-02 Fixes several parser bugs found through the \"Parsing JSON is a Minefield\" study (short files, encoding detection, surrogate pairs). All changes are backward-compatible. Highlights: fixes short-file handling; fixes encoding detection; fixes surrogate pairs. v2.0.6 2016-10-15 Fixes operator[] for JSON pointers so that it creates missing values like the other overloads. All changes are backward-compatible. Highlights: operator[] creates missing values for JSON pointers. v2.0.5 2016-09-14 Fixes a remaining stream end-of-file detection bug in the parser. All changes are backward-compatible. Highlights: fixes a remaining stream end-of-file bug. v2.0.4 2016-09-11 Fixes stream end-of-file detection in the parser. All changes are backward-compatible. Highlights: fixes stream end-of-file detection. v2.0.3 2016-08-31 Generalizes the parser to accept any contiguous sequence of one-byte elements and deprecates the input-stream constructor in favor of the parse function. All changes are backward-compatible. Highlights: parser accepts any contiguous sequence of one-byte elements; deprecates the input-stream constructor in favor of parse. v2.0.2 2016-07-31 Overhauls the parser (now rejecting unescaped control characters), tightens the class invariants, and cleans up the code. All changes are backward-compatible. Highlights: overhauled parser rejecting unescaped control characters; tighter class invariants; code cleanup. v2.0.1 2016-06-28 Fixes a performance regression in the dump function by adjusting the stream locale once per serialization. All changes are backward-compatible. Highlights: fixes a performance regression in dump. v2.0.0 2016-06-24 Feature release with a minor (potentially non-backward-compatible) API change from added noexcept and constexpr specifiers. Highlights: JSON Pointer support in at and operator[], plus flatten and unflatten; JSON Patch via diff and patch; unsigned 64-bit integers."},{"location":"home/releases/#version-11x","title":"Version 1.1.x","text":"Release Date Summary v1.1.0 2016-01-24 Bug-fix and feature release. All changes are backward-compatible. Highlights: improved floating-point round-tripping; get_ref; runtime assertions."},{"location":"home/releases/#version-10x","title":"Version 1.0.x","text":"Release Date Summary v1.0.0 2015-12-28 First official release."},{"location":"home/releases/#see-also","title":"See also","text":"
    • Migration Guide \u2014 how to future-proof your code for the next major version and replace deprecated functions.
    • Roadmap: Version 4.0 \u2014 what the next major version will change and how to try it today.
    "},{"location":"home/releases/unreleased/","title":"Unreleased","text":"

    These changes are part of the develop branch, but not of a release yet.

    • Converting an rvalue container to JSON (json j = std::move(vec);, json j = std::map<std::string, std::string>{...};) now moves the elements instead of copying them (e.g., std::vector<std::string> with 100,000 strings: 4.7 ms to 2.3 ms). Two consequences: the source container is left in a valid but unspecified (moved-from) state, and if an exception is thrown during the conversion, the source may be partially moved-from, so the strong exception guarantee no longer holds for the source of an rvalue conversion (the JSON value itself is unaffected). Lvalues and const objects are still copied. See basic_json.
    "},{"location":"home/releases/unreleased/#api-changes","title":"API changes","text":"

    Added (88 pages):

    • basic_json: as_base_class, format_as(basic_json), from_bon8, merge_diff, basic_json>, to_bon8, with_t
    • basic_json_document: (overview), accept, basic_json_document, erase, insert, is_discarded, load, memory_usage, node_count, owns_source, parse, parse_copy, push_back, read, root, save, set, shrink_to_fit, source
    • basic_json_view: (overview), at, back, basic_json_view, begin, cbegin, cend, contains, count, dump, empty, end, find, front, get, get_string, get_to, is_array, is_binary, is_boolean, is_discarded, is_null, is_number, is_number_float, is_number_integer, is_number_unsigned, is_object, is_primitive, is_string, is_structured, items, materialize, number_format, number_token, operator[], operator==, operator<<, operator!=, size, source_offset, type, type_name, value
    • json_pointer: front, pop_front, push_front
    • macros: JSON_BRACE_INIT_COPY_SEMANTICS, JSON_DELETE_DEPRECATED_FUNCTIONS, JSON_DISABLE_STREAM_BULK_SCAN, JSON_DISABLE_TUPLE_REFERENCE_CONVERSION, JSON_DISABLE_UNLOCKED_FILE_IO, JSON_HAS_RANGE_VIEW_CONVERSION, JSON_HAS_STD_FORMAT, JSON_NO_AUTOMATIC_UDLS, JSON_NO_SIMD, JSON_NO_THREAD_LOCAL, JSON_PRECISE_STREAM_POSITION, JSON_STRICT_BINARY_UTF8, JSON_STRICT_NUL_HANDLING, JSON_USE_OBJECTS_FOR_ENUM_KEYED_MAPS, JSON_USE_SIMDUTF, nlohmann_define_type_with_names

    Changed:

    • operator>>(basic_json): Fixed a null pointer dereference for an std::istream without a stream buffer (now throws parse_error.101), and a crash (std::terminate) when i has eofbit in its exception mask, in version 3.13.0 unreleased.
    • operator>>(basic_json): Changed to the strong exception safety guarantee in version 3.13.0 unreleased: j is no longer left with a partially parsed value if parsing throws.
    • operator>>(basic_json): Scans the characters in the stream buffer of i in bulk in version 3.13.0 unreleased; the position of i after the call is unchanged (JSON_DISABLE_STREAM_BULK_SCAN restores reading one character at a time).
    • operator\"\"_json: Added char8_t* overload in version 3.13.0 unreleased.
    • operator\"\"_json_pointer: Added char8_t* overload in version 3.13.0 unreleased.
    • ordered_map: Changed in version 3.13.0 unreleased: growing the storage moves the mapped values instead of copying them.
    • basic_json::accept: Added ignore_trailing_commas in version 3.13.0 unreleased.
    • basic_json::accept: Extended container support (1) to include types with lvalue-only ADL begin/end (matching std::begin/std::end semantics) in version 3.13.0 unreleased.
    • basic_json::accept: Extended overload (2) to accept heterogeneous iterator+sentinel pairs (C++20 ranges support) in version 3.13.0 unreleased.
    • basic_json::accept: Parsing from an std::istream scans the characters in its stream buffer in bulk in version 3.13.0 unreleased (JSON_DISABLE_STREAM_BULK_SCAN).
    • basic_json::accept: Parsing from a FILE* locks the file once instead of once per character in version 3.13.0 unreleased (JSON_DISABLE_UNLOCKED_FILE_IO).
    • basic_json::accept: Ill-formed UTF-16 and UTF-32 input (a lone surrogate, a high surrogate that is not followed by its low surrogate, or a code point above U+10FFFF) is rejected in version 3.13.0 unreleased; before that, some such sequences were accepted or ended the input silently.
    • basic_json::array_t: Made capacity() optional, so that array types such as std::deque can be used, in version 3.13.0 unreleased.
    • basic_json::at: Overload 3: Support for keys convertible to std::string_view added in version 3.13.0 unreleased, consistently across the lookup functions.
    • basic_json::basic_json: Overload 4: Explicit for different string types if JSON_USE_IMPLICIT_CONVERSIONS is 0 since version 3.13.0 unreleased.
    • basic_json::basic_json: Overload 7: Fixed in version 3.13.0 unreleased 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.
    • basic_json::binary_t: Fixed dump, std::hash, and to_ubjson for byte types that are not integers (e.g., std::byte) in version 3.13.0 unreleased.
    • basic_json::clear: Fixed in version 3.13.0 unreleased to also clear the subtype of a binary value; before, the subtype was left unchanged.
    • basic_json::contains: Overload 2: Support for keys convertible to std::string_view added in version 3.13.0 unreleased, consistently across the lookup functions.
    • basic_json::contains: Overload 4: Deleted overloads for integral key types added in version 3.13.0 unreleased to reject such calls at compile time instead of causing undefined behavior at runtime.
    • basic_json::count: Overload 2: Support for keys convertible to std::string_view added in version 3.13.0 unreleased, consistently across the lookup functions.
    • basic_json::count: Overload 3: Deleted overload for integral key types added in version 3.13.0 unreleased to reject such calls at compile time instead of causing undefined behavior at runtime.
    • basic_json::dump: Error handler keep added in version 3.13.0 unreleased.
    • basic_json::dump: Doubles are written with the shortest digits (\u017bmij instead of Grisu2) since version 3.13.0 unreleased; about 0.1% of doubles are written differently, most of them with fewer digits.
    • basic_json::emplace: Fixed in version 3.13.0 unreleased: for ordered_json, the value could previously only be passed as an rvalue; it can now also be passed as an lvalue or a const lvalue, matching the behavior of json.
    • basic_json::erase: Overload 4: Support for keys convertible to std::string_view added in version 3.13.0 unreleased, consistently across the lookup functions.
    • basic_json::error_handler_t: Added keep, and made this enumeration apply to the binary readers and writers in addition to dump, in version 3.13.0 unreleased.
    • basic_json::find: Overload 2: Support for keys convertible to std::string_view added in version 3.13.0 unreleased, consistently across the lookup functions.
    • basic_json::find: Overload 3: Deleted overloads for integral key types added in version 3.13.0 unreleased to reject such calls at compile time instead of causing undefined behavior at runtime.
    • basic_json::from_bjdata: Extended container support (1) to include types with lvalue-only ADL begin/end (matching std::begin/std::end semantics) in version 3.13.0 unreleased.
    • basic_json::from_bjdata: Extended overload (2) to accept heterogeneous iterator+sentinel pairs (C++20 ranges support) in version 3.13.0 unreleased.
    • basic_json::from_bjdata: Added error_handler parameter in version 3.13.0 unreleased.
    • basic_json::from_bson: Extended container support (1) to include types with lvalue-only ADL begin/end (matching std::begin/std::end semantics) in version 3.13.0 unreleased.
    • basic_json::from_bson: Extended overload (2) to accept heterogeneous iterator+sentinel pairs (C++20 ranges support) in version 3.13.0 unreleased.
    • basic_json::from_bson: Added error_handler parameter in version 3.13.0 unreleased.
    • basic_json::from_cbor: Extended container support (1) to include types with lvalue-only ADL begin/end (matching std::begin/std::end semantics) in version 3.13.0 unreleased.
    • basic_json::from_cbor: Extended overload (2) to accept heterogeneous iterator+sentinel pairs (C++20 ranges support) in version 3.13.0 unreleased.
    • basic_json::from_cbor: Added error_handler parameter in version 3.13.0 unreleased.
    • basic_json::from_msgpack: Extended container support (1) to include types with lvalue-only ADL begin/end (matching std::begin/std::end semantics) in version 3.13.0 unreleased.
    • basic_json::from_msgpack: Extended overload (2) to accept heterogeneous iterator+sentinel pairs (C++20 ranges support) in version 3.13.0 unreleased.
    • basic_json::from_msgpack: Added error_handler parameter in version 3.13.0 unreleased.
    • basic_json::from_ubjson: Extended container support (1) to include types with lvalue-only ADL begin/end (matching std::begin/std::end semantics) in version 3.13.0 unreleased.
    • basic_json::from_ubjson: Extended overload (2) to accept heterogeneous iterator+sentinel pairs (C++20 ranges support) in version 3.13.0 unreleased.
    • basic_json::from_ubjson: Added error_handler parameter in version 3.13.0 unreleased.
    • basic_json::get_to: Added a static_assert with a clear message for const arguments in version 3.13.0 unreleased.
    • basic_json::insert: Overload 4: Fixed in version 3.13.0 unreleased 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.
    • basic_json::json_base_class_t: Made a public member type in version 3.13.0 unreleased; it was private before, so it could not be named outside the class.
    • basic_json::merge_patch: Fixed use of freed or relocated memory when apply_patch is *this or refers to a value contained in *this, in version 3.13.0 unreleased.
    • basic_json::number_unsigned_t: Can be the same type as number_integer_t since version 3.13.0 unreleased.
    • basic_json::object_comparator_t: Fixed the fallback to default_object_comparator_t, which previously failed to compile for object types without a key_compare member type, in version 3.13.0 unreleased.
    • basic_json::object_t: Allowed object types whose erase(iterator) returns void in version 3.13.0 unreleased.
    • basic_json::operator[]: Overload 1: Fixed in version 3.13.0 unreleased to throw std::length_error instead of emptying the array and accessing it out of bounds when idx equals the maximum value of size_type.
    • basic_json::operator[]: Overload 1: A missing index in the const version is guarded by a runtime assertion since version 3.13.0 unreleased.
    • basic_json::operator[]: Overload 3: Support for keys convertible to std::string_view added in version 3.13.0 unreleased, consistently across the lookup functions.
    • basic_json::operator[]: Overload 4: A missing array index in the const version is guarded by a runtime assertion since version 3.13.0 unreleased.
    • basic_json::operator==: Overload 2: Made conditionally noexcept in version 3.13.0 unreleased; before, a throwing conversion called std::terminate.
    • basic_json::operator>=: Overload 2: Made conditionally noexcept in version 3.13.0 unreleased; before, a throwing conversion called std::terminate.
    • basic_json::operator>: Overload 2: Made conditionally noexcept in version 3.13.0 unreleased; before, a throwing conversion called std::terminate.
    • basic_json::operator<=: Overload 2: Made conditionally noexcept in version 3.13.0 unreleased; before, a throwing conversion called std::terminate.
    • basic_json::operator<: Overload 2: Made conditionally noexcept in version 3.13.0 unreleased; before, a throwing conversion called std::terminate.
    • basic_json::operator!=: Overload 1: Changed in version 3.13.0 unreleased to remove special-casing for NaN and discarded values; operator!= now consistently means !(a == b).
    • basic_json::operator!=: Overload 1: Removed the C++20 member function in version 3.13.0 unreleased; since C++20, the compiler rewrites a != b using operator==.
    • basic_json::operator!=: Overload 2: Changed in version 3.13.0 unreleased to remove special-casing for NaN and discarded values; operator!= now consistently means !(a == b).
    • basic_json::operator!=: Overload 2: Made conditionally noexcept in version 3.13.0 unreleased; before, a throwing conversion called std::terminate.
    • basic_json::operator<=>: Overload 2: Made conditionally noexcept in version 3.13.0 unreleased; before, a throwing conversion called std::terminate.
    • basic_json::parse: Added ignore_trailing_commas in version 3.13.0 unreleased.
    • basic_json::parse: Extended container support (1) to include types with lvalue-only ADL begin/end (matching std::begin/std::end semantics) in version 3.13.0 unreleased.
    • basic_json::parse: Extended overload (2) to accept heterogeneous iterator+sentinel pairs (C++20 ranges support) in version 3.13.0 unreleased.
    • basic_json::parse: 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 unreleased.
    • basic_json::parse: Parsing from an std::istream scans the characters in its stream buffer in bulk in version 3.13.0 unreleased (JSON_DISABLE_STREAM_BULK_SCAN restores reading one character at a time).
    • basic_json::parse: Parsing from a FILE* locks the file once instead of once per character in version 3.13.0 unreleased (JSON_DISABLE_UNLOCKED_FILE_IO restores std::fgetc).
    • basic_json::parse: Ill-formed UTF-16 and UTF-32 input (a lone surrogate, a high surrogate that is not followed by its low surrogate, or a code point above U+10FFFF) is rejected with parse_error.101 in version 3.13.0 unreleased; before that, some such sequences were accepted or ended the input silently.
    • basic_json::parser_callback_t: Fixed in version 3.13.0 unreleased 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.
    • basic_json::parser_callback_t: Fixed in version 3.13.0 unreleased 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.
    • basic_json::patch: Added out_of_range.411 and stopped relying on an internal assertion when an \"add\" operation's target location has a non-object/non-array parent in version 3.13.0 unreleased.
    • basic_json::patch: This includes a null parent, which was previously silently converted to an object, in version 3.13.0 unreleased.
    • basic_json::patch: Added out_of_range.413 and stopped silently ignoring a \"remove\" operation whose target location has a non-object/non-array parent in version 3.13.0 unreleased.
    • basic_json::patch: Added out_of_range.414 and rejected a \"move\" operation whose \"from\" location is a proper prefix of its \"path\" location instead of silently producing a corrupted result in version 3.13.0 unreleased.
    • basic_json::patch: Throws parse_error.109 instead of out_of_range.404 for a one-character array index that is not a digit (e.g., /x) in version 3.13.0 unreleased, as it already did for longer ones.
    • basic_json::patch_inplace: Added out_of_range.411 and stopped relying on an internal assertion when an \"add\" operation's target location has a non-object/non-array parent in version 3.13.0 unreleased.
    • basic_json::patch_inplace: This includes a null parent, which was previously silently converted to an object, in version 3.13.0 unreleased.
    • basic_json::patch_inplace: Added out_of_range.413 and stopped silently ignoring a \"remove\" operation whose target location has a non-object/non-array parent in version 3.13.0 unreleased.
    • basic_json::patch_inplace: Added out_of_range.414 and rejected a \"move\" operation whose \"from\" location is a proper prefix of its \"path\" location instead of silently producing a corrupted result in version 3.13.0 unreleased.
    • basic_json::patch_inplace: Throws parse_error.109 instead of out_of_range.404 for a one-character array index that is not a digit (e.g., /x) in version 3.13.0 unreleased, as it already did for longer ones.
    • basic_json::patch_inplace: Applying a JSON value as patch to itself (or, with JSON_DIAGNOSTICS, to a value stored inside it) no longer results in undefined behavior in version 3.13.0 unreleased.
    • basic_json::sax_parse: Added ignore_trailing_commas in version 3.13.0 unreleased.
    • basic_json::sax_parse: Added tag_handler in version 3.13.0 unreleased.
    • basic_json::sax_parse: Extended container support (1) to include types with lvalue-only ADL begin/end (matching std::begin/std::end semantics) in version 3.13.0 unreleased.
    • basic_json::sax_parse: Extended overload (2) to accept heterogeneous iterator+sentinel pairs (C++20 ranges support) in version 3.13.0 unreleased.
    • basic_json::sax_parse: JSON_PRECISE_STREAM_POSITION added in version 3.13.0 unreleased to optionally leave a std::istream positioned right after the parsed value when strict is false.
    • basic_json::sax_parse: Parsing from an std::istream scans the characters in its stream buffer in bulk in version 3.13.0 unreleased (JSON_DISABLE_STREAM_BULK_SCAN).
    • basic_json::sax_parse: Parsing from a FILE* locks the file once instead of once per character in version 3.13.0 unreleased (JSON_DISABLE_UNLOCKED_FILE_IO).
    • basic_json::sax_parse: Ill-formed UTF-16 and UTF-32 input (a lone surrogate, a high surrogate that is not followed by its low surrogate, or a code point above U+10FFFF) is rejected with parse_error.101 in version 3.13.0 unreleased; before that, some such sequences were accepted or ended the input silently.
    • std::hash<nlohmann::basic_json>: Numbers that compare equal hash equally since version 3.13.0 unreleased; before, 0, 0U, and 0.0 had different hash values.
    • basic_json::string_t: Removed the requirement that string_t be implicitly convertible from std::string, which the BSON writer and the UBJSON reader relied on, in version 3.13.0 unreleased.
    • basic_json::swap: Overload 1: Exchanges the json_base_class_t subobject along with the value since version 3.13.0 unreleased.
    • basic_json::swap: Overload 2: Exchanges the json_base_class_t subobject along with the value since version 3.13.0 unreleased.
    • basic_json::to_bjdata: Added error_handler parameter in version 3.13.0 unreleased.
    • basic_json::to_bjdata: Throws type_error.321 for a discarded value since version 3.13.0 unreleased; previously, a discarded value nested in an array or object was silently skipped, producing invalid BJData.
    • basic_json::to_bson: Throws out_of_range.412 and out_of_range.415 since version 3.13.0 unreleased.
    • basic_json::to_bson: Linear in the size of j, and no longer limited by the call stack for deeply nested values, since version 3.13.0 unreleased.
    • basic_json::to_bson: out_of_range.415 is now detected before anything is written, like the other exceptions above, since version 3.13.0 unreleased.
    • basic_json::to_bson: Throws type_error.321 for a discarded value nested in j since version 3.13.0 unreleased; previously, it was silently skipped, producing a document whose declared size did not match what was actually written.
    • basic_json::to_bson: Added error_handler parameter in version 3.13.0 unreleased.
    • basic_json::to_bson: Throws out_of_range.407 for integers that do not fit 64 bits since version 3.13.0 unreleased; previously, integers of a number type wider than 64 bits were silently truncated.
    • basic_json::to_cbor: Added error_handler parameter in version 3.13.0 unreleased.
    • basic_json::to_cbor: Throws type_error.321 for a discarded value since version 3.13.0 unreleased; previously, a discarded value nested in an array or object was silently skipped, producing invalid CBOR.
    • basic_json::to_cbor: Throws out_of_range.407 for integers that do not fit 64 bits since version 3.13.0 unreleased; previously, integers of a number type wider than 64 bits were silently truncated.
    • basic_json::to_msgpack: Throws out_of_range.412 and out_of_range.415 since version 3.13.0 unreleased.
    • basic_json::to_msgpack: Added error_handler parameter in version 3.13.0 unreleased.
    • basic_json::to_msgpack: Fixed in version 3.13.0 unreleased 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.
    • basic_json::to_msgpack: Throws type_error.321 for a discarded value since version 3.13.0 unreleased; previously, a discarded value nested in an array or object was silently skipped, producing invalid MessagePack.
    • basic_json::to_msgpack: Throws out_of_range.407 for integers that do not fit 64 bits since version 3.13.0 unreleased; previously, integers of a number type wider than 64 bits were silently truncated.
    • basic_json::to_ubjson: Added error_handler parameter in version 3.13.0 unreleased.
    • basic_json::to_ubjson: Throws type_error.321 for a discarded value since version 3.13.0 unreleased; previously, a discarded value nested in an array or object was silently skipped, producing invalid UBJSON.
    • basic_json::type_name: Added \"invalid\" return value for corrupted JSON values in version 3.13.0 unreleased.
    • basic_json::unflatten: Made the array/object decision independent of the object's iteration order in version 3.13.0 unreleased.
    • basic_json::unflatten: Throws parse_error.109 instead of out_of_range.404 for a one-character array index that is not a digit (e.g., /x) in version 3.13.0 unreleased, as it already did for longer ones.
    • basic_json::update: Fixed use of freed or relocated memory when the argument is *this or refers to a value contained in *this, in version 3.13.0 unreleased.
    • basic_json::value: Overload 1: Deleted overload for integral key types added in version 3.13.0 unreleased to reject such calls at compile time instead of causing undefined behavior at runtime.
    • basic_json::value: Overload 2: Support for keys convertible to std::string_view added in version 3.13.0 unreleased, consistently across the lookup functions.
    • basic_json::value: Overload 3: Extended to work with arrays in version 3.13.0 unreleased.
    • basic_json::value: Overload 3: Throws parse_error.109 instead of returning default_value for a one-character array index that is not a digit (e.g., /x) in version 3.13.0 unreleased, as it already did for longer ones.
    • json_pointer::operator/=: Overload 1: Appending a JSON pointer to itself no longer results in undefined behavior in version 3.13.0 unreleased.
    • JSON_HAS_CPP_11, JSON_HAS_CPP_14, JSON_HAS_CPP_17, JSON_HAS_CPP_20, JSON_HAS_CPP_23, JSON_HAS_CPP_26: Added JSON_HAS_CPP_26 in version 3.13.0 unreleased.
    • JSON_HAS_RANGES: Added the exclusions for libstdc++ < 11, Clang < 16 with libstdc++, libc++ < 16, and nvcc (CUDA) 12.0.x and 12.1.x in version 3.13.0 unreleased.
    • JSON_USE_IMPLICIT_CONVERSIONS: Also affects the conversion between basic_json specializations with different string types since version 3.13.0 unreleased.
    • JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON: Fixed in version 3.13.0 unreleased so <= and >= also emulate the legacy behavior in C++20 when the JSON value is the right-hand operand of a scalar comparison; before, only the 3-way-comparison-rewritten candidate was found, which yielded false instead of true.
    "},{"location":"home/releases/v1.0.0/","title":"v1.0.0","text":"

    Released on 2015-12-28.

    First official release. Full release notes.

    "},{"location":"home/releases/v1.0.0/#api-changes","title":"API changes","text":"

    Added (70 pages):

    • operator>>(basic_json)
    • operator\"\"_json
    • operator<<(basic_json), nlohmann::operator<<(json_pointer)
    • basic_json: (overview), array, array_t, at, back, basic_json, begin, boolean_t, cbegin, cend, clear, count, crbegin, crend, dump, empty, end, erase, find, front, get, get_allocator, get_ptr, insert, is_array, is_boolean, is_discarded, is_null, is_number, is_number_float, is_number_integer, is_object, is_primitive, is_string, is_structured, max_size, number_float_t, number_integer_t, object, object_t, operator+=, operator=, operator[], operator ValueType, operator==, operator>=, operator>, operator<=, operator<, operator!=, operator value_t, parse, parse_event_t, parser_callback_t, push_back, rbegin, rend, size, basic_json>, swap<basic_json>, string_t, swap, type, type_name, value, value_t, ~basic_json
    "},{"location":"home/releases/v1.1.0/","title":"v1.1.0","text":"

    Released on 2016-01-24.

    Bug-fix and feature release. All changes are backward-compatible.

    • Improves floating-point round-tripping, adds a get_ref accessor for stored values, and introduces runtime assertions.

    Full release notes.

    "},{"location":"home/releases/v1.1.0/#api-changes","title":"API changes","text":"

    Added (1 pages):

    • basic_json: get_ref

    Changed:

    • basic_json::operator[]: Overload 2: Added overloads for T* key in version 1.1.0.
    "},{"location":"home/releases/v2.0.0/","title":"v2.0.0","text":"

    Released on 2016-06-24.

    Feature release with a minor (potentially non-backward-compatible) API change from added noexcept and constexpr specifiers.

    • Adds JSON Pointer support in at and operator[], plus flatten and unflatten.
    • Adds JSON Patch via diff and patch, unsigned 64-bit integer support, and locale-independent serialization.

    Full release notes.

    "},{"location":"home/releases/v2.0.0/#api-changes","title":"API changes","text":"

    Added (11 pages):

    • operator\"\"_json_pointer
    • basic_json: diff, flatten, is_number_unsigned, number_unsigned_t, patch, unflatten
    • json_pointer: (overview), json_pointer, operator string_t, to_string

    Changed:

    • basic_json::at: Overload 4 added.
    • basic_json::is_number: Extended to also return true for unsigned integers in 2.0.0.
    • basic_json::is_number_integer: Extended to also return true for unsigned integers in 2.0.0.
    • basic_json::operator+=: Overload 3 added.
    • basic_json::operator[]: Overload 4 added.
    • basic_json::operator value_t: Added unsigned integer type in version 2.0.0.
    • basic_json::push_back: Overload 3 added.
    • basic_json::type: Added unsigned integer type in version 2.0.0.
    • basic_json::value_t: Added unsigned integer type in version 2.0.0.
    "},{"location":"home/releases/v2.0.1/","title":"v2.0.1","text":"

    Released on 2016-06-28.

    Fixes a performance regression in the dump function by adjusting the stream locale once per serialization. All changes are backward-compatible. Full release notes.

    "},{"location":"home/releases/v2.0.1/#api-changes","title":"API changes","text":"

    No documented API changes.

    "},{"location":"home/releases/v2.0.10/","title":"v2.0.10","text":"

    Released on 2017-01-02.

    Fixes several security-relevant bugs in the CBOR and MessagePack parsers found by OSS-Fuzz. All changes are backward-compatible. Full release notes.

    "},{"location":"home/releases/v2.0.10/#api-changes","title":"API changes","text":"

    No documented API changes.

    "},{"location":"home/releases/v2.0.2/","title":"v2.0.2","text":"

    Released on 2016-07-31.

    Overhauls the parser (now rejecting unescaped control characters), tightens the class invariants, and cleans up the code. All changes are backward-compatible. Full release notes.

    "},{"location":"home/releases/v2.0.2/#api-changes","title":"API changes","text":"

    Changed:

    • basic_json::value: Overload 3 added.
    "},{"location":"home/releases/v2.0.3/","title":"v2.0.3","text":"

    Released on 2016-08-31.

    Generalizes the parser to accept any contiguous sequence of one-byte elements and deprecates the input-stream constructor in favor of the parse function. All changes are backward-compatible. Full release notes.

    "},{"location":"home/releases/v2.0.3/#api-changes","title":"API changes","text":"

    Changed:

    • basic_json::parse: Overload for contiguous containers (1) added in version 2.0.3.
    "},{"location":"home/releases/v2.0.4/","title":"v2.0.4","text":"

    Released on 2016-09-11.

    Fixes stream end-of-file detection in the parser. All changes are backward-compatible. Full release notes.

    "},{"location":"home/releases/v2.0.4/#api-changes","title":"API changes","text":"

    No documented API changes.

    "},{"location":"home/releases/v2.0.5/","title":"v2.0.5","text":"

    Released on 2016-09-14.

    Fixes a remaining stream end-of-file detection bug in the parser. All changes are backward-compatible. Full release notes.

    "},{"location":"home/releases/v2.0.5/#api-changes","title":"API changes","text":"

    No documented API changes.

    "},{"location":"home/releases/v2.0.6/","title":"v2.0.6","text":"

    Released on 2016-10-15.

    Fixes operator[] for JSON pointers so that it creates missing values like the other overloads. All changes are backward-compatible. Full release notes.

    "},{"location":"home/releases/v2.0.6/#api-changes","title":"API changes","text":"

    No documented API changes.

    "},{"location":"home/releases/v2.0.7/","title":"v2.0.7","text":"

    Released on 2016-11-02.

    Fixes several parser bugs found through the \"Parsing JSON is a Minefield\" study (short files, encoding detection, surrogate pairs). All changes are backward-compatible. Full release notes.

    "},{"location":"home/releases/v2.0.7/#api-changes","title":"API changes","text":"

    No documented API changes.

    "},{"location":"home/releases/v2.0.8/","title":"v2.0.8","text":"

    Released on 2016-12-02.

    Adds the emplace and emplace_back functions and improves parsing and serialization performance. All changes are backward-compatible. Full release notes.

    "},{"location":"home/releases/v2.0.8/#api-changes","title":"API changes","text":"

    Added (2 pages):

    • basic_json: emplace, emplace_back
    "},{"location":"home/releases/v2.0.9/","title":"v2.0.9","text":"

    Released on 2016-12-16.

    Adds the CBOR and MessagePack binary formats. All changes are backward-compatible. Full release notes.

    "},{"location":"home/releases/v2.0.9/#api-changes","title":"API changes","text":"

    Added (4 pages):

    • basic_json: from_cbor, from_msgpack, to_cbor, to_msgpack
    "},{"location":"home/releases/v2.1.0/","title":"v2.1.0","text":"

    Released on 2017-01-28.

    Feature release. All changes are backward-compatible.

    • Adds conversions from and to arbitrary user-defined types via to_json/from_json, the meta function, and the option to switch off exceptions (JSON_NOEXCEPTION).

    Full release notes.

    "},{"location":"home/releases/v2.1.0/#api-changes","title":"API changes","text":"

    Added (7 pages):

    • adl_serializer: (overview), from_json, to_json
    • basic_json: json_serializer, meta
    • json_pointer: operator==, operator!=

    Changed:

    • basic_json::basic_json: Overload 3 added.
    • basic_json::get: Overload 1 added.
    • basic_json::get: Overload 2 added.
    • basic_json::type_name: Part of the public API version since 2.1.0.
    "},{"location":"home/releases/v2.1.1/","title":"v2.1.1","text":"

    Released on 2017-02-25.

    Bug-fix release. All changes are backward-compatible.

    • Makes number parsing and serialization locale-independent with correct floating-point round-tripping; commits and released files are GPG-signed.

    Full release notes.

    "},{"location":"home/releases/v2.1.1/#api-changes","title":"API changes","text":"

    Changed:

    • basic_json::from_cbor: Parameter start_index since version 2.1.1.
    • basic_json::from_msgpack: Parameter start_index since version 2.1.1.
    "},{"location":"home/releases/v3.0.0/","title":"v3.0.0","text":"

    Released on 2017-12-17.

    First 3.x release \u2014 a major release with breaking changes (see the migration guide).

    • Introduces user-defined exceptions (json::exception and subtypes, each with an identifier).
    • Adds a non-throwing accept function and an allow_exceptions flag for parse, and an update function to merge objects.
    • Adds streaming for CBOR and MessagePack and allows storing NaN/infinity.
    • Non-UTF-8 strings now throw on serialization, and the iterator category changed to bidirectional.

    Full release notes.

    "},{"location":"home/releases/v3.0.0/#api-changes","title":"API changes","text":"

    Added (9 pages):

    • basic_json: accept, exception, invalid_iterator, object_comparator_t, other_error, out_of_range, parse_error, type_error, update

    Changed:

    • operator<<(basic_json), nlohmann::operator<<(json_pointer): Overload 1: Added support for indentation character and deprecated std::ostream& operator>>(const basic_json& j, std::ostream& o) in version 3.0.0.
    • basic_json::dump: Indentation character indent_char, option ensure_ascii and exceptions added in version 3.0.0.
    • basic_json::from_cbor: Changed to consume input adapters, removed start_index parameter, and added strict parameter in version 3.0.0.
    • basic_json::from_msgpack: Changed to consume input adapters, removed start_index parameter, and added strict parameter in version 3.0.0.
    • basic_json::insert: Overload 5 added.
    • basic_json::type_name: Changed return value to const char* and added noexcept in version 3.0.0.
    "},{"location":"home/releases/v3.0.1/","title":"v3.0.1","text":"

    Released on 2017-12-29.

    Fixes small issues in the JSON Pointer and JSON Patch implementations (invalid \"copy\" targets and non-integer array indices). All changes are backward-compatible. Full release notes.

    "},{"location":"home/releases/v3.0.1/#api-changes","title":"API changes","text":"

    No documented API changes.

    "},{"location":"home/releases/v3.1.0/","title":"v3.1.0","text":"

    Released on 2018-02-01.

    Feature release. All changes are backward-compatible.

    • Adds UBJSON read/write support and JSON Merge Patch via merge_patch.
    • Switches to the Grisu2 algorithm for short, round-trippable floating-point output, and splits the header into multiple files with a forward-declaration header.

    Full release notes.

    "},{"location":"home/releases/v3.1.0/#api-changes","title":"API changes","text":"

    Added (6 pages):

    • basic_json: from_ubjson, items, merge_patch, to_ubjson
    • macros: JSON_CATCH_USER, JSON_THROW_USER, JSON_TRY_USER, NLOHMANN_JSON_VERSION_MAJOR, NLOHMANN_JSON_VERSION_MINOR, NLOHMANN_JSON_VERSION_PATCH
    "},{"location":"home/releases/v3.1.1/","title":"v3.1.1","text":"

    Released on 2018-02-13.

    Bug-fix release. All changes are backward-compatible.

    • Fixes parsing of indefinite-length CBOR strings, a user-defined conversion to vector types, and overflow detection for UBJSON containers.

    Full release notes.

    "},{"location":"home/releases/v3.1.1/#api-changes","title":"API changes","text":"

    No documented API changes.

    "},{"location":"home/releases/v3.1.2/","title":"v3.1.2","text":"

    Released on 2018-03-14.

    Bug-fix release. All changes are backward-compatible.

    • Fixes a memory leak in the parser callback and adds user-defined string-type support to the parser and serializer.

    Full release notes.

    "},{"location":"home/releases/v3.1.2/#api-changes","title":"API changes","text":"

    Changed:

    • basic_json::basic_json: Overload 4 added.
    • basic_json::get: Overload 2: Extended to work with other specializations of basic_json in version 3.1.2.
    "},{"location":"home/releases/v3.10.0/","title":"v3.10.0","text":"

    Released on 2021-08-17.

    Feature release. All changes are backward-compatible.

    • Adds extended diagnostic messages (JSON_DIAGNOSTICS) that prepend a JSON pointer to exception messages to pinpoint the offending value.
    • Adds a GDB pretty-printer and a cbor_tag_handler_t store option to keep CBOR tags as binary subtypes.
    • Supports containers with non-default-constructible types and parsing from std::byte.
    • Adds JSON_NO_IO to exclude the I/O headers and the JSON_HAS_CPP_* macros to override the detected C++ standard.

    Full release notes.

    "},{"location":"home/releases/v3.10.0/#api-changes","title":"API changes","text":"

    Added (3 pages):

    • macros: JSON_DIAGNOSTICS, JSON_HAS_CPP_11, JSON_HAS_CPP_14, JSON_HAS_CPP_17, JSON_HAS_CPP_20, JSON_HAS_CPP_23, JSON_HAS_CPP_26, JSON_NO_IO

    Changed:

    • basic_json::binary: Changed the type of subtype from std::uint8_t to binary_t::subtype_type (std::uint64_t) in version 3.10.0.
    • basic_json::binary_t: Changed the type of subtype to std::uint64_t in version 3.10.0.
    • basic_json::cbor_tag_handler_t: Added value store in 3.10.0.
    • byte_container_with_subtype: Changed the type of subtypes to std::uint64_t in 3.10.0.
    • byte_container_with_subtype::subtype: Fixed return value to properly return subtype_type(-1) as documented in version 3.10.0.
    "},{"location":"home/releases/v3.10.1/","title":"v3.10.1","text":"

    Released on 2021-08-24.

    Fixes a regression from 3.10.0. All changes are backward-compatible.

    • Fixes an extended-diagnostics assertion triggered when used with ordered_json, and hardens the GDB pretty-printer.

    Full release notes.

    "},{"location":"home/releases/v3.10.1/#api-changes","title":"API changes","text":"

    No documented API changes.

    "},{"location":"home/releases/v3.10.2/","title":"v3.10.2","text":"

    Released on 2021-08-26.

    Re-release of 3.10.1, whose Git tag pointed at the wrong commit due to a bug in the release script. All changes are backward-compatible. Full release notes.

    "},{"location":"home/releases/v3.10.2/#api-changes","title":"API changes","text":"

    No documented API changes.

    "},{"location":"home/releases/v3.10.3/","title":"v3.10.3","text":"

    Released on 2021-10-08.

    Fixes more regressions from 3.10.0. All changes are backward-compatible.

    • Fixes extended-diagnostics assertions triggered by update and by inserting into arrays.
    • Supports custom allocators when writing binary formats into a std::vector, and allows conversion from types that only provide begin()/end().

    Full release notes.

    "},{"location":"home/releases/v3.10.3/#api-changes","title":"API changes","text":"

    No documented API changes.

    "},{"location":"home/releases/v3.10.4/","title":"v3.10.4","text":"

    Released on 2021-10-16.

    Fixes regressions introduced in 3.10.0. All changes are backward-compatible.

    • Fixes the std::filesystem::path conversion (which could trigger a stack overflow and broke compilation on Windows).
    • Fixes compilation for types with an explicit defaulted constructor and for code relying on the return values of std::find and std::remove.

    Full release notes.

    "},{"location":"home/releases/v3.10.4/#api-changes","title":"API changes","text":"

    No documented API changes.

    "},{"location":"home/releases/v3.10.5/","title":"v3.10.5","text":"

    Released on 2022-01-03.

    Bug-fix release. All changes are backward-compatible.

    • Guards the std::filesystem conversions behind compiler-support checks (JSON_HAS_FILESYSTEM), which can be set to 0 to disable them altogether.

    Full release notes.

    "},{"location":"home/releases/v3.10.5/#api-changes","title":"API changes","text":"

    Added (1 pages):

    • macros: JSON_HAS_FILESYSTEM / JSON_HAS_EXPERIMENTAL_FILESYSTEM

    Changed:

    • std::hash<nlohmann::basic_json>: Extended for arbitrary basic_json types in version 3.10.5.
    • std::swap<basic_json>: Extended for arbitrary basic_json types in version 3.10.5.
    • basic_json::update: Added merge_objects parameter in 3.10.5.
    "},{"location":"home/releases/v3.11.0/","title":"v3.11.0","text":"

    Released on 2022-08-01.

    One of the largest releases ever. All changes are backward-compatible.

    • Allows std::string_view as object keys in at, operator[], value, erase, find, contains, and count.
    • Adds the BJData binary format (the fifth supported format).
    • Improves C++20 support, including operator<=> and <ranges>-compatible iterators.
    • Adds a versioned, ABI-tagged inline namespace (NLOHMANN_JSON_NAMESPACE) and the option to move the UDLs out of the global namespace (JSON_USE_GLOBAL_UDLS).
    • Adds patch_inplace, default values for the conversion macros, and an option to disable enum serialization (JSON_DISABLE_ENUM_SERIALIZATION).

    This release introduced a UDL regression that was fixed in 3.11.1. Full release notes.

    "},{"location":"home/releases/v3.11.0/#api-changes","title":"API changes","text":"

    Added (14 pages):

    • basic_json: default_object_comparator_t, from_bjdata, operator<=>, patch_inplace, to_bjdata
    • json_pointer: string_t
    • macros: JSON_DISABLE_ENUM_SERIALIZATION, JSON_HAS_RANGES, JSON_HAS_THREE_WAY_COMPARISON, JSON_SKIP_LIBRARY_VERSION_CHECK, JSON_USE_GLOBAL_UDLS, JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON, NLOHMANN_JSON_NAMESPACE, NLOHMANN_JSON_NAMESPACE_BEGIN, NLOHMANN_JSON_NAMESPACE_END

    Changed:

    • operator\"\"_json: Moved to namespace nlohmann::literals::json_literals in 3.11.0.
    • operator\"\"_json_pointer: Moved to namespace nlohmann::literals::json_literals in 3.11.0.
    • operator<<(basic_json), nlohmann::operator<<(json_pointer): Overload 2 added.
    • ordered_map: Added key_compare member in version 3.11.0.
    • basic_json::at: Overload 3 added.
    • basic_json::contains: Overload 1 added.
    • basic_json::contains: Overload 2: Extended template KeyType to support comparable types in version 3.11.0.
    • basic_json::count: Overload 1 added.
    • basic_json::count: Overload 2: Changed to support comparable key types in version 3.11.0.
    • basic_json::erase: Overload 4 added.
    • basic_json::find: Overload 1 added.
    • basic_json::find: Overload 2: Changed to support comparable types in version 3.11.0.
    • basic_json::object_comparator_t: Changed to be conditionally defined as typename object_t::key_compare or default_object_comparator_t in version 3.11.0.
    • basic_json::operator[]: Overload 2: The T* key overloads forward to overload 3 since version 3.11.0.
    • basic_json::operator[]: Overload 3 added.
    • basic_json::operator==: Overload 1: Added C++20 member functions in version 3.11.0.
    • basic_json::operator==: Overload 2: Added C++20 member functions in version 3.11.0.
    • basic_json::operator>=: Overload 1: Conditionally removed since C++20 in version 3.11.0.
    • basic_json::operator>=: Overload 2: Conditionally removed since C++20 in version 3.11.0.
    • basic_json::operator>: Overload 1: Conditionally removed since C++20 in version 3.11.0.
    • basic_json::operator>: Overload 2: Conditionally removed since C++20 in version 3.11.0.
    • basic_json::operator<=: Overload 1: Conditionally removed since C++20 in version 3.11.0.
    • basic_json::operator<=: Overload 2: Conditionally removed since C++20 in version 3.11.0.
    • basic_json::operator<: Overload 1: Conditionally removed since C++20 in version 3.11.0.
    • basic_json::operator<: Overload 2: Conditionally removed since C++20 in version 3.11.0.
    • basic_json::operator!=: Overload 1: Added a C++20 member function in version 3.11.0.
    • basic_json::value: Overload 1: Changed parameter default_value type from const ValueType& to ValueType&& in version 3.11.0.
    • basic_json::value: Overload 2 added.
    • json_pointer::back: Changed return type to string_t in version 3.11.0.
    • json_pointer: Changed template parameter from basic_json to string type in version 3.11.0.
    • json_pointer::json_pointer: Changed type of s to string_t in version 3.11.0.
    • json_pointer::operator/: Overload 2: Changed type of token to string_t in version 3.11.0.
    • json_pointer::operator/=: Overload 2: Changed type of token to string_t in version 3.11.0.
    • json_pointer::operator string_t: Changed type to string_t and deprecated in version 3.11.0.
    • json_pointer::push_back: Changed type of token to string_t in version 3.11.0.
    • json_pointer::to_string: Changed return type to string_t in version 3.11.0.
    • JSON_DIAGNOSTICS: As of version 3.11.0, the definition is allowed to vary between translation units.
    • NLOHMANN_DEFINE_TYPE_INTRUSIVE, NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT, NLOHMANN_DEFINE_TYPE_INTRUSIVE_ONLY_SERIALIZE: Overload 2 added.
    • NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE, NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT, NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE: Overload 2 added.
    "},{"location":"home/releases/v3.11.1/","title":"v3.11.1","text":"

    Released on 2022-08-01.

    Fixes a regression from 3.11.0. All changes are backward-compatible.

    • Restores the global user-defined string literals operator\"\"_json and operator\"\"_json_pointer, which 3.11.0 had moved into a namespace by default.

    Full release notes.

    "},{"location":"home/releases/v3.11.1/#api-changes","title":"API changes","text":"

    No documented API changes.

    "},{"location":"home/releases/v3.11.2/","title":"v3.11.2","text":"

    Released on 2022-08-12.

    Fixes bugs found in 3.11.1 and restructures the namespace. All changes are backward-compatible.

    • Fixes the value function (broken for strings, size types, and nullptr in 3.11.0) and makes json_fwd.hpp self-contained.
    • Restores using json_pointer as a key in associative containers and comparing it with strings.
    • Restructures the inline namespace and allows disabling the version component, and avoids heap allocations in the BJData parser.

    Full release notes.

    "},{"location":"home/releases/v3.11.2/#api-changes","title":"API changes","text":"

    Added (2 pages):

    • json_pointer: operator<=>
    • macros: NLOHMANN_JSON_NAMESPACE_NO_VERSION

    Changed:

    • basic_json::value: Overload 2: Made ValueType the first template parameter in version 3.11.2.
    • json_pointer::operator==: Overload 1: Added C++20 member functions in version 3.11.2.
    • json_pointer::operator==: Overload 2: Added for backward compatibility and deprecated in version 3.11.2.
    • json_pointer::operator!=: Overload 2: Added for backward compatibility and deprecated in version 3.11.2.
    • NLOHMANN_JSON_NAMESPACE: Changed inline namespace name in version 3.11.2.
    • NLOHMANN_JSON_NAMESPACE_BEGIN, NLOHMANN_JSON_NAMESPACE_END: Changed inline namespace name in version 3.11.2.
    "},{"location":"home/releases/v3.11.3/","title":"v3.11.3","text":"

    Released on 2023-11-28.

    Adds features and fixes bugs found in 3.11.2. All changes are backward-compatible.

    • Adds a custom base class as a node customization point.
    • Adds serialization-only conversion macros (NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE and NLOHMANN_DEFINE_TYPE_INTRUSIVE_ONLY_SERIALIZE) and a clearer parse error for empty input.
    • Adds Bazel and Swift Package Manager build support.
    • Fixes custom allocators, a memory leak in adl_serializer's to_json, initializer-list construction when size_type is not int, and many compiler warnings.

    Full release notes.

    "},{"location":"home/releases/v3.11.3/#api-changes","title":"API changes","text":"

    Added (2 pages):

    • basic_json: json_base_class_t
    • macros: JSON_HAS_STATIC_RTTI

    Changed:

    • NLOHMANN_DEFINE_TYPE_INTRUSIVE, NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT, NLOHMANN_DEFINE_TYPE_INTRUSIVE_ONLY_SERIALIZE: Overload 3 added.
    • NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE, NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT, NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE: Overload 3 added.
    "},{"location":"home/releases/v3.12.0/","title":"v3.12.0","text":"

    Released on 2025-04-11.

    Fixes bugs found in 3.11.3 and adds several features. No public API was removed or renamed.

    • Adds diagnostic byte positions via JSON_DIAGNOSTIC_POSITIONS, exposed through the new start_pos and end_pos member functions.
    • Makes the conversion macros templated (so they also work with ordered_json) and adds NLOHMANN_DEFINE_DERIVED_TYPE for derived classes.
    • Adds std::optional support (C++17) and lets patch, diff, and flatten work with arbitrary string types.
    • Extends the binary formats: BJData draft 3 and unsigned 64-bit integers for BSON.
    • Adds multidimensional C-array conversion and UTF-8 encoded std::filesystem::path conversions, and raises the minimum CMake version to 3.5 and supports CMake 4.0.

    Full release notes.

    "},{"location":"home/releases/v3.12.0/#api-changes","title":"API changes","text":"

    Added (5 pages):

    • basic_json: bjdata_version_t, end_pos, start_pos
    • macros: JSON_DIAGNOSTIC_POSITIONS, nlohmann_define_derived_type

    Changed:

    • basic_json::accept: Changed runtime assertion in case of FILE* null pointers to exception in version 3.12.0.
    • basic_json::parse: Changed runtime assertion in case of FILE* null pointers to exception in version 3.12.0.
    • basic_json::to_bjdata: BJData version parameter (for draft3 binary encoding) added in version 3.12.0.
    • JSON_HAS_CPP_11, JSON_HAS_CPP_14, JSON_HAS_CPP_17, JSON_HAS_CPP_20, JSON_HAS_CPP_23, JSON_HAS_CPP_26: Added JSON_HAS_CPP_23 in version 3.12.0.
    • NLOHMANN_JSON_NAMESPACE: Added the ABI tag _dp in version 3.12.0, and the ABI tags _bics, _psp, _snul, _sbu8, _ekmo, _dsbs, _dufio, and _ns in version 3.13.0 unreleased; see nlohmann Namespace.
    "},{"location":"home/releases/v3.2.0/","title":"v3.2.0","text":"

    Released on 2018-08-20.

    Feature release. All changes are backward-compatible.

    • Adds a SAX interface and a non-recursive parser.
    • Adds parsing from wide-string types (std::wstring, std::u16string, std::u32string), conversion to std::string_view (C++17), and round-tripping of std::map/std::unordered_map with non-string keys.

    Full release notes.

    "},{"location":"home/releases/v3.2.0/#api-changes","title":"API changes","text":"

    Added (16 pages):

    • basic_json: input_format_t, sax_parse
    • json_sax: (overview), boolean, end_array, end_object, key, null, number_float, number_integer, number_unsigned, parse_error, start_array, start_object, string
    • macros: JSON_SKIP_UNSUPPORTED_COMPILER_CHECK

    Changed:

    • basic_json::from_cbor: Added allow_exceptions parameter in version 3.2.0.
    • basic_json::from_msgpack: Added allow_exceptions parameter in version 3.2.0.
    • basic_json::from_ubjson: Added allow_exceptions parameter in version 3.2.0.
    "},{"location":"home/releases/v3.3.0/","title":"v3.3.0","text":"

    Released on 2018-10-05.

    Feature release. All changes are backward-compatible.

    • Adds GCC 4.8 support, the get_to function, and an overhauled and documented CMake integration.

    Full release notes.

    "},{"location":"home/releases/v3.3.0/#api-changes","title":"API changes","text":"

    Added (1 pages):

    • basic_json: get_to
    "},{"location":"home/releases/v3.4.0/","title":"v3.4.0","text":"

    Released on 2018-10-30.

    Feature release. All changes are backward-compatible.

    • Adds BSON read/write support.
    • Adds configurable Unicode error handlers to dump (throw, replace with U+FFFD, or ignore) and the NLOHMANN_JSON_SERIALIZE_ENUM macro for enum conversion.
    • Improves parse-error messages with line/column positions and context.

    Full release notes.

    "},{"location":"home/releases/v3.4.0/#api-changes","title":"API changes","text":"

    Added (3 pages):

    • basic_json: error_handler_t, from_bson, to_bson

    Changed:

    • basic_json::dump: Error handlers added in version 3.4.0.
    "},{"location":"home/releases/v3.5.0/","title":"v3.5.0","text":"

    Released on 2018-12-22.

    Feature release. All changes are backward-compatible.

    • Adds structured-binding support via the items function and reading from FILE* in the parse function.
    • Fixes the eofbit handling on input streams and a bug in the BSON SAX parser.

    Full release notes.

    "},{"location":"home/releases/v3.5.0/#api-changes","title":"API changes","text":"

    Changed:

    • basic_json::items: Added structured binding support in version 3.5.0.
    "},{"location":"home/releases/v3.6.0/","title":"v3.6.0","text":"

    Released on 2019-03-20.

    Feature release. All changes are backward-compatible.

    • Reworks the JSON pointer interface (operator/, push_back, parent_pointer, \u2026).
    • Adds a contains function to test for an object key and greatly improves the performance of integer serialization.

    Full release notes.

    "},{"location":"home/releases/v3.6.0/#api-changes","title":"API changes","text":"

    Added (5 pages):

    • basic_json: contains
    • json_pointer: back, operator/, operator/=, push_back
    "},{"location":"home/releases/v3.6.1/","title":"v3.6.1","text":"

    Released on 2019-03-20.

    Fixes a regression (GCC 7/8 compilation) and a <Windows.h> build error introduced in 3.6.0. All changes are backward-compatible. Full release notes.

    "},{"location":"home/releases/v3.6.1/#api-changes","title":"API changes","text":"

    No documented API changes.

    "},{"location":"home/releases/v3.7.0/","title":"v3.7.0","text":"

    Released on 2019-07-28.

    Convenience features and house-keeping. All changes are backward-compatible.

    • Adds a contains overload that checks a JSON pointer without throwing, a generic to_string, and a return value for emplace_back.

    Full release notes.

    "},{"location":"home/releases/v3.7.0/#api-changes","title":"API changes","text":"

    Changed:

    • basic_json::contains: Overload 3 added.
    • basic_json::emplace_back: Returns reference since 3.7.0.
    "},{"location":"home/releases/v3.7.1/","title":"v3.7.1","text":"

    Released on 2019-11-06.

    Bug-fix release. All changes are backward-compatible.

    • Fixes a segmentation fault when serializing the std::int64_t minimum value and fixes contains for JSON pointers.
    • Allows items with a custom string type and makes json_pointer::back const.

    Full release notes.

    "},{"location":"home/releases/v3.7.1/#api-changes","title":"API changes","text":"

    No documented API changes.

    "},{"location":"home/releases/v3.7.2/","title":"v3.7.2","text":"

    Released on 2019-11-10.

    Fixes a stack overflow for deeply nested input by making the destructor iterative; parsing of JSON text is now bounded only by available memory (the binary-format parsers still recurse). All changes are backward-compatible. Full release notes.

    "},{"location":"home/releases/v3.7.2/#api-changes","title":"API changes","text":"

    No documented API changes.

    "},{"location":"home/releases/v3.7.3/","title":"v3.7.3","text":"

    Released on 2019-11-17.

    Fixes a regression from 3.7.2 that could yield quadratic complexity in destructor calls. All changes are backward-compatible. Full release notes.

    "},{"location":"home/releases/v3.7.3/#api-changes","title":"API changes","text":"

    No documented API changes.

    "},{"location":"home/releases/v3.8.0/","title":"v3.8.0","text":"

    Released on 2020-06-14.

    Feature release. All changes are backward-compatible.

    • Introduces a binary value type that is read from and written to CBOR, BSON, and MessagePack, and can be shared between formats.
    • Generalizes the input adapters to read from any LegacyInputIterator container (3\u201310 % faster parsing).
    • Fixes contains for JSON pointers and makes the binary from_cbor/from_msgpack/etc. functions respect allow_exceptions.

    Full release notes.

    "},{"location":"home/releases/v3.8.0/#api-changes","title":"API changes","text":"

    Added (9 pages):

    • basic_json: binary, binary_t, get_binary, is_binary
    • byte_container_with_subtype: (overview), operator==, operator!=, subtype
    • json_sax: binary

    Changed:

    • basic_json::back: Binary values are supported since version 3.8.0.
    • basic_json::clear: Added support for binary types in version 3.8.0.
    • basic_json::dump: Serialization of binary values added in version 3.8.0.
    • basic_json::empty: Extended to return false for binary types in version 3.8.0.
    • basic_json::erase: Overload 1: Added support for binary types in version 3.8.0.
    • basic_json::erase: Overload 2: Added support for binary types in version 3.8.0.
    • basic_json::front: Binary values are supported since version 3.8.0.
    • basic_json::get_ptr: Extended to binary types in version 3.8.0.
    • basic_json::get_ref: Extended to binary types in version 3.8.0.
    • basic_json::is_primitive: Extended to return true for binary types in version 3.8.0.
    • basic_json::max_size: Extended to return 1 for binary types in version 3.8.0.
    • basic_json::operator value_t: Added binary type in version 3.8.0.
    • basic_json::size: Extended to return 1 for binary types in version 3.8.0.
    • basic_json::swap: Overload 6 added.
    • basic_json::swap: Overload 7 added.
    • basic_json::to_cbor: Compact representation of floating-point numbers added in version 3.8.0.
    • basic_json::type: Added binary type in version 3.8.0.
    • basic_json::type_name: Added support for binary type in version 3.8.0.
    • basic_json::value_t: Added binary type in version 3.8.0.
    • json_sax: Support for binary values (binary_t, binary) added in version 3.8.0.
    "},{"location":"home/releases/v3.9.0/","title":"v3.9.0","text":"

    Released on 2020-07-27.

    Feature release adding four long-requested features. All changes are backward-compatible.

    • Optional comment parsing in parse via the ignore_comments parameter.
    • ordered_json to preserve the insertion order of object keys.
    • An option to switch off implicit conversions.
    • The NLOHMANN_DEFINE_TYPE_* convenience macros, plus high-precision-number support for UBJSON and CBOR tag handling.

    Full release notes.

    "},{"location":"home/releases/v3.9.0/#api-changes","title":"API changes","text":"

    Added (6 pages):

    • ordered_map
    • basic_json: cbor_tag_handler_t
    • macros: JSON_ASSERT, JSON_USE_IMPLICIT_CONVERSIONS, NLOHMANN_DEFINE_TYPE_INTRUSIVE, NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT, NLOHMANN_DEFINE_TYPE_INTRUSIVE_ONLY_SERIALIZE, NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE, NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT, NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE

    Changed:

    • basic_json::accept: Ignoring comments via ignore_comments added in version 3.9.0.
    • basic_json::from_cbor: Added tag_handler parameter in version 3.9.0.
    • basic_json::operator ValueType: Macros JSON_EXPLICIT/JSON_USE_IMPLICIT_CONVERSIONS added in version 3.9.0.
    • basic_json::parse: Ignoring comments via ignore_comments added in version 3.9.0.
    • basic_json::sax_parse: Ignoring comments via ignore_comments added in version 3.9.0.
    "},{"location":"home/releases/v3.9.1/","title":"v3.9.1","text":"

    Released on 2020-08-06.

    Fixes two regressions from 3.9.0. All changes are backward-compatible.

    • Accepts consecutive comments and completes the ordered_json interface (e.g. ordered_json::parse).

    Full release notes.

    "},{"location":"home/releases/v3.9.1/#api-changes","title":"API changes","text":"

    No documented API changes.

    "},{"location":"integration/","title":"Integration","text":"

    There are several ways to add this header-only library to a C++ project. The following flowchart summarizes how to pick one:

    flowchart TD\n    A[Add the library to a C++ project] --> B{{Using CMake?}}\n    B -- no --> C{{Package manager available?}}\n    C -- yes --> D[\"<b>Use a package manager</b><br>see Package Managers\"]\n    C -- no --> E[\"<b>Copy the single header</b><br>see Header only\"]\n    B -- yes --> F{{Already installed?}}\n    F -- yes --> G[\"<b>find_package</b><br>see CMake, External\"]\n    F -- no --> H{{CMake 3.14 or later?}}\n    H -- yes --> I[\"<b>FetchContent</b><br>see CMake, FetchContent\"]\n    H -- no --> J[\"<b>add_subdirectory</b><br>see CMake, Embedded\"]\n    G --> T[\"<code>nlohmann_json::nlohmann_json</code>\"]\n    I --> T\n    J --> T

    Choosing an integration method: answer the questions in the hexagons from top to bottom to reach a method. All CMake methods end at the same target, nlohmann_json::nlohmann_json; the list below links to each method.

    • Single header: copy json.hpp into your project; no build-system integration required.
    • CMake, see CMake:
      • find_package() if the library is already installed;
      • FetchContent to download it at configure time (CMake 3.14 or later);
      • add_subdirectory() to embed a vendored copy of the source tree;
      • or support both with an option that selects installed or vendored.
    • Package managers: install the library with Homebrew, Conan, vcpkg, or one of the many others; see Package Managers for the full list.
    • pkg-config: if you use bare Makefiles instead of CMake, pkg-config supplies the include flags for an already-installed library.

    Once the library is integrated, see the Migration Guide for how to keep your code future-proof across releases.

    "},{"location":"integration/#header-only","title":"Header only","text":"

    json.hpp is the single required file in single_include/nlohmann or released here. You need to add

    #include <nlohmann/json.hpp>\n\n// for convenience\nusing nlohmann::json;\n

    to the files you want to process JSON and set the necessary switches to enable C++11 (e.g., -std=c++11 for GCC and Clang).

    Which file do I download?

    For a project without a package manager, the library itself, including the _json literals, is one file: json.hpp from the releases page. You do not need to clone the repository, build anything, or link a library. Put the file in a directory named nlohmann that is on your include path (for example third_party/nlohmann/json.hpp with -I third_party), so that #include <nlohmann/json.hpp> works. Download the companion headers listed below only if you use them: json_view.hpp for the zero-copy views, json_fwd.hpp for forward declarations, and json_literals.hpp if you define JSON_NO_AUTOMATIC_UDLS. Keep them in the same nlohmann directory.

    Do not copy only parts of the repository's include/ directory: the headers in it include each other and must be kept together. If your IDE reports \"cannot open source file\" while the compiler succeeds, the compiler's include path is set correctly but the IDE's is not; add the same directory to the IDE's include paths.

    You can further use file single_include/nlohmann/json_fwd.hpp for forward declarations (see Compile times), and file single_include/nlohmann/json_literals.hpp for the user-defined string literals if you define JSON_NO_AUTOMATIC_UDLS.

    For the read-only, non-owning basic_json_document/basic_json_view types, additionally include single_include/nlohmann/json_view.hpp; see Zero-copy JSON views.

    "},{"location":"integration/#notes-for-builds-and-distribution","title":"Notes for builds and distribution","text":"

    Reproducible and path-independent builds. The runtime assertions use assert, which embeds the name of the source file (__FILE__) in the binary. Release builds do not contain them, because they define NDEBUG. If you compile with assertions enabled and need binaries that do not depend on the build directory, either define NDEBUG or map the prefix of the path with the compiler option -ffile-prefix-map=<old>=<new> (GCC 8 and later, Clang 10 and later). See Runtime assertions.

    There is no separate source file to compile. The library is header-only, so there is no .cpp that could be built with different options than the code that includes it. It is also not available as a precompiled library. To compile the library with optimizations in an otherwise unoptimized build (for example to parse large files in a debug build, which is slow because of the unoptimized code and the checks of the debug standard library), keep the code that uses json in a separate source file and set the options for that file only. Compile times shows how to instantiate basic_json once.

    Debugger visualization. The Natvis file works with the Visual Studio debugger, including the cppvsdbg engine in Visual Studio Code, but not with debuggers that wrap LLDB, such as codelldb; see Debugging.

    "},{"location":"integration/#see-also","title":"See also","text":"
    • CMake - integrate the library into a CMake project
    • Package managers - install the library with a package manager
    • pkg-config - generate include flags for plain Makefiles
    • Compile times - reduce the compile time overhead
    • Migration guide - upgrade from an earlier version
    • Releases - release notes of all versions
    • basic_json - the main class and all its member functions
    • Macros - reference of all macros
    • Supported Macros - configure the library with macros
    • Modules - C++20 module support
    • NLOHMANN_JSON_VERSION_MAJOR - library version macros
    "},{"location":"integration/cmake/","title":"CMake","text":""},{"location":"integration/cmake/#integration","title":"Integration","text":"

    You can use the nlohmann_json::nlohmann_json interface target in CMake. This target populates the appropriate usage requirements for INTERFACE_INCLUDE_DIRECTORIES to point to the appropriate include directories and INTERFACE_COMPILE_FEATURES for the necessary C++11 flags. Most package managers that provide a CMake package configuration for this library expose this same target.

    All ways of adding the library described below end at this one target:

    flowchart LR\n    FP[\"<b>find_package()</b><br>installed package\"] --> T\n    AS[\"<b>add_subdirectory()</b><br>embedded source tree\"] --> T\n    FC[\"<b>FetchContent</b><br>downloaded at configure time\"] --> T\n    PM[\"<b>Package manager</b><br>its CMake package\"] --> T\n    T[\"<b>nlohmann_json::nlohmann_json</b><br>one INTERFACE target\"] --> L[\"<b>target_link_libraries()</b><br>link it PRIVATE\"]

    The four ways to add the library in CMake all lead to the same nlohmann_json::nlohmann_json interface target, which a project links with target_link_libraries. The CMake options below apply to add_subdirectory() and FetchContent; installed packages have their options fixed at install time.

    "},{"location":"integration/cmake/#external","title":"External","text":"

    To use this library from a CMake project, you can locate it directly with find_package() and use the namespaced imported target from the generated package configuration:

    Example

    CMakeLists.txt
    cmake_minimum_required(VERSION 3.5)\nproject(ExampleProject LANGUAGES CXX)\n\nfind_package(nlohmann_json 3.12.0 REQUIRED)\n\nadd_executable(example example.cpp)\ntarget_link_libraries(example PRIVATE nlohmann_json::nlohmann_json)\n

    The package configuration file, nlohmann_jsonConfig.cmake, can be used either from an install tree or directly out of the build tree.

    "},{"location":"integration/cmake/#embedded","title":"Embedded","text":"

    To embed the library directly into an existing CMake project, place the entire source tree in a subdirectory and call add_subdirectory() in your CMakeLists.txt file.

    Example

    CMakeLists.txt
    cmake_minimum_required(VERSION 3.5)\nproject(ExampleProject LANGUAGES CXX)\n\n# If you only include this third party in PRIVATE source files, you do not need to install it\n# when your main project gets installed.\nset(JSON_Install OFF CACHE INTERNAL \"\")\n\nadd_subdirectory(nlohmann_json)\n\nadd_executable(example example.cpp)\ntarget_link_libraries(example PRIVATE nlohmann_json::nlohmann_json)\n

    Note

    Do not use include(nlohmann_json/CMakeLists.txt), since that carries with it unintended consequences that will break the build. It is generally discouraged (although not necessarily well documented as such) to use include(...) for pulling in other CMake projects anyways.

    "},{"location":"integration/cmake/#supporting-both","title":"Supporting Both","text":"

    To allow your project to support either an externally supplied or an embedded JSON library, you can use a pattern akin to the following.

    Example

    CMakeLists.txt
    project(ExampleProject LANGUAGES CXX)\n\noption(EXAMPLE_USE_EXTERNAL_JSON \"Use an external JSON library\" OFF)\n\nadd_subdirectory(thirdparty)\n\nadd_executable(example example.cpp)\n\n# Note that the namespaced target will always be available regardless of the import method\ntarget_link_libraries(example PRIVATE nlohmann_json::nlohmann_json)\n
    thirdparty/CMakeLists.txt
    if(EXAMPLE_USE_EXTERNAL_JSON)\n    find_package(nlohmann_json 3.12.0 REQUIRED)\nelse()\n    set(JSON_BuildTests OFF CACHE INTERNAL \"\")\n    add_subdirectory(nlohmann_json)\nendif()\n

    thirdparty/nlohmann_json is then a complete copy of this source tree.

    "},{"location":"integration/cmake/#fetchcontent","title":"FetchContent","text":"

    Since CMake v3.14, FetchContent can be used to automatically download a release as a dependency at configure time.

    Example

    CMakeLists.txt
    cmake_minimum_required(VERSION 3.14)\nproject(ExampleProject LANGUAGES CXX)\n\ninclude(FetchContent)\n\nFetchContent_Declare(json URL https://github.com/nlohmann/json/releases/download/v3.12.0/json.tar.xz)\nFetchContent_MakeAvailable(json)\n\nadd_executable(example example.cpp)\ntarget_link_libraries(example PRIVATE nlohmann_json::nlohmann_json)\n

    Note

    It is recommended to use the URL approach described above which is supported as of version 3.10.0. It is also possible to pass the Git repository like

    FetchContent_Declare(json\n    GIT_REPOSITORY https://github.com/nlohmann/json\n    GIT_TAG v3.12.0\n)\n

    However, the repository https://github.com/nlohmann/json download size is quite large.

    "},{"location":"integration/cmake/#cmake-options","title":"CMake Options","text":""},{"location":"integration/cmake/#json_buildtests","title":"JSON_BuildTests","text":"

    Build the unit tests when BUILD_TESTING is enabled. This option is ON by default if the library's CMake project is the top project and the tests directory exists (the release archive json.tar.xz does not contain it). That is, when integrating the library as described above, the test suite is not built unless explicitly switched on with this option.

    "},{"location":"integration/cmake/#json_ci","title":"JSON_CI","text":"

    Enable CI build targets. The exact targets are used during the several CI steps and are subject to change without notice. This option is OFF by default.

    "},{"location":"integration/cmake/#json_deletedeprecatedfunctions","title":"JSON_DeleteDeprecatedFunctions","text":"

    Delete the deprecated functions instead of only deprecating them by defining the macro JSON_DELETE_DEPRECATED_FUNCTIONS. This option is OFF by default.

    "},{"location":"integration/cmake/#json_diagnostics","title":"JSON_Diagnostics","text":"

    Enable extended diagnostic messages by defining macro JSON_DIAGNOSTICS. This option is OFF by default.

    Does not apply to a pre-installed package

    This option only takes effect when building nlohmann/json from source as part of your own CMake project (e.g. via FetchContent or add_subdirectory). It has no effect on a package that was already built and installed elsewhere (Homebrew, vcpkg, a system package, etc.) \u2014 the resulting compile definition is baked into the exported nlohmann_jsonTargets.cmake at install time, and set(JSON_Diagnostics ON) before find_package() does not change it (verified against the Homebrew-installed package: the exported target still carries a fixed $<$<BOOL:OFF>:JSON_DIAGNOSTICS=1>, regardless of any variable set in the consuming project).

    To enable extended diagnostics for a pre-installed package, override the imported target's property directly after find_package():

    find_package(nlohmann_json REQUIRED)\nset_target_properties(nlohmann_json::nlohmann_json PROPERTIES\n    INTERFACE_COMPILE_DEFINITIONS \"JSON_DIAGNOSTICS=1\")\n

    This only works cleanly when your project is the sole consumer of that imported target. If nlohmann_json is pulled in from more than one place in your dependency graph with different JSON_DIAGNOSTICS values, you may see a \"JSON_DIAGNOSTICS\" redefined compiler error, since conflicting -D flags can end up on the same compile command line.

    "},{"location":"integration/cmake/#json_diagnostic_positions","title":"JSON_Diagnostic_Positions","text":"

    Enable position diagnostics by defining macro JSON_DIAGNOSTIC_POSITIONS. This option is OFF by default.

    "},{"location":"integration/cmake/#json_disableenumserialization","title":"JSON_DisableEnumSerialization","text":"

    Disable default enum serialization by defining the macro JSON_DISABLE_ENUM_SERIALIZATION. This option is OFF by default.

    "},{"location":"integration/cmake/#json_disabletuplereferenceconversion","title":"JSON_DisableTupleReferenceConversion","text":"

    Disable the conversion from a one-element std::tuple holding a reference to a JSON value by defining the macro JSON_DISABLE_TUPLE_REFERENCE_CONVERSION. This option is OFF by default.

    "},{"location":"integration/cmake/#json_fasttests","title":"JSON_FastTests","text":"

    Skip expensive/slow test suites. This option is OFF by default. Depends on JSON_BuildTests.

    "},{"location":"integration/cmake/#json_globaludls","title":"JSON_GlobalUDLs","text":"

    Place user-defined string literals in the global namespace by defining the macro JSON_USE_GLOBAL_UDLS. This option is ON by default; see the migration guide for how to prepare code for the next major release, where the literals are removed from the global namespace.

    "},{"location":"integration/cmake/#json_implicitconversions","title":"JSON_ImplicitConversions","text":"

    Enable implicit conversions by defining macro JSON_USE_IMPLICIT_CONVERSIONS. This option is ON by default; see the migration guide for how to prepare code for the next major release, where implicit conversions are switched off by default.

    "},{"location":"integration/cmake/#json_install","title":"JSON_Install","text":"

    Install CMake targets during install step. This option is ON by default if the library's CMake project is the top project. Installing also generates a pkg-config file for tools that rely on pkg-config instead of CMake.

    "},{"location":"integration/cmake/#json_legacydiscardedvaluecomparison","title":"JSON_LegacyDiscardedValueComparison","text":"

    Enable the (incorrect) legacy comparison behavior of discarded JSON values by defining macro JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON. This option is OFF by default.

    "},{"location":"integration/cmake/#json_multipleheaders","title":"JSON_MultipleHeaders","text":"

    Use the non-amalgamated version of the library. This option is ON by default.

    "},{"location":"integration/cmake/#json_systeminclude","title":"JSON_SystemInclude","text":"

    Treat the library headers like system headers (i.e., adding SYSTEM to the target_include_directories call) to check for this library by tools like Clang-Tidy. This option is OFF by default.

    "},{"location":"integration/cmake/#json_strictbinaryutf8","title":"JSON_StrictBinaryUTF8","text":"

    Check string values and object keys for valid UTF-8 in the CBOR, UBJSON, BJData, and BSON writers, by defining the macro JSON_STRICT_BINARY_UTF8. This option is OFF by default.

    "},{"location":"integration/cmake/#json_strictnulhandling","title":"JSON_StrictNulHandling","text":"

    Reject a '\\0' (NUL) byte in the input instead of treating it as end of input, by defining the macro JSON_STRICT_NUL_HANDLING. This option is OFF by default.

    "},{"location":"integration/cmake/#json_testsimdutf","title":"JSON_TestSimdutf","text":"

    Build the unit tests against the simdutf UTF-8 validation backend by defining JSON_USE_SIMDUTF for every test target. simdutf is fetched during configuration; its version is set by the cache variable JSON_SIMDUTF_VERSION. This option is OFF by default. Depends on JSON_BuildTests.

    "},{"location":"integration/cmake/#json_valgrind","title":"JSON_Valgrind","text":"

    Execute the test suite with Valgrind. This option is OFF by default. Depends on JSON_BuildTests.

    "},{"location":"integration/cmake/#nlohmann_json_build_modules","title":"NLOHMANN_JSON_BUILD_MODULES","text":"

    Build the experimental C++ module nlohmann.json (requires CMake 3.28 or later and C++20). This option is OFF by default.

    A consuming project must link the dedicated nlohmann_json_modules CMake target (not just nlohmann_json::nlohmann_json) for import nlohmann.json; to resolve:

    set(NLOHMANN_JSON_BUILD_MODULES ON)\nadd_subdirectory(path/to/json)\n\nadd_executable(myproject main.cpp)\ntarget_link_libraries(myproject PRIVATE nlohmann_json_modules)\ntarget_compile_definitions(myproject PRIVATE NLOHMANN_JSON_BUILD_MODULES)\n
    "},{"location":"integration/cmake/#see-also","title":"See also","text":"
    • Macros - reference of all macros
    • Supported Macros - the macros that the CMake options set
    • Modules - C++20 module support
    • nlohmann Namespace - namespace options set by CMake
    "},{"location":"integration/compile_times/","title":"Compile times","text":"

    The library is header-only and makes heavy use of templates, so every translation unit that includes <nlohmann/json.hpp> pays for parsing the header and instantiating what it uses. This page lists the options to reduce that cost, ordered by how much they typically save.

    Measurements

    The numbers below are medians of the wall-clock time of nine runs compiling a single translation unit with -std=c++17 -c against the single-header version, with Apple clang 21.0.0 (clang-2100.3.34.2) and Homebrew GCC 16.2.0 on macOS (Apple M1 Max). All configurations were run interleaved, in alternating order. They show the order of magnitude to expect; measure your own code before and after a change.

    The translation units are listed below. They replace the ones used for earlier versions of this page, whose sources were not published, so the numbers differ from earlier versions.

    Measured translation units

    The model and parsing translation units start with #include <string>, #include <vector>, and #include <nlohmann/json.hpp>; the header-only translation unit includes only the library header.

    model translation unit
    struct person\n{\n    std::string name;\n    int age = 0;\n    std::vector<std::string> tags;\n};\n\nvoid to_json(nlohmann::json& j, const person& p)\n{\n    j = nlohmann::json{{\"name\", p.name}, {\"age\", p.age}, {\"tags\", p.tags}};\n}\n\nvoid from_json(const nlohmann::json& j, person& p)\n{\n    j.at(\"name\").get_to(p.name);\n    j.at(\"age\").get_to(p.age);\n    j.at(\"tags\").get_to(p.tags);\n}\n\nnlohmann::json roundtrip(const person& p)\n{\n    nlohmann::json j = p;\n    return nlohmann::json(j.get<person>());\n}\n
    parsing translation unit
    std::size_t parse_and_dump(const std::string& s)\n{\n    const nlohmann::json j = nlohmann::json::parse(s);\n    return j.dump(2).size();\n}\n
    header-only translation unit
    #include <nlohmann/json.hpp> // or <nlohmann/json_fwd.hpp>\n\nstruct person;\nvoid to_json(nlohmann::json& j, const person& p);\nvoid from_json(const nlohmann::json& j, person& p);\n

    Change in compile time against the default configuration at -O0, Apple clang and G\u200bCC 16 Grouped horizontal bars, negative is faster. json_fwd.hpp instead of json.hpp on a header-only translation unit: Apple clang -62 %, G\u200bCC 16 -82 %; extern template on a parsing translation unit: Apple clang -7 %, G\u200bCC 16 -21 %; JSON_NO_AUTOMATIC_UDLS on a model translation unit: Apple clang -11 %, G\u200bCC 16 -11 %; JSON_NO_AUTOMATIC_UDLS on a parsing translation unit: Apple clang -1 %, G\u200bCC 16 -2 %; JSON_HAS_FILESYSTEM=0 + JSON_NO_IO on a model translation unit: Apple clang -8 %, G\u200bCC 16 -11 %; JSON_HAS_FILESYSTEM=0 on a model translation unit: Apple clang -5 %, G\u200bCC 16 -9 %; JSON_NO_IO on a model translation unit: Apple clang -2 %, G\u200bCC 16 -2 %; JSON_USE_GLOBAL_UDLS=0 on a model translation unit: Apple clang 0 %, G\u200bCC 16 -1 %. Apple clang G\u200bCC 16 \u221280 % \u221260 % \u221240 % \u221220 % 0 % \u2190 faster slower \u2192 json_fwd.hpp instead of json.hpp \u00b7 header-only TU json_fwd.hpp instead of json.hpp, header-only TU (Apple clang): \u221262 % \u221262 % json_fwd.hpp instead of json.hpp, header-only TU (G\u200bCC 16): \u221282 % \u221282 % extern template \u00b7 parsing TU extern template, parsing TU (Apple clang): \u22127 % \u22127 % extern template, parsing TU (G\u200bCC 16): \u221221 % \u221221 % JSON_NO_AUTOMATIC_UDLS \u00b7 model TU JSON_NO_AUTOMATIC_UDLS, model TU (Apple clang): \u221211 % \u221211 % JSON_NO_AUTOMATIC_UDLS, model TU (G\u200bCC 16): \u221211 % \u221211 % JSON_NO_AUTOMATIC_UDLS \u00b7 parsing TU JSON_NO_AUTOMATIC_UDLS, parsing TU (Apple clang): \u22121 % \u22121 % JSON_NO_AUTOMATIC_UDLS, parsing TU (G\u200bCC 16): \u22122 % \u22122 % JSON_HAS_FILESYSTEM=0 + JSON_NO_IO \u00b7 model TU JSON_HAS_FILESYSTEM=0 + JSON_NO_IO, model TU (Apple clang): \u22128 % \u22128 % JSON_HAS_FILESYSTEM=0 + JSON_NO_IO, model TU (G\u200bCC 16): \u221211 % \u221211 % JSON_HAS_FILESYSTEM=0 \u00b7 model TU JSON_HAS_FILESYSTEM=0, model TU (Apple clang): \u22125 % \u22125 % JSON_HAS_FILESYSTEM=0, model TU (G\u200bCC 16): \u22129 % \u22129 % JSON_NO_IO \u00b7 model TU* JSON_NO_IO, model TU (Apple clang): \u22122 % \u22122 % JSON_NO_IO, model TU (G\u200bCC 16): \u22122 % \u22122 % JSON_USE_GLOBAL_UDLS=0 \u00b7 model TU* JSON_USE_GLOBAL_UDLS=0, model TU (Apple clang): 0 % 0 % JSON_USE_GLOBAL_UDLS=0, model TU (G\u200bCC 16): \u22121 % \u22121 %

    Change in compile time at -O0 against the default configuration of the same translation unit, taken from the tables below (medians of nine runs, see above). * computed from the milliseconds in Options without effect on compile times.

    "},{"location":"integration/compile_times/#include-json_fwdhpp-in-headers","title":"Include json_fwd.hpp in headers","text":"

    Header files that only need to name the json type \u2014 for function declarations, members held by pointer or reference, or friend declarations \u2014 can include <nlohmann/json_fwd.hpp> instead of <nlohmann/json.hpp>. It only forward-declares basic_json, json_pointer, adl_serializer, and ordered_map, and defines the aliases json and ordered_json. The translation units that actually use the values then include <nlohmann/json.hpp>.

    person.hpp
    #pragma once\n#include <nlohmann/json_fwd.hpp>\n\nstruct person;\nvoid to_json(nlohmann::json& j, const person& p);\nvoid from_json(const nlohmann::json& j, person& p);\n
    person.cpp
    #include \"person.hpp\"\n#include <nlohmann/json.hpp>\n\nvoid to_json(nlohmann::json& j, const person& p) { /* ... */ }\nvoid from_json(const nlohmann::json& j, person& p) { /* ... */ }\n
    Compiler json.hpp (-O0) json_fwd.hpp (-O0) Change Apple clang 868 ms 332 ms \u221262% GCC 16 1164 ms 210 ms \u221282%

    Compile time of the header-only translation unit at -O0 with each header, as the median wall-clock time of nine runs (see \"Measurements\" above). A negative change means a faster build.

    This is the most effective option, because it avoids the full header in every translation unit that includes your headers.

    "},{"location":"integration/compile_times/#opt-out-of-the-automatic-user-defined-string-literals","title":"Opt out of the automatic user-defined string literals","text":"

    The user-defined string literals operator\"\"_json and operator\"\"_json_pointer are ordinary inline functions whose bodies call the parser. As <nlohmann/json.hpp> includes them by default, every translation unit instantiates the parser, even if it never parses anything itself.

    Define JSON_NO_AUTOMATIC_UDLS for the whole project and include <nlohmann/json_literals.hpp> instead of <nlohmann/json.hpp> in the files that use the literals (it includes <nlohmann/json.hpp> itself):

    target_compile_definitions(my_target PRIVATE JSON_NO_AUTOMATIC_UDLS)\n
    #include <nlohmann/json_literals.hpp> // only where \"...\"_json is used; includes <nlohmann/json.hpp>\n

    The saving applies to translation units that do not parse JSON, for example ones that define types and their conversions or only pass json values around:

    Compiler Translation unit Default (-O0 / -O2) JSON_NO_AUTOMATIC_UDLS (-O0 / -O2) Change Apple clang model 1051 ms / 1300 ms 935 ms / 1170 ms \u221211% / \u221210% GCC 16 model 1801 ms / 2106 ms 1598 ms / 1983 ms \u221211% / \u22126% Apple clang parsing 1157 ms / 2016 ms 1146 ms / 2006 ms \u22121% / 0% GCC 16 parsing 2529 ms / 4087 ms 2484 ms / 4059 ms \u22122% / \u22121%

    Compile time of the model and parsing translation units without and with JSON_NO_AUTOMATIC_UDLS, at -O0 and -O2.

    The model translation unit saves about a tenth. Translation units that parse anyway instantiate the parser regardless and see no difference.

    "},{"location":"integration/compile_times/#instantiate-basic_json-once","title":"Instantiate basic_json once","text":"

    Each translation unit instantiates the member functions of nlohmann::json it uses. An explicit instantiation declaration tells the compiler that the non-template members are instantiated elsewhere, so it can skip them:

    json_instance.hpp
    #pragma once\n#include <nlohmann/json.hpp>\n\nextern template class nlohmann::basic_json<>;\n
    json_instance.cpp
    #include \"json_instance.hpp\"\n\ntemplate class nlohmann::basic_json<>;\n

    Include json_instance.hpp instead of <nlohmann/json.hpp> and compile and link json_instance.cpp once.

    Compiler Translation unit Default (-O0 / -O2) extern template (-O0 / -O2) Change Apple clang parsing 1157 ms / 2016 ms 1071 ms / 1844 ms \u22127% / \u22129% GCC 16 parsing 2529 ms / 4087 ms 1994 ms / 3190 ms \u221221% / \u221222% Apple clang json_instance.cpp \u2014 2573 ms / 6221 ms \u2014 GCC 16 json_instance.cpp \u2014 6489 ms / 13759 ms \u2014

    Compile time of the parsing translation unit without and with the extern template declaration, at -O0 and -O2. The json_instance.cpp rows are the one-off cost of the translation unit that holds the instantiation.

    Notes:

    • The saving grows with the number of translation units that use json, while the instantiation translation unit is compiled only once (and is rarely recompiled, as it does not depend on your code).
    • Member function templates (such as get<T>(), parse(InputType&&), or value(key, default)) are not covered by the explicit instantiation and are still instantiated where they are used.
    • The declaration covers exactly nlohmann::json. Add the same lines for nlohmann::ordered_json (nlohmann::basic_json<nlohmann::ordered_map>) or your own basic_json specializations if you use them.
    "},{"location":"integration/compile_times/#switch-off-filesystem-support","title":"Switch off filesystem support","text":"

    With C++17, the library includes <filesystem> to provide conversions from and to std::filesystem::path (see JSON_HAS_FILESYSTEM). Parsing <filesystem> is a fixed cost in every translation unit, and it also pulls in <iomanip>, <istream>, and <ostream> (and, with GCC's libstdc++, <sstream>). If you do not convert paths, switch the detection off for the whole project:

    target_compile_definitions(my_target PRIVATE JSON_HAS_FILESYSTEM=0 JSON_HAS_EXPERIMENTAL_FILESYSTEM=0)\n
    Compiler Translation unit Default (-O0 / -O2) Filesystem off (-O0 / -O2) Change Apple clang model 1051 ms / 1300 ms 998 ms / 1257 ms \u22125% / \u22123% GCC 16 model 1801 ms / 2106 ms 1636 ms / 2008 ms \u22129% / \u22125% Apple clang parsing 1157 ms / 2016 ms 1107 ms / 1971 ms \u22124% / \u22122% GCC 16 parsing 2529 ms / 4087 ms 2405 ms / 4029 ms \u22125% / \u22121%

    Compile time with JSON_HAS_FILESYSTEM=0 and JSON_HAS_EXPERIMENTAL_FILESYSTEM=0 against the default configuration, at -O0 and -O2.

    Only with filesystem support switched off does JSON_NO_IO remove the stream headers from the translation unit, so the two macros save most together:

    Compiler Translation unit Default (-O0 / -O2) Filesystem off and JSON_NO_IO (-O0 / -O2) Change Apple clang model 1051 ms / 1300 ms 969 ms / 1219 ms \u22128% / \u22126% GCC 16 model 1801 ms / 2106 ms 1605 ms / 1982 ms \u221211% / \u22126% Apple clang parsing 1157 ms / 2016 ms 1083 ms / 1947 ms \u22126% / \u22123% GCC 16 parsing 2529 ms / 4087 ms 2384 ms / 3972 ms \u22126% / \u22123%

    Compile time with filesystem support switched off and JSON_NO_IO defined, against the default configuration, at -O0 and -O2.

    The trade-off: the library's own to_json/from_json overloads for std::filesystem::path (which store the path as UTF-8) are removed. In a test with both compilers on macOS, paths still converted through their implicit conversion from and to std::string; whether that fallback exists depends on the platform's native path string type (std::wstring on Windows), so check code that converts paths. JSON_NO_IO additionally removes all stream functions (see Options without effect).

    "},{"location":"integration/compile_times/#use-c20-modules","title":"Use C++20 modules","text":"

    With a toolchain that supports named modules, import nlohmann.json; compiles the library once into a module and avoids parsing the header in every translation unit. See Modules for requirements and known issues. Module support is experimental and currently depends heavily on the compiler version.

    Compile time per translation unit with import nlohmann.json at -O0, and the one-off cost of the module Horizontal bars, negative is faster, medians of nine runs, -std=c++20 for both. model TU, Apple clang: -48 % (1311 ms to 680 ms); model TU, G\u200bCC 16: -47 % (2156 ms to 1153 ms); parsing TU, Apple clang: -42 % (1387 ms to 800 ms); parsing TU, G\u200bCC 16: -36 % (2838 ms to 1810 ms); one-off build, Apple clang: 1630 ms; one-off build, G\u200bCC 16: 2538 ms. Apple clang G\u200bCC 16 \u221250 % \u221225 % 0 % \u2190 faster per TU model TU \u00b7 import nlohmann.json model TU, Apple clang: 1311 ms by default, 680 ms import nlohmann.json (\u221248 %) \u221248 % model TU, G\u200bCC 16: 2156 ms by default, 1153 ms import nlohmann.json (\u221247 %) \u221247 % parsing TU \u00b7 import nlohmann.json parsing TU, Apple clang: 1387 ms by default, 800 ms import nlohmann.json (\u221242 %) \u221242 % parsing TU, G\u200bCC 16: 2838 ms by default, 1810 ms import nlohmann.json (\u221236 %) \u221236 % One-off cost \u00b7 built once, reused by every TU Apple clang: 1630 ms once, saves 587 to 631 ms per TU G\u200bCC 16: 2538 ms once, saves 1003 to 1028 ms per TU

    Change in compile time per translation unit at -O0 when #include <nlohmann/json.hpp> is replaced by import nlohmann.json;, both with -std=c++20, and the one-off cost of building the module, taken from the table below.

    Compiler Translation unit #include (-O0 / -O2) import nlohmann.json; (-O0 / -O2) Change Apple clang model 1311 ms / 1597 ms 680 ms / 914 ms \u221248% / \u221243% GCC 16 model 2156 ms / 2588 ms 1153 ms / 1580 ms \u221247% / \u221239% Apple clang parsing 1387 ms / 2319 ms 800 ms / 1676 ms \u221242% / \u221228% GCC 16 parsing 2838 ms / 4520 ms 1810 ms / 3476 ms \u221236% / \u221223% Apple clang json.cppm (module) \u2014 1630 ms / 1642 ms \u2014 GCC 16 json.cppm (module) \u2014 2538 ms / 2547 ms \u2014

    Compile time with #include <nlohmann/json.hpp> and with import nlohmann.json;, both with -std=c++20, at -O0 and -O2. The json.cppm rows are the one-off cost of building the module.

    Both columns use -std=c++20; with -std=c++17, the #include baseline is 17% to 20% faster (see the next section). The module is built once per set of compiler flags and pays for itself from about the third translation unit that imports it. Notes from the measurement:

    • Apple clang only accepts the module declarations with -fcxx-modules; without it, module; is a syntax error.
    • GCC 16 warns with -Wexpose-global-module-tu-local about internal constants of the library when building the module. With GCC 16.2, including <string> and <vector> before import nlohmann.json; works, but including them after it fails with redefinition errors (#5103).
    How these numbers were measured

    The model and parsing translation units are the ones listed at the top of this page, with import nlohmann.json; in place of #include <nlohmann/json.hpp> (after #include <string> and #include <vector>). Same method as for the other tables, with -std=c++20.

    # Apple clang: build the module once, then import it\nclang++ -std=c++20 -fcxx-modules -O0 -I single_include -c -x c++-module src/modules/json.cppm \\\n    -fmodule-output=nlohmann.json.pcm -o json_mod.o\nclang++ -std=c++20 -fcxx-modules -O0 -fmodule-file=nlohmann.json=nlohmann.json.pcm -c model.cpp\n\n# GCC 16 (Homebrew on macOS): writes gcm.cache/nlohmann.json.gcm, found by the importing translation unit\ng++-16 --sysroot=$(xcrun --show-sdk-path) -std=c++20 -fmodules -O0 -I single_include -c src/modules/json.cppm \\\n    -o json_mod.o\ng++-16 --sysroot=$(xcrun --show-sdk-path) -std=c++20 -fmodules -O0 -c model.cpp\n

    Link json_mod.o into the program.

    "},{"location":"integration/compile_times/#use-precompiled-headers","title":"Use precompiled headers","text":"

    Build systems can precompile <nlohmann/json.hpp> together with other stable headers, for example with CMake's target_precompile_headers:

    target_precompile_headers(my_target PRIVATE <nlohmann/json.hpp>)\n

    This removes the cost of parsing the header, but not of instantiating templates in each translation unit, so it combines well with the options above.

    Compile time per translation unit with a precompiled json.hpp at -O0, and the one-off cost of the PCH Horizontal bars, negative is faster, medians of nine runs, -std=c++17. model TU, Apple clang: -43 % (1045 ms to 594 ms); model TU, G\u200bCC 16: -41 % (1789 ms to 1060 ms); parsing TU, Apple clang: -38 % (1148 ms to 714 ms); parsing TU, G\u200bCC 16: -25 % (2498 ms to 1884 ms); one-off build, Apple clang: 771 ms; one-off build, G\u200bCC 16: 2254 ms. Apple clang G\u200bCC 16 \u221250 % \u221225 % 0 % \u2190 faster per TU model TU \u00b7 with PCH model TU, Apple clang: 1045 ms by default, 594 ms with PCH (\u221243 %) \u221243 % model TU, G\u200bCC 16: 1789 ms by default, 1060 ms with PCH (\u221241 %) \u221241 % parsing TU \u00b7 with PCH parsing TU, Apple clang: 1148 ms by default, 714 ms with PCH (\u221238 %) \u221238 % parsing TU, G\u200bCC 16: 2498 ms by default, 1884 ms with PCH (\u221225 %) \u221225 % One-off cost \u00b7 built once, reused by every TU Apple clang: 771 ms once, saves 434 to 451 ms per TU G\u200bCC 16: 2254 ms once, saves 614 to 729 ms per TU

    Change in compile time per translation unit at -O0 with a precompiled <nlohmann/json.hpp> (-std=c++17), and the one-off cost of building the precompiled header, taken from the table below.

    Compiler Translation unit Default (-O0 / -O2) With PCH (-O0 / -O2) Change Apple clang model 1045 ms / 1295 ms 594 ms / 842 ms \u221243% / \u221235% GCC 16 model 1789 ms / 2101 ms 1060 ms / 1376 ms \u221241% / \u221235% Apple clang parsing 1148 ms / 2008 ms 714 ms / 1584 ms \u221238% / \u221221% GCC 16 parsing 2498 ms / 4075 ms 1884 ms / 3452 ms \u221225% / \u221215% Apple clang building the PCH \u2014 771 ms / 760 ms \u2014 GCC 16 building the PCH \u2014 2254 ms / 2218 ms \u2014

    Compile time without and with a precompiled <nlohmann/json.hpp>, at -O0 and -O2. The last two rows are the one-off cost of building the precompiled header.

    The saving is largest in translation units that instantiate little, and the PCH pays for itself from the second (Apple clang) or fourth (GCC) translation unit. A precompiled header only works with the flags it was built with: GCC silently ignores a mismatching .gch file (for example one built with another -O level) unless -Winvalid-pch is given.

    How these numbers were measured

    pch.hpp contains only #include <nlohmann/json.hpp>; the translation units are the ones listed at the top of this page.

    # Apple clang\nclang++ -std=c++17 -O0 -I single_include -x c++-header pch.hpp -o pch.hpp.pch\nclang++ -std=c++17 -O0 -I single_include -include-pch pch.hpp.pch -include pch.hpp -c model.cpp\n\n# GCC 16 (Homebrew on macOS): pch.hpp.gch next to pch.hpp is picked up by -include pch.hpp\ng++-16 --sysroot=$(xcrun --show-sdk-path) -std=c++17 -O0 -I single_include -x c++-header pch.hpp -o pch.hpp.gch\ng++-16 --sysroot=$(xcrun --show-sdk-path) -std=c++17 -O0 -I single_include -include pch.hpp -Winvalid-pch -c model.cpp\n
    "},{"location":"integration/compile_times/#options-without-effect-on-compile-times","title":"Options without effect on compile times","text":"

    Some configuration macros change what the library declares, but do not measurably change compile times:

    Macro Apple clang, model (-O0 / -O2) GCC 16, model (-O0 / -O2) default 1051 ms / 1300 ms 1801 ms / 2106 ms JSON_NO_IO 1034 ms / 1288 ms 1756 ms / 2087 ms JSON_USE_GLOBAL_UDLS=0 1055 ms / 1298 ms 1783 ms / 2109 ms

    Compile time of the model translation unit with each macro defined; the first row is the default configuration for comparison.

    JSON_NO_IO removes the library's stream functions and its #includes of <istream> and <ostream>, but with the default C++17 settings <filesystem> includes these headers anyway (and with libc++, <vector> already includes <streambuf> via <locale>), so only a few hundred lines of the library's own stream code go away. It also does not change what the translation unit instantiates. On the parsing translation unit, the change is 0% / 0% (Apple clang) and \u22122% / 0% (GCC). To get a saving, combine it with switching off filesystem support.

    JSON_USE_GLOBAL_UDLS only controls where the literals are declared; to avoid their cost, use JSON_NO_AUTOMATIC_UDLS instead.

    "},{"location":"integration/compile_times/#see-also","title":"See also","text":"
    • JSON_HAS_FILESYSTEM - control the conversions from and to std::filesystem::path
    • JSON_NO_AUTOMATIC_UDLS - do not include the user-defined string literals automatically
    • Modules - C++20 module support
    • Header only - including the library
    • Macros - reference of all macros
    • Supported Macros - overview of all configuration macros
    • Performance - run-time performance
    • JSON_NO_IO - remove all stream and file I/O
    "},{"location":"integration/migration_guide/","title":"Migration Guide","text":"

    This page collects some guidelines on how to future-proof your code for future versions of this library. For how to add the library to your project in the first place, see Integration, CMake, or Package Managers. The roadmap lists what will change in version 4.0, including the macros that let you try its behavior with a 3.x release; this page describes how to adjust your code.

    "},{"location":"integration/migration_guide/#replace-deprecated-functions","title":"Replace deprecated functions","text":"

    The following functions have been deprecated and will be removed in the next major version (i.e., 4.0.0), see the roadmap for an overview. All deprecations are annotated with HEDLEY_DEPRECATED_FOR to report which function to use instead.

    Find all calls of deprecated functions

    Define JSON_DELETE_DEPRECATED_FUNCTIONS to 1 (or set the CMake option JSON_DeleteDeprecatedFunctions) to delete all deprecated functions. Every remaining call then fails to compile, even if deprecation warnings are disabled, so your code is ready for version 4.0.0 unreleased once it compiles with the macro.

    "},{"location":"integration/migration_guide/#parsing","title":"Parsing","text":"
    • Function friend std::istream& operator<<(basic_json&, std::istream&) is deprecated since 3.0.0. Please use friend std::istream& operator>>(std::istream&, basic_json&) instead.

      DeprecatedFuture-proof
      nlohmann::json j;\nstd::stringstream ss(\"[1,2,3]\");\nj << ss;\n
      nlohmann::json j;\nstd::stringstream ss(\"[1,2,3]\");\nss >> j;\n
    • Passing iterator pairs or pointer/length pairs to parsing functions (parse, accept, sax_parse, from_cbor, from_msgpack, from_ubjson, and from_bson) via initializer lists is deprecated since 3.8.0. Instead, pass two iterators; for instance, call from_cbor(ptr, ptr+len) instead of from_cbor({ptr, len}). Likewise, passing a pointer and a length as two separate arguments to from_cbor, from_msgpack, from_ubjson, and from_bson is deprecated since 3.8.0, and to from_bjdata and from_bon8 since 3.13.0; call from_cbor(ptr, ptr+len) instead of from_cbor(ptr, len). These overloads will not be removed in version 4.0.0, but deleted, so a call like from_cbor(ptr, len) cannot compile and convert len to the strict parameter.

      DeprecatedFuture-proof
      const char* s = \"[1,2,3]\";\nbool ok = nlohmann::json::accept({s, s + std::strlen(s)});\n
      const char* s = \"[1,2,3]\";\nbool ok = nlohmann::json::accept(s, s + std::strlen(s));\n
    "},{"location":"integration/migration_guide/#json-pointers","title":"JSON Pointers","text":"
    • Comparing JSON Pointers with strings via operator== and operator!= is deprecated since 3.11.2. To compare a json_pointer p with a string s, convert s to a json_pointer first and use json_pointer::operator== or json_pointer::operator!=.

      DeprecatedFuture-proof
      nlohmann::json::json_pointer lhs(\"/foo/bar/1\");\nassert(lhs == \"/foo/bar/1\");\n
      nlohmann::json::json_pointer lhs(\"/foo/bar/1\");\nassert(lhs == nlohmann::json::json_pointer(\"/foo/bar/1\"));\n
    • The implicit conversion from JSON Pointers to string (json_pointer::operator string_t) is deprecated since 3.11.0. Use json_pointer::to_string instead.

      DeprecatedFuture-proof
      nlohmann::json::json_pointer ptr(\"/foo/bar/1\");\nstd::string s = ptr;\n
      nlohmann::json::json_pointer ptr(\"/foo/bar/1\");\nstd::string s = ptr.to_string();\n
    • Passing a basic_json specialization as template parameter RefStringType to json_pointer is deprecated since 3.11.0. The string type can now be directly provided. This also applies to passing such a JSON pointer to at, contains, operator[], and value.

      DeprecatedFuture-proof
      using my_json = nlohmann::json::with_string_t<my_string_type>;\nnlohmann::json_pointer<my_json> ptr(\"/foo/bar/1\");\n
      nlohmann::json_pointer<my_string_type> ptr(\"/foo/bar/1\");\n

      Thereby, my_json::json_pointer is an alias for nlohmann::json_pointer<my_string_type>; in general, basic_json::json_pointer is always an alias to the json_pointer with the appropriate string type for all specializations of basic_json.

    "},{"location":"integration/migration_guide/#miscellaneous-functions","title":"Miscellaneous functions","text":"
    • The function iterator_wrapper is deprecated since 3.1.0. Please use the member function items instead.

      DeprecatedFuture-proof
      for (auto &x : nlohmann::json::iterator_wrapper(j))\n{\n    std::cout << x.key() << \":\" << x.value() << std::endl;\n}\n
      for (auto &x : j.items())\n{\n    std::cout << x.key() << \":\" << x.value() << std::endl;\n}\n
    • Function friend std::ostream& operator>>(const basic_json&, std::ostream&) is deprecated since 3.0.0. Please use friend operator<<(std::ostream&, const basic_json&) instead.

      DeprecatedFuture-proof
      j >> std::cout;\n
      std::cout << j;\n
    • The legacy comparison behavior for discarded values is deprecated since 3.11.0. It is already disabled by default and can still be enabled by defining JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON to 1.

      DeprecatedFuture-proof
      #define JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON 1\n#include <nlohmann/json.hpp>\n
      #include <nlohmann/json.hpp>\n
    "},{"location":"integration/migration_guide/#replace-implicit-conversions","title":"Replace implicit conversions","text":"

    Implicit conversions via operator ValueType will be switched off by default in the next major release of the library.

    You can prepare existing code by already defining JSON_USE_IMPLICIT_CONVERSIONS to 0 and replace any implicit conversions with calls to get, get_to, get_ref, or get_ptr.

    Automatic migration

    The community-maintained clang-tidy check modernize-nlohmann-json-explicit-conversions rewrites most implicit conversions into calls to get. It is not part of clang-tidy itself; see discussion #4610 for how to build and use it.

    DeprecatedFuture-proofFuture-proof (alternative)
    nlohmann::json j = \"Hello, world!\";\nstd::string s = j;\n
    nlohmann::json j = \"Hello, world!\";\nauto s = j.get<std::string>();\n
    nlohmann::json j = \"Hello, world!\";\nstd::string s;\nj.get_to(s);\n
    "},{"location":"integration/migration_guide/#import-namespace-literals-for-udls","title":"Import namespace literals for UDLs","text":"

    The user-defined string literals operator\"\"_json and operator\"\"_json_pointer will be removed from the global namespace in the next major release of the library.

    DeprecatedFuture-proof
    nlohmann::json j = \"[1,2,3]\"_json;\n
    using namespace nlohmann::literals;\nnlohmann::json j = \"[1,2,3]\"_json;\n

    To prepare existing code, define JSON_USE_GLOBAL_UDLS to 0 and bring the string literals into scope where needed.

    "},{"location":"integration/migration_guide/#do-not-hard-code-the-complete-library-namespace","title":"Do not hard-code the complete library namespace","text":"

    The nlohmann namespace contains a sub-namespace to avoid problems when different versions or configurations of the library are used in the same project. Always use nlohmann as namespace or, when the exact version and configuration is relevant, use macro NLOHMANN_JSON_NAMESPACE to denote the namespace.

    DangerousFuture-proofFuture-proof (alternative)
    void to_json(nlohmann::json_abi_v3_11_2::json& j, const person& p)\n{\n    j[\"age\"] = p.age;\n}\n
    void to_json(nlohmann::json& j, const person& p)\n{\n    j[\"age\"] = p.age;\n}\n
    void to_json(NLOHMANN_JSON_NAMESPACE::json& j, const person& p)\n{\n    j[\"age\"] = p.age;\n}\n
    "},{"location":"integration/migration_guide/#do-not-use-the-detail-namespace","title":"Do not use the detail namespace","text":"

    The nlohmann::detail namespace is not part of the public API of the library and can change in any version without an announcement. Do not rely on any function or type in the detail namespace.

    "},{"location":"integration/migration_guide/#see-also","title":"See also","text":"
    • JSON_DELETE_DEPRECATED_FUNCTIONS - remove deprecated functions to check the migration
    • JSON_USE_IMPLICIT_CONVERSIONS - control implicit conversions
    • NLOHMANN_JSON_NAMESPACE - refer to the library namespace without hard-coding it
    • nlohmann Namespace - how the library namespace is structured
    • Converting values - explicit conversions with get
    • basic_json - the main class and all its member functions
    "},{"location":"integration/package_managers/","title":"Package Managers","text":"

    Homebrew nlohmann-json Meson nlohmann_json Bazel nlohmann_json Conan nlohmann_json Spack nlohmann-json Hunter nlohmann_json vcpkg nlohmann-json cget nlohmann/json Swift Package Manager nlohmann/json NuGet nlohmann.json Conda nlohmann_json MacPorts nlohmann-json CPM.cmake gh:nlohmann/json xmake nlohmann_json

    "},{"location":"integration/package_managers/#running-example","title":"Running example","text":"

    Throughout this page, we will describe how to compile the example file example.cpp below.

    #include <nlohmann/json.hpp>\n#include <iostream>\n#include <iomanip>\n\nusing nlohmann::json;\n\nint main()\n{\n    std::cout << std::setw(4) << json::meta() << std::endl;\n}\n

    When executed, this program should create output similar to

    {\n    \"compiler\": {\n        \"c++\": \"201103\",\n        \"family\": \"gcc\",\n        \"version\": \"12.4.0\"\n    },\n    \"copyright\": \"(C) 2013-2026 Niels Lohmann\",\n    \"name\": \"JSON for Modern C++\",\n    \"platform\": \"apple\",\n    \"url\": \"https://github.com/nlohmann/json\",\n    \"version\": {\n        \"major\": 3,\n        \"minor\": 12,\n        \"patch\": 0,\n        \"string\": \"3.12.0\"\n    }\n}\n

    Many of the package managers below install a CMake package configuration that exposes the same nlohmann_json::nlohmann_json interface target described in CMake; their CMake examples below link against that target.

    "},{"location":"integration/package_managers/#homebrew","title":"Homebrew","text":"

    Summary

    formula: nlohmann-json

    • Available versions: current version and development version (with --HEAD parameter)
    • The formula is updated with every release.
    • Maintainer: Niels Lohmann
    • File issues at the Homebrew issue tracker
    • Homebrew website

    If you are using Homebrew, you can install the library with

    brew install nlohmann-json\n

    The header can be used directly in your code or via CMake.

    Example: Raw compilation
    1. Create the following file:

      example.cpp
      #include <nlohmann/json.hpp>\n#include <iostream>\n#include <iomanip>\n\nusing nlohmann::json;\n\nint main()\n{\n    std::cout << std::setw(4) << json::meta() << std::endl;\n}\n
    2. Install the package:

      brew install nlohmann-json\n
    3. Compile the code and pass the Homebrew prefix to the include path such that the library can be found:

      c++ example.cpp -I$(brew --prefix nlohmann-json)/include -std=c++11 -o example\n
    Example: CMake
    1. Create the following files:

      example.cpp
      #include <nlohmann/json.hpp>\n#include <iostream>\n#include <iomanip>\n\nusing nlohmann::json;\n\nint main()\n{\n    std::cout << std::setw(4) << json::meta() << std::endl;\n}\n
      CMakeLists.txt
      cmake_minimum_required(VERSION 3.15)\nproject(json_example)\n\nfind_package(nlohmann_json CONFIG REQUIRED)\n\nadd_executable(json_example example.cpp)\ntarget_link_libraries(json_example PRIVATE nlohmann_json::nlohmann_json)\n
    2. Install the package:

      brew install nlohmann-json\n
    3. Compile the code and pass the Homebrew prefix to CMake to find installed packages via find_package:

      CMAKE_PREFIX_PATH=$(brew --prefix) cmake -S . -B build\ncmake --build build\n
    "},{"location":"integration/package_managers/#meson","title":"Meson","text":"

    Summary

    wrap: nlohmann_json

    • Available versions: current version and select older versions (see WrapDB)
    • The package is updated automatically from file meson.build.
    • File issues at the library issue tracker
    • Meson website

    If you are using the Meson Build System, add this source tree as a meson subproject. You may also use the include.zip published in this project's Releases to reduce the size of the vendored source tree. Alternatively, you can get a wrap file by downloading it from Meson WrapDB, or use

    meson wrap install nlohmann_json\n

    Please see the Meson project for any issues regarding the packaging.

    The provided meson.build can also be used as an alternative to CMake for installing nlohmann_json system-wide in which case a pkg-config file and the CMake package config files are installed. To use it, have your build system require the nlohmann_json pkg-config dependency, or use find_package(nlohmann_json) in CMake. In Meson, it is preferred to use the dependency() object with a subproject fallback, rather than using the subproject directly.

    The options that change the library's configuration are available in Meson as well, named like the CMake options without the JSON_ prefix: MultipleHeaders, GlobalUDLs, ImplicitConversions, DisableEnumSerialization, DisableTupleReferenceConversion, Diagnostics, Diagnostic_Positions, LegacyDiscardedValueComparison, StrictNulHandling, StrictBinaryUTF8, and DeleteDeprecatedFunctions. They have the same defaults as in CMake, except that MultipleHeaders is false. Set them with -D when setting up the build, or with the subproject name as prefix when the library is used as a subproject:

    meson setup build -Dnlohmann_json:Diagnostics=true\n

    The resulting compile definitions are part of the Meson dependency, the pkg-config file, and the CMake target.

    Example: Wrap
    1. Create the following files:

      meson.build
      project('json_example', 'cpp',\n  version: '1.0',\n  default_options: ['cpp_std=c++11']\n)\n\ndependency_json = dependency('nlohmann_json', required: true)\n\nexecutable('json_example',\n  sources: ['example.cpp'],\n  dependencies: [dependency_json],\n  install: true\n)\n
      example.cpp
      #include <nlohmann/json.hpp>\n#include <iostream>\n#include <iomanip>\n\nusing nlohmann::json;\n\nint main()\n{\n    std::cout << std::setw(4) << json::meta() << std::endl;\n}\n
    2. Use the Meson WrapDB to fetch the nlohmann/json wrap:

      mkdir subprojects\nmeson wrap install nlohmann_json\n
    3. Build:

      meson setup build\nmeson compile -C build\n
    "},{"location":"integration/package_managers/#bazel","title":"Bazel","text":"

    Summary

    use bazel_dep, git_override, or local_path_override

    • Any version, that is available via Bazel Central Registry
    • File issues at the library issue tracker
    • Bazel website

    This repository provides a Bazel MODULE.bazel and a corresponding BUILD.bazel file. Therefore, this repository can be referenced within a MODULE.bazel by rules such as archive_override, git_override, or local_path_override. To use the library, you need to depend on the target @nlohmann_json//:json (i.e., via deps attribute).

    Example: Bazel module with bazel_dep
    1. Create the following files:

      BUILD
      cc_binary(\n    name = \"main\",\n    srcs = [\"example.cpp\"],\n    deps = [\"@nlohmann_json//:json\"],\n)\n
      MODULE.bazel
      bazel_dep(name = \"nlohmann_json\", version = \"3.12.0.bcr.2\")\n
      example.cpp
      #include <nlohmann/json.hpp>\n#include <iostream>\n#include <iomanip>\n\nusing nlohmann::json;\n\nint main()\n{\n    std::cout << std::setw(4) << json::meta() << std::endl;\n}\n
    2. Build and run:

      bazel build //:main\nbazel run //:main\n
    "},{"location":"integration/package_managers/#conan","title":"Conan","text":"

    Summary

    recipe: nlohmann_json

    • Available versions: current version and older versions (see Conan Center)
    • The package is updated automatically via this recipe.
    • File issues at the Conan Center issue tracker
    • Conan website

    If you are using Conan to manage your dependencies, merely add nlohmann_json/x.y.z to your conanfile's requires, where x.y.z is the release version you want to use.

    Example: CMake with the Conan toolchain
    1. Create the following files:

      Conanfile.txt
      [requires]\nnlohmann_json/3.12.0\n\n[generators]\nCMakeToolchain\nCMakeDeps\n
      CMakeLists.txt
      cmake_minimum_required(VERSION 3.15)\nproject(json_example)\n\nfind_package(nlohmann_json REQUIRED)\n\nadd_executable(json_example example.cpp)\ntarget_link_libraries(json_example PRIVATE nlohmann_json::nlohmann_json)\n
      example.cpp
      #include <nlohmann/json.hpp>\n#include <iostream>\n#include <iomanip>\n\nusing nlohmann::json;\n\nint main()\n{\n    std::cout << std::setw(4) << json::meta() << std::endl;\n}\n
    2. Call Conan:

      conan install . --output-folder=build --build=missing\n
    3. Build:

      cmake -S . -B build -DCMAKE_TOOLCHAIN_FILE=\"conan_toolchain.cmake\" -DCMAKE_BUILD_TYPE=Release\ncmake --build build\n
    "},{"location":"integration/package_managers/#spack","title":"Spack","text":"

    Summary

    package: nlohmann-json

    • Available versions: current version and older versions (see Spack package)
    • The package is updated with every release.
    • Maintainer: Axel Huebl
    • File issues at the Spack issue tracker
    • Spack website

    If you are using Spack to manage your dependencies, you can use the nlohmann-json package via

    spack install nlohmann-json\n

    Please see the Spack project for any issues regarding the packaging.

    Example: CMake with a Spack-installed package
    1. Create the following files:

      CMakeLists.txt
      cmake_minimum_required(VERSION 3.15)\nproject(json_example)\n\nfind_package(nlohmann_json REQUIRED)\n\nadd_executable(json_example example.cpp)\ntarget_link_libraries(json_example PRIVATE nlohmann_json::nlohmann_json)\n
      example.cpp
      #include <nlohmann/json.hpp>\n#include <iostream>\n#include <iomanip>\n\nusing nlohmann::json;\n\nint main()\n{\n    std::cout << std::setw(4) << json::meta() << std::endl;\n}\n
    2. Install the library:

      spack install nlohmann-json\n
    3. Load the environment for your Spack-installed packages:

      spack load nlohmann-json\n
    4. Build the project with CMake:

      cmake -S . -B build -DCMAKE_PREFIX_PATH=$(spack location -i nlohmann-json)\ncmake --build build\n
    "},{"location":"integration/package_managers/#hunter","title":"Hunter","text":"

    Summary

    package: nlohmann_json

    • Available versions: current version and older versions (see Hunter package)
    • The package is updated with every release.
    • File issues at the Hunter issue tracker
    • Hunter website

    If you are using Hunter on your project for external dependencies, then you can use the nlohmann_json package via

    hunter_add_package(nlohmann_json)\n

    Please see the Hunter project for any issues regarding the packaging.

    Example: CMake with HunterGate
    1. Create the following files:

      CMakeLists.txt
      cmake_minimum_required(VERSION 3.15)\n\ninclude(\"cmake/HunterGate.cmake\")\nHunterGate(\n    URL \"https://github.com/cpp-pm/hunter/archive/v0.26.12.tar.gz\"\n    SHA1 \"6498c5d0dec25d7fffb2b0574ebaf265179b894d\"\n)\n\nproject(json_example)\n\nhunter_add_package(nlohmann_json)\nfind_package(nlohmann_json CONFIG REQUIRED)\n\nadd_executable(json_example example.cpp)\ntarget_link_libraries(json_example PRIVATE nlohmann_json::nlohmann_json)\n
      example.cpp
      #include <nlohmann/json.hpp>\n#include <iostream>\n#include <iomanip>\n\nusing nlohmann::json;\n\nint main()\n{\n    std::cout << std::setw(4) << json::meta() << std::endl;\n}\n
    2. Download required files

      mkdir cmake\nwget https://raw.githubusercontent.com/cpp-pm/gate/master/cmake/HunterGate.cmake -O cmake/HunterGate.cmake\n
    3. Build the project with CMake:

      cmake -S . -B build\ncmake --build build\n
    "},{"location":"integration/package_managers/#vcpkg","title":"vcpkg","text":"

    Summary

    package: nlohmann-json

    • Available versions: current version
    • The package is updated with every release.
    • File issues at the vcpkg issue tracker
    • vcpkg website

    If you are using vcpkg on your project for external dependencies, then you can install the nlohmann-json package with

    vcpkg install nlohmann-json\n

    and follow the then displayed descriptions. Please see the vcpkg project for any issues regarding the packaging.

    Example: CMake with the vcpkg toolchain
    1. Create the following files:

      CMakeLists.txt
      cmake_minimum_required(VERSION 3.15)\nproject(json_example)\n\nfind_package(nlohmann_json CONFIG REQUIRED)\n\nadd_executable(json_example example.cpp)\ntarget_link_libraries(json_example PRIVATE nlohmann_json::nlohmann_json)\n
      example.cpp
      #include <nlohmann/json.hpp>\n#include <iostream>\n#include <iomanip>\n\nusing nlohmann::json;\n\nint main()\n{\n    std::cout << std::setw(4) << json::meta() << std::endl;\n}\n
    2. Install package:

      vcpkg install nlohmann-json\n
    3. Build:

      cmake -S . -B build -DCMAKE_TOOLCHAIN_FILE=$VCPKG_ROOT/scripts/buildsystems/vcpkg.cmake\ncmake --build build\n
    "},{"location":"integration/package_managers/#cget","title":"cget","text":"

    Summary

    package: nlohmann/json

    • Available versions: current version and older versions
    • The package is updated with every release.
    • File issues at the cget issue tracker
    • cget website

    If you are using cget, you can install the latest master version with

    cget install nlohmann/json\n

    A specific version can be installed with cget install nlohmann/json@v3.12.0. Also, the multiple header version can be installed by adding the -DJSON_MultipleHeaders=ON flag (i.e., cget install nlohmann/json -DJSON_MultipleHeaders=ON).

    Example: CMake with the cget toolchain
    1. Create the following files:

      CMakeLists.txt
      cmake_minimum_required(VERSION 3.15)\nproject(json_example)\n\nfind_package(nlohmann_json REQUIRED)\n\nadd_executable(json_example example.cpp)\ntarget_link_libraries(json_example PRIVATE nlohmann_json::nlohmann_json)\n
      example.cpp
      #include <nlohmann/json.hpp>\n#include <iostream>\n#include <iomanip>\n\nusing nlohmann::json;\n\nint main()\n{\n    std::cout << std::setw(4) << json::meta() << std::endl;\n}\n
    2. Initialize cget

      cget init\n
    3. Install the library

      cget install nlohmann/json\n
    4. Build

      cmake -S . -B build -DCMAKE_TOOLCHAIN_FILE=cget/cget/cget.cmake\ncmake --build build\n
    "},{"location":"integration/package_managers/#swift-package-manager","title":"Swift Package Manager","text":"

    Summary

    package: nlohmann/json

    • Available versions: current version and older versions
    • The package is updated with every release.
    • File issues at the library issue tracker
    • Xcode documentation

    If you are using the Swift Package Manager, add this repository as a package dependency and depend on its json product:

    dependencies: [\n    .package(url: \"https://github.com/nlohmann/json\", from: \"3.12.0\")\n],\ntargets: [\n    .target(name: \"MyTarget\", dependencies: [.product(name: \"json\", package: \"json\")])\n]\n

    The library's own Package.swift publishes single_include/nlohmann (not single_include) as the public headers directory, so include the header without the nlohmann/ prefix:

    #include <json.hpp>\n
    Example: a minimal executable package
    1. Create the following files (the source file goes into Sources/json_example/, following Swift Package Manager's directory layout convention):

      Package.swift
      // swift-tools-version: 5.9\nimport PackageDescription\n\nlet package = Package(\n    name: \"json_example\",\n    dependencies: [\n        .package(url: \"https://github.com/nlohmann/json\", from: \"3.12.0\")\n    ],\n    targets: [\n        .executableTarget(\n            name: \"json_example\",\n            dependencies: [\n                .product(name: \"json\", package: \"json\")\n            ]\n        )\n    ]\n)\n
      Sources/json_example/example.cpp
      #include <json.hpp>\n#include <iostream>\n#include <iomanip>\n\nusing nlohmann::json;\n\nint main()\n{\n    std::cout << std::setw(4) << json::meta() << std::endl;\n}\n
    2. Build and run:

      swift run --build-system native\n

    Warning

    On some toolchains, swift run/swift build fail to link an executable target against the header-only json product with an error such as Build input file cannot be found: '.../json.o', because the product itself has no compiled sources; see #4650 and the upstream Swift Package Manager issue. Passing --build-system native (shown above) selects Swift Package Manager's legacy build system, which does not have this problem; depending on the library from a library target instead of an executable is not affected either.

    You can also add the dependency from within Xcode via File \u2192 Add Package Dependencies\u2026 and the same repository URL; see Apple's documentation.

    "},{"location":"integration/package_managers/#nuget","title":"NuGet","text":"

    Summary

    package: nlohmann.json

    • Available versions: current and previous versions
    • The package is updated with every release.
    • Maintainer: Hani Kaabi
    • File issues at the maintainer's issue tracker
    • NuGet website

    If you are using NuGet, you can use the package nlohmann.json with

    dotnet add package nlohmann.json\n

    NuGet integrates with C++ projects through MSBuild, so it is mainly useful for Visual Studio/MSBuild projects; using it as a dependency from other build systems, such as CMake, is possible but more cumbersome than the other package managers on this page.

    Example: Visual Studio project
    1. Right-click the project (any C++ project) in \"Solution Explorer\" and select \"Manage NuGet Packages\u2026\"

    2. Switch to the \"Browse\" tab.

    3. Search for nlohmann.json, select it, and click \"Install\".

    4. #include <nlohmann/json.hpp> in your code and build the project. The package's build/native/nlohmann.json.targets file adds $(MSBuildThisFileDirectory)include to the project's AdditionalIncludeDirectories, so no further include path configuration is needed.

    For further details, see the original discussion this section is based on.

    "},{"location":"integration/package_managers/#conda","title":"Conda","text":"

    Summary

    package: nlohmann_json

    • Available versions: current and previous versions
    • The package is updated with every release.
    • File issues at the feedstock's issue tracker
    • Conda documentation

    If you are using conda, you can use the package nlohmann_json from conda-forge executing

    conda install -c conda-forge nlohmann_json\n
    Example: Raw compilation
    1. Create the following file:

      example.cpp
      #include <nlohmann/json.hpp>\n#include <iostream>\n#include <iomanip>\n\nusing nlohmann::json;\n\nint main()\n{\n    std::cout << std::setw(4) << json::meta() << std::endl;\n}\n
    2. Create and activate an environment json:

      conda create -n json\nconda activate json\n
    3. Install the package:

      conda install -c conda-forge nlohmann_json\n
    4. Build the code:

      g++ -std=c++11 -I$(conda info --base)/envs/json/include example.cpp -o example\n
    "},{"location":"integration/package_managers/#msys2","title":"MSYS2","text":"

    Summary

    package: mingw-w64-nlohmann-json

    • The package is updated automatically.
    • File issues at the MINGW-packages issue tracker
    • MSYS2 website

    If you are using MSYS2, you can use the mingw-w64-nlohmann-json package; type pacman -S mingw-w64-i686-nlohmann-json or pacman -S mingw-w64-x86_64-nlohmann-json for installation.

    Example: Raw compilation
    1. Create the following file:

      example.cpp
      #include <nlohmann/json.hpp>\n#include <iostream>\n#include <iomanip>\n\nusing nlohmann::json;\n\nint main()\n{\n    std::cout << std::setw(4) << json::meta() << std::endl;\n}\n
    2. Install the package (from an MSYS2 MinGW 64-bit shell):

      pacman -S mingw-w64-x86_64-nlohmann-json\n
    3. Compile the code:

      g++ example.cpp -std=c++11 -o example\n
    "},{"location":"integration/package_managers/#macports","title":"MacPorts","text":"

    Summary

    port: nlohmann-json

    • Available versions: current version
    • The port is updated with every release.
    • File issues at the MacPorts issue tracker
    • MacPorts website

    If you are using MacPorts, execute

    sudo port install nlohmann-json\n

    to install the nlohmann-json package.

    Example: Raw compilation
    1. Create the following file:

      example.cpp
      #include <nlohmann/json.hpp>\n#include <iostream>\n#include <iomanip>\n\nusing nlohmann::json;\n\nint main()\n{\n    std::cout << std::setw(4) << json::meta() << std::endl;\n}\n
    2. Install the package:

      sudo port install nlohmann-json\n
    3. Compile the code and pass the MacPorts prefix to the include path such that the library can be found:

      c++ example.cpp -I/opt/local/include -std=c++11 -o example\n
    Example: CMake
    1. Create the following files:

      example.cpp
      #include <nlohmann/json.hpp>\n#include <iostream>\n#include <iomanip>\n\nusing nlohmann::json;\n\nint main()\n{\n    std::cout << std::setw(4) << json::meta() << std::endl;\n}\n
      CMakeLists.txt
      cmake_minimum_required(VERSION 3.15)\nproject(json_example)\n\nfind_package(nlohmann_json CONFIG REQUIRED)\n\nadd_executable(json_example example.cpp)\ntarget_link_libraries(json_example PRIVATE nlohmann_json::nlohmann_json)\n
    2. Install the package:

      sudo port install nlohmann-json\n
    3. Compile the code:

      cmake -S . -B build\ncmake --build build\n
    "},{"location":"integration/package_managers/#build2","title":"build2","text":"

    Summary

    package: nlohmann-json library target: nlohmann-json%lib{json} available in package repositories: - cppget.org (recommended) - package's sources (for advanced users)

    • Available versions: current version and older versions since 3.7.3 (see cppget.org)
    • The package is maintained and published by the build2 community in this repository.
    • File issues at the package source repository
    • build2 website

    Note: build2 should not be considered as a standalone package-manager. It is a build-system + package manager + project manager, a set of tools that work hand-in-hand. build2-based projects do not rely on existing CMake scripts and the build scripts defining the project's targets are specific to build2.

    To use this package in an existing build2 project, the general steps are:

    1. Make the package available to download from a package repository that provides it.

      Your project's repositories.manifest specifies where the package manager will try to acquire packages by default. Make sure one of the repositories specified in this file provides nlohmann-json package. The recommended open-source repository is cppget.org.

      If the project has been created using bdep new, cppget.org is already specified in repositories.manifest but commented, just uncomment these lines:

      :\nrole: prerequisite\nlocation: https://pkg.cppget.org/1/stable\n

    2. Add this package as dependency of your project.

      In your project's manifest add the dependency to the package using depends: nlohmann-json. You could also add some version constraints. For example, to depend on the latest version available:

      depends: nlohmann-json\n

    3. Add this library as dependency of your target that uses it.

      In the buildfile defining the target that will use this library:

      - import the target `lib{json}` from the `nlohmann-json` package, for example:\n    ```\n    import nljson = nlohmann-json%lib{json}\n    ```\n\n- then add the library's target as requirement for your target using it, for example:\n    ```\n    exe{example} : ... $nljson\n    ```\n
    4. Use the library in your project's code and build it.

      At this point, assuming your project is initialized in a build-configuration, any b or bdep update command that will update/build the project will also acquire the missing dependency automatically, then build it and link it with your target.

      If you just want to synchronize dependencies for all your configurations to download the ones you just added:

      bdep sync -af\n

      Example: from scratch, using build2's bdep new command
      1. Create a new executable project \"example\" (see bdep new command details for the various options to create a new project):

        bdep new example\n
      2. Edit these files by replacing their content:

        • example/repositories.manifest: Enable acquiring packages from https://cppget.org by uncommenting the related lines:

          project's `repositories.manifest`
          : 1\nsummary: example project repository\n\n:\nrole: prerequisite\nlocation: https://pkg.cppget.org/1/stable\n#trust: ...\n\n#:\n#role: prerequisite\n#location: https://git.build2.org/hello/libhello.git\n
        • example/manifest: Add the latest version of the nlohmann-json package as dependency to the project:

          project's `manifest`
          name: example\nversion: 0.1.0-a.0.z\nlanguage: c++\nsummary: example C++ executable\nlicense: other: proprietary ; Not free/open source.\ndescription-file: README.md\nurl: https://example.org/example\nemail: your@emailprovider.com\n#build-error-email: your@emailprovider.com\ndepends: * build2 >= 0.16.0\ndepends: * bpkg >= 0.16.0\n#depends: libhello ^1.0.0\n\ndepends: nlohmann-json\n
        • example/example/buildfile: import the library's target to be used as requirement for building the executable target exe{example}:

          project's `buildfile`
          libs =\nimport libs = nlohmann-json%lib{json}\n\nexe{example}: {hxx ixx txx cxx}{**} $libs testscript\n\ncxx.poptions =+ \"-I$out_root\" \"-I$src_root\"\n
        • example/example/example.cxx: bdep new generates a \"hello world\" by default, replace it by this:

          example.cxx
          #include <nlohmann/json.hpp>\n#include <iostream>\n#include <iomanip>\n\nusing nlohmann::json;\n\nint main()\n{\n    std::cout << std::setw(4) << json::meta() << std::endl;\n}\n
        • example/example/testscript: (optional) if you want to be able to test that executable's output is correct using b test:

          `testscript` checking the output of the program
          : json basics\n:\n$* >>~/EOO/\n{\n    \"compiler\": {\n/        \"c\\+\\+\": \"\\d+\",/\n/        \"family\": \"[\\w\\d]+\",/\n/        \"version\": \\d+/\n    },\n/    \"copyright\": \"\\(C\\) 2013-\\d+ Niels Lohmann\",/\n    \"name\": \"JSON for Modern C++\",\n/    \"platform\": \"[\\w\\d]+\",/\n    \"url\": \"https://github.com/nlohmann/json\",\n    \"version\": {\n        \"major\": 3,\n/        \"minor\": \\d+,/\n/        \"patch\": \\d+,/\n/        \"string\": \"3\\.\\d+\\.\\d+\"/\n    }\n}\nEOO\n
      3. Initialize the project in a default C/C++ build configuration directory, then build and test:

        cd example/\n\n# create default C/C++ build configuration in ../example-myconfig/, initialize the project in it (downloads it's dependencies in it too)\nbdep init -C @myconfig cc\n\n# build only,\nb\n\n# or build and test the executable's output, will only work if the `testscript` is correct\nb test\n
      "},{"location":"integration/package_managers/#cpmcmake","title":"CPM.cmake","text":"

      Summary

      package: gh:nlohmann/json

      • Available versions: current and previous versions
      • The package is updated with every release.
      • File issues at the CPM.cmake issue tracker
      • CPM.cmake website

      If you are using CPM.cmake, add the CPM.cmake script and the following snippet to your CMake project:

      CPMAddPackage(\"gh:nlohmann/json@3.12.0\")\n
      Example: CMake with CPMAddPackage
      1. Create the following files:

        example.cpp
        #include <nlohmann/json.hpp>\n#include <iostream>\n#include <iomanip>\n\nusing nlohmann::json;\n\nint main()\n{\n    std::cout << std::setw(4) << json::meta() << std::endl;\n}\n
        CMakeLists.txt
        cmake_minimum_required(VERSION 3.15)\nproject(json_example)\n\ninclude(${CMAKE_SOURCE_DIR}/cmake/CPM.cmake)\n\nCPMAddPackage(\"gh:nlohmann/json@3.12.0\")\n\nadd_executable(json_example example.cpp)\ntarget_link_libraries(json_example PRIVATE nlohmann_json::nlohmann_json)\n
      2. Download CPM.cmake

        mkdir -p cmake\nwget -O cmake/CPM.cmake https://github.com/cpm-cmake/CPM.cmake/releases/latest/download/get_cpm.cmake\n
      3. Build

        cmake -S . -B build\ncmake --build build\n
      "},{"location":"integration/package_managers/#xmake","title":"xmake","text":"

      Summary

      package: nlohmann_json

      • Available versions: current and previous versions
      • The package is updated with every release.
      • File issues at the xmake issue tracker
      • xmake website
      Example: xmake project
      1. Create the following files:

        example.cpp
        #include <nlohmann/json.hpp>\n#include <iostream>\n#include <iomanip>\n\nusing nlohmann::json;\n\nint main()\n{\n    std::cout << std::setw(4) << json::meta() << std::endl;\n}\n
        xmake.lua
        add_requires(\"nlohmann_json\")\n\nadd_rules(\"mode.debug\", \"mode.release\")\ntarget(\"xm\")\n    set_kind(\"binary\")\n    add_files(\"example.cpp\")\n    add_packages(\"nlohmann_json\")\n    set_languages(\"cxx11\")\n
      2. Build

        xmake\n
      3. Run

        xmake run\n
      "},{"location":"integration/package_managers/#other-package-managers","title":"Other package managers","text":"

      The library is also contained in many other package repositories; Repology tracks the packaged versions across repositories.

      "},{"location":"integration/package_managers/#buckaroo","title":"Buckaroo","text":"

      If you are using Buckaroo, you can install this library's module with buckaroo add github.com/buckaroo-pm/nlohmann-json. There is a demo repo here.

      Warning

      The module is outdated as the respective repository has not been updated in years.

      "},{"location":"integration/package_managers/#cocoapods","title":"CocoaPods","text":"

      If you are using CocoaPods, you can use the library by adding pod \"nlohmann_json\", '~>3.1.2' to your podfile (see an example). Please file issues at the repository, as its issue tracker is no longer reachable.

      Warning

      The module is outdated as the respective pod has not been updated in years.

      "},{"location":"integration/package_managers/#npm","title":"npm","text":"

      This project does not publish an official npm package. The npm package nlohmann-json (or similarly named packages) is not maintained or endorsed by this project. Use one of the package managers listed above, or integrate the single header directly.

      "},{"location":"integration/package_managers/#esp-idf-and-platformio","title":"ESP-IDF and PlatformIO","text":"

      There is no official package published to the ESP-IDF Component Registry or the PlatformIO Registry. A community-maintained fork, Johboh/nlohmann-json, publishes this library to both registries on each new release and can be used as an unofficial component/package for ESP-IDF and PlatformIO projects. As the library is header-only, it can otherwise be used directly by adding its include/ directory to your component's/project's include paths, like any other integration method described on this page.

      "},{"location":"integration/package_managers/#see-also","title":"See also","text":"
      • CMake - use the library from CMake
      • Pkg-config - use the library with pkg-config
      • meta - query the library version at run time
      • NLOHMANN_JSON_VERSION_MAJOR - library version macros
      "},{"location":"integration/pkg-config/","title":"Pkg-config","text":"

      If you are using bare Makefiles, you can use pkg-config to generate the include flags that point to where the library is installed:

      pkg-config nlohmann_json --cflags\n

      A pkg-config file is installed by CMake (when the JSON_Install option is enabled, which is the default for a top-level build) as well as by several package managers.

      Users of the Meson build system will also be able to use a system-wide library, which will be found by pkg-config:

      json = dependency('nlohmann_json', required: true)\n
      "},{"location":"integration/pkg-config/#see-also","title":"See also","text":"
      • Integration - all ways to integrate the library
      • CMake - use the library from CMake
      • Package Managers - install the library via package managers
      "}]} \ No newline at end of file diff --git a/sitemap.xml b/sitemap.xml index fb256a096..a188e8f06 100644 --- a/sitemap.xml +++ b/sitemap.xml @@ -2,1614 +2,1614 @@ https://json.nlohmann.me/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/is_json_view/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/json/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/json_document/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/json_editable_document/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/json_editable_view/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/json_view/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/operator_gtgt/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/operator_literal_json/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/operator_literal_json_pointer/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/operator_ltlt/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/ordered_json/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/ordered_json_document/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/ordered_json_editable_document/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/ordered_json_editable_view/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/ordered_json_view/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/ordered_map/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/view_mode/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/adl_serializer/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/adl_serializer/from_json/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/adl_serializer/to_json/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json/accept/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json/array/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json/array_t/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json/as_base_class/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json/at/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json/back/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json/basic_json/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json/begin/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json/binary/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json/binary_t/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json/bjdata_version_t/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json/boolean_t/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json/cbegin/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json/cbor_tag_handler_t/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json/cend/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json/clear/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json/contains/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json/count/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json/crbegin/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json/crend/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json/default_object_comparator_t/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json/diff/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json/dump/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json/emplace/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json/emplace_back/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json/empty/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json/end/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json/end_pos/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json/erase/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json/error_handler_t/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json/exception/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json/find/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json/flatten/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json/format_as/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json/from_bjdata/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json/from_bon8/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json/from_bson/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json/from_cbor/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json/from_msgpack/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json/from_ubjson/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json/front/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json/get/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json/get_allocator/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json/get_binary/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json/get_ptr/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json/get_ref/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json/get_to/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json/input_format_t/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json/insert/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json/invalid_iterator/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json/is_array/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json/is_binary/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json/is_boolean/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json/is_discarded/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json/is_null/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json/is_number/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json/is_number_float/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json/is_number_integer/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json/is_number_unsigned/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json/is_object/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json/is_primitive/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json/is_string/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json/is_structured/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json/items/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json/json_base_class_t/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json/json_serializer/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json/max_size/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json/merge_diff/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json/merge_patch/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json/meta/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json/number_float_t/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json/number_integer_t/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json/number_unsigned_t/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json/object/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json/object_comparator_t/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json/object_t/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json/operator%2B%3D/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json/operator%3D/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json/operator%5B%5D/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json/operator_ValueType/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json/operator_eq/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json/operator_ge/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json/operator_gt/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json/operator_le/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json/operator_lt/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json/operator_ne/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json/operator_spaceship/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json/operator_value_t/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json/other_error/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json/out_of_range/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json/parse/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json/parse_error/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json/parse_event_t/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json/parser_callback_t/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json/patch/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json/patch_inplace/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json/push_back/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json/rbegin/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json/rend/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json/sax_parse/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json/size/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json/start_pos/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json/std_formatter/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json/std_hash/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json/std_swap/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json/string_t/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json/swap/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json/to_bjdata/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json/to_bon8/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json/to_bson/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json/to_cbor/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json/to_msgpack/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json/to_string/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json/to_ubjson/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json/type/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json/type_error/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json/type_name/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json/unflatten/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json/update/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json/value/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json/value_t/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json/with_t/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json/~basic_json/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json_document/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json_document/accept/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json_document/basic_json_document/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json_document/erase/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json_document/insert/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json_document/is_discarded/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json_document/load/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json_document/memory_usage/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json_document/node_count/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json_document/owns_source/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json_document/parse/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json_document/parse_copy/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json_document/push_back/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json_document/read/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json_document/root/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json_document/save/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json_document/set/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json_document/shrink_to_fit/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json_document/source/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json_view/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json_view/at/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json_view/back/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json_view/basic_json_view/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json_view/begin/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json_view/cbegin/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json_view/cend/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json_view/contains/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json_view/count/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json_view/dump/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json_view/empty/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json_view/end/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json_view/find/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json_view/front/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json_view/get/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json_view/get_string/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json_view/get_to/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json_view/is_array/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json_view/is_binary/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json_view/is_boolean/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json_view/is_discarded/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json_view/is_null/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json_view/is_number/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json_view/is_number_float/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json_view/is_number_integer/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json_view/is_number_unsigned/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json_view/is_object/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json_view/is_primitive/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json_view/is_string/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json_view/is_structured/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json_view/items/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json_view/materialize/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json_view/number_format/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json_view/number_token/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json_view/operator%5B%5D/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json_view/operator_eq/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json_view/operator_ltlt/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json_view/operator_ne/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json_view/size/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json_view/source_offset/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json_view/type/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json_view/type_name/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/basic_json_view/value/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/byte_container_with_subtype/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/byte_container_with_subtype/byte_container_with_subtype/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/byte_container_with_subtype/clear_subtype/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/byte_container_with_subtype/has_subtype/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/byte_container_with_subtype/operator_eq/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/byte_container_with_subtype/operator_ne/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/byte_container_with_subtype/set_subtype/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/byte_container_with_subtype/subtype/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/json_pointer/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/json_pointer/back/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/json_pointer/empty/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/json_pointer/front/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/json_pointer/json_pointer/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/json_pointer/operator_eq/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/json_pointer/operator_ne/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/json_pointer/operator_slash/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/json_pointer/operator_slasheq/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/json_pointer/operator_spaceship/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/json_pointer/operator_string_t/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/json_pointer/parent_pointer/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/json_pointer/pop_back/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/json_pointer/pop_front/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/json_pointer/push_back/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/json_pointer/push_front/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/json_pointer/string_t/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/json_pointer/to_string/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/json_sax/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/json_sax/binary/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/json_sax/boolean/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/json_sax/end_array/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/json_sax/end_object/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/json_sax/key/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/json_sax/null/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/json_sax/number_float/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/json_sax/number_integer/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/json_sax/number_unsigned/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/json_sax/parse_error/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/json_sax/start_array/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/json_sax/start_object/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/json_sax/string/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/macros/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/macros/json_assert/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/macros/json_brace_init_copy_semantics/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/macros/json_delete_deprecated_functions/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/macros/json_diagnostic_positions/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/macros/json_diagnostics/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/macros/json_disable_enum_serialization/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/macros/json_disable_stream_bulk_scan/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/macros/json_disable_tuple_reference_conversion/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/macros/json_disable_unlocked_file_io/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/macros/json_has_cpp_11/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/macros/json_has_filesystem/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/macros/json_has_range_view_conversion/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/macros/json_has_ranges/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/macros/json_has_static_rtti/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/macros/json_has_std_format/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/macros/json_has_three_way_comparison/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/macros/json_no_automatic_udls/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/macros/json_no_io/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/macros/json_no_simd/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/macros/json_no_thread_local/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/macros/json_noexception/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/macros/json_precise_stream_position/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/macros/json_skip_library_version_check/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/macros/json_skip_unsupported_compiler_check/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/macros/json_strict_binary_utf8/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/macros/json_strict_nul_handling/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/macros/json_throw_user/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/macros/json_use_global_udls/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/macros/json_use_implicit_conversions/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/macros/json_use_legacy_discarded_value_comparison/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/macros/json_use_objects_for_enum_keyed_maps/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/macros/json_use_simdutf/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/macros/nlohmann_define_derived_type/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/macros/nlohmann_define_type_intrusive/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/macros/nlohmann_define_type_non_intrusive/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/macros/nlohmann_define_type_with_names/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/macros/nlohmann_json_namespace/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/macros/nlohmann_json_namespace_begin/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/macros/nlohmann_json_namespace_no_version/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/macros/nlohmann_json_serialize_enum/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/macros/nlohmann_json_serialize_enum_strict/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/api/macros/nlohmann_json_version_major/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/community/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/community/assurance_case/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/community/code_of_conduct/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/community/contribution_guidelines/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/community/ecosystem/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/community/governance/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/community/quality_assurance/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/community/roadmap/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/community/security_policy/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/features/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/features/arbitrary_types/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/features/assertions/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/features/binary_values/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/features/comments/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/features/conversions/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/features/creating_values/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/features/enum_conversion/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/features/iterators/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/features/json_patch/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/features/json_pointer/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/features/json_view/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/features/macros/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/features/merge_patch/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/features/modifying_values/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/features/modules/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/features/namespace/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/features/no_exceptions/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/features/object_order/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/features/performance/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/features/serialization/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/features/trailing_commas/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/features/type_recipes/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/features/binary_formats/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/features/binary_formats/bjdata/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/features/binary_formats/bon8/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/features/binary_formats/bson/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/features/binary_formats/cbor/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/features/binary_formats/messagepack/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/features/binary_formats/ubjson/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/features/element_access/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/features/element_access/checked_access/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/features/element_access/default_value/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/features/element_access/unchecked_access/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/features/parsing/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/features/parsing/json_lines/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/features/parsing/large_and_partial_input/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/features/parsing/parse_exceptions/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/features/parsing/parser_callbacks/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/features/parsing/sax_interface/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/features/parsing/untrusted_input/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/features/types/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/features/types/number_handling/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/features/types/template_parameters/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/home/architecture/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/home/customers/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/home/debugging/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/home/design_goals/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/home/exceptions/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/home/faq/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/home/license/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/home/sponsors/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/home/releases/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/home/releases/unreleased/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/home/releases/v1.0.0/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/home/releases/v1.1.0/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/home/releases/v2.0.0/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/home/releases/v2.0.1/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/home/releases/v2.0.10/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/home/releases/v2.0.2/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/home/releases/v2.0.3/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/home/releases/v2.0.4/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/home/releases/v2.0.5/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/home/releases/v2.0.6/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/home/releases/v2.0.7/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/home/releases/v2.0.8/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/home/releases/v2.0.9/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/home/releases/v2.1.0/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/home/releases/v2.1.1/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/home/releases/v3.0.0/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/home/releases/v3.0.1/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/home/releases/v3.1.0/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/home/releases/v3.1.1/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/home/releases/v3.1.2/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/home/releases/v3.10.0/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/home/releases/v3.10.1/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/home/releases/v3.10.2/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/home/releases/v3.10.3/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/home/releases/v3.10.4/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/home/releases/v3.10.5/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/home/releases/v3.11.0/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/home/releases/v3.11.1/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/home/releases/v3.11.2/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/home/releases/v3.11.3/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/home/releases/v3.12.0/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/home/releases/v3.2.0/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/home/releases/v3.3.0/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/home/releases/v3.4.0/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/home/releases/v3.5.0/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/home/releases/v3.6.0/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/home/releases/v3.6.1/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/home/releases/v3.7.0/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/home/releases/v3.7.1/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/home/releases/v3.7.2/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/home/releases/v3.7.3/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/home/releases/v3.8.0/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/home/releases/v3.9.0/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/home/releases/v3.9.1/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/integration/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/integration/cmake/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/integration/compile_times/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/integration/migration_guide/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/integration/package_managers/ - 2026-10-27 + 2026-10-28 https://json.nlohmann.me/integration/pkg-config/ - 2026-10-27 + 2026-10-28 \ No newline at end of file diff --git a/sitemap.xml.gz b/sitemap.xml.gz index 91bc1b46c5598c92a01e7d34b9d2dbf1bfb705a6..a13a851312f3360979195cbb2436a631ae4a0fd0 100644 GIT binary patch delta 2625 zcmV-H3cmH>6yX#HABzYG06XE42O)prERqZ`80-_w?kz#Ft6PlOB*TMk?ZrO(lI&Ku zq}Z8VEWn@Ri`bSG{a^D?ERt2^=U<;k_2!YBmqvfN*j!#;ydf=2C-v~<;vawf{oVb= zuU~)p9G&tM-lR8c|K(yAg8kdo)zj0{rI&$5ZvCZk!<84i^ozfmU%a}${B(cu^_Ms4 zD}TWBQ~CO=jQE;A#ix(?=8eA8%Irq2_2o!cpRe+tkKfIG7)|%}=KAKtyUq2xoBQ;Z z`L*feua?jMpOm%w*9sDo6&ku<9RpD>_}(aSIh<8TZD)X!c+ zUFH0+EPYaKw}W?zd2*5~`LF8s=S;kJW<=P7GmKym5L@o001I;=$OfRkb9@h$XUOOG zEd54Iq!0H%3}6v#xp+XT<2&J&28ooHn!7z(AK44H-#Q*Rn^z;CB*uRz;!p$uZjNG` zrYC_9Y{zw{$U)13bO%&VO~C=>jSgIDk0gj1S^Ey%6&$qvb=32y0yEohBmxs=w0v4U z09HyT`yQwsM~hRZ(JC$o4#2QJTcQX+e+AknlQ^>mXp_mM`3h3rCHvEWYe3I=<}8u( zhF&6DVy}1zgnWGCMjn3{2X=*0OOWi0|=~F2Dultg5-bToS}^}iQ3CSgWKq| z1_(v4PL49jM}kuL;G`bV2vLOSpiLss2%LDAaG`bQ9O>B<6j(sb5y;4&nNJ8n0&)W} z>RiuAE_Ldr8q3;bq3@wzz&_I7>s)dqJEtG_Ap(MQJg8WX}23Q`m)qoBv zVVAs(vQ-U)h=G}&Ij)gLBRLr!Esw5=8RC&N)YT~%jtQ<*j^DweK&NL#KFv$O(Ns42 z9XON<9pQ)#aP<6{fejRP!Nv#f0ydt^hi=}U49LZ^jIn>?eupLSPuwC2^3pbPT);km zFz{Hei~x<~$^g*Fp#*@9;z|JU7_P*C-e*b(=peEHUHHlB=$S)d(0l|IL)7p<-)NIj z1{OhCPXNm!N989Oc1ZnyH;|-@I;i6%0&vp)3eslrU^7%!4sgih5l9PxZYz#5yakMr zM&tG@dOm-&&|0+Vh+z|6R~Yl8J@Y0y(L&K+muSv7QXScS3o!7-!Zyss*rjRg152~XUN*r4Hfn$)&d$|=0oD@$)@scNE!7Bi6J}x%O+X;GgJuNu zsV4^vs3%w$pod*d2-u?@W(IhhgeLmW2+)Myi2;9^)w>X&7v@(GU|Q(}0ncPyFu>`I zD+f5IaRF&yz2|@e&2BuRfTlQ}ae(t2&uP%fj^{k^jK>8CoUO5N;By}rlqSZ%HnJdR z7HBHu#4z%3$Up>>91L6u>1u-|m3mONsB47h?CJsm_%0A>>ud*zbtZ9h`@o|f&m7kFOH7LuG&JA+yxNndOI8OaH zRJx_I@_A{hxf;X}0Wa7(kp^sZo#-Q0&rbjltHvh)t+WK3C3_h|Qxh0o)la$k2}vWB zgUY3Tg$9!qbOK|!%gM71bYyERL!0%?0JndvsQ9xVA>c*PLJvV@3{9t>@n@7QWan>H zhwS$)^7%3d#18BU0A!0~A$TCz!vi)pkF;Uii02HL&BJpF(3atXfjekqL70;Hq4r=x zz*+>zFgSAIs-L1TiavWQ+j8R0$C^>DGHRnSx15g>R5jt zwaAzDK&d1jwDGBI^2r;r9ULr$FISLLvggZbx*Tx7(o0auq!1t3HmV2a1#bZ$7>~h>rJiD^JeCD&*pj}NV}~Wk z?SpqL-*u&+B&gdMk14W~DgELt9DF+c_G>yg3-{WC)RMTyzusLm^NgdrhvFNL>^BhAYc{V7s#ePlxm`_4(V(iX*)54I?zRfhzd!T)y9Jxi8TpmhOhsRJHUS=Kj zQs?ywCm-`I74;)$ULh*sk5UI0ef=DSpE2oFe=TyAAgCNK>cLQxf0RLN{j-jL4#N-` z=YN8fd|K#?_>^n8RjOFa_K1IGC#40jgLgafZ&i0-(%3piEvtsvt(x5X=y+NGt9$0z ziXig2Ri@8gP#3GVg=2;^1jud7(=9ec*->(rtD4@Gg@mcT%(to!CUpdzTLeV@drZb5 z?Ag*TAr#K=ZmfEc^s4PiM3;-enlwA8X%%|nIUCX=B)QwlP*xeT_k({yC>x-aCt-{F zyk=15TM&TU0!asuHev$2%DePa4#2~eesP8%yD1C8;bL>h^H1xal`nNUQ?DKye5zmh z7_mjXdgRHf47q7_l{cO2_t<`)J}D}UG-6J_iW|1UmUw)jn(DHJ+&PMU=z) z>+Zn+AYEn|wbwO&pin$J{aknX;>3`gkbI413`nFo^#baTp0IzccdSBL^6i#oPTYfL z2?vl^HfVFG53H@gmL(_QIY|i+$a4k~XtaulJZ*Pr0+|{|%~IK!yoKk)P6jGR_tn-G zsTrp4^&h&UZ5)QWRX+>oyf`)(uBtyY#3UExo`0_`siYw7tG8%xQ}LSm4ca9qjeElB zMm_)7!4Mudm)C!n*GTydQvL?}^jUrbmIpun4OadZEB_uVe}|R-fR+D z{%^4L50<~h%D>0T-(lrHpyi>K=Ogy%Kcb)h1}hJ>y7v^=y8nchui5m delta 2625 zcmV-H3cmH>6yX#HABzYGfa%|n2O)nBi^KyA2KxlFdrMI4>K1J_$?#xXd$G^HB)iou zDRE{O3-IUoBDQ5k|JOVei)0n~<=2-{y?G+%rO{t6Hka2IZ%7N%Nj-eM_{SfAfA{I) z*ZW_-M5jE3H|fpVf4$g+VE=Y?_5A#N>1CjiTYqWXaOK4={o=3Y7q6}_KVN^`|MDh% z91eEOINZ}g>BW;b%JFGsria+Uvl{BG{UXuA8G>zfbnHrMZNKBl+K zuT39+wS4~nq{OYflAh()*^{K_%F_8ofF$dTh$HEM(56lXzE#u)1gO#xy2g^@!8kUA zA)vHXvJ8$Z259*|WMI}voqm6Xu>@7UE?h^BI!F~9Nu&Dz2?N>~{TK#e9F9SN`q^u! ztDGN}rBABucJNLyPfl_r|5e@ooQe0&j0k&hh7k+`V#~c0U|}u<*#Ojcj_<+p4Eg+? zrQe8&^x+Z4!Y-;KaLx3#~inNYAFAzyfNHKt}$;d_n*ckQ<0$ zSLi1O%Y)bXrUyA2Kp;gEtG_6p(Jz*CE+a>26Rvf zyX0+@t!f}d49xV*ag8(@$;t3&d2~(85Kp9`u1>*lOmL-g{06{u<>L*bo2IPKrWtTj2(aXJ1l{J<`zkim$s4P0`~cX zfyZ)X1ZX5z27pEmB>-#`R|0^?a3u!xK2t(K2ayHn!cSI5&m0Pa<|D8eqJ{_hMw^T> zun5X}0$3h7DnHAxL+by#fh1kjK^;FL04MFQAZ->8HbZ6Q0EavtfwU0lw&EzmTfi7; zG;YtL=R|7lfU_Aj~t=5dtQjK6YVI~IA1O#$BXhuMv zdUC*kdV+-kdf3H;fIaGAW`MUzXrlj&08Qwf7?6Kiy$b<)VSWVxrjH8DGV~F<%|SyAH}OI8r_FHz8g>Lq|Efa zhtGeypm9Je0yYq5;(&yr>_gu5D$8QYnwDq~AGe5F`3cEigR&gy+#uJE`v$3ibZt3eDA@Pe%qX~0I;i9TZW`~(28YJ39FN=v|5vL9n;Y68Qn`YAU*A!(#? zP`T8v&|tEHPGBr|IeE5$j%@)a0iVn2vagY)E-O- zSc?D|21hPj^-~mP(emWn1Cou70k$q*3?;P;B}0OFO79F(APc1c>qziG9qWIi z7WvX1D3#=cHa?Y2K6yj7gM+2;WA1J;{U!|%DQ|2DYuRQ4hR8+X_dd`F1}O)^mEFWP8qLDw z!4S!L$u`-AAmJn(CV=J~Btc3Frt8sKgT$S@hM{d5$5HJR6kRa)p03{+UFM zR!LE&y9X}{jihMcV!tMT%qJl?F?MIZX<^7`-)5TVJ<>i=j@+V4E)S)t!(%88FSCw% zsq=b;lTZ1Uiu#c=uMm~+N2!C0zJ3nE&zN+ozZSVl5LAvA^YjPF zB8Yr$mFcq=)Wxc8;g}%}0dgDjbc+p9c9h)Zs-|~kAz`X7^R4QGNgYAw76Fm}7L#!Z zd$zPo2!%7e8>=29y=r?B(d8nrCe03NT7{l?&W7{|N$$2XlvRf8{a}9($_8lVN!X%3 zuNjp276c%-K+*xEjhFzh@-F?91MqOAUz{PxZpwmixY!)>{L}hp02PEes|5QAa!rBc@@KB`oMh#aRJ^8sgLcVD0T-(lrHVC6qz>AJI>LgO!I`-A@$Qy8n!pui5m