* Review and extend the documentation, and check it in CI A review of all documentation pages found factual errors, dead links, missing cross-references, and gaps in examples. This fixes them and adds checks so the same problems are caught automatically. Fixes: - wrong signatures and version histories (operator!= C++20 member, binary() subtype type, get<PointerType>(), JSON_NO_THREAD_LOCAL, ...) - stale descriptions (number parsing since #5283, UBJSON table, SAX example that no longer compiled, tsl::ordered_map advice) - dead internal and external links; repology.org badges (the domain is suspended) replaced by badges that query the registries directly - deprecation notes link the migration guide; the guide itself fixed Additions: - "See also" sections, cross-references, 25 runnable examples, 12 Mermaid diagrams, new API pages for json_pointer::operator<=> and byte_container_with_subtype::operator==/!= - landing page, guides for untrusted input and performance - "unreleased" badge after versions newer than the latest release Checks: - strict documentation build (broken links/anchors fail it); CI and the publish workflow fetch the full history the build needs - weekly external link check, Mermaid syntax check in CI - check_structure.py: example titles, heading levels, alt texts, header links, docset index coverage; its unused-example check works again - all examples produce the same output on every platform Signed-off-by: Niels Lohmann <mail@nlohmann.me> * Keep the customer links that could not be fixed A dead link on the customers page is still the evidence of where the use of the library was documented. Keep the original URLs of the entries without a working replacement (Marne, Cisco Webex Desk Camera, Philips Hue, CyberArk) and exclude exactly these URLs from the link check. Signed-off-by: Niels Lohmann <mail@nlohmann.me> * Correct the duplicate-key recipe's claim about SAX positions The SAX interface's key() receives no position either; only parse_error() does. Also note that the recipe does not report the path to the repeated key (see discussion #5085). Signed-off-by: Niels Lohmann <mail@nlohmann.me> * Say the library is available as a single header and mention json_fwd.hpp Signed-off-by: Niels Lohmann <mail@nlohmann.me> * Correct documentation errors found while hunting for bugs - patch/patch_inplace: list the JSON pointer errors parse_error.106-109 and out_of_range.402/404, and quote the actual parse_error.105 message. - unflatten: list parse_error.106/107/108 and out_of_range.404. - to_bson: list out_of_range.415 (binary subtype above 255) and note that 412 and 415 are new in 3.13.0. - to_string: state that string_t must be convertible to std::string, also in the StringType requirements table. - JSON Lines: a `while (input >> j)` loop also throws after the last value for concatenated JSON values; show a loop that works for both. - BON8: a string gets 0xFF only if nothing follows it in the message; a string at the end of an array or object is ended by 0xFE. - custom_string_type.hpp: add operator+=(char), which the "Always required" list asks for (json_pointer::to_string, flatten, unflatten, and diff did not compile), and an ADL int_to_string for diff and items. Signed-off-by: Niels Lohmann <mail@nlohmann.me> * Cache the release headers with functools.lru_cache Codacy (Pylint) flagged the mutable default argument that header() used as its cache. functools.lru_cache keeps the same memoization without it. The script's output is unchanged. Signed-off-by: Niels Lohmann <mail@nlohmann.me> --------- Signed-off-by: Niels Lohmann <mail@nlohmann.me>
19 KiB
nlohmann::basic_json::basic_json
// (1)
basic_json(const value_t v);
// (2)
basic_json(std::nullptr_t = nullptr) noexcept;
// (3)
template<typename CompatibleType>
basic_json(CompatibleType&& val) noexcept(noexcept(
JSONSerializer<U>::to_json(std::declval<basic_json_t&>(),
std::forward<CompatibleType>(val))));
// (4)
template<typename BasicJsonType>
basic_json(const BasicJsonType& val);
// (5)
basic_json(initializer_list_t init,
bool type_deduction = true,
value_t manual_type = value_t::array);
// (6)
basic_json(size_type cnt, const basic_json& val);
// (7)
basic_json(iterator first, iterator last);
basic_json(const_iterator first, const_iterator last);
// (8)
basic_json(const basic_json& other);
// (9)
basic_json(basic_json&& other) noexcept;
-
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 #!json nullboolean #!json falsestring #!json ""number #!json 0object #!json {}array #!json []binary empty array The postcondition of this constructor can be restored by calling
clear(). -
Create a
#!json nullJSON value. It either takes a null pointer as parameter (explicitly creating#!json null) or no parameter (implicitly creating#!json 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 parametervalto that method (tojson_serializer<U>::to_jsonmethod withU = uncvref_t<CompatibleType>, to be exact).Template type
CompatibleTypeincludes, but is not limited to, the following types:- arrays:
array_tand all kinds of compatible containers such asstd::vector,std::deque,std::list,std::forward_list,std::array,std::valarray,std::set,std::unordered_set,std::multiset, andstd::unordered_multisetwith avalue_typefrom which abasic_jsonvalue can be constructed. - objects:
object_tand all kinds of compatible associative containers such asstd::map,std::unordered_map,std::multimap, andstd::unordered_multimapwith akey_typecompatible tostring_tand avalue_typefrom which abasic_jsonvalue 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 asint,size_t,int64_t,floatordoublecan be used. - boolean:
boolean_t/boolcan 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 withconst 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.
- arrays:
-
This is a constructor for existing
basic_jsontypes. 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_valueof the parameter. Each member value (object, array, string, etc.) is serialized via the correspondingto_json()overload. For objects and strings, the conversion requires that the targetbasic_jsontype'sobject_t::key_type(orstring_t) be directly constructible from the source type's corresponding member type viais_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 casetype_deductionis#!cpp true(default), the type of the JSON value to be created is deducted from the initializer listinitaccording 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_deductionis#!cpp false, in which casemanual_typedecides between object and array, and an object can only be forced ifinitactually matches rule 2 (or is empty):flowchart TD A(["initializer_list init"]) --> B{"empty, or every element is a 2-element<br/>array whose first element is a string?"} B -->|"yes"| C{"type_deduction"} B -->|"no"| D{"type_deduction"} C -->|"true"| OBJ["create object"] C -->|"false"| E{"manual_type"} E -->|"object"| OBJ E -->|"array"| ARR["create array"] D -->|"true"| ARR D -->|"false"| F{"manual_type"} F -->|"array"| ARR F -->|"object"| ERR["throw type_error.301"]The rules aim to create the best fit between a C++ initializer list and JSON values. The rationale is as follows:
- The empty initializer list is written as
#!cpp {}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 (
#!json []): usearray(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()andobject()force array and object creation from initializer lists, respectively.!!! warning "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: ```cpp json j1 = "hello"; json j2{j1}; // [!] j2 is ["hello"], NOT a copy of j1 json j3(j1); // j3 is "hello" -- parentheses copy as expected ``` See the FAQ entry on [brace initialization](../../home/faq.md#brace-initialization-yields-arrays) 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. - If the list is empty, an empty JSON object value
-
Constructs a JSON array value by creating
cntcopies of a passed value. In casecntis0, 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
#!json nulltype, invalid_iterator.206 is thrown. - In case of other primitive types (number, boolean, string, or binary),
firstmust bebegin()andlastmust beend(). In this case, the value is copied. Otherwise,invalid_iterator.204is thrown. - In case of structured types (array, object), the constructor behaves as similar versions for
std::vectororstd::map; that is, a JSON array or object is constructed from the values in the range.
- In case of a
-
Creates a copy of a given JSON value.
-
Move constructor. Constructs a JSON value with the contents of the given value
otherusing move semantics. It "steals" the resources fromotherand leaves it as JSON#!json nullvalue.
Template parameters
CompatibleType- a type such that:
CompatibleTypeis not derived fromstd::istream,CompatibleTypeis notbasic_json(to avoid hijacking copy/move constructors),CompatibleTypeis not a differentbasic_jsontype (i.e. with different template arguments)CompatibleTypeis not abasic_jsonnested type (e.g.,json_pointer,iterator, etc.)- if
JSON_DISABLE_TUPLE_REFERENCE_CONVERSIONis defined to1:CompatibleTypeis not a one-elementstd::tupleholding a reference tobasic_json json_serializer<U>(withU = uncvref_t<CompatibleType>) has ato_json(basic_json_t&, CompatibleType&&)method
BasicJsonType:- a type such that:
BasicJsonTypeis abasic_jsontype.BasicJsonTypehas different template arguments thanbasic_json_t.
Note: For cross-
basic_jsonconversions to produce correct results, the targetbasic_json'sobject_t::key_typeandstring_tmust be directly constructible from the sourcebasic_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>
Parameters
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
#!cpp true, the type of the JSON value is deducted from the initializer listinit; when set to#!cpp false, the type provided viamanual_typeis forced. This mode is used by the functionsarray(initializer_list_t)andobject(initializer_list_t). manual_type(in)- internal parameter; when
type_deductionis set to#!cpp false, the created JSON value will use the provided type (onlyvalue_t::arrayandvalue_t::objectare valid); whentype_deductionis set to#!cpp true, this parameter has no effect cnt(in)- the number of JSON copies of
valto 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
Exception safety
- 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.
Exceptions
- (none)
- The function does not throw exceptions.
- (none)
- (none)
- The function can throw the following exceptions:
- Throws
type_error.301iftype_deductionis#!cpp false,manual_typeisvalue_t::object, butinitcontains an element which is not a pair whose first element is a string. In this case, the constructor could not create an object. Iftype_deductionwould have been#!cpp true, an array would have been created. Seeobject(initializer_list_t)for an example.
- Throws
- (none)
- The function can throw the following exceptions:
- Throws
invalid_iterator.201if iteratorsfirstandlastare not compatible (i.e., do not belong to the same JSON value). In this case, the range[first, last)is undefined. - Throws
invalid_iterator.204if iteratorsfirstandlastbelong to a primitive type (number, boolean, string, or binary), butfirstdoes not point to the first element anymore. In this case, the range[first, last)is undefined. See the example code below. - Throws
invalid_iterator.206if iteratorsfirstandlastbelong to a#!json nullvalue. In this case, the range[first, last)is undefined.
- Throws
- (none)
- The function does not throw exceptions.
Complexity
- Constant.
- Constant.
- Usually linear in the size of the passed
val, also depending on the implementation of the calledto_json()method. - Usually linear in the size of the passed
val, also depending on the implementation of the calledto_json()method. - Linear in the size of the initializer list
init. - Linear in
cnt. - Linear in distance between
firstandlast. - Linear in the size of
other. - Constant.
Notes
-
Overload 5:
!!! note "Empty initializer list"
When used without parentheses around an empty initializer list, `basic_json()` is called instead of this function, yielding the JSON `#!json null` value. -
Overload 7:
!!! info "Preconditions"
- Iterators `first` and `last` must be initialized. **This precondition is enforced with a [runtime assertion](../../features/assertions.md). - 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.!!! danger "Runtime assertion"
A precondition is enforced with a [runtime assertion](../../features/assertions.md). -
Overload 8:
!!! info "Postcondition"
`#!cpp *this == other` -
Overload 9:
!!! info "Postconditions"
- `#!cpp `*this` has the same value as `other` before the call. - `other` is a JSON `#!json null` value
Examples
??? example "Example: (1) create an empty value with a given type"
The following code shows the constructor for different `value_t` values.
```cpp
--8<-- "examples/basic_json__value_t.cpp"
```
Output:
```json
--8<-- "examples/basic_json__value_t.output"
```
??? example "Example: (2) create a #!json null object"
The following code shows the constructor with and without a null pointer parameter.
```cpp
--8<-- "examples/basic_json__nullptr_t.cpp"
```
Output:
```json
--8<-- "examples/basic_json__nullptr_t.output"
```
??? example "Example: (3) create a JSON value from compatible types"
The following code shows the constructor with several compatible types.
```cpp
--8<-- "examples/basic_json__CompatibleType.cpp"
```
Output:
```json
--8<-- "examples/basic_json__CompatibleType.output"
```
Note the output is platform-dependent.
??? example "Example: (4) create a JSON value from another basic_json specialization"
The example below shows how a `json` value is converted to an `ordered_json` value and back using the converting
constructor. Note how the original insertion order of `oj` is not restored, because it was already given up when
converting to `json`, whose `object_t` sorts by key.
```cpp
--8<-- "examples/basic_json__BasicJsonType.cpp"
```
Output:
```json
--8<-- "examples/basic_json__BasicJsonType.output"
```
??? example "Example: (5) create a container (array or object) from an initializer list"
The example below shows how JSON values are created from initializer lists.
```cpp
--8<-- "examples/basic_json__list_init_t.cpp"
```
Output:
```json
--8<-- "examples/basic_json__list_init_t.output"
```
??? example "Example: (6) construct an array with count copies of a given value"
The following code shows examples for creating arrays with several copies of a given value.
```cpp
--8<-- "examples/basic_json__size_type_basic_json.cpp"
```
Output:
```json
--8<-- "examples/basic_json__size_type_basic_json.output"
```
??? example "Example: (7) construct a JSON container given an iterator range"
The example below shows several ways to create JSON values by specifying a subrange with iterators.
```cpp
--8<-- "examples/basic_json__InputIt_InputIt.cpp"
```
Output:
```json
--8<-- "examples/basic_json__InputIt_InputIt.output"
```
??? example "Example: (8) copy constructor"
The following code shows an example for the copy constructor.
```cpp
--8<-- "examples/basic_json__basic_json.cpp"
```
Output:
```json
--8<-- "examples/basic_json__basic_json.output"
```
??? example "Example: (9) move constructor"
The code below shows the move constructor explicitly called via `std::move`.
```cpp
--8<-- "examples/basic_json__moveconstructor.cpp"
```
Output:
```json
--8<-- "examples/basic_json__moveconstructor.output"
```
See also
- array create a JSON array value, forcing array creation from an initializer list even when it looks like an object
- object create a JSON object value, forcing object creation from an initializer list
- binary create a JSON binary array value
- operator= copy assignment operator
- Creating JSON values - the article on creating JSON values
Version history
- Since version 1.0.0.
- Since version 1.0.0.
- Since version 2.1.0.
- Since version 3.2.0.
- Since version 1.0.0.
- Since version 1.0.0.
- Since version 1.0.0. Fixed in version 3.13.0 to also check the iterator range for binary values; before, a range
that did not cover the whole value (such as
(end(), end())) was accepted and the whole binary value was copied, unlike the other primitive types. - Since version 1.0.0.
- Since version 1.0.0.