From 1eb9589abb1b098ae0fb777f00b30f420559a70f Mon Sep 17 00:00:00 2001
From: nlohmann
Date: Fri, 9 Oct 2026 06:04:53 +0000
Subject: [PATCH] deploy: d33068da730aa1ffa3f1acb332e36653681efa2c
---
community/roadmap.md | 32 +-
community/roadmap/index.html | 4 +-
community/roadmap/index.md | 22 +-
search/search_index.json | 2 +-
sitemap.xml | 552 +++++++++++++++++------------------
sitemap.xml.gz | Bin 2053 -> 2053 bytes
6 files changed, 318 insertions(+), 294 deletions(-)
diff --git a/community/roadmap.md b/community/roadmap.md
index 27afeb4c5..1b1f287a9 100644
--- a/community/roadmap.md
+++ b/community/roadmap.md
@@ -36,13 +36,26 @@ work items are tracked in the [GitHub milestones](https://github.com/nlohmann/js
## API stability
Releases follow [semantic versioning](https://semver.org): a minor or patch release of version 3.x does not break code
-that uses the public API. In particular, a 3.x release does not:
+that uses the public API, unless that code opts in to a change with a macro as described [below](#version-40). In
+particular, a 3.x release does not:
-- change the signature of a function (its parameter types, return type, number of parameters, or the const-ness of a
- member function);
-- remove or rename a function or class;
+- 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](../home/exceptions.md);
-- change access specifiers or default arguments.
+- 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`](../api/ordered_json.md) 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`](../api/adl_serializer/index.md);
+- add pure virtual functions to the [`json_sax`](../api/json_sax/index.md) 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](../home/releases.md).
@@ -51,13 +64,14 @@ The following are **not** part of the public API and may change in any release,
- The text of exception messages returned by `what()`. Use the [exception id](../home/exceptions.md) to tell errors
apart.
-- The ABI, including `sizeof(basic_json)` and the memory layout of its values. Recompile your code when you upgrade the
- library. The [versioned inline namespace](../features/namespace.md) turns mixing versions into a link error.
+- The ABI, including `sizeof(basic_json)` and the memory layout of its values. The
+ [versioned inline namespace](../features/namespace.md) 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](../api/basic_json/index.md).
-Changes that would break the public API are only added behind a macro whose default keeps the 3.x behavior, see
-[Version 4.0](#version-40).
+Breaking changes are only added behind a macro whose default keeps the 3.x behavior. See [Version 4.0](#version-40) and
+the [macro overview](../features/macros.md).
## Version 4.0
diff --git a/community/roadmap/index.html b/community/roadmap/index.html
index 6644169e7..738747f05 100644
--- a/community/roadmap/index.html
+++ b/community/roadmap/index.html
@@ -1,4 +1,4 @@
- Roadmap - JSON for Modern C++
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.
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.
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.
Releases follow semantic versioning: a minor or patch release of version 3.x does not break code that uses the public API. In particular, a 3.x release does not:
change the signature of a function (its parameter types, return type, number of parameters, or the const-ness of a member function);
remove or rename a function or class;
change which exceptions a function throws, or the exception ids;
change access specifiers or default arguments.
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. Recompile your code when you upgrade the library. The versioned inline namespace turns mixing versions into a link error.
Everything in namespace nlohmann::detail, and macros and type traits that are not documented in the API reference.
Changes that would break the public API are only added behind a macro whose default keeps the 3.x behavior, see Version 4.0.
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.
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.
The following macros guard changes that are planned to become the default in version 4.0:
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.
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.
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.
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.
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.
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.
The following macros guard changes that are planned to become the default in version 4.0:
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.
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.
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.
\ No newline at end of file
diff --git a/community/roadmap/index.md b/community/roadmap/index.md
index 80d0385c5..888efe473 100644
--- a/community/roadmap/index.md
+++ b/community/roadmap/index.md
@@ -22,22 +22,32 @@ This page describes what the project intends to do, and what it does not intend
## API stability
-Releases follow [semantic versioning](https://semver.org): a minor or patch release of version 3.x does not break code that uses the public API. In particular, a 3.x release does not:
+Releases follow [semantic versioning](https://semver.org): 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](#version-40). In particular, a 3.x release does not:
-- change the signature of a function (its parameter types, return type, number of parameters, or the const-ness of a member function);
-- remove or rename a function or class;
+- 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](https://json.nlohmann.me/home/exceptions/index.md);
-- change access specifiers or default arguments.
+- 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`](https://json.nlohmann.me/api/ordered_json/index.md) 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`](https://json.nlohmann.me/api/adl_serializer/index.md);
+- add pure virtual functions to the [`json_sax`](https://json.nlohmann.me/api/json_sax/index.md) 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](https://json.nlohmann.me/home/releases/index.md).
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](https://json.nlohmann.me/home/exceptions/index.md) to tell errors apart.
-- The ABI, including `sizeof(basic_json)` and the memory layout of its values. Recompile your code when you upgrade the library. The [versioned inline namespace](https://json.nlohmann.me/features/namespace/index.md) turns mixing versions into a link error.
+- The ABI, including `sizeof(basic_json)` and the memory layout of its values. The [versioned inline namespace](https://json.nlohmann.me/features/namespace/index.md) 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](https://json.nlohmann.me/api/basic_json/index.md).
-Changes that would break the public API are only added behind a macro whose default keeps the 3.x behavior, see [Version 4.0](#version-40).
+Breaking changes are only added behind a macro whose default keeps the 3.x behavior. See [Version 4.0](#version-40) and the [macro overview](https://json.nlohmann.me/features/macros/index.md).
## Version 4.0
diff --git a/search/search_index.json b/search/search_index.json
index fe6a62ea8..ae8c005fd 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":"
JSON for Modern C++ is a header-only C++11 library that turns JSON into a first-class C++ data type, using the operator magic of modern C++ so that creating, reading, and modifying JSON values feels as natural as it does in languages like Python. The whole library is available as a single header, json.hpp, with no dependencies, no subproject, and no complex build system to set up; a companion header, json_fwd.hpp, provides forward declarations to keep compile times down. See header-only integration for details. It is heavily unit-tested with 100% code coverage, checked with Valgrind and the Clang Sanitizers for memory leaks, and continuously fuzz-tested by Google OSS-Fuzz.
Add the single header to your project and use the library like this:
#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n // parse a JSON string\n json j = json::parse(R\"({\"happy\": true, \"pi\": 3.141})\");\n\n // access and modify values\n j[\"name\"] = \"Niels\";\n j[\"list\"] = {1, 0, 2};\n\n // serialize with an indent of 4 spaces\n std::cout << j.dump(4) << '\\n';\n}\n
Get the library by copying the single header json.hpp from the releases page into a directory nlohmann on your include path, or by installing it with a package manager:
See Integration for CMake in detail, all supported package managers (Conan, Meson, Bazel, Conda, and more), and pkg-config.
"},{"location":"#explore-the-documentation","title":"Explore the documentation","text":"
Features
Creating, parsing, accessing, and serializing JSON values, JSON Pointer/Patch, binary formats, 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.
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
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; see Releases for what shipped in each version.
The library is licensed under the MIT License. The source code, issue tracker, and discussions are on GitHub.
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":"
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.
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:
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 -- 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.
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.
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:
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":"
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:
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":"
std::ostream& operator<<(std::ostream& o, const basic_json& j); // (1)\n\nstd::ostream& operator<<(std::ostream& o, const json_pointer& ptr); // (2)\n
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.
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":"
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.
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.
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.
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.
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.
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.
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.
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):
njsonordered_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 -- see object order.
This function is usually called by the get() function of the basic_json class (either explicitly or via the conversion operators).
This function is chosen for default-constructible value types.
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":"
(none) -- the converted value is written to the output parameter val.
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 json = 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 << std::endl;\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 json = 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 << std::endl;\n}\n
Output:
Ned Flanders (60) lives in 744 Evergreen Terrace\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.
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_tArrayType type for JSON arrays array_tStringType type for JSON strings and object keys string_tBooleanType type for JSON booleans boolean_tNumberIntegerType type for JSON integer numbers number_integer_tNumberUnsignedType type for JSON unsigned integer numbers number_unsigned_tNumberFloatType type for JSON floating-point numbers number_float_tAllocatorType type of the allocator to use JSONSerializer the serializer to resolve internal calls to to_json() and from_json()json_serializerBinaryType type for binary arrays binary_tCustomBaseClass 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.
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.
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.
json_serializer - type of the serializer to for conversions from/to JSON
error_handler_t - type to choose behavior on decoding errors
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
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_typebasic_jsonreferencevalue_type&const_referenceconst value_type&difference_typestd::ptrdiff_tsize_typestd::size_tallocator_typeAllocatorType<basic_json>pointerstd::allocator_traits<allocator_type>::pointerconst_pointerstd::allocator_traits<allocator_type>::const_pointeriterator LegacyBidirectionalIterator const_iterator constant LegacyBidirectionalIterator reverse_iterator reverse iterator, derived from iteratorconst_reverse_iterator reverse iterator, derived from const_iteratoriteration_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)
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!=.
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.
a pointer to a null-terminated string of single byte characters (throws if null)
a std::string
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, 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":"
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.
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 json = 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
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.
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.
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":"
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:
creating an array whose elements are all pairs whose first element is a string -- in this case, the initializer list constructor would create an object, taking the first elements as keys
creating an empty array -- passing the empty initializer list to the initializer list constructor yields an empty object
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 value for array_t is:
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.
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.
Returns a reference to the array element at specified location idx, with bounds checking.
Returns a reference to the object element with specified key key, with bounds checking.
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.
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":"
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.
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.
See 2.
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).
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 json = 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 json = 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.
\"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.
\"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 json = 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 json = 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 json = 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 json = 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
Added in version 3.11.0. Fixed in version 3.13.0 unreleased to consistently accept std::string_view-convertible keys, as already supported by operator[], value, find, and other lookup functions.
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.
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().
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 -- it is only used to choose the right constructor.
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.
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.
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.
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:
If the list is empty, an empty JSON object value {} is created.
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.
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\"]
The rules aim to create the best fit between a C++ initializer list and JSON values. The rationale is as follows:
The empty initializer list is written as {} which is exactly an empty JSON object.
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.
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.
Constructs a JSON array value by creating cnt copies of a passed value. In case cnt is 0, an empty array is created.
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.
Creates a copy of a given JSON value.
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.
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":"
Strong guarantee: if an exception is thrown, there are no changes to any JSON value.
No-throw guarantee: this constructor never throws exceptions.
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.
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.
Strong guarantee: if an exception is thrown, there are no changes to any JSON value.
Strong guarantee: if an exception is thrown, there are no changes to any JSON value.
Strong guarantee: if an exception is thrown, there are no changes to any JSON value.
Strong guarantee: if an exception is thrown, there are no changes to any JSON value.
No-throw guarantee: this constructor never throws 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.
(none)
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.
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.
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 json = 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 json = nlohmann::json;\nusing ordered_json = 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
The code below shows the move constructor explicitly called via std::move.
#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing json = 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
Since version 3.2.0. Explicit for different string types if JSON_USE_IMPLICIT_CONVERSIONS is 0 since version 3.13.0 unreleased.
Since version 1.0.0.
Since version 1.0.0.
Since 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.
#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing json = 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
Creates a JSON binary array value from a given binary container.
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":"
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.
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++.
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 -- 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.
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.
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:
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.
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) is used. For other sizes, the ext family (ext8, ext16, ext32) is used. The subtype is then added as a signed 8-bit integer.
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.
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.
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 value for boolean_t is bool.
#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing json = 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
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 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 innermost one is stored."},{"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 json = 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
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 []
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.
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.
Check whether the given JSON pointer ptr can be resolved in the current JSON value.
"},{"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":"
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.
See 1.
true if the JSON pointer can be resolved to a stored value, false otherwise.
This method always returns false when executed on a JSON type that is not an object.
This method can be executed on any JSON value type.
Calling this function with an integer argument (for example, 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
Added in version 3.6.0. Extended template KeyType to support comparable types in version 3.11.0. Fixed in version 3.13.0 unreleased to consistently accept std::string_view-convertible keys, as already supported by operator[], at, value, and other lookup functions.
Added in version 3.7.0.
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.
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).
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.
"},{"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.
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 json = 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 json = 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
Added in version 1.0.0. Changed parameter key type to KeyType&& in version 3.11.0. Fixed in version 3.13.0 unreleased to consistently accept std::string_view-convertible keys, as already supported by operator[], at, value, and other lookup functions.
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.
The following code shows an example for crbegin().
#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing json = 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
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.
#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing json = 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
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 always yields true:
source.patch(diff(source, target)) == target;\n
"},{"location":"api/basic_json/diff/#parameters","title":"Parameters","text":"source (in) JSON value to compare from target (in) JSON value to compare against"},{"location":"api/basic_json/diff/#return-value","title":"Return value","text":"
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
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.
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.
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.
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 json = 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
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.
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":"
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.
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.
This function does not return whether a string stored as JSON value is empty -- it returns whether the JSON container itself is empty which is false in the case of a string.
#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing json = 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
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
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.
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.
Removes an element from a JSON object by key.
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.
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":"
Iterator following the last removed element. If the iterator pos refers to the last element, the end() iterator is returned.
Iterator following the last removed element. If the iterator last refers to the last element, the end() iterator is returned.
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).
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\"
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\"
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\"
See 3.
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\"
Added in version 1.0.0. Added support for binary types in version 3.8.0.
Added in version 1.0.0. Added support for binary types in version 3.8.0.
Added in version 1.0.0.
Added in version 3.11.0. Fixed in version 3.13.0 unreleased to consistently accept std::string_view-convertible keys, as already supported by operator[], at, value, and other lookup functions.
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] (dump.md) itself must produce text, and keep there writes the ill-formed bytes to the output as is, so the result is then not valid UTF-8 (but still equals the input bytes exactly, including around any well-formed 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 json = 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() << std::endl;\n }\n catch (const json::type_error& e)\n {\n std::cout << e.what() << std::endl;\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
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
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
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.
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.
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.
"},{"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.
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
Added in version 1.0.0. Changed to support comparable types in version 3.11.0. Fixed in version 3.13.0 unreleased to consistently accept std::string_view-convertible keys, as already supported by operator[], at, value, and other lookup functions.
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.
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.
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 json = 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
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())
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.
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.
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. This overload will be removed in version 4.0.0. 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.
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.
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. This overload will be removed in version 4.0.0. 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.
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.
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. This overload will be removed in version 4.0.0. 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.
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_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.
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), or if a string value or object key is not valid UTF-8 and error_handler is strict
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. This overload will be removed in version 4.0.0. 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.
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.
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
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. This overload will be removed in version 4.0.0. 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.
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.
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. This overload will be removed in version 4.0.0. 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.
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.
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.
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.
Overload for basic_json specializations. The function is equivalent to executing
return *this;\n
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_jsonPointerType 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":"
copy of the JSON value, converted to ValueType
a copy of *this, converted into BasicJsonType
pointer to the internally stored JSON value if the requested pointer type fits to the JSON value; nullptr otherwise
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.
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 json = 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 (auto i : v8)\n {\n std::cout << i.first << \": \" << i.second << '\\n';\n }\n}\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 json = nlohmann::json;\n\nint main()\n{\n // create a JSON number\n json value = 17;\n\n // explicitly getting pointers\n 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 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
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
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.
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 json = nlohmann::json;\n\nint main()\n{\n // create a JSON number\n json value = 17;\n\n // explicitly getting pointers\n 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 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
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
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\".
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.
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":"
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.
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 json = 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 (auto i : v8)\n {\n std::cout << i.first << \": \" << i.second << '\\n';\n }\n}\n
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":"
iterator pointing to the inserted val.
iterator pointing to the first element inserted, or pos if cnt==0
iterator pointing to the first element inserted, or pos if first==last
iterator pointing to the first element inserted, or pos if ilist is empty
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\"
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\"
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\"
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\"
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\"
Constant plus linear in the distance between pos and end of the container.
Linear in cnt plus linear in the distance between pos and end of the container.
Linear in std::distance(first, last) plus linear in the distance between pos and end of the container.
Linear in ilist.size() plus linear in the distance between pos and end of the container.
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 json = 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 json = 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 json = 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
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 json = 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 json = 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
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.
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.
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 json = 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
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.
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 -- decltype is the supported way to obtain it, but its exact name/definition may change between versions.
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.
Added items and deprecated iterator_wrapper in 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.
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.
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.
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_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.
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.
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 json = 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 << std::endl;\n}\n
Output:
Ned Flanders (60) lives in 744 Evergreen Terrace\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.
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.
This function does not return the maximal length of a string stored as JSON value -- it returns the maximal number of string elements the JSON value can store which is 1.
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.
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.
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.
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. Parsing and serialization are implemented in terms of std::strtof/std::strtod/std::strtold and std::snprintf, so the type must be float, double, or long double. 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 value for number_float_t is double.
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.
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. Note values smaller than -1.79769313486232e+308 and values greater than 1.79769313486232e+308 will be stored as NaN internally and be serialized to null.
During deserialization (from JSON text or any of the binary formats), a finite number that does not fit into number_float_t is rejected with out_of_range.406, for example a double-precision number in a binary format when number_float_t is float.
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 value for number_integer_t is std::int64_t.
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.
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.
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. 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 value for number_unsigned_t is std::uint64_t.
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.
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.
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":"
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.
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).
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.
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 -- 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 value for object_t is:
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.
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.
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.
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.
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.
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.
This function allows using operator+= with an initializer list. In case
the current value is an object,
the initializer list init contains only two elements, and
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&&).
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":"
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.
(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.
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.
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.
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 json = 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
Returns a reference to the array element at specified location idx.
Returns a reference to the object element with specified key key. The non-const qualified overload takes the key by value.
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.
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":"
(const) reference to the element at index idx
(const) reference to the element at key key
(const) reference to the element at key key
(const) reference to the element pointed to by ptr
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.)
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.
See 2.
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.
The following cases apply to the const overloads; the non-const overloads instead insert the missing element (see the notes below).
If the element at index idx does not exist, the behavior is undefined and is guarded by a runtime assertion!
If the element with key key does not exist, the behavior is undefined and is guarded by a runtime assertion!
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!
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.
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.
See 2.
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 parses as a non-negative integer: a numeric token creates an array, a non-numeric 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. 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 json = 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
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.
Added in version 1.0.0. Added overloads for T* key in version 1.1.0. Removed overloads for T* key (replaced by 3) in version 3.11.0.
Added in version 3.11.0. Fixed in version 3.13.0 unreleased to consistently accept std::string_view-convertible keys, as already supported by at, value, find, and other lookup functions.
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.
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":"
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().
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.
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>.
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
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 automatically converted before comparison.
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":"
No-throw guarantee: this function never throws exceptions.
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.
NaN values are unordered within the domain of numbers. The following comparisons all yield false:
Comparing a NaN with itself.
Comparing a NaN with another NaN.
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:
Added in version 1.0.0. Added C++20 member functions in version 3.11.0.
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.
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<).
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":"
No-throw guarantee: this function never throws exceptions.
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.
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.
Added in version 1.0.0. Conditionally removed since C++20 in version 3.11.0.
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.
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<=).
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":"
No-throw guarantee: this function never throws exceptions.
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.
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<=>.
Added in version 1.0.0. Conditionally removed since C++20 in version 3.11.0.
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.
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<).
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":"
No-throw guarantee: this function never throws exceptions.
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.
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.
Added in version 1.0.0. Conditionally removed since C++20 in version 3.11.0.
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.
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 automatically converted before comparison.
In case lhs and rhs have different types, the values are ignored and the order of the types is considered, which is:
null
boolean
number (all types)
object
array
string
binary For instance, any boolean value is considered less than any string.
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":"
No-throw guarantee: this function never throws exceptions.
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.
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<=>.
Added in version 1.0.0. Conditionally removed since C++20 in version 3.11.0.
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.
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.
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
No-throw guarantee: this function never throws exceptions.
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.
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.
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==.
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.
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 converted to their common type and then 3-way compared using their respective operator<=>. For instance, comparing an integer and a floating-point value will 3-way compare the first value converted to floating-point with the second value.
Otherwise, yields a result by comparing the type (see value_t).
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
No-throw guarantee: this function never throws exceptions.
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.
Value type return value nullvalue_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.
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
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!=.
a pointer to a null-terminated string of single byte characters (throws if null)
a std::string
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, 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.
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.
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.
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.
"},{"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.
[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.
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.
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.
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
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.
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
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 json = 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 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
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 parsedparse_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
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.
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 json = nlohmann::json;\n\nint main()\n{\n // a JSON text with an array and a number inside an object\n 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
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.
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.
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 (\"add\", \"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.
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.
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.
"},{"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.
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 json = 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 << std::endl;\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
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.
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.
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.
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 (\"add\", \"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.
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.
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.
"},{"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.
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 json = 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 << std::endl;\n}\n
Output:
[json.exception.out_of_range.403] key 'nonexistent' not found\n{\n \"a\": 99,\n \"b\": 2\n}\n
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.
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.
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.
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.
This function allows using push_back with an initializer list. In case
the current value is an object,
the initializer list init contains only two elements, and
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&&).
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.
(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.
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 json = 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
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.
#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing json = 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
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!=.
The SAX event lister must follow the interface of json_sax.
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 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":"
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.
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
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.
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.
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.
This function does not return the length of a string stored as JSON value -- it returns the number of elements in the JSON value which is 1 in the case of a string.
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
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.
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.
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_swap/#parameters","title":"Parameters","text":"j1 (in, out) value to be replaced by j2j2 (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.
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.
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 -- 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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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":"
No-throw guarantee: this function never throws exceptions.
No-throw guarantee: this function never throws exceptions.
Strong guarantee: if an exception is thrown, there are no changes to any JSON value.
Strong guarantee: if an exception is thrown, there are no changes to any JSON value.
Strong guarantee: if an exception is thrown, there are no changes to any JSON value.
Strong guarantee: if an exception is thrown, there are no changes to any JSON value.
Strong guarantee: if an exception is thrown, there are no changes to any JSON value.
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.
Returns a byte vector containing the BJData serialization.
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 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":"
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 BJData\"
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.
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.
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.
Returns a byte vector containing the BON8 serialization.
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":"
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.
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).
Returns a byte vector containing the BSON serialization.
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":"
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.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\"
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.
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.
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.
Returns a byte vector containing the CBOR serialization.
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":"
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\"
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.
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.
Returns a byte vector containing the MessagePack serialization.
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":"
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 maximum of the 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\"
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 json = 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
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.
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
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.
Returns a byte vector containing the UBJSON serialization.
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":"
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\"
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.
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.
Value type return value nullvalue_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.
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
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.
The following code exemplifies type_name() for all JSON types.
#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing json = 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
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:
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 cannot be an array index; example: \"unresolved reference token 'x'\"
Empty objects and arrays are flattened by flatten() to null values and cannot 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.
Apart from these two cases, for a JSON value j, the following is always true: j == j.flatten().unflatten().
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.
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
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.
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.
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":"
copy of the element at key key or default_value if key is not found
copy of the element at key key or default_value if key is not found
copy of the element at JSON Pointer ptr or default_value if no value for ptr is found
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.
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.
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 json = 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
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.
Added in version 3.11.0. Made ValueType the first template parameter in version 3.11.2. Fixed in version 3.13.0 unreleased to consistently accept std::string_view-convertible keys, as already supported by operator[], at, find, and other lookup functions.
Added in version 2.0.2. Extended to work with arrays in version 3.13.0 unreleased, including fixing an issue where resolving ptr through an array unexpectedly threw out_of_range instead of returning the resolved element (or default_value, as documented).
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.
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]
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
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.
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.
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() << std::endl;\n}\n
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 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)
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.
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 -- 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":"
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.
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):
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.
The example shows the construction several valid JSON pointers as well as the exceptional behavior.
#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing json = 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
Compares two JSON pointers for equality by comparing their reference tokens.
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":"
\"\" == \"\": 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
Compares two JSON pointers for inequality by comparing their reference tokens.
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
\"\" != \"\": 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
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.
append another JSON pointer at the end of this JSON pointer
append an unescaped reference token at the end of this JSON pointer
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":"
JSON pointer with ptr appended
JSON pointer with token appended without escaping token
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.
Strong guarantee: if an exception is thrown, there are no changes to the JSON pointer.
Strong guarantee: if an exception is thrown, there are no changes to the JSON pointer.
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
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.
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.
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()
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)
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
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
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
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
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/#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":"
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
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
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/#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).
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/#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":"
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/#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":"
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
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
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_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
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.
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.
#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.
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():
#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.
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 json = 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 json = 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
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.
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.
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.
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.
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.
#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.
Enum serialization can also be controlled with the CMake option JSON_DisableEnumSerialization (OFF by default) which defines JSON_DISABLE_ENUM_SERIALIZATION accordingly.
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 json = 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 json = 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
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_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).
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 json = 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 json = 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
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.
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.
#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.
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:
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.
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.
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)
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.
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.
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.
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.
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.
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.
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)).
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.
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.
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.
#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.
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.
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:
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.
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 they always return the bytes unchanged.
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 json = 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 json = 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
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.
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 json = 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 json = 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
// (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.
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.
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.
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:
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
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.
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
#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).
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:
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.
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.
#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.
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:
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:
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 scalar validator. On text with many non-ASCII characters (e.g. CJK or emoji) this can validate several times faster.
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). Streaming inputs (files, std::istream, 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 -- 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.
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.
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:
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
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:
NLOHMANN_DEFINE_TYPE_INTRUSIVE / NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT / NLOHMANN_DEFINE_TYPE_INTRUSIVE_ONLY_SERIALIZE for 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 for similar macros that can be defined outside a non-derived type.
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.
Will use at during deserialization and will throw out_of_range.403 if a key is missing in the JSON object.
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.
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:
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.
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:
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.
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.
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.
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.
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE, NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT, NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE for 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 for similar macros for derived types
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.
Will use at during deserialization and will throw out_of_range.403 if a key is missing in the JSON object.
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.
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:
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.
The macro must be used outside the type (class/struct).
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:
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.
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.
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.
NLOHMANN_DEFINE_TYPE_INTRUSIVE, NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT, NLOHMANN_DEFINE_TYPE_INTRUSIVE_ONLY_SERIALIZE for 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 for similar macros for derived types
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
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.
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
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 json = 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) << std::endl;\n}\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:
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.
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.
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:
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.
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.
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 json = 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() << std::endl;\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() << std::endl;\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
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.
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, 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).
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]
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, and merge_patch, recurse only up to a fixed depth and continue with an explicit stack below it. Some operations, such as diff, flatten, and the binary writers, still recurse once per nesting level; work on them is in progress. 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.
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.
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.
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.
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.
Community leaders will follow these Community Impact Guidelines in determining the consequences for any action they deem in violation of this Code of Conduct:
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.
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.
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.
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.
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.
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.
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:
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.
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
A new API page also needs an entry in docs/docset/docSet.sql, the search index of the docset; make build reports missing entries.
"},{"location":"community/contribution_guidelines/#amalgamate-the-source-code","title":"Amalgamate the source code","text":"
The single-header files single_include/nlohmann/json.hpp and single_include/nlohmann/json_fwd.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/#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 Studio 13.0 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.
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.
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 Clang.
Improving the efficiency of the JSON parser. The current parser is implemented as a naive recursive descent parser with hand-coded string handling. More sophisticated approaches like LALR parsers would be really appreciated. That said, 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, and I am not aware of approaches similar to re2c for parsing.
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!
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.
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
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
"},{"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 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 8 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.
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.
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.
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.
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.
Releases follow semantic versioning: a minor or patch release of version 3.x does not break code that uses the public API. In particular, a 3.x release does not:
change the signature of a function (its parameter types, return type, number of parameters, or the const-ness of a member function);
remove or rename a function or class;
change which exceptions a function throws, or the exception ids;
change access specifiers or default arguments.
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. Recompile your code when you upgrade the library. The versioned inline namespace turns mixing versions into a link error.
Everything in namespace nlohmann::detail, and macros and type traits that are not documented in the API reference.
Changes that would break the public API are only added behind a macro whose default keeps the 3.x behavior, see Version 4.0.
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.
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_CONVERSIONS10: no implicit conversions from basic_json to other types; use get instead JSON_ImplicitConversions 3.9.0 JSON_USE_GLOBAL_UDLS10: the string literals _json and _json_pointer are only available in namespace nlohmann::literalsJSON_GlobalUDLs 3.11.0 JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON0 removed: the deprecated legacy comparison of discarded values can no longer be enabled JSON_LegacyDiscardedValueComparison 3.11.0 JSON_BRACE_INIT_COPY_SEMANTICS01: single-element brace initialization such as json j{obj}; copies the element instead of creating an array \u2013 3.13.0 JSON_PRECISE_STREAM_POSITION01: reading from a stream does not consume the character after a number \u2013 3.13.0 JSON_STRICT_NUL_HANDLING01: a NUL byte in the input is a parse error instead of the end of input JSON_StrictNulHandling 3.13.0 JSON_STRICT_BINARY_UTF801: 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_CONVERSION01: 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_FUNCTIONS0 removed: the deprecated functions are removed (see below); the from_*(ptr, len) overloads stay deleted JSON_DeleteDeprecatedFunctions 3.13.0
For example, the following makes a 3.x release behave like version 4.0 with respect to these changes:
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
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.
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.
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.
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, and parsing untrusted input.
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.
Specializing enum conversion \u2014 map enums to strings instead of integers.
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.
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/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:
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: deserialize a person from JSON with from_json
#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing json = 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 << std::endl;\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\"]
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
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
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.
Example: using the NLOHMANN_DEFINE_TYPE_* macros
The to_json/from_json functions for the person struct above can be created with:
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 -- no separate macro or extra code is needed.
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):
There is currently no NLOHMANN_DEFINE_TYPE_*-style macro for types that are not DefaultConstructible. This is not an intentional omission of documentation -- 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\"]
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
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 json = 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 << std::endl;\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-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 -- 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 -- 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:
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.
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 json = 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 json = 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:
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:
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:
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":"
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:
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
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.
BJData 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 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:
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 as a 2-byte integer)\n
Note that the subtype is lost, and deserializing v would yield the following value:
BSON supports binary values and subtypes. 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.
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:
CBOR supports binary values, but no subtypes. Subtypes will be serialized as tags. Any binary value will be serialized as byte strings. 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:
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).
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, ext8, ext16, and ext32. The subtype is then added as a signed 8-bit integer.
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:
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:
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:
This library does not support comments by default. It does so for three reasons:
Comments are not part of the JSON specification. You may argue that // or /* */ are allowed in JavaScript, but JSON is not JavaScript.
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.
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) -- 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).
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:
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.
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 json = 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 (auto i : v8)\n {\n std::cout << i.first << \": \" << i.second << '\\n';\n }\n}\n
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:
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:
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:
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.
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.
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:
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 -- 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 -- 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 -- 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
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 -- no intermediate container is needed:
This requires JSON_HAS_RANGES to be enabled and is unavailable on MinGW due to incomplete C++20 ranges support there.
"},{"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.
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.
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.
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
"},{"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.
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 json = 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() << std::endl;\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() << std::endl;\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
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().
"},{"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.
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()
"},{"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.
rbegin() and rend() return iterators in the reverse sequence.
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/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.
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.
Example: apply a JSON Patch
The following code shows how a JSON patch is applied to a value.
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
Invariant
For two JSON values source and target, the following code yields always true:
source.patch(diff(source, target)) == target;\n
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.
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.
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
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.
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.
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.
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.
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
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.
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.
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.
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.
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.
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)).
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.
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.
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.
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.
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.
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.
When defined to 1, the library restores the legacy behavior in which a discarded value compared equal to itself. This behavior is deprecated and switched off (0) by default.
See full documentation of JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON.
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.
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.
The library defines 12 macros to simplify the serialization/deserialization of types. See the page on arbitrary type conversion for a detailed discussion.
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.
The library supports JSON Merge Patch (RFC 7386) 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. This function applies a merge patch to the current JSON value.
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.
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 json = 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 << std::endl;\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
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:
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.
To merge one object into another, update copies all members from another object, overwriting existing keys (similar to Python's dict.update). This is the idiomatic way to combine two objects.
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.
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.
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.
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:
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.
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.
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.
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:
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.
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.
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:
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.
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:
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.
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 -- without repeating the detailed pages it links to.
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 -- a std::string, a std::vector<char>, a string literal, or a pointer range -- 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 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) or FILE*, by contrast, is read through input_stream_adapter or file_input_adapter, which read one character (or one block, for binary formats) at a time and expose neither optimization -- the lexer falls back to the same byte-at-a-time path it uses for any non-contiguous, general-purpose iterator range. 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 additionally requires contiguous storage.
Practically: if the JSON text is already in memory, or small enough to read into memory, prefer passing a std::string, a std::vector<char>, or a pointer range to parse over a std::istream. For a file, that means reading it into a string first and then parsing the string, rather than passing a std::ifstream directly to parse -- the latter never benefits from either optimization:
// gets the contiguous fast paths\nstd::ifstream f(\"example.json\");\nstd::string contents((std::istreambuf_iterator<char>(f)), std::istreambuf_iterator<char>());\njson j = json::parse(contents);\n\n// does not: input_stream_adapter has no fast path\nstd::ifstream f2(\"example.json\");\njson j2 = json::parse(f2);\n
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.
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, two 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 -- see the recipe for streaming a large homogeneous array.
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.
JSON text is not a compact format. If the data is only exchanged between programs (not read by humans), the binary formats -- BJData, BON8, BSON, CBOR, MessagePack, and UBJSON -- 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 -- and whether it is worth the loss of human readability at all -- depends on the actual data; see the comparison tables before choosing one.
"},{"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 -- 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).
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) -- see Object Order for the full list.
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.
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.\" -- 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 -- 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) -- 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 -- see \"reserving array capacity\" for the one-line recipe.
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 -- 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.
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\" -- 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.
<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 -- in a function signature or a class member declaration, for instance -- 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:
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 -- whether it includes json_fwd.hpp or the full header -- 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.
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.
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.
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:
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.
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:
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 json = 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() << std::endl;\n }\n catch (const json::type_error& e)\n {\n std::cout << e.what() << std::endl;\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).
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).
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:
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 complete 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 complete UBJSON complete complete"},{"location":"features/binary_formats/#binary-values","title":"Binary values","text":"Format Binary values Binary subtypes BJData not supported not supported BON8 not supported not supported BSON supported supported CBOR supported supported MessagePack supported supported UBJSON not supported not supported
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 5 new type markers - [u] - uint16, [m] - uint32, [M] - uint64, [h] - float16 and [B] - byte - to unambiguously map common binary numeric types; 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.
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
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 used in the conversion:
Z: no-op values are not created.
C: single-byte strings are serialized with S markers.
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 2 3 1 2 3 4 5 6 or [$U#[i2 i3] 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
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:
\"_ArrayType_\" is one of uint8, int8, uint16, int16, uint32, int32, uint64, int64, single, double, char, or byte,
\"_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 1\u00d7N row vector (first entry 1), since other shapes are parsed back as a regular array,
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, a value that fits the named width; for double, any value; for single, a value that survives narrowing to float and back without change (for instance, 0.1 does not, since it is not exactly representable as float).
An annotated object is always read back with its keys in the order shown above, \"_ArrayType_\", \"_ArraySize_\", \"_ArrayData_\", regardless of the order the ND-array's header stores them in on the wire. This matters for ordered_json, whose comparison takes key order into account.
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 UiuImlMLhdDCB. This also means other variable ([{SH) or zero-length types (TFN) can not be used in an optimized array or object in BJData.
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 using the version parameter of to_bjdata.
In Draft2 mode (default), if the JSON data contains the binary type, the value 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 json = 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 << (char)byte;\n }\n else\n {\n std::cout << (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 << std::endl;\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 << std::endl;\n\n for (auto& byte : v_array_size)\n {\n print_byte(byte);\n }\n std::cout << std::endl;\n\n for (auto& byte : v_array_size_and_type)\n {\n print_byte(byte);\n }\n std::cout << std::endl;\n}\n
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 nullZ false falseF true trueT float16 number_float h float32 number_float d float64 number_float D 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 in the sense that any BJData value can be converted to a JSON value.
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.
BON8 (Binary Object Notation 8) is a compact binary serialization format for JSON values. It uses the 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.
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:
unsigned integers above 9223372036854775807, because BON8 has no unsigned 64-bit integer type (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.
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.
Info
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.
Info
Any BON8 output created by to_bon8 can be successfully parsed by from_bon8.
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.
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 a zero-terminated c-strings.
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.
Example: serialize a JSON value to BSON
#include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing json = 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') << (int)byte << \" \";\n }\n std::cout << std::endl;\n}\n
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, and
the payload for binary subtype 0x02 is returned as-is, including its inner length prefix.
If BSON input must be validated for strict specification compliance, validate it separately before passing it to from_bson().
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 never validated on read, since they are read byte-by-byte as a C string. binary values (type 0x05) are unaffected, since they are not required to hold 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
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.
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.13.0 unreleased, NaN and Infinity were instead serialized as a CBOR double-precision float (type 0xFB, 9 bytes total), because the check used to select a smaller encoding compared magnitudes with NaN, which is always false and caused the intended half-precision path to be skipped.
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)
half-precision floats (0xF9)
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 json = 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') << (int)byte << \" \";\n }\n std::cout << std::endl;\n}\n
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.
Ill-formed UTF-8 in text strings
RFC 8949, Section 3.1 requires CBOR text strings (major type 3) to be valid UTF-8, but leaves it up to the decoder whether to enforce 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.
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 innermost one is stored. Note that no tag is ever interpreted: for instance, a text string tagged with tag 0 (date/time) stays a string.
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.
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 compared magnitudes with NaN, which is always false and caused the float 32 path to be skipped.
Example: serialize a JSON value to MessagePack
#include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing json = 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') << (int)byte << \" \";\n }\n std::cout << std::endl;\n}\n
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) 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 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 expects a deserializer to hand the original bytes back unchanged. 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
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.
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 D string with shortest length indicator string S array see notes on optimized format array [ object see notes on optimized format map {
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:
Z: no-op values are not created.
C: single-byte strings are serialized with S markers.
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.
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.
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 without the annotation, so any value it produces can be read back.
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 json = 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 << (char)byte;\n }\n else\n {\n std::cout << (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 << std::endl;\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 << std::endl;\n\n for (auto& byte : v_array_size)\n {\n print_byte(byte);\n }\n std::cout << std::endl;\n\n for (auto& byte : v_array_size_and_type)\n {\n print_byte(byte);\n }\n std::cout << std::endl;\n}\n
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 nullZ false falseF true trueT 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 array array (optimized values are supported) [ object object (optimized values are supported) {
Complete mapping
The mapping is complete in the sense that any UBJSON value can be converted to a JSON value.
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.
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).
flowchart TD\n A[\"accessing a value\"] --> B{\"must it exist?\"}\n B -->|\"yes, missing is an error\"| C[\"at() -- throws\"]\n B -->|\"yes, but checking is my job\"| D[\"operator[] -- unchecked\"]\n B -->|\"no, a fallback is fine\"| E[\"value() -- default value\"]\n A --> F{\"just testing first?\"}\n F -->|\"yes\"| G[\"contains() / find()\"]
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.
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
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"},{"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).
expression value j{\"logOutput\": \"result.log\", \"append\": true}j.value(\"logOutput\", \"logfile.log\")\"result.log\"j.value(\"append\", true)truej.value(\"append\", false)truej.value(\"logLevel\", \"verbose\")\"verbose\""},{"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.
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.
operator[]: 18446744073709551615\ndefault value (int): -1\ndefault value (uint64_t): 18446744073709551615\nexplicit return value type: 18446744073709551615\n
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.
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.
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.
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"},{"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 parse function reads a JSON value from an input. The input can be
a string (std::string, C string, or 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. A single input may contain only one JSON value. Inputs consisting of multiple values separated by newlines are handled by the JSON Lines format.
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.
"},{"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/#sax-vs-dom-parsing","title":"SAX vs. DOM parsing","text":"
The library offers two parsing models:
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.
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.
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.
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.
{\"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
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:
A value that is a number must be followed by whitespace -- see the notes of operator>> for details.
"},{"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
In case exceptions are undesired or not supported by the environment, there are different ways to proceed:
"},{"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).
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.
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
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 parsedparse_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: sequence of callback events
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).
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 -- 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 json = 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
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 -- 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:
// 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.
To implement your own SAX handler, proceed as follows:
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.
Create an object of your SAX interface class, e.g. my_sax.
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.
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.
"},{"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() -- there is no way to recover from a parse error of untrusted input in that configuration; see Switch off exceptions for the details and for overriding this with JSON_THROW_USER.
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, and applying a merge_patch -- 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.
Not every operation is bounded yet
diff, flatten, and the binary writers (to_cbor, to_msgpack, ...) still recurse once per nesting level; this is called out as work in progress in the assurance case. A value deep enough to matter for these operations would typically first have to survive parsing without hitting a self-imposed depth limit, as described above.
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.
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 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.
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.
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.
"},{"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.
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.
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.
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:
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.
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.
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.
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.
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.
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
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.
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.
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.
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.
With the default values for NumberIntegerType (std::int64_t), the default value for number_integer_t is std::int64_t. With the default values for NumberUnsignedType (std::uint64_t), the default value for number_unsigned_t is std::uint64_t. With the default values for NumberFloatType (double), the default value for number_float_t is double.
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.
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. Note values smaller than -1.79769313486232e+308 and values greater than 1.79769313486232e+308 will be stored as NaN internally and be serialized to null.
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:
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.
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
Notes
Numbers with a decimal digit or scientific notation are always stored as double.
The number types can be changed, see Template number types.
Integers are converted by the library's own digit parser. Floating-point numbers are converted with std::from_chars if the library is compiled with C++17 and the standard library supports it, then with an exact fast path for double values with few significant digits, and otherwise with the locale-aware std::strtod (std::strtof/std::strtold for the other floating-point types). 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.
Any 64-bit signed or unsigned integer can be stored without loss of precision.
Numbers exceeding the limits of double (i.e., numbers that after conversion via std::strtod are not satisfying std::isfinite such as 1E400) will throw exception json.exception.out_of_range.406 during parsing.
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.
The JSON number grammar allows for different ways to express zero, and this library will store zeros differently:
Literal Stored value and type Serialization 0std::uint64_t(0)0-0std::int64_t(0)00.0double(0.0)0.0-0.0double(-0.0)-0.00E0double(0.0)0.0-0E0double(-0.0)-0.0
That is, -0 is stored as a signed integer, but the serialization does not reproduce the -.
Integer numbers are serialized as is; that is, no scientific notation is used.
Floating-point numbers are serialized as specified by the %g printf modifier with std::numeric_limits<double>::max_digits10 significant digits. The rationale is to use the shortest representation while still allowing round-tripping.
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:
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:
JSON does not define a number type or precision (see above).
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()truetruetruefalseis_number_integer()truetruefalsefalseis_number_unsigned()truefalsefalsefalseis_number_float()falsefalsetruefalsetype_name()\"number\"\"number\"\"number\"\"string\"type()number_unsignednumber_integernumber_floatstring"},{"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_tstd::int32_t, std::int16_t, etc. 6 unsigned integers std::uint64_tstd::uint32_t, std::uint16_t, etc. 7 floating-point doublefloat, 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 types for signed and unsigned integers must be distinct, see #2573.
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.
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 -- 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 -- needed to instantiate basic_json at all, or needed by functions that virtually every program uses (construction, element access, dump).
Required for ... -- 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 can silently misparse floating-point numbers, because the lexer may hand the buffer to std::strtod, which reads up to the terminating null character.
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 ObjectTypestd::mapnlohmann::ordered_map, Abseil hash maps ArrayTypestd::vectorstd::dequeStringTypestd::stringstd::string-like types over charBooleanTypebool none worth using NumberIntegerTypestd::int64_t any signed integer type NumberUnsignedTypestd::uint64_t any unsigned integer type at least as wide as NumberIntegerTypeNumberFloatTypedoublefloat (long double: no binary formats) AllocatorTypestd::allocator stateless allocators JSONSerializeradl_serializer serializers with the same interface BinaryTypestd::vector<std::uint8_t>std::vector<char>CustomBaseClassvoid any default-constructible class
Third-party containers and incomplete types
object_t is instantiated inside the definition of basic_json -- it is probed for a key_compare member to form object_comparator_t -- 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 -- 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.
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 -- 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 -- 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.
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.
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 -- 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 -- a good starting point for a custom ObjectType.
"},{"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_traitstsl::ordered_map its iterators expose the mapped value as constQMap 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_multimapemplace 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
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 -- a good starting point for a custom ArrayType.
"},{"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, devectorboost::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).
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::strtod. 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 -- the parser may hand it to std::strtod, which reads up to the null character. A type whose data() is not null-terminated does not fail to compile; it can silently misparse floating-point numbers.
append(const char*, size_type), used by dump, and append(const StringType&), used by the CBOR reader for indefinite-length strings. 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-constdata() 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) -- 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().
begin() and end() -- 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_bsonfind(value_type) and nposparse from a string_t the input adapters must accept it; otherwise pass a character range operator<<(std::ostream&, const json_pointer&) streamability to std::ostreamto_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 -- 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 -- from parse, from dump, or by default construction -- 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 -- 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 -- 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
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 -- an explicit constructor is not enough, because the to_json overload for a custom BooleanType is constrained on std::is_convertible -- and contextually convertible to bool (here an explicit operator bool is fine).
bool is the only usable choice. Another trivially copyable type that is implicitly convertible to and from bool -- std::uint8_t, say -- 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.
std::is_integral must be satisfied: NumberIntegerType must be a signed integer type, NumberUnsignedType an unsigned integer type. Class types are not supported -- 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.
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.
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/#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 class types, enumerations not usable; std::is_integral must hold bool, or a type already used for 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.
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 with std::from_chars or, as a fallback, with std::strtof, std::strtod, or 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 binary32 or binary64 number, dump uses the Grisu2 algorithm, which produces the shortest 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; short round-trip output through Grisu2 float full; short round-trip output through Grisu2 long doubledump 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.
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.
The template must accept two type arguments. It does not have to give the second one a default -- 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
A non-final class type -- 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_castdata(). data() + n would do for the readers too, but they share one helper with StringType, whose non-constdata() 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, and insert(pos, first, last), which the CBOR reader uses to join the chunks of an indefinite-length byte string. 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 -- a good starting point for a custom BinaryType.
"},{"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::stringbinary_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 -- 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.
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.
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.
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).
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 ObjectTypestd::map objects, see object_tArrayTypestd::vector arrays, see array_tStringTypestd::string strings and object keys, see string_tBooleanTypebool Booleans, see boolean_tNumberIntegerTypestd::int64_t signed integers, see number_integer_tNumberUnsignedTypestd::uint64_t unsigned integers, see number_unsigned_tNumberFloatTypedouble floating-point numbers, see number_float_tAllocatorTypestd::allocator allocating objects, arrays, strings, and binary values JSONSerializeradl_serializer conversions from/to other types, see adl_serializerBinaryTypestd::vector<std::uint8_t> binary values, see binary_tCustomBaseClassvoid 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.
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.
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. Only iterator_input_adapter provides them, and only for random-access input of single-byte characters:
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.
supports_bulk_scan, bulk_data(), bulk_remaining(), and bulk_skip() let the lexer scan strings directly in contiguous memory, several bytes at a time.
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.
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.
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.
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
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.
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
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
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
This page collects the library's built-in debugger integrations and other debugging-related features. They are not linked from a single place elsewhere in the docs, so 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.
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.
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 -- see Parsing and exceptions for how parse errors report their own location instead.
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.
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.
classDiagram\n direction LR\n class `std::exception` {\n <<interface>>\n }\n\n class `json::exception` {\n +const int id\n +const char* what() const\n }\n\n class `json::parse_error` {\n +const std::size_t byte\n }\n\n class `json::invalid_iterator`\n class `json::type_error`\n class `json::out_of_range`\n class `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`
"},{"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).
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.
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.
[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
The library throws this exception when a parse error occurs. Parse errors can occur during the deserialization of JSON text, CBOR, MessagePack, 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.
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
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 http://jsonlint.com or a tool like jq.
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
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.
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
An unexpected byte was read in a binary format or length information is invalid (BSON).
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
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; see the ill-formed UTF-8 notes on the individual binary format pages for how such a string is handled depending on error_handler.
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
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
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
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
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
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
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
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
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.
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
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.
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
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
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.
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
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}
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.
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, or BSON.
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.
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.
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
number overflow parsing '10E1000'\n
[json.exception.out_of_range.406] syntax error while parsing CBOR value: number overflow\n
This exception previously indicated that the UBJSON and BSON binary formats did not support integer numbers greater than 9223372036854775807 due to limitations in the implemented mapping. However, these limitations have since been resolved, and this exception no longer occurs.
Exception cannot occur any more
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.
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 size and type annotation, so any value it produces can still be read back.
Example messages
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
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
enum value out of range\narray index 18446744073709551616 exceeds size_type\n
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
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.
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
BSON length 2147483661 exceeds maximum of 2147483647\n
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.
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
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).
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
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.
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.
Example message
[json.exception.out_of_range.415] subtype 70000 is too large for the MessagePack ext type (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.
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.
This is a known issue, and -- even worse -- 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:
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.
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:
Only 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. These encodings are not supported when reading from files or other input containers.
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:
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:
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
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 -- or a concurrent read while another thread writes to the same object -- is a data race and requires external synchronization (e.g., a std::mutex) by the caller.
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/#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.
"},{"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.
It seems that precision is lost when serializing a double.
Can I change the precision for floating-point serialization?
The library uses std::numeric_limits<number_float_t>::digits10 (15 for IEEE doubles) digits for serialization. This value is sufficient to guarantee roundtripping. If one uses more than this number of digits of precision, then string -> value -> string is not guaranteed to round-trip.
cppreference.com
The value of std::numeric_limits<T>::digits10 is the number of base-10 digits that can be represented by the type T without change, that is, any number with this many significant decimal digits can be converted to a value of type T and back to decimal form, without change due to rounding or overflow.
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.
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.
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:
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.
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 copy of Hedley from Evan Nemerson which is licensed as CC0-1.0.
The class contains an adapted version of the Eisel-Lemire algorithm and its table of powers of five 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
This page 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.
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.
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.
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.
Fixes a stack overflow for deeply nested input by making the destructor iterative; parsing is now bounded only by available memory. All changes are backward-compatible. Full release notes.
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.
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) and std::string_view (C++17), and round-tripping of std::map/std::unordered_map with non-string keys.
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.
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.
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).
Adds the emplace and emplace_back functions and improves parsing and serialization performance. All changes are backward-compatible. Full release notes.
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.
Fixes operator[] for JSON pointers so that it creates missing values like the other overloads. All changes are backward-compatible. Full release notes.
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.
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.
Fixes a performance regression in the dump function by adjusting the stream locale once per serialization. All changes are backward-compatible. Full release notes.
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{Already using CMake?}\n B -- no --> C{Using pkg-config or plain Makefiles?}\n C -- yes --> D[pkg-config]\n C -- no --> E[Copy the single header]\n B -- yes --> F{Library installed system-wide?}\n F -- yes --> G[\"find_package()\"]\n F -- no --> H{Use a package manager?}\n H -- yes --> I[Package manager]\n H -- no --> J[\"add_subdirectory() or FetchContent\"]
Copy the single header, as described below \u2014 no build-system integration required.
CMake: use find_package() if the library is already installed, add_subdirectory() to embed the source tree, or FetchContent to download it at configure time; see CMake.
Package managers: install the library with a package manager such as Homebrew, Conan, or vcpkg; see Package Managers.
pkg-config: if you use bare Makefiles instead of CMake, pkg-config can supply 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.
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 json = 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).
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.
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.
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.
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.
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.
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.
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.
Delete the deprecated functions instead of only deprecating them by defining the macro JSON_DELETE_DEPRECATED_FUNCTIONS. This option is OFF by default.
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():
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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:
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 nine runs compiling a single translation unit with -std=c++17 -c against the single-header version, with Apple clang and GCC 16 on macOS (Apple silicon). They show the order of magnitude to expect; measure your own code before and after a change.
"},{"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, ordered_json, json_pointer, and adl_serializer. The translation units that actually use the values then include <nlohmann/json.hpp>.
Compiler json.hpp (-O0) json_fwd.hpp (-O0) Change Apple clang 704 ms 329 ms \u221253% GCC 16 779 ms 242 ms \u221269%
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):
#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 776 ms / 846 ms 629 ms / 692 ms \u221219% / \u221218% GCC 16 model 1022 ms / 1120 ms 882 ms / 965 ms \u221214% / \u221214% Apple clang parsing 992 ms / 1815 ms 1006 ms / 1823 ms +1% / 0% GCC 16 parsing 2018 ms / 3420 ms 1990 ms / 3454 ms \u22121% / +1%
Translation units that include only the header save up to a third. Translation units that parse anyway instantiate the parser regardless and see no difference.
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 992 ms / 1815 ms 953 ms / 1625 ms \u22124% / \u221210% GCC 16 parsing 2018 ms / 3420 ms 1522 ms / 2728 ms \u221225% / \u221220% Apple clang json_instance.cpp \u2014 2166 ms / 4660 ms \u2014 GCC 16 json_instance.cpp \u2014 5085 ms / 10616 ms \u2014
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.
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.
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.
"},{"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 776 ms / 846 ms 1022 ms / 1120 ms JSON_NO_IO 764 ms / 836 ms 1022 ms / 1117 ms JSON_USE_GLOBAL_UDLS=0 763 ms / 852 ms 1019 ms / 1106 ms
JSON_USE_GLOBAL_UDLS only controls where the literals are declared; to avoid their cost, use JSON_NO_AUTOMATIC_UDLS instead.
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.
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.
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.
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
Comparing JSON Pointers with strings via operator== and operator!= is deprecated since 3.11.2. To compare a json_pointerp with a string s, convert s to a json_pointer first and use json_pointer::operator== or json_pointer::operator!=.
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
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.
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.
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
"},{"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.
"},{"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.
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.
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:
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
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
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.
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).
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
Create the following files (the source file goes into Sources/json_example/, following Swift Package Manager's directory layout convention):
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.
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
Right-click the project (any C++ project) in \"Solution Explorer\" and select \"Manage NuGet Packages\u2026\"
Switch to the \"Browse\" tab.
Search for nlohmann.json, select it, and click \"Install\".
#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.
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.
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:
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:
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
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
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
Create a new executable project \"example\" (see bdep new command details for the various options to create a new project):
bdep new example\n
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}:
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
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.
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.
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:
"}]}
\ 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":"
JSON for Modern C++ is a header-only C++11 library that turns JSON into a first-class C++ data type, using the operator magic of modern C++ so that creating, reading, and modifying JSON values feels as natural as it does in languages like Python. The whole library is available as a single header, json.hpp, with no dependencies, no subproject, and no complex build system to set up; a companion header, json_fwd.hpp, provides forward declarations to keep compile times down. See header-only integration for details. It is heavily unit-tested with 100% code coverage, checked with Valgrind and the Clang Sanitizers for memory leaks, and continuously fuzz-tested by Google OSS-Fuzz.
Add the single header to your project and use the library like this:
#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing json = nlohmann::json;\n\nint main()\n{\n // parse a JSON string\n json j = json::parse(R\"({\"happy\": true, \"pi\": 3.141})\");\n\n // access and modify values\n j[\"name\"] = \"Niels\";\n j[\"list\"] = {1, 0, 2};\n\n // serialize with an indent of 4 spaces\n std::cout << j.dump(4) << '\\n';\n}\n
Get the library by copying the single header json.hpp from the releases page into a directory nlohmann on your include path, or by installing it with a package manager:
See Integration for CMake in detail, all supported package managers (Conan, Meson, Bazel, Conda, and more), and pkg-config.
"},{"location":"#explore-the-documentation","title":"Explore the documentation","text":"
Features
Creating, parsing, accessing, and serializing JSON values, JSON Pointer/Patch, binary formats, 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.
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
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; see Releases for what shipped in each version.
The library is licensed under the MIT License. The source code, issue tracker, and discussions are on GitHub.
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":"
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.
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:
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 -- 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.
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.
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:
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":"
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:
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":"
std::ostream& operator<<(std::ostream& o, const basic_json& j); // (1)\n\nstd::ostream& operator<<(std::ostream& o, const json_pointer& ptr); // (2)\n
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.
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":"
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.
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.
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.
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.
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.
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.
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.
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):
njsonordered_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 -- see object order.
This function is usually called by the get() function of the basic_json class (either explicitly or via the conversion operators).
This function is chosen for default-constructible value types.
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":"
(none) -- the converted value is written to the output parameter val.
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 json = 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 << std::endl;\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 json = 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 << std::endl;\n}\n
Output:
Ned Flanders (60) lives in 744 Evergreen Terrace\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.
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_tArrayType type for JSON arrays array_tStringType type for JSON strings and object keys string_tBooleanType type for JSON booleans boolean_tNumberIntegerType type for JSON integer numbers number_integer_tNumberUnsignedType type for JSON unsigned integer numbers number_unsigned_tNumberFloatType type for JSON floating-point numbers number_float_tAllocatorType type of the allocator to use JSONSerializer the serializer to resolve internal calls to to_json() and from_json()json_serializerBinaryType type for binary arrays binary_tCustomBaseClass 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.
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.
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.
json_serializer - type of the serializer to for conversions from/to JSON
error_handler_t - type to choose behavior on decoding errors
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
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_typebasic_jsonreferencevalue_type&const_referenceconst value_type&difference_typestd::ptrdiff_tsize_typestd::size_tallocator_typeAllocatorType<basic_json>pointerstd::allocator_traits<allocator_type>::pointerconst_pointerstd::allocator_traits<allocator_type>::const_pointeriterator LegacyBidirectionalIterator const_iterator constant LegacyBidirectionalIterator reverse_iterator reverse iterator, derived from iteratorconst_reverse_iterator reverse iterator, derived from const_iteratoriteration_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)
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!=.
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.
a pointer to a null-terminated string of single byte characters (throws if null)
a std::string
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, 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":"
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.
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 json = 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
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.
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.
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":"
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:
creating an array whose elements are all pairs whose first element is a string -- in this case, the initializer list constructor would create an object, taking the first elements as keys
creating an empty array -- passing the empty initializer list to the initializer list constructor yields an empty object
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 value for array_t is:
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.
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.
Returns a reference to the array element at specified location idx, with bounds checking.
Returns a reference to the object element with specified key key, with bounds checking.
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.
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":"
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.
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.
See 2.
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).
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 json = 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 json = 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.
\"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.
\"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 json = 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 json = 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 json = 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 json = 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
Added in version 3.11.0. Fixed in version 3.13.0 unreleased to consistently accept std::string_view-convertible keys, as already supported by operator[], value, find, and other lookup functions.
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.
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().
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 -- it is only used to choose the right constructor.
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.
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.
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.
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:
If the list is empty, an empty JSON object value {} is created.
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.
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\"]
The rules aim to create the best fit between a C++ initializer list and JSON values. The rationale is as follows:
The empty initializer list is written as {} which is exactly an empty JSON object.
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.
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.
Constructs a JSON array value by creating cnt copies of a passed value. In case cnt is 0, an empty array is created.
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.
Creates a copy of a given JSON value.
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.
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":"
Strong guarantee: if an exception is thrown, there are no changes to any JSON value.
No-throw guarantee: this constructor never throws exceptions.
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.
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.
Strong guarantee: if an exception is thrown, there are no changes to any JSON value.
Strong guarantee: if an exception is thrown, there are no changes to any JSON value.
Strong guarantee: if an exception is thrown, there are no changes to any JSON value.
Strong guarantee: if an exception is thrown, there are no changes to any JSON value.
No-throw guarantee: this constructor never throws 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.
(none)
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.
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.
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 json = 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 json = nlohmann::json;\nusing ordered_json = 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
The code below shows the move constructor explicitly called via std::move.
#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing json = 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
Since version 3.2.0. Explicit for different string types if JSON_USE_IMPLICIT_CONVERSIONS is 0 since version 3.13.0 unreleased.
Since version 1.0.0.
Since version 1.0.0.
Since 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.
#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing json = 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
Creates a JSON binary array value from a given binary container.
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":"
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.
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++.
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 -- 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.
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.
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:
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.
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) is used. For other sizes, the ext family (ext8, ext16, ext32) is used. The subtype is then added as a signed 8-bit integer.
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.
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.
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 value for boolean_t is bool.
#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing json = 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
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 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 innermost one is stored."},{"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 json = 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
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 []
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.
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.
Check whether the given JSON pointer ptr can be resolved in the current JSON value.
"},{"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":"
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.
See 1.
true if the JSON pointer can be resolved to a stored value, false otherwise.
This method always returns false when executed on a JSON type that is not an object.
This method can be executed on any JSON value type.
Calling this function with an integer argument (for example, 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
Added in version 3.6.0. Extended template KeyType to support comparable types in version 3.11.0. Fixed in version 3.13.0 unreleased to consistently accept std::string_view-convertible keys, as already supported by operator[], at, value, and other lookup functions.
Added in version 3.7.0.
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.
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).
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.
"},{"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.
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 json = 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 json = 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
Added in version 1.0.0. Changed parameter key type to KeyType&& in version 3.11.0. Fixed in version 3.13.0 unreleased to consistently accept std::string_view-convertible keys, as already supported by operator[], at, value, and other lookup functions.
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.
The following code shows an example for crbegin().
#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing json = 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
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.
#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing json = 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
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 always yields true:
source.patch(diff(source, target)) == target;\n
"},{"location":"api/basic_json/diff/#parameters","title":"Parameters","text":"source (in) JSON value to compare from target (in) JSON value to compare against"},{"location":"api/basic_json/diff/#return-value","title":"Return value","text":"
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
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.
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.
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.
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 json = 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
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.
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":"
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.
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.
This function does not return whether a string stored as JSON value is empty -- it returns whether the JSON container itself is empty which is false in the case of a string.
#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing json = 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
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
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.
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.
Removes an element from a JSON object by key.
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.
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":"
Iterator following the last removed element. If the iterator pos refers to the last element, the end() iterator is returned.
Iterator following the last removed element. If the iterator last refers to the last element, the end() iterator is returned.
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).
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\"
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\"
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\"
See 3.
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\"
Added in version 1.0.0. Added support for binary types in version 3.8.0.
Added in version 1.0.0. Added support for binary types in version 3.8.0.
Added in version 1.0.0.
Added in version 3.11.0. Fixed in version 3.13.0 unreleased to consistently accept std::string_view-convertible keys, as already supported by operator[], at, value, and other lookup functions.
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] (dump.md) itself must produce text, and keep there writes the ill-formed bytes to the output as is, so the result is then not valid UTF-8 (but still equals the input bytes exactly, including around any well-formed 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 json = 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() << std::endl;\n }\n catch (const json::type_error& e)\n {\n std::cout << e.what() << std::endl;\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
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
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
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.
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.
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.
"},{"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.
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
Added in version 1.0.0. Changed to support comparable types in version 3.11.0. Fixed in version 3.13.0 unreleased to consistently accept std::string_view-convertible keys, as already supported by operator[], at, value, and other lookup functions.
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.
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.
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 json = 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
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())
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.
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.
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. This overload will be removed in version 4.0.0. 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.
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.
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. This overload will be removed in version 4.0.0. 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.
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.
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. This overload will be removed in version 4.0.0. 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.
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_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.
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), or if a string value or object key is not valid UTF-8 and error_handler is strict
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. This overload will be removed in version 4.0.0. 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.
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.
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
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. This overload will be removed in version 4.0.0. 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.
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.
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. This overload will be removed in version 4.0.0. 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.
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.
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.
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.
Overload for basic_json specializations. The function is equivalent to executing
return *this;\n
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_jsonPointerType 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":"
copy of the JSON value, converted to ValueType
a copy of *this, converted into BasicJsonType
pointer to the internally stored JSON value if the requested pointer type fits to the JSON value; nullptr otherwise
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.
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 json = 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 (auto i : v8)\n {\n std::cout << i.first << \": \" << i.second << '\\n';\n }\n}\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 json = nlohmann::json;\n\nint main()\n{\n // create a JSON number\n json value = 17;\n\n // explicitly getting pointers\n 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 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
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
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.
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 json = nlohmann::json;\n\nint main()\n{\n // create a JSON number\n json value = 17;\n\n // explicitly getting pointers\n 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 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
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
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\".
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.
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":"
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.
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 json = 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 (auto i : v8)\n {\n std::cout << i.first << \": \" << i.second << '\\n';\n }\n}\n
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":"
iterator pointing to the inserted val.
iterator pointing to the first element inserted, or pos if cnt==0
iterator pointing to the first element inserted, or pos if first==last
iterator pointing to the first element inserted, or pos if ilist is empty
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\"
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\"
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\"
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\"
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\"
Constant plus linear in the distance between pos and end of the container.
Linear in cnt plus linear in the distance between pos and end of the container.
Linear in std::distance(first, last) plus linear in the distance between pos and end of the container.
Linear in ilist.size() plus linear in the distance between pos and end of the container.
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 json = 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 json = 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 json = 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
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 json = 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 json = 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
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.
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.
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 json = 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
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.
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 -- decltype is the supported way to obtain it, but its exact name/definition may change between versions.
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.
Added items and deprecated iterator_wrapper in 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.
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.
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.
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_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.
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.
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 json = 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 << std::endl;\n}\n
Output:
Ned Flanders (60) lives in 744 Evergreen Terrace\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.
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.
This function does not return the maximal length of a string stored as JSON value -- it returns the maximal number of string elements the JSON value can store which is 1.
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.
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.
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.
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. Parsing and serialization are implemented in terms of std::strtof/std::strtod/std::strtold and std::snprintf, so the type must be float, double, or long double. 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 value for number_float_t is double.
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.
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. Note values smaller than -1.79769313486232e+308 and values greater than 1.79769313486232e+308 will be stored as NaN internally and be serialized to null.
During deserialization (from JSON text or any of the binary formats), a finite number that does not fit into number_float_t is rejected with out_of_range.406, for example a double-precision number in a binary format when number_float_t is float.
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 value for number_integer_t is std::int64_t.
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.
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.
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. 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 value for number_unsigned_t is std::uint64_t.
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.
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.
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":"
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.
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).
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.
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 -- 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 value for object_t is:
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.
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.
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.
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.
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.
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.
This function allows using operator+= with an initializer list. In case
the current value is an object,
the initializer list init contains only two elements, and
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&&).
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":"
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.
(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.
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.
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.
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 json = 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
Returns a reference to the array element at specified location idx.
Returns a reference to the object element with specified key key. The non-const qualified overload takes the key by value.
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.
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":"
(const) reference to the element at index idx
(const) reference to the element at key key
(const) reference to the element at key key
(const) reference to the element pointed to by ptr
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.)
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.
See 2.
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.
The following cases apply to the const overloads; the non-const overloads instead insert the missing element (see the notes below).
If the element at index idx does not exist, the behavior is undefined and is guarded by a runtime assertion!
If the element with key key does not exist, the behavior is undefined and is guarded by a runtime assertion!
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!
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.
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.
See 2.
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 parses as a non-negative integer: a numeric token creates an array, a non-numeric 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. 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 json = 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
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.
Added in version 1.0.0. Added overloads for T* key in version 1.1.0. Removed overloads for T* key (replaced by 3) in version 3.11.0.
Added in version 3.11.0. Fixed in version 3.13.0 unreleased to consistently accept std::string_view-convertible keys, as already supported by at, value, find, and other lookup functions.
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.
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":"
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().
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.
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>.
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
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 automatically converted before comparison.
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":"
No-throw guarantee: this function never throws exceptions.
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.
NaN values are unordered within the domain of numbers. The following comparisons all yield false:
Comparing a NaN with itself.
Comparing a NaN with another NaN.
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:
Added in version 1.0.0. Added C++20 member functions in version 3.11.0.
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.
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<).
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":"
No-throw guarantee: this function never throws exceptions.
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.
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.
Added in version 1.0.0. Conditionally removed since C++20 in version 3.11.0.
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.
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<=).
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":"
No-throw guarantee: this function never throws exceptions.
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.
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<=>.
Added in version 1.0.0. Conditionally removed since C++20 in version 3.11.0.
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.
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<).
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":"
No-throw guarantee: this function never throws exceptions.
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.
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.
Added in version 1.0.0. Conditionally removed since C++20 in version 3.11.0.
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.
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 automatically converted before comparison.
In case lhs and rhs have different types, the values are ignored and the order of the types is considered, which is:
null
boolean
number (all types)
object
array
string
binary For instance, any boolean value is considered less than any string.
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":"
No-throw guarantee: this function never throws exceptions.
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.
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<=>.
Added in version 1.0.0. Conditionally removed since C++20 in version 3.11.0.
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.
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.
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
No-throw guarantee: this function never throws exceptions.
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.
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.
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==.
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.
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 converted to their common type and then 3-way compared using their respective operator<=>. For instance, comparing an integer and a floating-point value will 3-way compare the first value converted to floating-point with the second value.
Otherwise, yields a result by comparing the type (see value_t).
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
No-throw guarantee: this function never throws exceptions.
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.
Value type return value nullvalue_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.
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
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!=.
a pointer to a null-terminated string of single byte characters (throws if null)
a std::string
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, 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.
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.
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.
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.
"},{"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.
[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.
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.
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.
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
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.
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
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 json = 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 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
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 parsedparse_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
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.
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 json = nlohmann::json;\n\nint main()\n{\n // a JSON text with an array and a number inside an object\n 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
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.
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.
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 (\"add\", \"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.
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.
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.
"},{"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.
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 json = 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 << std::endl;\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
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.
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.
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.
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 (\"add\", \"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.
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.
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.
"},{"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.
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 json = 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 << std::endl;\n}\n
Output:
[json.exception.out_of_range.403] key 'nonexistent' not found\n{\n \"a\": 99,\n \"b\": 2\n}\n
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.
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.
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.
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.
This function allows using push_back with an initializer list. In case
the current value is an object,
the initializer list init contains only two elements, and
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&&).
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.
(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.
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 json = 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
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.
#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing json = 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
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!=.
The SAX event lister must follow the interface of json_sax.
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 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":"
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.
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
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.
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.
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.
This function does not return the length of a string stored as JSON value -- it returns the number of elements in the JSON value which is 1 in the case of a string.
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
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.
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.
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_swap/#parameters","title":"Parameters","text":"j1 (in, out) value to be replaced by j2j2 (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.
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.
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 -- 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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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":"
No-throw guarantee: this function never throws exceptions.
No-throw guarantee: this function never throws exceptions.
Strong guarantee: if an exception is thrown, there are no changes to any JSON value.
Strong guarantee: if an exception is thrown, there are no changes to any JSON value.
Strong guarantee: if an exception is thrown, there are no changes to any JSON value.
Strong guarantee: if an exception is thrown, there are no changes to any JSON value.
Strong guarantee: if an exception is thrown, there are no changes to any JSON value.
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.
Returns a byte vector containing the BJData serialization.
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 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":"
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 BJData\"
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.
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.
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.
Returns a byte vector containing the BON8 serialization.
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":"
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.
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).
Returns a byte vector containing the BSON serialization.
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":"
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.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\"
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.
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.
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.
Returns a byte vector containing the CBOR serialization.
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":"
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\"
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.
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.
Returns a byte vector containing the MessagePack serialization.
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":"
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 maximum of the 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\"
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 json = 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
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.
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
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.
Returns a byte vector containing the UBJSON serialization.
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":"
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\"
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.
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.
Value type return value nullvalue_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.
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
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.
The following code exemplifies type_name() for all JSON types.
#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing json = 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
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:
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 cannot be an array index; example: \"unresolved reference token 'x'\"
Empty objects and arrays are flattened by flatten() to null values and cannot 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.
Apart from these two cases, for a JSON value j, the following is always true: j == j.flatten().unflatten().
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.
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
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.
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.
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":"
copy of the element at key key or default_value if key is not found
copy of the element at key key or default_value if key is not found
copy of the element at JSON Pointer ptr or default_value if no value for ptr is found
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.
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.
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 json = 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
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.
Added in version 3.11.0. Made ValueType the first template parameter in version 3.11.2. Fixed in version 3.13.0 unreleased to consistently accept std::string_view-convertible keys, as already supported by operator[], at, find, and other lookup functions.
Added in version 2.0.2. Extended to work with arrays in version 3.13.0 unreleased, including fixing an issue where resolving ptr through an array unexpectedly threw out_of_range instead of returning the resolved element (or default_value, as documented).
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.
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]
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
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.
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.
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() << std::endl;\n}\n
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 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)
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.
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 -- 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":"
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.
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):
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.
The example shows the construction several valid JSON pointers as well as the exceptional behavior.
#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing json = 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
Compares two JSON pointers for equality by comparing their reference tokens.
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":"
\"\" == \"\": 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
Compares two JSON pointers for inequality by comparing their reference tokens.
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
\"\" != \"\": 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
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.
append another JSON pointer at the end of this JSON pointer
append an unescaped reference token at the end of this JSON pointer
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":"
JSON pointer with ptr appended
JSON pointer with token appended without escaping token
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.
Strong guarantee: if an exception is thrown, there are no changes to the JSON pointer.
Strong guarantee: if an exception is thrown, there are no changes to the JSON pointer.
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
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.
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.
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()
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)
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
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
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
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
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/#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":"
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
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
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/#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).
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/#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":"
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/#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":"
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
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
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_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
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.
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.
#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.
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():
#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.
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 json = 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 json = 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
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.
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.
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.
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.
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.
#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.
Enum serialization can also be controlled with the CMake option JSON_DisableEnumSerialization (OFF by default) which defines JSON_DISABLE_ENUM_SERIALIZATION accordingly.
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 json = 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 json = 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
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_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).
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 json = 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 json = 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
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.
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.
#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.
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:
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.
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.
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)
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.
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.
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.
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.
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.
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.
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)).
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.
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.
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.
#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.
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.
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:
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.
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 they always return the bytes unchanged.
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 json = 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 json = 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
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.
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 json = 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 json = 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
// (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.
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.
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.
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:
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
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.
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
#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).
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:
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.
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.
#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.
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:
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:
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 scalar validator. On text with many non-ASCII characters (e.g. CJK or emoji) this can validate several times faster.
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). Streaming inputs (files, std::istream, 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 -- 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.
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.
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:
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
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:
NLOHMANN_DEFINE_TYPE_INTRUSIVE / NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT / NLOHMANN_DEFINE_TYPE_INTRUSIVE_ONLY_SERIALIZE for 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 for similar macros that can be defined outside a non-derived type.
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.
Will use at during deserialization and will throw out_of_range.403 if a key is missing in the JSON object.
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.
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:
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.
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:
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.
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.
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.
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.
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE, NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT, NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE for 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 for similar macros for derived types
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.
Will use at during deserialization and will throw out_of_range.403 if a key is missing in the JSON object.
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.
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:
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.
The macro must be used outside the type (class/struct).
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:
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.
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.
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.
NLOHMANN_DEFINE_TYPE_INTRUSIVE, NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT, NLOHMANN_DEFINE_TYPE_INTRUSIVE_ONLY_SERIALIZE for 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 for similar macros for derived types
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
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.
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
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 json = 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) << std::endl;\n}\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:
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.
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.
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:
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.
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.
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 json = 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() << std::endl;\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() << std::endl;\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
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.
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, 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).
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]
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, and merge_patch, recurse only up to a fixed depth and continue with an explicit stack below it. Some operations, such as diff, flatten, and the binary writers, still recurse once per nesting level; work on them is in progress. 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.
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.
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.
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.
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.
Community leaders will follow these Community Impact Guidelines in determining the consequences for any action they deem in violation of this Code of Conduct:
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.
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.
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.
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.
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.
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.
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:
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.
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
A new API page also needs an entry in docs/docset/docSet.sql, the search index of the docset; make build reports missing entries.
"},{"location":"community/contribution_guidelines/#amalgamate-the-source-code","title":"Amalgamate the source code","text":"
The single-header files single_include/nlohmann/json.hpp and single_include/nlohmann/json_fwd.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/#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 Studio 13.0 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.
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.
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 Clang.
Improving the efficiency of the JSON parser. The current parser is implemented as a naive recursive descent parser with hand-coded string handling. More sophisticated approaches like LALR parsers would be really appreciated. That said, 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, and I am not aware of approaches similar to re2c for parsing.
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!
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.
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
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
"},{"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 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 8 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.
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.
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.
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.
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.
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.
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.
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_CONVERSIONS10: no implicit conversions from basic_json to other types; use get instead JSON_ImplicitConversions 3.9.0 JSON_USE_GLOBAL_UDLS10: the string literals _json and _json_pointer are only available in namespace nlohmann::literalsJSON_GlobalUDLs 3.11.0 JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON0 removed: the deprecated legacy comparison of discarded values can no longer be enabled JSON_LegacyDiscardedValueComparison 3.11.0 JSON_BRACE_INIT_COPY_SEMANTICS01: single-element brace initialization such as json j{obj}; copies the element instead of creating an array \u2013 3.13.0 JSON_PRECISE_STREAM_POSITION01: reading from a stream does not consume the character after a number \u2013 3.13.0 JSON_STRICT_NUL_HANDLING01: a NUL byte in the input is a parse error instead of the end of input JSON_StrictNulHandling 3.13.0 JSON_STRICT_BINARY_UTF801: 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_CONVERSION01: 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_FUNCTIONS0 removed: the deprecated functions are removed (see below); the from_*(ptr, len) overloads stay deleted JSON_DeleteDeprecatedFunctions 3.13.0
For example, the following makes a 3.x release behave like version 4.0 with respect to these changes:
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
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.
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.
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.
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, and parsing untrusted input.
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.
Specializing enum conversion \u2014 map enums to strings instead of integers.
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.
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/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:
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: deserialize a person from JSON with from_json
#include <iostream>\n#include <nlohmann/json.hpp>\n\nusing json = 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 << std::endl;\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\"]
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
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
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.
Example: using the NLOHMANN_DEFINE_TYPE_* macros
The to_json/from_json functions for the person struct above can be created with:
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 -- no separate macro or extra code is needed.
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):
There is currently no NLOHMANN_DEFINE_TYPE_*-style macro for types that are not DefaultConstructible. This is not an intentional omission of documentation -- 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\"]
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
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 json = 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 << std::endl;\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-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 -- 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 -- 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:
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.
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 json = 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 json = 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:
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:
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:
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":"
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:
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
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.
BJData 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 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:
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 as a 2-byte integer)\n
Note that the subtype is lost, and deserializing v would yield the following value:
BSON supports binary values and subtypes. 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.
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:
CBOR supports binary values, but no subtypes. Subtypes will be serialized as tags. Any binary value will be serialized as byte strings. 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:
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).
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, ext8, ext16, and ext32. The subtype is then added as a signed 8-bit integer.
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:
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:
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:
This library does not support comments by default. It does so for three reasons:
Comments are not part of the JSON specification. You may argue that // or /* */ are allowed in JavaScript, but JSON is not JavaScript.
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.
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) -- 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).
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:
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.
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 json = 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 (auto i : v8)\n {\n std::cout << i.first << \": \" << i.second << '\\n';\n }\n}\n
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:
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:
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:
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.
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.
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:
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 -- 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 -- 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 -- 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
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 -- no intermediate container is needed:
This requires JSON_HAS_RANGES to be enabled and is unavailable on MinGW due to incomplete C++20 ranges support there.
"},{"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.
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.
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.
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
"},{"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.
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 json = 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() << std::endl;\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() << std::endl;\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
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().
"},{"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.
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()
"},{"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.
rbegin() and rend() return iterators in the reverse sequence.
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/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.
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.
Example: apply a JSON Patch
The following code shows how a JSON patch is applied to a value.
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
Invariant
For two JSON values source and target, the following code yields always true:
source.patch(diff(source, target)) == target;\n
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.
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.
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
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.
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.
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.
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.
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
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.
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.
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.
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.
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.
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)).
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.
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.
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.
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.
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.
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.
When defined to 1, the library restores the legacy behavior in which a discarded value compared equal to itself. This behavior is deprecated and switched off (0) by default.
See full documentation of JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON.
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.
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.
The library defines 12 macros to simplify the serialization/deserialization of types. See the page on arbitrary type conversion for a detailed discussion.
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.
The library supports JSON Merge Patch (RFC 7386) 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. This function applies a merge patch to the current JSON value.
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.
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 json = 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 << std::endl;\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
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:
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.
To merge one object into another, update copies all members from another object, overwriting existing keys (similar to Python's dict.update). This is the idiomatic way to combine two objects.
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.
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.
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.
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:
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.
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.
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.
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:
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.
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.
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:
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.
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:
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.
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 -- without repeating the detailed pages it links to.
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 -- a std::string, a std::vector<char>, a string literal, or a pointer range -- 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 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) or FILE*, by contrast, is read through input_stream_adapter or file_input_adapter, which read one character (or one block, for binary formats) at a time and expose neither optimization -- the lexer falls back to the same byte-at-a-time path it uses for any non-contiguous, general-purpose iterator range. 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 additionally requires contiguous storage.
Practically: if the JSON text is already in memory, or small enough to read into memory, prefer passing a std::string, a std::vector<char>, or a pointer range to parse over a std::istream. For a file, that means reading it into a string first and then parsing the string, rather than passing a std::ifstream directly to parse -- the latter never benefits from either optimization:
// gets the contiguous fast paths\nstd::ifstream f(\"example.json\");\nstd::string contents((std::istreambuf_iterator<char>(f)), std::istreambuf_iterator<char>());\njson j = json::parse(contents);\n\n// does not: input_stream_adapter has no fast path\nstd::ifstream f2(\"example.json\");\njson j2 = json::parse(f2);\n
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.
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, two 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 -- see the recipe for streaming a large homogeneous array.
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.
JSON text is not a compact format. If the data is only exchanged between programs (not read by humans), the binary formats -- BJData, BON8, BSON, CBOR, MessagePack, and UBJSON -- 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 -- and whether it is worth the loss of human readability at all -- depends on the actual data; see the comparison tables before choosing one.
"},{"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 -- 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).
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) -- see Object Order for the full list.
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.
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.\" -- 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 -- 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) -- 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 -- see \"reserving array capacity\" for the one-line recipe.
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 -- 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.
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\" -- 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.
<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 -- in a function signature or a class member declaration, for instance -- 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:
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 -- whether it includes json_fwd.hpp or the full header -- 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.
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.
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.
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:
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.
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:
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 json = 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() << std::endl;\n }\n catch (const json::type_error& e)\n {\n std::cout << e.what() << std::endl;\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).
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).
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:
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 complete 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 complete UBJSON complete complete"},{"location":"features/binary_formats/#binary-values","title":"Binary values","text":"Format Binary values Binary subtypes BJData not supported not supported BON8 not supported not supported BSON supported supported CBOR supported supported MessagePack supported supported UBJSON not supported not supported
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 5 new type markers - [u] - uint16, [m] - uint32, [M] - uint64, [h] - float16 and [B] - byte - to unambiguously map common binary numeric types; 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.
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
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 used in the conversion:
Z: no-op values are not created.
C: single-byte strings are serialized with S markers.
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 2 3 1 2 3 4 5 6 or [$U#[i2 i3] 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
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:
\"_ArrayType_\" is one of uint8, int8, uint16, int16, uint32, int32, uint64, int64, single, double, char, or byte,
\"_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 1\u00d7N row vector (first entry 1), since other shapes are parsed back as a regular array,
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, a value that fits the named width; for double, any value; for single, a value that survives narrowing to float and back without change (for instance, 0.1 does not, since it is not exactly representable as float).
An annotated object is always read back with its keys in the order shown above, \"_ArrayType_\", \"_ArraySize_\", \"_ArrayData_\", regardless of the order the ND-array's header stores them in on the wire. This matters for ordered_json, whose comparison takes key order into account.
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 UiuImlMLhdDCB. This also means other variable ([{SH) or zero-length types (TFN) can not be used in an optimized array or object in BJData.
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 using the version parameter of to_bjdata.
In Draft2 mode (default), if the JSON data contains the binary type, the value 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 json = 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 << (char)byte;\n }\n else\n {\n std::cout << (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 << std::endl;\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 << std::endl;\n\n for (auto& byte : v_array_size)\n {\n print_byte(byte);\n }\n std::cout << std::endl;\n\n for (auto& byte : v_array_size_and_type)\n {\n print_byte(byte);\n }\n std::cout << std::endl;\n}\n
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 nullZ false falseF true trueT float16 number_float h float32 number_float d float64 number_float D 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 in the sense that any BJData value can be converted to a JSON value.
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.
BON8 (Binary Object Notation 8) is a compact binary serialization format for JSON values. It uses the 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.
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:
unsigned integers above 9223372036854775807, because BON8 has no unsigned 64-bit integer type (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.
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.
Info
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.
Info
Any BON8 output created by to_bon8 can be successfully parsed by from_bon8.
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.
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 a zero-terminated c-strings.
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.
Example: serialize a JSON value to BSON
#include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing json = 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') << (int)byte << \" \";\n }\n std::cout << std::endl;\n}\n
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, and
the payload for binary subtype 0x02 is returned as-is, including its inner length prefix.
If BSON input must be validated for strict specification compliance, validate it separately before passing it to from_bson().
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 never validated on read, since they are read byte-by-byte as a C string. binary values (type 0x05) are unaffected, since they are not required to hold 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
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.
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.13.0 unreleased, NaN and Infinity were instead serialized as a CBOR double-precision float (type 0xFB, 9 bytes total), because the check used to select a smaller encoding compared magnitudes with NaN, which is always false and caused the intended half-precision path to be skipped.
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)
half-precision floats (0xF9)
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 json = 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') << (int)byte << \" \";\n }\n std::cout << std::endl;\n}\n
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.
Ill-formed UTF-8 in text strings
RFC 8949, Section 3.1 requires CBOR text strings (major type 3) to be valid UTF-8, but leaves it up to the decoder whether to enforce 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.
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 innermost one is stored. Note that no tag is ever interpreted: for instance, a text string tagged with tag 0 (date/time) stays a string.
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.
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 compared magnitudes with NaN, which is always false and caused the float 32 path to be skipped.
Example: serialize a JSON value to MessagePack
#include <iostream>\n#include <iomanip>\n#include <nlohmann/json.hpp>\n\nusing json = 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') << (int)byte << \" \";\n }\n std::cout << std::endl;\n}\n
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) 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 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 expects a deserializer to hand the original bytes back unchanged. 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
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.
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 D string with shortest length indicator string S array see notes on optimized format array [ object see notes on optimized format map {
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:
Z: no-op values are not created.
C: single-byte strings are serialized with S markers.
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.
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.
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 without the annotation, so any value it produces can be read back.
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 json = 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 << (char)byte;\n }\n else\n {\n std::cout << (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 << std::endl;\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 << std::endl;\n\n for (auto& byte : v_array_size)\n {\n print_byte(byte);\n }\n std::cout << std::endl;\n\n for (auto& byte : v_array_size_and_type)\n {\n print_byte(byte);\n }\n std::cout << std::endl;\n}\n
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 nullZ false falseF true trueT 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 array array (optimized values are supported) [ object object (optimized values are supported) {
Complete mapping
The mapping is complete in the sense that any UBJSON value can be converted to a JSON value.
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.
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).
flowchart TD\n A[\"accessing a value\"] --> B{\"must it exist?\"}\n B -->|\"yes, missing is an error\"| C[\"at() -- throws\"]\n B -->|\"yes, but checking is my job\"| D[\"operator[] -- unchecked\"]\n B -->|\"no, a fallback is fine\"| E[\"value() -- default value\"]\n A --> F{\"just testing first?\"}\n F -->|\"yes\"| G[\"contains() / find()\"]
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.
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
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"},{"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).
expression value j{\"logOutput\": \"result.log\", \"append\": true}j.value(\"logOutput\", \"logfile.log\")\"result.log\"j.value(\"append\", true)truej.value(\"append\", false)truej.value(\"logLevel\", \"verbose\")\"verbose\""},{"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.
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.
operator[]: 18446744073709551615\ndefault value (int): -1\ndefault value (uint64_t): 18446744073709551615\nexplicit return value type: 18446744073709551615\n
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.
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.
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.
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"},{"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 parse function reads a JSON value from an input. The input can be
a string (std::string, C string, or 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. A single input may contain only one JSON value. Inputs consisting of multiple values separated by newlines are handled by the JSON Lines format.
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.
"},{"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/#sax-vs-dom-parsing","title":"SAX vs. DOM parsing","text":"
The library offers two parsing models:
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.
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.
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.
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.
{\"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
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:
A value that is a number must be followed by whitespace -- see the notes of operator>> for details.
"},{"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
In case exceptions are undesired or not supported by the environment, there are different ways to proceed:
"},{"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).
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.
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
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 parsedparse_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: sequence of callback events
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).
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 -- 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 json = 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
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 -- 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:
// 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.
To implement your own SAX handler, proceed as follows:
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.
Create an object of your SAX interface class, e.g. my_sax.
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.
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.
"},{"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() -- there is no way to recover from a parse error of untrusted input in that configuration; see Switch off exceptions for the details and for overriding this with JSON_THROW_USER.
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, and applying a merge_patch -- 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.
Not every operation is bounded yet
diff, flatten, and the binary writers (to_cbor, to_msgpack, ...) still recurse once per nesting level; this is called out as work in progress in the assurance case. A value deep enough to matter for these operations would typically first have to survive parsing without hitting a self-imposed depth limit, as described above.
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.
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 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.
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.
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.
"},{"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.
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.
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.
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:
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.
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.
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.
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.
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.
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
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.
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.
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.
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.
With the default values for NumberIntegerType (std::int64_t), the default value for number_integer_t is std::int64_t. With the default values for NumberUnsignedType (std::uint64_t), the default value for number_unsigned_t is std::uint64_t. With the default values for NumberFloatType (double), the default value for number_float_t is double.
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.
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. Note values smaller than -1.79769313486232e+308 and values greater than 1.79769313486232e+308 will be stored as NaN internally and be serialized to null.
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:
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.
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
Notes
Numbers with a decimal digit or scientific notation are always stored as double.
The number types can be changed, see Template number types.
Integers are converted by the library's own digit parser. Floating-point numbers are converted with std::from_chars if the library is compiled with C++17 and the standard library supports it, then with an exact fast path for double values with few significant digits, and otherwise with the locale-aware std::strtod (std::strtof/std::strtold for the other floating-point types). 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.
Any 64-bit signed or unsigned integer can be stored without loss of precision.
Numbers exceeding the limits of double (i.e., numbers that after conversion via std::strtod are not satisfying std::isfinite such as 1E400) will throw exception json.exception.out_of_range.406 during parsing.
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.
The JSON number grammar allows for different ways to express zero, and this library will store zeros differently:
Literal Stored value and type Serialization 0std::uint64_t(0)0-0std::int64_t(0)00.0double(0.0)0.0-0.0double(-0.0)-0.00E0double(0.0)0.0-0E0double(-0.0)-0.0
That is, -0 is stored as a signed integer, but the serialization does not reproduce the -.
Integer numbers are serialized as is; that is, no scientific notation is used.
Floating-point numbers are serialized as specified by the %g printf modifier with std::numeric_limits<double>::max_digits10 significant digits. The rationale is to use the shortest representation while still allowing round-tripping.
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:
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:
JSON does not define a number type or precision (see above).
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()truetruetruefalseis_number_integer()truetruefalsefalseis_number_unsigned()truefalsefalsefalseis_number_float()falsefalsetruefalsetype_name()\"number\"\"number\"\"number\"\"string\"type()number_unsignednumber_integernumber_floatstring"},{"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_tstd::int32_t, std::int16_t, etc. 6 unsigned integers std::uint64_tstd::uint32_t, std::uint16_t, etc. 7 floating-point doublefloat, 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 types for signed and unsigned integers must be distinct, see #2573.
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.
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 -- 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 -- needed to instantiate basic_json at all, or needed by functions that virtually every program uses (construction, element access, dump).
Required for ... -- 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 can silently misparse floating-point numbers, because the lexer may hand the buffer to std::strtod, which reads up to the terminating null character.
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 ObjectTypestd::mapnlohmann::ordered_map, Abseil hash maps ArrayTypestd::vectorstd::dequeStringTypestd::stringstd::string-like types over charBooleanTypebool none worth using NumberIntegerTypestd::int64_t any signed integer type NumberUnsignedTypestd::uint64_t any unsigned integer type at least as wide as NumberIntegerTypeNumberFloatTypedoublefloat (long double: no binary formats) AllocatorTypestd::allocator stateless allocators JSONSerializeradl_serializer serializers with the same interface BinaryTypestd::vector<std::uint8_t>std::vector<char>CustomBaseClassvoid any default-constructible class
Third-party containers and incomplete types
object_t is instantiated inside the definition of basic_json -- it is probed for a key_compare member to form object_comparator_t -- 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 -- 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.
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 -- 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 -- 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.
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.
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 -- 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 -- a good starting point for a custom ObjectType.
"},{"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_traitstsl::ordered_map its iterators expose the mapped value as constQMap 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_multimapemplace 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
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 -- a good starting point for a custom ArrayType.
"},{"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, devectorboost::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).
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::strtod. 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 -- the parser may hand it to std::strtod, which reads up to the null character. A type whose data() is not null-terminated does not fail to compile; it can silently misparse floating-point numbers.
append(const char*, size_type), used by dump, and append(const StringType&), used by the CBOR reader for indefinite-length strings. 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-constdata() 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) -- 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().
begin() and end() -- 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_bsonfind(value_type) and nposparse from a string_t the input adapters must accept it; otherwise pass a character range operator<<(std::ostream&, const json_pointer&) streamability to std::ostreamto_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 -- 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 -- from parse, from dump, or by default construction -- 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 -- 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 -- 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
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 -- an explicit constructor is not enough, because the to_json overload for a custom BooleanType is constrained on std::is_convertible -- and contextually convertible to bool (here an explicit operator bool is fine).
bool is the only usable choice. Another trivially copyable type that is implicitly convertible to and from bool -- std::uint8_t, say -- 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.
std::is_integral must be satisfied: NumberIntegerType must be a signed integer type, NumberUnsignedType an unsigned integer type. Class types are not supported -- 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.
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.
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/#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 class types, enumerations not usable; std::is_integral must hold bool, or a type already used for 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.
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 with std::from_chars or, as a fallback, with std::strtof, std::strtod, or 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 binary32 or binary64 number, dump uses the Grisu2 algorithm, which produces the shortest 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; short round-trip output through Grisu2 float full; short round-trip output through Grisu2 long doubledump 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.
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.
The template must accept two type arguments. It does not have to give the second one a default -- 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
A non-final class type -- 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_castdata(). data() + n would do for the readers too, but they share one helper with StringType, whose non-constdata() 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, and insert(pos, first, last), which the CBOR reader uses to join the chunks of an indefinite-length byte string. 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 -- a good starting point for a custom BinaryType.
"},{"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::stringbinary_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 -- 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.
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.
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.
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).
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 ObjectTypestd::map objects, see object_tArrayTypestd::vector arrays, see array_tStringTypestd::string strings and object keys, see string_tBooleanTypebool Booleans, see boolean_tNumberIntegerTypestd::int64_t signed integers, see number_integer_tNumberUnsignedTypestd::uint64_t unsigned integers, see number_unsigned_tNumberFloatTypedouble floating-point numbers, see number_float_tAllocatorTypestd::allocator allocating objects, arrays, strings, and binary values JSONSerializeradl_serializer conversions from/to other types, see adl_serializerBinaryTypestd::vector<std::uint8_t> binary values, see binary_tCustomBaseClassvoid 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.
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.
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. Only iterator_input_adapter provides them, and only for random-access input of single-byte characters:
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.
supports_bulk_scan, bulk_data(), bulk_remaining(), and bulk_skip() let the lexer scan strings directly in contiguous memory, several bytes at a time.
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.
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.
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.
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
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.
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
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
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
This page collects the library's built-in debugger integrations and other debugging-related features. They are not linked from a single place elsewhere in the docs, so 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.
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.
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 -- see Parsing and exceptions for how parse errors report their own location instead.
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.
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.
classDiagram\n direction LR\n class `std::exception` {\n <<interface>>\n }\n\n class `json::exception` {\n +const int id\n +const char* what() const\n }\n\n class `json::parse_error` {\n +const std::size_t byte\n }\n\n class `json::invalid_iterator`\n class `json::type_error`\n class `json::out_of_range`\n class `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`
"},{"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).
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.
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.
[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
The library throws this exception when a parse error occurs. Parse errors can occur during the deserialization of JSON text, CBOR, MessagePack, 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.
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
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 http://jsonlint.com or a tool like jq.
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
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.
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
An unexpected byte was read in a binary format or length information is invalid (BSON).
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
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; see the ill-formed UTF-8 notes on the individual binary format pages for how such a string is handled depending on error_handler.
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
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
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
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
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
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
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
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
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.
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
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.
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
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
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.
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
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}
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.
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, or BSON.
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.
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.
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
number overflow parsing '10E1000'\n
[json.exception.out_of_range.406] syntax error while parsing CBOR value: number overflow\n
This exception previously indicated that the UBJSON and BSON binary formats did not support integer numbers greater than 9223372036854775807 due to limitations in the implemented mapping. However, these limitations have since been resolved, and this exception no longer occurs.
Exception cannot occur any more
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.
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 size and type annotation, so any value it produces can still be read back.
Example messages
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
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
enum value out of range\narray index 18446744073709551616 exceeds size_type\n
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
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.
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
BSON length 2147483661 exceeds maximum of 2147483647\n
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.
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
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).
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
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.
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.
Example message
[json.exception.out_of_range.415] subtype 70000 is too large for the MessagePack ext type (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.
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.
This is a known issue, and -- even worse -- 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:
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.
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:
Only 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. These encodings are not supported when reading from files or other input containers.
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:
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:
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
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 -- or a concurrent read while another thread writes to the same object -- is a data race and requires external synchronization (e.g., a std::mutex) by the caller.
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/#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.
"},{"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.
It seems that precision is lost when serializing a double.
Can I change the precision for floating-point serialization?
The library uses std::numeric_limits<number_float_t>::digits10 (15 for IEEE doubles) digits for serialization. This value is sufficient to guarantee roundtripping. If one uses more than this number of digits of precision, then string -> value -> string is not guaranteed to round-trip.
cppreference.com
The value of std::numeric_limits<T>::digits10 is the number of base-10 digits that can be represented by the type T without change, that is, any number with this many significant decimal digits can be converted to a value of type T and back to decimal form, without change due to rounding or overflow.
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.
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.
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:
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.
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 copy of Hedley from Evan Nemerson which is licensed as CC0-1.0.
The class contains an adapted version of the Eisel-Lemire algorithm and its table of powers of five 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
This page 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.
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.
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.
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.
Fixes a stack overflow for deeply nested input by making the destructor iterative; parsing is now bounded only by available memory. All changes are backward-compatible. Full release notes.
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.
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) and std::string_view (C++17), and round-tripping of std::map/std::unordered_map with non-string keys.
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.
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.
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).
Adds the emplace and emplace_back functions and improves parsing and serialization performance. All changes are backward-compatible. Full release notes.
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.
Fixes operator[] for JSON pointers so that it creates missing values like the other overloads. All changes are backward-compatible. Full release notes.
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.
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.
Fixes a performance regression in the dump function by adjusting the stream locale once per serialization. All changes are backward-compatible. Full release notes.
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{Already using CMake?}\n B -- no --> C{Using pkg-config or plain Makefiles?}\n C -- yes --> D[pkg-config]\n C -- no --> E[Copy the single header]\n B -- yes --> F{Library installed system-wide?}\n F -- yes --> G[\"find_package()\"]\n F -- no --> H{Use a package manager?}\n H -- yes --> I[Package manager]\n H -- no --> J[\"add_subdirectory() or FetchContent\"]
Copy the single header, as described below \u2014 no build-system integration required.
CMake: use find_package() if the library is already installed, add_subdirectory() to embed the source tree, or FetchContent to download it at configure time; see CMake.
Package managers: install the library with a package manager such as Homebrew, Conan, or vcpkg; see Package Managers.
pkg-config: if you use bare Makefiles instead of CMake, pkg-config can supply 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.
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 json = 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).
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.
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.
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.
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.
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.
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.
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.
Delete the deprecated functions instead of only deprecating them by defining the macro JSON_DELETE_DEPRECATED_FUNCTIONS. This option is OFF by default.
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():
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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:
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 nine runs compiling a single translation unit with -std=c++17 -c against the single-header version, with Apple clang and GCC 16 on macOS (Apple silicon). They show the order of magnitude to expect; measure your own code before and after a change.
"},{"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, ordered_json, json_pointer, and adl_serializer. The translation units that actually use the values then include <nlohmann/json.hpp>.
Compiler json.hpp (-O0) json_fwd.hpp (-O0) Change Apple clang 704 ms 329 ms \u221253% GCC 16 779 ms 242 ms \u221269%
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):
#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 776 ms / 846 ms 629 ms / 692 ms \u221219% / \u221218% GCC 16 model 1022 ms / 1120 ms 882 ms / 965 ms \u221214% / \u221214% Apple clang parsing 992 ms / 1815 ms 1006 ms / 1823 ms +1% / 0% GCC 16 parsing 2018 ms / 3420 ms 1990 ms / 3454 ms \u22121% / +1%
Translation units that include only the header save up to a third. Translation units that parse anyway instantiate the parser regardless and see no difference.
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 992 ms / 1815 ms 953 ms / 1625 ms \u22124% / \u221210% GCC 16 parsing 2018 ms / 3420 ms 1522 ms / 2728 ms \u221225% / \u221220% Apple clang json_instance.cpp \u2014 2166 ms / 4660 ms \u2014 GCC 16 json_instance.cpp \u2014 5085 ms / 10616 ms \u2014
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.
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.
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.
"},{"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 776 ms / 846 ms 1022 ms / 1120 ms JSON_NO_IO 764 ms / 836 ms 1022 ms / 1117 ms JSON_USE_GLOBAL_UDLS=0 763 ms / 852 ms 1019 ms / 1106 ms
JSON_USE_GLOBAL_UDLS only controls where the literals are declared; to avoid their cost, use JSON_NO_AUTOMATIC_UDLS instead.
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.
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.
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.
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
Comparing JSON Pointers with strings via operator== and operator!= is deprecated since 3.11.2. To compare a json_pointerp with a string s, convert s to a json_pointer first and use json_pointer::operator== or json_pointer::operator!=.
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
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.
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.
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
"},{"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.
"},{"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.
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.
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:
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
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
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.
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).
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
Create the following files (the source file goes into Sources/json_example/, following Swift Package Manager's directory layout convention):
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.
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
Right-click the project (any C++ project) in \"Solution Explorer\" and select \"Manage NuGet Packages\u2026\"
Switch to the \"Browse\" tab.
Search for nlohmann.json, select it, and click \"Install\".
#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.
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.
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:
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:
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
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
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
Create a new executable project \"example\" (see bdep new command details for the various options to create a new project):
bdep new example\n
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}:
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
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.
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.
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: