Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2638f276d0 | ||
|
|
66d4f3602b | ||
|
|
612e9ade2c | ||
|
|
b3ab23e11c | ||
|
|
31538a91ed | ||
|
|
bf8dca5c16 | ||
|
|
d19e030bf1 | ||
|
|
e359852b76 | ||
|
|
734912bed6 | ||
|
|
91cc42b302 | ||
|
|
95412a36d0 | ||
|
|
d2309300e9 | ||
|
|
d3d39a9c10 | ||
|
|
24ff6eaa43 | ||
|
|
9d9bf927ff | ||
|
|
cc39e1f8da | ||
|
|
5ac95db5a9 | ||
|
|
d1d142633a | ||
|
|
49e9eaac4f | ||
|
|
4b35877ae5 | ||
|
|
34f9be2aa2 | ||
|
|
8c4818d5f7 | ||
|
|
df1bca6dae | ||
|
|
b22cad367c | ||
|
|
95169a63fa |
No files matched your search
@@ -113,22 +113,19 @@ basic_json(basic_json&& other) noexcept;
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A(["initializer_list init"]) --> B{{"empty, or every element is a 2-element<br/>array whose first element is a string?"}}
|
||||
B -->|"yes"| C{{"type_deduction"}}
|
||||
B -->|"no"| D{{"type_deduction"}}
|
||||
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"}}
|
||||
C -->|"false"| E{"manual_type"}
|
||||
E -->|"object"| OBJ
|
||||
E -->|"array"| ARR["create array"]
|
||||
D -->|"true"| ARR
|
||||
D -->|"false"| F{{"manual_type"}}
|
||||
D -->|"false"| F{"manual_type"}
|
||||
F -->|"array"| ARR
|
||||
F -->|"object"| ERR["throw type_error.301"]
|
||||
```
|
||||
|
||||
<p class="nj-caption" markdown>Decision flow for an initializer list: hexagons are checks, edge labels are their
|
||||
outcomes, and rectangles are the resulting value or exception.</p>
|
||||
|
||||
The rules aim to create the best fit between a C++ initializer list and JSON values. The rationale is as follows:
|
||||
|
||||
1. The empty initializer list is written as `#!cpp {}` which is exactly an empty JSON object.
|
||||
|
||||
@@ -7,12 +7,7 @@ const_iterator begin() const noexcept;
|
||||
|
||||
Returns an iterator to the first element.
|
||||
|
||||
<div class="nj-fig-wrap" markdown>
|
||||
--8<-- "images/range-begin-end.svg"
|
||||
</div>
|
||||
|
||||
<p class="nj-caption" markdown>`begin()` points to the first element and `end()` to the position after the last element;
|
||||
the dashed cell is the past-the-last position, which must not be dereferenced.</p>
|
||||

|
||||
|
||||
## Return value
|
||||
|
||||
|
||||
@@ -90,8 +90,9 @@ type `#!cpp binary_t*` must be dereferenced.
|
||||
|
||||
- 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.
|
||||
fixext2, fixext4, fixext8, fixext16) is used. For other sizes, the ext family (ext8, ext16, ext32) is used. The
|
||||
subtype is then written as the signed 8-bit ext type: subtypes 128 to 255 map to the negative (reserved) ext
|
||||
types, and on reading the ext type is exposed as an unsigned subtype from 0 to 255.
|
||||
- If no subtype is given, the bin family (bin8, bin16, bin32) is used.
|
||||
|
||||
- BSON
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
# <small>nlohmann::basic_json::</small>bjdata_version_t
|
||||
|
||||
```cpp
|
||||
enum class bjdata_version_t
|
||||
{
|
||||
draft2,
|
||||
draft3
|
||||
};
|
||||
```
|
||||
|
||||
This enumeration is used in [`to_bjdata`](to_bjdata.md) to choose the version of the BJData specification to write:
|
||||
|
||||
draft2
|
||||
: BJData Draft 2 (the default). Binary values are written as arrays of `U` integers, and ND-arrays with
|
||||
`"_ArrayType_": "byte"` are written as regular objects, since the `B` marker is not part of Draft 2.
|
||||
|
||||
draft3
|
||||
: BJData Draft 3. Binary values are written as `B` elements: as an optimized binary array (`[$B#`) if both `use_size`
|
||||
and `use_type` are set, and as an array of `B`-prefixed elements otherwise. ND-arrays with
|
||||
`"_ArrayType_": "byte"` are written as packed arrays (`[$B#[...]`).
|
||||
|
||||
Only the writer is affected by the version. [`from_bjdata`](from_bjdata.md) reads the markers of both drafts.
|
||||
|
||||
## Examples
|
||||
|
||||
??? example
|
||||
|
||||
The example below shows how the different values of the `bjdata_version_t` influence the serialization of a binary
|
||||
value with [`to_bjdata`](to_bjdata.md).
|
||||
|
||||
```cpp
|
||||
--8<-- "examples/bjdata_version_t.cpp"
|
||||
```
|
||||
|
||||
Output:
|
||||
|
||||
```json
|
||||
--8<-- "examples/bjdata_version_t.output"
|
||||
```
|
||||
|
||||
## See also
|
||||
|
||||
- [to_bjdata](to_bjdata.md) serializes a JSON value to BJData
|
||||
- [BJData](../../features/binary_formats/bjdata.md) - the article on the BJData format
|
||||
|
||||
## Version history
|
||||
|
||||
- Added in version 3.12.0.
|
||||
@@ -6,12 +6,7 @@ const_iterator cbegin() const noexcept;
|
||||
|
||||
Returns an iterator to the first element.
|
||||
|
||||
<div class="nj-fig-wrap" markdown>
|
||||
--8<-- "images/range-begin-end.svg"
|
||||
</div>
|
||||
|
||||
<p class="nj-caption" markdown>`cbegin()` points to the first element, like `begin()`, and `end()` to the position after
|
||||
the last element; the dashed cell is the past-the-last position, which must not be dereferenced.</p>
|
||||

|
||||
|
||||
## Return value
|
||||
|
||||
|
||||
@@ -15,11 +15,13 @@ error
|
||||
: report a parse error in case of a tag (the `from_cbor` overloads throw a `parse_error` exception by default)
|
||||
|
||||
ignore
|
||||
: ignore tags
|
||||
: ignore tags (also in front of a text string map key)
|
||||
|
||||
store
|
||||
: store tagged byte strings (for bytes 0xd8..0xdb) as binary values with the tag as subtype; other tagged values are
|
||||
read as if the tag were ignored. If several tags precede a byte string, only the innermost one is stored.
|
||||
read as if the tag were ignored. If several tags precede a byte string, only the tag directly in front of it is
|
||||
stored, and only when it has the form 0xd8..0xdb (a tag 0..23 written as 0xc0..0xd7 is skipped). Tags in front of a
|
||||
text string map key are skipped.
|
||||
|
||||
## Examples
|
||||
|
||||
|
||||
@@ -6,12 +6,7 @@ const_iterator cend() const noexcept;
|
||||
|
||||
Returns an iterator to one past the last element.
|
||||
|
||||
<div class="nj-fig-wrap" markdown>
|
||||
--8<-- "images/range-begin-end.svg"
|
||||
</div>
|
||||
|
||||
<p class="nj-caption" markdown>`cend()` points to the position after the last element, like `end()`, and `begin()` to
|
||||
the first element; the dashed cell is the past-the-last position, which must not be dereferenced.</p>
|
||||

|
||||
|
||||
## Return value
|
||||
|
||||
|
||||
@@ -6,13 +6,7 @@ const_reverse_iterator crbegin() const noexcept;
|
||||
|
||||
Returns an iterator to the reverse-beginning; that is, the last element.
|
||||
|
||||
<div class="nj-fig-wrap" markdown>
|
||||
--8<-- "images/range-rbegin-rend.svg"
|
||||
</div>
|
||||
|
||||
<p class="nj-caption" markdown>`crbegin()` points to the last element, like `rbegin()`, and `rend()` to the position
|
||||
before the first element. The upper row is the reversed sequence and the lower row the forward sequence; dashed arrows
|
||||
link each reverse iterator to the forward iterator it stores, and dashed cells are past-the-last positions.</p>
|
||||

|
||||
|
||||
## Return value
|
||||
|
||||
|
||||
@@ -7,13 +7,7 @@ const_reverse_iterator crend() const noexcept;
|
||||
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.
|
||||
|
||||
<div class="nj-fig-wrap" markdown>
|
||||
--8<-- "images/range-rbegin-rend.svg"
|
||||
</div>
|
||||
|
||||
<p class="nj-caption" markdown>`crend()` points to the position before the first element, like `rend()`, and `rbegin()`
|
||||
to the last element. The upper row is the reversed sequence and the lower row the forward sequence; dashed arrows link
|
||||
each reverse iterator to the forward iterator it stores, and dashed cells are past-the-last positions.</p>
|
||||

|
||||
|
||||
## Return value
|
||||
|
||||
|
||||
@@ -7,12 +7,7 @@ const_iterator end() const noexcept;
|
||||
|
||||
Returns an iterator to one past the last element.
|
||||
|
||||
<div class="nj-fig-wrap" markdown>
|
||||
--8<-- "images/range-begin-end.svg"
|
||||
</div>
|
||||
|
||||
<p class="nj-caption" markdown>`end()` points to the position after the last element and `begin()` to the first element;
|
||||
the dashed cell is the past-the-last position, which must not be dereferenced.</p>
|
||||

|
||||
|
||||
## Return value
|
||||
|
||||
|
||||
@@ -40,9 +40,6 @@ classDiagram
|
||||
style json_exception fill:#CCCCFF
|
||||
```
|
||||
|
||||
<p class="nj-caption" markdown>Class hierarchy of the library's exceptions; arrows point from a derived class to its
|
||||
base class, and the highlighted box is `basic_json::exception`.</p>
|
||||
|
||||
Subclasses:
|
||||
|
||||
- [`parse_error`](parse_error.md) for exceptions indicating a parse error
|
||||
|
||||
@@ -82,8 +82,11 @@ Strong guarantee: if an exception is thrown, there are no changes in the JSON va
|
||||
- Throws [parse_error.112](../../home/exceptions.md#jsonexceptionparse_error112) if a parse error occurs
|
||||
- Throws [parse_error.113](../../home/exceptions.md#jsonexceptionparse_error113) if a string could not be parsed
|
||||
successfully, or if a string value or object key is not valid UTF-8 and `error_handler` is `strict`
|
||||
- Throws [parse_error.115](../../home/exceptions.md#jsonexceptionparse_error115) if the text of a high-precision
|
||||
number (`H`) is not a valid number
|
||||
- Throws [out_of_range.408](../../home/exceptions.md#jsonexceptionout_of_range408) if the size of an optimized container
|
||||
or n-dimensional array cannot be represented by `std::size_t`
|
||||
cannot be represented by `std::size_t` or exceeds the container's `max_size()`, or if the product of the dimensions of
|
||||
an n-dimensional array overflows
|
||||
|
||||
## Complexity
|
||||
|
||||
|
||||
@@ -80,7 +80,8 @@ Strong guarantee: if an exception is thrown, there are no changes in the JSON va
|
||||
- Throws [`parse_error.110`](../../home/exceptions.md#jsonexceptionparse_error110) if the given input ends prematurely or
|
||||
the end of the input was not reached when `strict` was set to true
|
||||
- Throws [`parse_error.112`](../../home/exceptions.md#jsonexceptionparse_error112) if a parse error occurs (e.g., an
|
||||
invalid string or byte array length)
|
||||
invalid string or byte array length, an invalid inner length of a binary value with subtype `0x02`, or a document size
|
||||
that does not match the content; `strict` does not affect the document size checks)
|
||||
- Throws [`parse_error.114`](../../home/exceptions.md#jsonexceptionparse_error114) if an unsupported BSON record type is
|
||||
encountered
|
||||
- Throws [`parse_error.113`](../../home/exceptions.md#jsonexceptionparse_error113) if a string value or object key is
|
||||
|
||||
@@ -32,8 +32,10 @@ The exact mapping and its limitations are described on a [dedicated page](../../
|
||||
|
||||
- an `std::istream` object
|
||||
- a `FILE` pointer
|
||||
- a C-style array of characters
|
||||
- a pointer to a null-terminated string of single byte characters
|
||||
- a C-style array of characters (its terminating NUL is read as trailing data: `parse_error.110` unless `strict` is
|
||||
`false`)
|
||||
- a pointer to a null-terminated string of single byte characters (read up to the first 0x00 byte, which is a valid
|
||||
CBOR byte)
|
||||
- a container `obj` for which `begin(obj)` and `end(obj)` produce a valid pair of iterators
|
||||
(as found via ADL or member functions, with semantics compatible to `std::begin` and `std::end`)
|
||||
|
||||
@@ -89,8 +91,14 @@ Strong guarantee: if an exception is thrown, there are no changes in the JSON va
|
||||
- Throws [parse_error.112](../../home/exceptions.md#jsonexceptionparse_error112) if unsupported features from CBOR were
|
||||
used in the given input or if the input is not valid CBOR
|
||||
- Throws [parse_error.113](../../home/exceptions.md#jsonexceptionparse_error113) if a 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`
|
||||
other types are not supported, as JSON object keys are always strings), if the head of a string or byte string is
|
||||
malformed (including a chunk of the wrong type or an indefinite-length string nested inside an indefinite-length
|
||||
string), or if a string value or object key (or one chunk of an indefinite-length string) is not valid UTF-8 and
|
||||
`error_handler` is `strict`
|
||||
- Throws [out_of_range.408](../../home/exceptions.md#jsonexceptionout_of_range408) if an array or map announces
|
||||
a length that `std::size_t` cannot hold, or that equals `std::size_t(-1)` (for example `9B FF FF FF FF FF FF FF FF`)
|
||||
- Throws [out_of_range.406](../../home/exceptions.md#jsonexceptionout_of_range406) if a floating-point number does not
|
||||
fit into `number_float_t`
|
||||
|
||||
## Complexity
|
||||
|
||||
|
||||
@@ -79,11 +79,18 @@ Strong guarantee: if an exception is thrown, there are no changes in the JSON va
|
||||
|
||||
- Throws [parse_error.110](../../home/exceptions.md#jsonexceptionparse_error110) 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](../../home/exceptions.md#jsonexceptionparse_error112) if a parse error occurs
|
||||
- Throws [parse_error.112](../../home/exceptions.md#jsonexceptionparse_error112) if an invalid type marker is read
|
||||
(including a type marker after `$` of an optimized container, even if its count is 0), or if `$` is not followed by `#`
|
||||
- Throws [parse_error.113](../../home/exceptions.md#jsonexceptionparse_error113) if a string could not be parsed
|
||||
successfully, or if a string value or object key is not valid UTF-8 and `error_handler` is `strict`
|
||||
- Throws [out_of_range.408](../../home/exceptions.md#jsonexceptionout_of_range408) if the size of an optimized container
|
||||
or n-dimensional array cannot be represented by `std::size_t`
|
||||
successfully (negative or non-integer length, `C` followed by a byte above 0x7F), if the count of an optimized
|
||||
container is negative, or if a string value or object key is not valid UTF-8 and `error_handler` is `strict`
|
||||
- Throws [parse_error.115](../../home/exceptions.md#jsonexceptionparse_error115) if the text of a high-precision number
|
||||
(`H`) is not a valid JSON number
|
||||
- Throws [out_of_range.406](../../home/exceptions.md#jsonexceptionout_of_range406) if a high-precision number, or a
|
||||
float64 when `number_float_t` is `float`, does not fit into `number_float_t`
|
||||
- Throws [out_of_range.408](../../home/exceptions.md#jsonexceptionout_of_range408) if the count of an optimized
|
||||
container exceeds the capacity of the container (or of `std::size_t`), or if an optimized array of `Z`, `T`, or `F` has
|
||||
more than 1,048,576 elements
|
||||
|
||||
## Complexity
|
||||
|
||||
|
||||
@@ -121,6 +121,7 @@ The class satisfies the following concept requirements:
|
||||
- [**json_pointer**](../json_pointer/index.md) - JSON Pointer implementation
|
||||
- [**json_serializer**](json_serializer.md) - type of the serializer to for conversions from/to JSON
|
||||
- [**error_handler_t**](error_handler_t.md) - type to choose behavior on decoding errors
|
||||
- [**bjdata_version_t**](bjdata_version_t.md) - type to choose the BJData version to write
|
||||
- [**cbor_tag_handler_t**](cbor_tag_handler_t.md) - type to choose how to handle CBOR tags
|
||||
- **initializer_list_t** - type for initializer lists of `basic_json` values
|
||||
- [**input_format_t**](input_format_t.md) - type to choose the format to parse
|
||||
|
||||
@@ -40,9 +40,6 @@ classDiagram
|
||||
style json_invalid_iterator fill:#CCCCFF
|
||||
```
|
||||
|
||||
<p class="nj-caption" markdown>Class hierarchy of the library's exceptions; arrows point from a derived class to its
|
||||
base class, and the highlighted box is `basic_json::invalid_iterator`.</p>
|
||||
|
||||
## Member functions
|
||||
|
||||
- **what** - returns explanatory string
|
||||
|
||||
@@ -40,9 +40,6 @@ classDiagram
|
||||
style json_other_error fill:#CCCCFF
|
||||
```
|
||||
|
||||
<p class="nj-caption" markdown>Class hierarchy of the library's exceptions; arrows point from a derived class to its
|
||||
base class, and the highlighted box is `basic_json::other_error`.</p>
|
||||
|
||||
## Member functions
|
||||
|
||||
- **what** - returns explanatory string
|
||||
|
||||
@@ -41,9 +41,6 @@ classDiagram
|
||||
style json_out_of_range fill:#CCCCFF
|
||||
```
|
||||
|
||||
<p class="nj-caption" markdown>Class hierarchy of the library's exceptions; arrows point from a derived class to its
|
||||
base class, and the highlighted box is `basic_json::out_of_range`.</p>
|
||||
|
||||
## Member functions
|
||||
|
||||
- **what** - returns explanatory string
|
||||
|
||||
@@ -43,9 +43,6 @@ classDiagram
|
||||
style json_parse_error fill:#CCCCFF
|
||||
```
|
||||
|
||||
<p class="nj-caption" markdown>Class hierarchy of the library's exceptions; arrows point from a derived class to its
|
||||
base class, and the highlighted box is `basic_json::parse_error`.</p>
|
||||
|
||||
## Member functions
|
||||
|
||||
- **what** - returns explanatory string
|
||||
|
||||
@@ -22,12 +22,7 @@ The parser callback distinguishes the following events:
|
||||
|
||||
## Examples
|
||||
|
||||
<div class="nj-fig-wrap" markdown>
|
||||
--8<-- "images/callback_events.svg"
|
||||
</div>
|
||||
|
||||
<p class="nj-caption" markdown>Each coloured dot marks where the parser reports a `parse_event_t` event while reading
|
||||
the JSON text on the left; the legend on the right names the event per colour.</p>
|
||||

|
||||
|
||||
??? example
|
||||
|
||||
|
||||
@@ -23,12 +23,7 @@ table describes the values of the parameters `depth`, `event`, and `parsed`.
|
||||
| `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 |
|
||||
|
||||
<div class="nj-fig-wrap" markdown>
|
||||
--8<-- "images/callback_events.svg"
|
||||
</div>
|
||||
|
||||
<p class="nj-caption" markdown>Parse events for a small JSON text: each coloured dot marks the position at which the
|
||||
parser calls the callback, and the legend on the right names the event per colour.</p>
|
||||

|
||||
|
||||
Discarding a value (i.e., returning `#!cpp false`) has different effects depending on the context in which function was
|
||||
called:
|
||||
|
||||
@@ -7,13 +7,7 @@ const_reverse_iterator rbegin() const noexcept;
|
||||
|
||||
Returns an iterator to the reverse-beginning; that is, the last element.
|
||||
|
||||
<div class="nj-fig-wrap" markdown>
|
||||
--8<-- "images/range-rbegin-rend.svg"
|
||||
</div>
|
||||
|
||||
<p class="nj-caption" markdown>`rbegin()` points to the last element and `rend()` to the position before the first
|
||||
element. The upper row is the reversed sequence and the lower row the forward sequence; dashed arrows link each reverse
|
||||
iterator to the forward iterator it stores, and dashed cells are past-the-last positions.</p>
|
||||

|
||||
|
||||
## Return value
|
||||
|
||||
|
||||
@@ -8,13 +8,7 @@ const_reverse_iterator rend() const noexcept;
|
||||
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.
|
||||
|
||||
<div class="nj-fig-wrap" markdown>
|
||||
--8<-- "images/range-rbegin-rend.svg"
|
||||
</div>
|
||||
|
||||
<p class="nj-caption" markdown>`rend()` points to the position before the first element and `rbegin()` to the last
|
||||
element. The upper row is the reversed sequence and the lower row the forward sequence; dashed arrows link each reverse
|
||||
iterator to the forward iterator it stores, and dashed cells are past-the-last positions.</p>
|
||||

|
||||
|
||||
## Return value
|
||||
|
||||
|
||||
@@ -43,7 +43,8 @@ The exact mapping and its limitations are described on a [dedicated page](../../
|
||||
`#!cpp false` by default.
|
||||
|
||||
`version` (in)
|
||||
: which version of BJData to use (see note on "Binary values" on [BJData](../../features/binary_formats/bjdata.md));
|
||||
: which version of BJData to use, see [`bjdata_version_t`](bjdata_version_t.md) and the note on "Binary values" on
|
||||
[BJData](../../features/binary_formats/bjdata.md);
|
||||
optional, `#!cpp bjdata_version_t::draft2` by default.
|
||||
|
||||
`error_handler` (in)
|
||||
@@ -64,7 +65,9 @@ Strong guarantee: if an exception is thrown, there are no changes in the JSON va
|
||||
## Exceptions
|
||||
|
||||
- Throws [`other_error.502`](../../home/exceptions.md#jsonexceptionother_error502) if `use_type` is true and `use_size`
|
||||
is false, and `j` contains a non-empty array, object, or binary value.
|
||||
is false, and `j` contains a non-empty array or object, or a non-empty binary value (with
|
||||
`version = bjdata_version_t::draft3`, any binary value, including an empty one).
|
||||
Scalars, empty arrays, and empty objects do not throw.
|
||||
- Throws [type_error.316](../../home/exceptions.md#jsonexceptiontype_error316) 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`](../macros/json_strict_binary_utf8.md) is enabled)
|
||||
|
||||
@@ -13,7 +13,7 @@ static void to_bson(const basic_json& j, detail::output_adapter<char> o,
|
||||
```
|
||||
|
||||
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).
|
||||
so-called document). The members of an object are written in the order in which iteration visits them.
|
||||
|
||||
1. Returns a byte vector containing the BSON serialization.
|
||||
2. Writes the BSON serialization to an output adapter.
|
||||
|
||||
@@ -42,7 +42,8 @@ The exact mapping and its limitations are described on a [dedicated page](../../
|
||||
|
||||
## Exception safety
|
||||
|
||||
Strong guarantee: if an exception is thrown, there are no changes in the JSON value.
|
||||
Strong guarantee: if an exception is thrown, there are no changes in the JSON value. Bytes that were already written to
|
||||
the output adapter are not taken back.
|
||||
|
||||
## Exceptions
|
||||
|
||||
|
||||
@@ -53,7 +53,7 @@ Strong guarantee: if an exception is thrown, there are no changes in the JSON va
|
||||
value, array, or object exceeds 4294967295, the maximum MessagePack can store; example:
|
||||
`"MessagePack length 4294967296 exceeds maximum of 4294967295"`
|
||||
- Throws [`out_of_range.415`](../../home/exceptions.md#jsonexceptionout_of_range415) if the subtype of a binary value
|
||||
exceeds 255, the maximum of the MessagePack ext type; example:
|
||||
exceeds 255, the largest value the library can store in the one-byte MessagePack ext type; example:
|
||||
`"subtype 70000 is too large for the MessagePack ext type (max 255)"`
|
||||
- Throws [type_error.316](../../home/exceptions.md#jsonexceptiontype_error316) if a string or object key in `j` is
|
||||
not valid UTF-8 and `error_handler` is `strict`
|
||||
|
||||
@@ -41,9 +41,6 @@ classDiagram
|
||||
style json_type_error fill:#CCCCFF
|
||||
```
|
||||
|
||||
<p class="nj-caption" markdown>Class hierarchy of the library's exceptions; arrows point from a derived class to its
|
||||
base class, and the highlighted box is `basic_json::type_error`.</p>
|
||||
|
||||
## Member functions
|
||||
|
||||
- **what** - returns explanatory string
|
||||
|
||||
@@ -48,9 +48,6 @@ functions [`is_null`](is_null.md), [`is_object`](is_object.md), [`is_array`](is_
|
||||
F --> G[binary]
|
||||
```
|
||||
|
||||
<p class="nj-caption" markdown>Arrows point from a type to the next greater type in the ordering used by
|
||||
`operator<`.</p>
|
||||
|
||||
!!! note "Types of numbers"
|
||||
|
||||
There are three enumerators for numbers (`number_integer`, `number_unsigned`, and `number_float`) to distinguish
|
||||
|
||||
@@ -6,7 +6,7 @@ class byte_container_with_subtype : public BinaryType;
|
||||
```
|
||||
|
||||
This type extends the template parameter `BinaryType` provided to [`basic_json`](../basic_json/index.md) 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
|
||||
used by BSON, CBOR, and MessagePack. This type exists so that the user does not have to specify a type themselves with a
|
||||
specific naming scheme in order to override the binary type.
|
||||
|
||||
## Template parameters
|
||||
|
||||
@@ -36,9 +36,6 @@ flowchart LR
|
||||
parent["parent_pointer() returns /a/b"] -.-> B
|
||||
```
|
||||
|
||||
<p class="nj-caption" markdown>Boxes are the reference tokens in order; dotted arrows show which token each member
|
||||
function reads, removes, or adds to.</p>
|
||||
|
||||
The diagram shows the reference tokens of the JSON pointer `/a/b/c`.
|
||||
|
||||
## Member types
|
||||
|
||||
@@ -25,9 +25,6 @@ sequenceDiagram
|
||||
P->>H: end_object()
|
||||
```
|
||||
|
||||
<p class="nj-caption" markdown>Each arrow is one call from the parser to the SAX handler, from top to bottom in the
|
||||
order the calls happen.</p>
|
||||
|
||||
Note `elements` is passed as `#!cpp 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
|
||||
|
||||
@@ -41,8 +41,6 @@ flowchart LR
|
||||
E --> F[Trusted caller]
|
||||
```
|
||||
|
||||
<p class="nj-caption" markdown>The trust boundary: untrusted input enters on the left through the parser, the SAX interface, or the binary readers, and only a value tree reaches the trusted caller on the right.</p>
|
||||
|
||||
## Secure design
|
||||
|
||||
- **Strict parsing.** The parser accepts exactly the JSON grammar of [RFC 8259](https://datatracker.ietf.org/doc/html/rfc8259).
|
||||
|
||||
@@ -4,15 +4,6 @@ Ensuring quality is paramount for this project, particularly because [numerous o
|
||||
depend on it. Each commit to the library undergoes rigorous checks against the following requirements, and any
|
||||
violations will result in a failed build.
|
||||
|
||||
The overview shows the checks a change passes on its way from a push or pull request to a release; the sections below
|
||||
describe each of them.
|
||||
|
||||
<div class="nj-fig-wrap" markdown>
|
||||
--8<-- "images/qa_pipeline.svg"
|
||||
</div>
|
||||
|
||||
<p class="nj-caption" markdown>The checks grouped by the stage at which they run, from push or pull request through the merge into develop to a release. The badge on each card says whether the check runs on every push or PR, on a schedule, or continuously.</p>
|
||||
|
||||
## C++ language compliance and compiler compatibility
|
||||
|
||||
!!! success "Requirement: Compiler support"
|
||||
|
||||
@@ -91,14 +91,6 @@ Version 4.0 is therefore the sum of these macros: you can try it on the 3.x rele
|
||||
to its 4.0 value and fixing what no longer compiles or behaves differently. Once your code works with all of them, it
|
||||
is ready for version 4.0.
|
||||
|
||||
Each macro has a default value in 3.x and a different value in version 4.0. Define the macro to the 4.0 value to try it on the 3.x release train today; version 4.0 makes that value the default:
|
||||
|
||||
<div class="nj-fig-wrap" markdown>
|
||||
--8<-- "images/roadmap_lanes.svg"
|
||||
</div>
|
||||
|
||||
<p class="nj-caption" markdown>Each row is one macro: the 3.x release that added it, its default in 3.x, and its value in version 4.0 (highlighted) or "removed". Versions on the 3.x lane are not to scale.</p>
|
||||
|
||||
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 |
|
||||
@@ -113,8 +105,6 @@ The following macros guard changes that are planned to become the default in ver
|
||||
| [`JSON_DISABLE_TUPLE_REFERENCE_CONVERSION`](../api/macros/json_disable_tuple_reference_conversion.md) | `0` | `1`: a `basic_json` value can no longer be created from a one-element tuple of a reference to it, such as `std::forward_as_tuple(j)`| [`JSON_DisableTupleReferenceConversion`](../integration/cmake.md#json_disabletuplereferenceconversion) | 3.13.0 |
|
||||
| [`JSON_DELETE_DEPRECATED_FUNCTIONS`](../api/macros/json_delete_deprecated_functions.md) | `0` | removed: the deprecated functions are removed (see below); the `from_*(ptr, len)` overloads stay deleted | [`JSON_DeleteDeprecatedFunctions`](../integration/cmake.md#json_deletedeprecatedfunctions) | 3.13.0 |
|
||||
|
||||
<p class="nj-table-caption" markdown>Opt-in macros for the version 4.0 behavior. "3.x default" is the value the library uses when the macro is not defined, "Added" is the release that introduced the macro, and – means there is no CMake option.</p>
|
||||
|
||||
For example, the following makes a 3.x release behave like version 4.0 with respect to these changes:
|
||||
|
||||
```cpp
|
||||
@@ -156,8 +146,6 @@ to the `strict` parameter.
|
||||
| Comparing a [`json_pointer`](../api/json_pointer/index.md) with a string via [`operator==`](../api/json_pointer/operator_eq.md) or [`operator!=`](../api/json_pointer/operator_ne.md) | 3.11.2 | [JSON Pointers](../integration/migration_guide.md#json-pointers) |
|
||||
| [`from_bjdata`](../api/basic_json/from_bjdata.md) and [`from_bon8`](../api/basic_json/from_bon8.md) with `(ptr, len)` | 3.13.0 | [Parsing](../integration/migration_guide.md#parsing) |
|
||||
|
||||
<p class="nj-table-caption" markdown>Deprecated functions, with the release that deprecated each one and the section of the migration guide that shows its replacement.</p>
|
||||
|
||||
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.
|
||||
@@ -1,782 +0,0 @@
|
||||
/* nlohmann/json brand for Material for MkDocs (values from brand/kit/tokens.css) */
|
||||
|
||||
@font-face {
|
||||
font-family: "Inter";
|
||||
src: url("fonts/Inter.woff2") format("woff2");
|
||||
font-weight: 100 900;
|
||||
font-display: swap;
|
||||
}
|
||||
@font-face {
|
||||
font-family: "Inter";
|
||||
src: url("fonts/Inter-Italic.woff2") format("woff2");
|
||||
font-style: italic;
|
||||
font-weight: 100 900;
|
||||
font-display: swap;
|
||||
}
|
||||
@font-face {
|
||||
font-family: "JetBrains Mono";
|
||||
src: url("fonts/JetBrainsMono.woff2") format("woff2");
|
||||
font-weight: 100 800;
|
||||
font-display: swap;
|
||||
}
|
||||
@font-face {
|
||||
font-family: "JetBrains Mono";
|
||||
src: url("fonts/JetBrainsMono-Italic.woff2") format("woff2");
|
||||
font-style: italic;
|
||||
font-weight: 400;
|
||||
font-display: swap;
|
||||
}
|
||||
|
||||
:root {
|
||||
--md-text-font: "Inter";
|
||||
--md-code-font: "JetBrains Mono";
|
||||
}
|
||||
|
||||
/* light */
|
||||
[data-md-color-scheme="default"] {
|
||||
--nj-blue: #1747a6;
|
||||
--nj-blue-deep: #10357d;
|
||||
--nj-blue-soft: #eaf1fd;
|
||||
--nj-band: #1747a6;
|
||||
--nj-red: #d93a3f;
|
||||
--nj-red-soft: #fdeced;
|
||||
--nj-string: #b4322a;
|
||||
--nj-comment: #646d7a;
|
||||
|
||||
--md-primary-fg-color: var(--nj-band);
|
||||
--md-primary-fg-color--light: #1d55c4;
|
||||
--md-primary-fg-color--dark: #10357d;
|
||||
--md-accent-fg-color: var(--nj-blue-deep);
|
||||
--md-accent-fg-color--transparent: rgba(23, 71, 166, .1);
|
||||
--md-typeset-a-color: var(--nj-blue);
|
||||
--md-default-fg-color: #0f1419;
|
||||
--md-default-fg-color--light: #4a515c;
|
||||
--md-default-fg-color--lighter: #8a919c;
|
||||
--md-default-fg-color--lightest: #e3e6eb;
|
||||
--md-typeset-color: #0f1419;
|
||||
--md-code-bg-color: #f5f7fa;
|
||||
--md-code-fg-color: #0f1419;
|
||||
}
|
||||
|
||||
/* dark */
|
||||
[data-md-color-scheme="slate"] {
|
||||
--nj-blue: #7aa7f5;
|
||||
--nj-blue-deep: #a9c6f8;
|
||||
--nj-blue-soft: #16233b;
|
||||
--nj-band: #173e8c;
|
||||
--nj-red: #f06a6e;
|
||||
--nj-red-soft: #3a1c1e;
|
||||
--nj-string: #f08a7e;
|
||||
--nj-comment: #8b929e;
|
||||
|
||||
--md-hue: 220;
|
||||
--md-primary-fg-color: var(--nj-band);
|
||||
--md-primary-fg-color--light: #163f93;
|
||||
--md-primary-fg-color--dark: #0c2556;
|
||||
--md-accent-fg-color: var(--nj-blue-deep);
|
||||
--md-accent-fg-color--transparent: rgba(122, 167, 245, .12);
|
||||
--md-typeset-a-color: var(--nj-blue);
|
||||
--md-default-bg-color: #0f1218;
|
||||
--md-default-fg-color: #f2f4f7;
|
||||
--md-default-fg-color--light: #b3b9c4;
|
||||
--md-default-fg-color--lighter: #7b828e;
|
||||
--md-default-fg-color--lightest: #272c36;
|
||||
--md-typeset-color: #f2f4f7;
|
||||
--md-code-bg-color: #171b23;
|
||||
--md-code-fg-color: #f2f4f7;
|
||||
--md-footer-bg-color: #0b0e13;
|
||||
--md-footer-bg-color--dark: #08090d;
|
||||
}
|
||||
|
||||
/* syntax colours (all at least 4.5:1 on the code panel in both schemes) */
|
||||
[data-md-color-scheme="default"] {
|
||||
--nj-hl-keyword: #1747a6;
|
||||
--nj-hl-type: #0d6e72;
|
||||
--nj-hl-function: #6b3fb8;
|
||||
--nj-hl-string: #23793a;
|
||||
--nj-hl-escape: #0f5d2a;
|
||||
--nj-hl-key: #10357d;
|
||||
--nj-hl-number: #b04a07;
|
||||
--nj-hl-preproc: #a3247a;
|
||||
}
|
||||
[data-md-color-scheme="slate"] {
|
||||
--nj-hl-keyword: #7aa7f5;
|
||||
--nj-hl-type: #4fd1c5;
|
||||
--nj-hl-function: #c4a3ff;
|
||||
--nj-hl-string: #7ed491;
|
||||
--nj-hl-escape: #b2ecc0;
|
||||
--nj-hl-key: #a9c6f8;
|
||||
--nj-hl-number: #f5a65b;
|
||||
--nj-hl-preproc: #f48fc8;
|
||||
}
|
||||
.md-typeset .highlight :is(.k, .kd, .kn, .kr, .kp, .kv, .ow) { color: var(--nj-hl-keyword); font-weight: 600; }
|
||||
.md-typeset .highlight :is(.kt, .nc, .nn, .na) { color: var(--nj-hl-type); }
|
||||
.md-typeset .highlight :is(.nf, .fm, .nb, .bp) { color: var(--nj-hl-function); }
|
||||
.md-typeset .highlight :is(.s, .s1, .s2, .sb, .sc, .sd, .sh, .sx, .sr, .ss, .sa, .dl, .cpf) { color: var(--nj-hl-string); }
|
||||
.md-typeset .highlight :is(.se, .si) { color: var(--nj-hl-escape); font-weight: 600; }
|
||||
.md-typeset .highlight .nt { color: var(--nj-hl-key); }
|
||||
.md-typeset .highlight :is(.m, .mi, .mf, .mh, .mo, .mb, .il, .kc) { color: var(--nj-hl-number); }
|
||||
.md-typeset .highlight .kc { font-weight: 500; }
|
||||
.md-typeset .highlight .cp { color: var(--nj-hl-preproc); }
|
||||
.md-typeset .highlight :is(.c, .c1, .cm, .ch, .cs) { color: var(--nj-comment); font-style: italic; }
|
||||
.md-typeset .highlight :is(.o, .p) { color: var(--md-default-fg-color--light); }
|
||||
.md-typeset .highlight :is(.n, .nx, .nv, .no, .ni, .nl, .py) { color: var(--md-code-fg-color); }
|
||||
.md-typeset .highlight .err { color: inherit; background: none; }
|
||||
|
||||
/* typography: Inter with cv11/ss03, bold headlines with negative tracking */
|
||||
body {
|
||||
font-feature-settings: "cv11", "ss03";
|
||||
}
|
||||
.md-typeset {
|
||||
font-size: .85rem; /* 17 px body */
|
||||
line-height: 1.65;
|
||||
}
|
||||
.md-typeset h1 {
|
||||
color: var(--md-typeset-color);
|
||||
font-weight: 800;
|
||||
letter-spacing: -.035em;
|
||||
line-height: 1.1;
|
||||
}
|
||||
.md-typeset h2 {
|
||||
font-weight: 800;
|
||||
letter-spacing: -.025em;
|
||||
line-height: 1.15;
|
||||
}
|
||||
.md-typeset h3 {
|
||||
font-weight: 700;
|
||||
letter-spacing: -.015em;
|
||||
}
|
||||
.md-typeset table:not([class]) {
|
||||
font-variant-numeric: tabular-nums;
|
||||
}
|
||||
|
||||
/* header and tabs: one blue band with the faint syntax pattern; wordmark instead of the site name.
|
||||
A veil over the tile keeps the glyphs from running through the navigation text; the hero shows the pattern at full strength. */
|
||||
.md-header, .md-tabs {
|
||||
--nj-veil: linear-gradient(color-mix(in srgb, var(--md-primary-fg-color) 62%, transparent), color-mix(in srgb, var(--md-primary-fg-color) 62%, transparent));
|
||||
background-color: var(--md-primary-fg-color);
|
||||
background-image: var(--nj-veil), url("pattern-on-blue.svg");
|
||||
background-size: auto, 160px 160px;
|
||||
background-position: 0 0, 0 0;
|
||||
}
|
||||
.md-tabs {
|
||||
background-position: 0 0, 0 -48px; /* continue the header's tile */
|
||||
}
|
||||
.md-header__button.md-logo img {
|
||||
width: auto;
|
||||
height: 1.5rem;
|
||||
}
|
||||
.md-header__topic:first-child .md-ellipsis { /* the wordmark replaces the site name at every width */
|
||||
display: none;
|
||||
}
|
||||
@media screen and (max-width: 76.234375em) { /* Material hides the header logo here: show the wordmark on phones, too */
|
||||
.md-header__button.md-logo {
|
||||
display: block;
|
||||
margin: 0 0 0 .2rem;
|
||||
padding: .4rem .2rem;
|
||||
}
|
||||
.md-header__button[for="__drawer"] {
|
||||
order: -1;
|
||||
}
|
||||
}
|
||||
.md-nav__button.md-logo img {
|
||||
width: auto;
|
||||
height: 1.4rem;
|
||||
}
|
||||
|
||||
/* shapes: 6 px corners on blocks, 4 px on inline code */
|
||||
.md-typeset pre > code, .md-typeset .highlight, .md-typeset .highlighttable,
|
||||
.md-typeset .admonition, .md-typeset details, .md-typeset .tabbed-set,
|
||||
.md-typeset .grid.cards > ul > li, .md-typeset .md-button {
|
||||
border-radius: 6px;
|
||||
}
|
||||
.md-typeset code {
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
/* inline code: the font alone marks it, no grey box; linked code keeps the link colour */
|
||||
.md-typeset :not(pre) > code {
|
||||
padding: 0;
|
||||
background-color: transparent;
|
||||
box-shadow: none;
|
||||
color: inherit;
|
||||
font-size: .88em;
|
||||
}
|
||||
.md-typeset .highlight pre > code, .md-typeset .highlighttable {
|
||||
border: 1px solid var(--md-default-fg-color--lightest);
|
||||
}
|
||||
|
||||
/* callouts: 3 px left border; note/info/tip in blue on blue-soft, danger/bug in red on red-soft */
|
||||
.md-typeset .admonition, .md-typeset details {
|
||||
border-width: 0 0 0 3px;
|
||||
box-shadow: none;
|
||||
font-size: .8rem;
|
||||
}
|
||||
.md-typeset :is(.admonition, details):is(.note, .info, .tip, .abstract, .example, .question) {
|
||||
border-color: var(--nj-blue);
|
||||
background-color: var(--nj-blue-soft);
|
||||
}
|
||||
.md-typeset :is(.note, .info, .tip, .abstract, .example, .question) > :is(.admonition-title, summary) {
|
||||
background-color: transparent;
|
||||
}
|
||||
.md-typeset :is(.note, .info, .tip, .abstract, .example, .question) > :is(.admonition-title, summary)::before {
|
||||
background-color: var(--nj-blue);
|
||||
}
|
||||
.md-typeset :is(.admonition, details):is(.danger, .bug, .failure) {
|
||||
border-color: var(--nj-red);
|
||||
background-color: var(--nj-red-soft);
|
||||
}
|
||||
.md-typeset :is(.danger, .bug, .failure) > :is(.admonition-title, summary) {
|
||||
background-color: transparent;
|
||||
}
|
||||
.md-typeset :is(.danger, .bug, .failure) > :is(.admonition-title, summary)::before {
|
||||
background-color: var(--nj-red);
|
||||
}
|
||||
|
||||
/* buttons */
|
||||
.md-typeset .md-button--primary {
|
||||
background-color: var(--nj-blue);
|
||||
border-color: var(--nj-blue);
|
||||
}
|
||||
|
||||
/* home page hero (overrides/home.html): blue band with the syntax pattern, headline, lead, buttons, code panel */
|
||||
.nj-hero {
|
||||
--nj-hero-to: #123a8a;
|
||||
color: #fff;
|
||||
background-color: var(--md-primary-fg-color);
|
||||
background-image: url("pattern-on-blue.svg"), linear-gradient(160deg, var(--md-primary-fg-color), var(--nj-hero-to));
|
||||
background-size: 160px 160px, auto;
|
||||
background-position: 0 -96px, 0 0; /* continue the tile of header and tabs */
|
||||
}
|
||||
[data-md-color-scheme="slate"] .nj-hero {
|
||||
--nj-hero-to: #0c2556;
|
||||
}
|
||||
.nj-hero__inner {
|
||||
display: grid;
|
||||
grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr);
|
||||
gap: 2.4rem;
|
||||
align-items: center;
|
||||
padding: 3rem .8rem 3.6rem;
|
||||
}
|
||||
.nj-hero__kicker {
|
||||
display: inline-block;
|
||||
margin: 0;
|
||||
padding: .15rem .55rem;
|
||||
border: 1px solid rgba(255, 255, 255, .35);
|
||||
border-radius: 4px;
|
||||
color: #bcd3fb;
|
||||
font-family: var(--md-code-font-family);
|
||||
font-size: .65rem; /* 13 px */
|
||||
font-weight: 500;
|
||||
letter-spacing: .02em;
|
||||
}
|
||||
.nj-hero__title {
|
||||
margin: 0 0 .8rem;
|
||||
color: #fff;
|
||||
font-size: clamp(1.7rem, 4.2vw, 3.2rem); /* 34-64 px */
|
||||
font-weight: 800;
|
||||
line-height: 1.02;
|
||||
letter-spacing: -.035em;
|
||||
}
|
||||
.nj-hero__title span {
|
||||
color: #bcd3fb;
|
||||
}
|
||||
.nj-hero__lead {
|
||||
max-width: 22em;
|
||||
margin: 0 0 2rem;
|
||||
color: rgba(255, 255, 255, .9);
|
||||
font-size: clamp(1.1rem, 2.2vw, 1.6rem); /* 22-32 px */
|
||||
font-style: italic;
|
||||
font-weight: 500;
|
||||
line-height: 1.35;
|
||||
letter-spacing: -.015em;
|
||||
}
|
||||
.nj-hero__actions {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: .6rem;
|
||||
margin: 0;
|
||||
}
|
||||
.nj-hero .md-button.nj-hero__button {
|
||||
margin: 0;
|
||||
padding: .55em 1.3em;
|
||||
border: 1px solid rgba(255, 255, 255, .6);
|
||||
border-radius: 6px;
|
||||
color: #fff;
|
||||
font-size: .75rem;
|
||||
font-weight: 600;
|
||||
}
|
||||
.nj-hero .md-button--primary.nj-hero__button {
|
||||
border-color: #fff;
|
||||
background-color: #fff;
|
||||
color: var(--md-primary-fg-color);
|
||||
}
|
||||
.nj-hero .md-button.nj-hero__button:is(:hover, :focus) {
|
||||
border-color: #fff;
|
||||
background-color: rgba(255, 255, 255, .12);
|
||||
color: #fff;
|
||||
}
|
||||
.nj-hero .md-button--primary.nj-hero__button:is(:hover, :focus) {
|
||||
background-color: #eaf1fd;
|
||||
color: var(--md-primary-fg-color);
|
||||
}
|
||||
.nj-hero__code {
|
||||
border-radius: 6px;
|
||||
background-color: var(--md-code-bg-color);
|
||||
box-shadow: 0 12px 32px rgba(5, 18, 48, .35);
|
||||
}
|
||||
.nj-hero__code pre {
|
||||
margin: 0;
|
||||
padding: 1.1rem 1.3rem;
|
||||
overflow-x: auto;
|
||||
color: var(--md-code-fg-color);
|
||||
font-family: var(--md-code-font-family);
|
||||
font-size: .7rem; /* 14 px */
|
||||
line-height: 1.7;
|
||||
}
|
||||
.nj-hero__code .nj-k { color: var(--nj-hl-type); }
|
||||
.nj-hero__code .nj-s { color: var(--nj-hl-string); }
|
||||
.nj-hero__code .nj-n { color: var(--nj-hl-number); }
|
||||
.nj-hero__code .nj-c { color: var(--nj-comment); font-style: italic; }
|
||||
@media screen and (max-width: 59.984375em) {
|
||||
.nj-hero__inner {
|
||||
grid-template-columns: minmax(0, 1fr);
|
||||
gap: 1.8rem;
|
||||
padding: 2rem .8rem 2.4rem;
|
||||
}
|
||||
}
|
||||
@media screen and (max-width: 29.984375em) {
|
||||
.nj-hero__code pre {
|
||||
font-size: .6rem;
|
||||
}
|
||||
}
|
||||
|
||||
/* the hero carries the headline: keep the page's h1 for the title and screen readers only */
|
||||
body:has(.nj-hero) .md-content__inner > h1 {
|
||||
position: absolute;
|
||||
width: 1px;
|
||||
height: 1px;
|
||||
overflow: hidden;
|
||||
clip: rect(0 0 0 0);
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
/* cards: 1 px line border, 6 px corners, blue icon on soft blue, blue border on hover */
|
||||
.md-typeset .grid.cards > ul > li {
|
||||
padding: 1rem 1.1rem;
|
||||
border: 1px solid var(--md-default-fg-color--lightest);
|
||||
background-color: var(--md-default-bg-color);
|
||||
transition: border-color 150ms, box-shadow 150ms, transform 150ms;
|
||||
}
|
||||
.md-typeset .grid.cards > ul > li:is(:hover, :focus-within) {
|
||||
border-color: var(--nj-blue);
|
||||
box-shadow: 0 6px 18px rgba(23, 71, 166, .12);
|
||||
transform: translateY(-1px);
|
||||
}
|
||||
.md-typeset .grid.cards > ul > li > hr {
|
||||
display: none;
|
||||
}
|
||||
.md-typeset .grid.cards .twemoji.lg {
|
||||
box-sizing: content-box;
|
||||
margin-right: .5rem;
|
||||
padding: .3rem;
|
||||
border-radius: 6px;
|
||||
background-color: var(--nj-blue-soft);
|
||||
color: var(--nj-blue);
|
||||
}
|
||||
.md-typeset .grid.cards > ul > li > p:first-child strong {
|
||||
font-size: .9rem;
|
||||
font-weight: 700;
|
||||
letter-spacing: -.01em;
|
||||
}
|
||||
.md-typeset .grid.cards > ul > li > p:last-child a {
|
||||
font-weight: 600;
|
||||
}
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
.md-typeset .grid.cards > ul > li { transition: none; transform: none !important; }
|
||||
}
|
||||
|
||||
/* home page: no table of contents, so keep the text at reading width and the cards in three columns */
|
||||
body:has(.nj-hero) .md-content {
|
||||
max-width: 58rem;
|
||||
margin: 0 auto;
|
||||
}
|
||||
@media screen and (min-width: 60em) {
|
||||
body:has(.nj-hero) .md-typeset .grid.cards {
|
||||
grid-template-columns: repeat(3, minmax(0, 1fr));
|
||||
}
|
||||
}
|
||||
|
||||
/* lists: Material's indent, bullets as small blue squares, numbers in the secondary text colour */
|
||||
.md-typeset ul:not(.task-list, .md-annotation-list) > li {
|
||||
position: relative;
|
||||
list-style: none;
|
||||
}
|
||||
.md-typeset ul:not(.task-list, .md-annotation-list) > li::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: .65em; /* middle of the first line at line-height 1.65 */
|
||||
left: -.95em;
|
||||
width: .36em;
|
||||
height: .36em;
|
||||
background-color: var(--nj-blue);
|
||||
}
|
||||
.md-typeset ol > li::marker {
|
||||
color: var(--md-default-fg-color--light);
|
||||
font-variant-numeric: tabular-nums;
|
||||
}
|
||||
.md-typeset .grid.cards > ul > li::before {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* wider page: Material's grid stops at 61rem (1220 px) */
|
||||
.md-grid {
|
||||
max-width: 72rem; /* 1440 px */
|
||||
}
|
||||
|
||||
/* tables: full width, 1 px line border with 6 px corners, header row on the panel colour, 15 px text */
|
||||
.md-typeset__table {
|
||||
display: block; /* Material: inline-block, so tables only grow to their content */
|
||||
}
|
||||
.md-typeset table:not([class]) {
|
||||
display: table;
|
||||
width: 100%;
|
||||
border: 1px solid var(--md-default-fg-color--lightest);
|
||||
border-radius: 6px;
|
||||
font-size: .75rem;
|
||||
line-height: 1.55;
|
||||
}
|
||||
.md-typeset table:not([class]) th {
|
||||
padding: .65em 1em;
|
||||
border-bottom: 1px solid var(--md-default-fg-color--lightest);
|
||||
background-color: var(--md-code-bg-color);
|
||||
color: var(--md-typeset-color);
|
||||
font-weight: 600;
|
||||
vertical-align: bottom;
|
||||
}
|
||||
.md-typeset table:not([class]) th:first-child { border-top-left-radius: 5px; }
|
||||
.md-typeset table:not([class]) th:last-child { border-top-right-radius: 5px; }
|
||||
.md-typeset table:not([class]) td {
|
||||
padding: .65em 1em;
|
||||
border-top: 1px solid var(--md-default-fg-color--lightest);
|
||||
}
|
||||
.md-typeset table:not([class]) tbody tr:first-child td {
|
||||
border-top: 0;
|
||||
}
|
||||
.md-typeset table:not([class]) tbody tr:hover {
|
||||
background-color: var(--nj-blue-soft);
|
||||
box-shadow: none;
|
||||
}
|
||||
.md-typeset table:not([class]) td code {
|
||||
white-space: nowrap;
|
||||
}
|
||||
/* numbers and header code stay on one line; a table wider than the screen scrolls sideways instead */
|
||||
.md-typeset table:not([class]) :is(td, th):is([align="right"], [style*="right"]),
|
||||
.md-typeset table:not([class]) th code {
|
||||
white-space: nowrap;
|
||||
}
|
||||
@media screen and (max-width: 44.984375em) {
|
||||
.md-typeset table:not([class]) {
|
||||
font-size: .7rem;
|
||||
}
|
||||
.md-typeset table:not([class]) :is(th, td) {
|
||||
padding: .55em .75em;
|
||||
}
|
||||
}
|
||||
|
||||
/* more room before headings (Material: h2 1.6em, h3 1.6em, h4-h6 1-1.25em) and at the end of each page (1.2rem) */
|
||||
.md-typeset h2 { margin-top: 2.4em; }
|
||||
.md-typeset h3 { margin-top: 2.2em; }
|
||||
.md-typeset h2 + h3 { margin-top: .8em; }
|
||||
.md-typeset :is(h4, h5, h6) { margin-top: 1.8em; }
|
||||
.md-content__inner {
|
||||
margin-bottom: 4.8rem; /* 96 px */
|
||||
}
|
||||
|
||||
/* Mermaid diagrams: white boxes with a blue outline, grey lines, Inter; shapes and spacing in js/mermaid-brand.js */
|
||||
:root > * {
|
||||
--md-mermaid-font-family: var(--md-text-font-family), sans-serif;
|
||||
--md-mermaid-edge-color: var(--md-default-fg-color--lighter);
|
||||
--md-mermaid-node-bg-color: var(--md-default-bg-color);
|
||||
--md-mermaid-node-fg-color: var(--nj-blue);
|
||||
--md-mermaid-label-bg-color: var(--md-default-bg-color);
|
||||
--md-mermaid-label-fg-color: var(--md-default-fg-color);
|
||||
--md-mermaid-sequence-actor-bg-color: var(--nj-blue-soft);
|
||||
--md-mermaid-sequence-actor-line-color: var(--md-default-fg-color--lighter);
|
||||
--md-mermaid-sequence-note-bg-color: var(--md-code-bg-color);
|
||||
--md-mermaid-sequence-note-border-color: var(--md-default-fg-color--lightest);
|
||||
--md-mermaid-sequence-number-fg-color: #fff;
|
||||
}
|
||||
|
||||
/* a diagram wider than the column scrolls sideways (js/mermaid-brand.js stops shrinking it at 80 %) */
|
||||
.md-typeset .mermaid {
|
||||
overflow-x: auto;
|
||||
}
|
||||
|
||||
|
||||
/* ---- polish pass ---- */
|
||||
|
||||
/* header: a search field that reads as a field on the band, tabs with an active marker, readable GitHub facts */
|
||||
.md-header .md-search__form {
|
||||
border: 1px solid rgba(255, 255, 255, .22);
|
||||
border-radius: 6px;
|
||||
background-color: rgba(255, 255, 255, .12);
|
||||
transition: background-color 150ms, border-color 150ms;
|
||||
}
|
||||
.md-header .md-search__form:hover {
|
||||
border-color: rgba(255, 255, 255, .4);
|
||||
background-color: rgba(255, 255, 255, .2);
|
||||
}
|
||||
.md-search__output {
|
||||
border-radius: 0 0 6px 6px;
|
||||
box-shadow: 0 16px 40px rgba(5, 18, 48, .28);
|
||||
}
|
||||
.md-search-result__link:focus-visible, .md-search-result__more summary:focus-visible {
|
||||
outline: 2px solid var(--nj-blue);
|
||||
outline-offset: -2px;
|
||||
}
|
||||
.md-tabs__link {
|
||||
font-size: .72rem;
|
||||
font-weight: 500;
|
||||
opacity: .85;
|
||||
}
|
||||
.md-tabs__item--active .md-tabs__link, .md-tabs__link:hover {
|
||||
opacity: 1;
|
||||
}
|
||||
.md-tabs__item--active {
|
||||
box-shadow: inset 0 -2px 0 #fff;
|
||||
}
|
||||
.md-source__facts {
|
||||
font-size: .62rem;
|
||||
}
|
||||
|
||||
/* footer: deep brand blue instead of neutral black (the dark scheme keeps its own near-black) */
|
||||
[data-md-color-scheme="default"] {
|
||||
--md-footer-bg-color: #0d2a66;
|
||||
--md-footer-bg-color--dark: #0a2152;
|
||||
}
|
||||
.md-footer-meta .md-copyright, .md-footer-meta .md-copyright a {
|
||||
color: rgba(255, 255, 255, .72);
|
||||
}
|
||||
.md-footer__link {
|
||||
border-radius: 6px;
|
||||
transition: background-color 150ms;
|
||||
}
|
||||
.md-footer__link:is(:hover, :focus-visible) {
|
||||
background-color: rgba(255, 255, 255, .08);
|
||||
}
|
||||
|
||||
/* page title: tighter to the first paragraph; page actions (view/edit source) stay in the background */
|
||||
.md-typeset h1 {
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
.md-content__button {
|
||||
opacity: .55;
|
||||
transition: opacity 150ms;
|
||||
}
|
||||
.md-content__button:is(:hover, :focus-visible) {
|
||||
opacity: 1;
|
||||
}
|
||||
body:has(.nj-hero) .md-content__button {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* sidebars: bold marker for the current page, rail and marker for the table of contents */
|
||||
.md-nav__link--active {
|
||||
font-weight: 600;
|
||||
}
|
||||
.md-nav--secondary > .md-nav__list {
|
||||
margin-left: -.1rem;
|
||||
border-left: 1px solid color-mix(in srgb, var(--md-default-fg-color) 16%, transparent);
|
||||
}
|
||||
.md-nav--secondary .md-nav__link {
|
||||
margin-left: -1px;
|
||||
padding-left: .6rem;
|
||||
border-left: 2px solid transparent;
|
||||
}
|
||||
.md-nav--secondary .md-nav__link--active {
|
||||
border-left-color: var(--nj-blue);
|
||||
color: var(--nj-blue);
|
||||
}
|
||||
.md-nav--secondary .md-nav__list .md-nav__list {
|
||||
padding-left: .6rem;
|
||||
}
|
||||
.md-nav--secondary .md-nav__title {
|
||||
font-size: .64rem;
|
||||
letter-spacing: .04em;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
/* keyboard focus: one visible ring in the brand blue */
|
||||
.md-typeset a:focus-visible, .md-typeset .md-button:focus-visible, .md-typeset summary:focus-visible,
|
||||
.md-nav__link:focus-visible, .md-tabs__link:focus-visible, .md-top:focus-visible {
|
||||
outline: 2px solid var(--nj-blue);
|
||||
outline-offset: 2px;
|
||||
border-radius: 3px;
|
||||
}
|
||||
.md-header :is(a, button, label):focus-visible, .nj-hero a:focus-visible {
|
||||
outline: 2px solid #fff;
|
||||
outline-offset: 2px;
|
||||
}
|
||||
|
||||
/* inline code must not stretch the line box (JetBrains Mono has tall metrics), abbreviations stay quiet */
|
||||
.md-typeset :not(pre) > code {
|
||||
line-height: 1;
|
||||
}
|
||||
.md-typeset abbr {
|
||||
border-bottom-color: var(--md-default-fg-color--lighter);
|
||||
}
|
||||
.md-typeset :is(h1, h2, h3, h4, a, .grid.cards > ul > li > p:first-child) abbr {
|
||||
border-bottom-color: transparent;
|
||||
}
|
||||
|
||||
/* number railroad diagram: inline SVG (docs/images/json_syntax_number.svg), follows the colour scheme */
|
||||
.md-typeset .railroad-wrap, .md-typeset .nj-fig-wrap {
|
||||
overflow-x: auto;
|
||||
margin: 1.5rem 0;
|
||||
}
|
||||
.md-typeset svg.railroad {
|
||||
display: block;
|
||||
width: 100%;
|
||||
min-width: 36rem;
|
||||
max-width: 52rem;
|
||||
margin-inline: auto;
|
||||
color: var(--md-default-fg-color);
|
||||
font-family: var(--md-text-font-family), sans-serif;
|
||||
}
|
||||
.railroad .rr-t { fill: color-mix(in srgb, var(--md-typeset-a-color) 10%, transparent); stroke: var(--md-typeset-a-color); stroke-width: 2; }
|
||||
.railroad .rr-track, .railroad .rr-n { stroke: color-mix(in srgb, currentColor 60%, var(--md-default-bg-color)); stroke-opacity: 1; } /* opaque, so overlapping segments do not darken */
|
||||
.railroad .rr-n { fill: color-mix(in srgb, currentColor 6%, transparent); stroke-width: 2; }
|
||||
.railroad .rr-bg { fill: var(--md-default-bg-color); }
|
||||
.railroad .rr-arrow { fill: currentColor; fill-opacity: .6; }
|
||||
.railroad text { fill: currentColor; text-anchor: middle; }
|
||||
.railroad .rr-c { font-family: var(--md-code-font-family), monospace; font-size: 16px; font-weight: 500; }
|
||||
.railroad .rr-b { font-size: 14.5px; font-weight: 500; }
|
||||
.railroad .rr-l { font-size: 14px; text-anchor: start; fill-opacity: .6; }
|
||||
.railroad .rr-name { font-size: 17px; font-weight: 700; fill-opacity: 1; }
|
||||
/* figures drawn as inline SVG (docs/images/callback_events.svg, range-*.svg): they follow the colour scheme */
|
||||
.md-typeset svg.nj-fig {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: auto;
|
||||
margin-inline: auto;
|
||||
color: var(--md-default-fg-color);
|
||||
font-family: var(--md-text-font-family), sans-serif;
|
||||
}
|
||||
.md-typeset svg.nj-fig--range { min-width: 30rem; max-width: 40rem; }
|
||||
.md-typeset svg.nj-fig--cb { max-width: 30rem; }
|
||||
.nj-fig { --fg-line: color-mix(in srgb, currentColor 55%, var(--md-default-bg-color)); }
|
||||
.nj-fig .fg-cell { fill: color-mix(in srgb, var(--md-typeset-a-color) 14%, var(--md-default-bg-color)); stroke: var(--fg-line); stroke-width: 1.5; }
|
||||
.nj-fig .fg-cell--end { fill: none; stroke-dasharray: 4 3; }
|
||||
.nj-fig .fg-pill { fill: color-mix(in srgb, var(--md-typeset-a-color) 10%, var(--md-default-bg-color)); stroke: var(--md-typeset-a-color); stroke-width: 1.5; }
|
||||
.nj-fig .fg-pilltext { fill: var(--md-typeset-a-color); font-family: var(--md-code-font-family), monospace; font-size: 14px; font-weight: 500; text-anchor: middle; }
|
||||
.nj-fig .fg-arrow { stroke: var(--fg-line); stroke-width: 1.5; fill: none; }
|
||||
.nj-fig .fg-arrow--dash { stroke-dasharray: 3 3; }
|
||||
.nj-fig .fg-head { fill: var(--fg-line); }
|
||||
.nj-fig .fg-note { fill: currentColor; fill-opacity: .7; font-size: 13.5px; text-anchor: middle; }
|
||||
.nj-fig .fg-note--r { text-anchor: end; }
|
||||
.nj-fig .fg-note--l { text-anchor: start; }
|
||||
.nj-fig .fg-h { fill: currentColor; fill-opacity: .7; font-size: 15px; font-weight: 600; }
|
||||
.nj-fig .fg-code { fill: currentColor; font-family: var(--md-code-font-family), monospace; font-size: 16px; white-space: pre; }
|
||||
.nj-fig .fg-leg { font-size: 15px; }
|
||||
.nj-fig { --cb-os: #4eb05a; --cb-oe: #1a6b34; --cb-k: #e5534b; --cb-as: #f0c000; --cb-ae: #b07d00; --cb-v: #1f6fd1; }
|
||||
[data-md-color-scheme="slate"] .nj-fig { --cb-os: #7ee787; --cb-oe: #2ea043; --cb-k: #ff7b72; --cb-as: #f2cc60; --cb-ae: #c69026; --cb-v: #58a6ff; }
|
||||
.nj-fig .cb-os { fill: var(--cb-os); }
|
||||
.nj-fig .cb-oe { fill: var(--cb-oe); }
|
||||
.nj-fig .cb-k { fill: var(--cb-k); }
|
||||
.nj-fig .cb-as { fill: var(--cb-as); }
|
||||
.nj-fig .cb-ae { fill: var(--cb-ae); }
|
||||
.nj-fig .cb-v { fill: var(--cb-v); }
|
||||
.md-typeset img[src*="json-light"], .md-typeset img[src*="json-dark"] {
|
||||
border-radius: 8px;
|
||||
}
|
||||
.md-typeset img {
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
/* home page: content uses the same column as every other page */
|
||||
body:has(.nj-hero) .md-content {
|
||||
max-width: none;
|
||||
margin: 0;
|
||||
}
|
||||
.md-typeset .grid.cards {
|
||||
width: auto;
|
||||
}
|
||||
|
||||
/* 404 page (overrides/404.html) */
|
||||
.nj-404 {
|
||||
max-width: 30rem;
|
||||
padding: 2rem 0 3rem;
|
||||
}
|
||||
.nj-404__code {
|
||||
margin: 0 0 .4rem;
|
||||
color: var(--nj-blue);
|
||||
font-family: var(--md-code-font-family);
|
||||
font-size: .8rem;
|
||||
font-weight: 500;
|
||||
}
|
||||
.md-typeset .nj-404 h1 {
|
||||
margin-bottom: .8rem;
|
||||
}
|
||||
.nj-404 .md-button {
|
||||
margin: .4rem .4rem 0 0;
|
||||
}
|
||||
|
||||
/* touch targets and phones */
|
||||
@media screen and (max-width: 59.984375em) {
|
||||
.md-nav__link {
|
||||
padding-block: .2rem;
|
||||
}
|
||||
}
|
||||
@media screen and (max-width: 29.984375em) {
|
||||
.md-typeset h1 {
|
||||
font-size: 1.7em;
|
||||
}
|
||||
.md-typeset .highlight pre > code {
|
||||
font-size: .68rem;
|
||||
}
|
||||
}
|
||||
|
||||
/* figure captions: "Figure N." in bold, close to the figure, set in from the text column; figures and tables are
|
||||
numbered per page, each with its own counter */
|
||||
.md-content__inner { counter-reset: nj-figure nj-table; }
|
||||
.md-typeset :is(.nj-caption, .nj-charts-caption) {
|
||||
max-width: none;
|
||||
margin: .3rem 2rem 1.5rem;
|
||||
font-size: .75rem;
|
||||
line-height: 1.5;
|
||||
text-align: left;
|
||||
color: var(--md-default-fg-color--light);
|
||||
}
|
||||
.md-typeset :is(.nj-fig-wrap, .railroad-wrap, .nj-charts-grid-wrap) + :is(.nj-caption, .nj-charts-caption) { margin-top: -1.1rem; }
|
||||
.md-typeset .nj-charts-grid-wrap + :is(.nj-caption, .nj-charts-caption) { margin-top: .3rem; }
|
||||
.md-typeset :is(.nj-caption, .nj-charts-caption)::before {
|
||||
counter-increment: nj-figure;
|
||||
content: "Figure " counter(nj-figure) ". ";
|
||||
font-weight: 700;
|
||||
color: var(--md-default-fg-color);
|
||||
}
|
||||
@media screen and (max-width: 44.9375em) {
|
||||
.md-typeset :is(.nj-caption, .nj-charts-caption) { margin-inline: 1rem; }
|
||||
}
|
||||
|
||||
/* table captions: "Table N." in bold, directly below the table, in the figure caption style */
|
||||
.md-typeset .nj-table-caption {
|
||||
max-width: none;
|
||||
margin: .3rem 2rem 1.5rem;
|
||||
font-size: .75rem;
|
||||
line-height: 1.5;
|
||||
text-align: left;
|
||||
color: var(--md-default-fg-color--light);
|
||||
}
|
||||
.md-typeset :is(.md-typeset__scrollwrap, .md-typeset__table) + .nj-table-caption { margin-top: -.4rem; }
|
||||
.md-typeset .nj-table-caption::before {
|
||||
counter-increment: nj-table;
|
||||
content: "Table " counter(nj-table) ". ";
|
||||
font-weight: 700;
|
||||
color: var(--md-default-fg-color);
|
||||
}
|
||||
@media screen and (max-width: 44.9375em) {
|
||||
.md-typeset .nj-table-caption { margin-inline: 1rem; }
|
||||
}
|
||||
@@ -1,142 +0,0 @@
|
||||
/* figures: charts (docs/images/compile_times.svg, binary_sizes_*.svg, ordered_json_scaling.svg from
|
||||
scripts/figures/charts.py) and the number literal explorer on features/types/number_handling.md */
|
||||
|
||||
/* series colours: categorical slots validated for CVD separation on the light and the slate surface */
|
||||
.nj-charts, .nj-charts-key {
|
||||
--nj-charts-c1: #2a78d6;
|
||||
--nj-charts-c2: #eb6834;
|
||||
--nj-charts-c3: #1baf7a;
|
||||
--nj-charts-c4: #eda100;
|
||||
--nj-charts-c5: #e87ba4;
|
||||
--nj-charts-c6: #008300;
|
||||
--nj-charts-ink2: var(--md-default-fg-color--light);
|
||||
--nj-charts-grid: color-mix(in srgb, currentColor 12%, var(--md-default-bg-color));
|
||||
--nj-charts-base: color-mix(in srgb, currentColor 35%, var(--md-default-bg-color));
|
||||
}
|
||||
[data-md-color-scheme="slate"] :is(.nj-charts, .nj-charts-key) {
|
||||
--nj-charts-c1: #3987e5;
|
||||
--nj-charts-c2: #d95926;
|
||||
--nj-charts-c3: #199e70;
|
||||
--nj-charts-c4: #c98500;
|
||||
--nj-charts-c5: #d55181;
|
||||
--nj-charts-c6: #008300;
|
||||
}
|
||||
/* concepts: two compilers, two object types */
|
||||
.nj-charts { --nj-charts-clang-c: var(--nj-charts-c1); --nj-charts-gcc-c: var(--nj-charts-c2);
|
||||
--nj-charts-json-c: var(--nj-charts-c1); --nj-charts-ojson-c: var(--nj-charts-c2); }
|
||||
|
||||
.md-typeset svg.nj-charts--compile, .md-typeset svg.nj-charts--scaling { max-width: 26rem; }
|
||||
.md-typeset svg.nj-charts--sizes { max-width: 26rem; }
|
||||
|
||||
.nj-charts text { fill: currentColor; font-size: 13px; }
|
||||
.nj-charts .nj-charts-leg { font-size: 13.5px; }
|
||||
.nj-charts .nj-charts-rowlabel { font-size: 13.5px; font-weight: 500; }
|
||||
.nj-charts .nj-charts-code { font-family: var(--md-code-font-family), monospace; font-size: 12.5px; }
|
||||
.nj-charts .nj-charts-sub { fill: var(--nj-charts-ink2); font-weight: 400; }
|
||||
.nj-charts .nj-charts-fmt { text-anchor: end; font-weight: 400; }
|
||||
.nj-charts .nj-charts-best { font-weight: 700; }
|
||||
.nj-charts .nj-charts-panel { font-family: var(--md-code-font-family), monospace; font-size: 14px; font-weight: 600; }
|
||||
.nj-charts .nj-charts-tick { fill: var(--nj-charts-ink2); font-size: 12px; text-anchor: middle; font-variant-numeric: tabular-nums; }
|
||||
.nj-charts .nj-charts-tick--l { text-anchor: start; }
|
||||
.nj-charts .nj-charts-tick--r { text-anchor: end; }
|
||||
.nj-charts .nj-charts-val { font-size: 12px; font-variant-numeric: tabular-nums;
|
||||
paint-order: stroke; stroke: var(--md-default-bg-color); stroke-width: 4px; stroke-linejoin: round; }
|
||||
.nj-charts .nj-charts-factor { fill: var(--nj-charts-ink2); font-size: 12px; font-weight: 600; text-anchor: middle; }
|
||||
.nj-charts .nj-charts-note { fill: var(--nj-charts-ink2); font-size: 12px; }
|
||||
|
||||
.nj-charts .nj-charts-grid { stroke: var(--nj-charts-grid); stroke-width: 1; }
|
||||
.nj-charts .nj-charts-zero, .nj-charts .nj-charts-axis { stroke: var(--nj-charts-base); stroke-width: 1.5; }
|
||||
.nj-charts .nj-charts-ref { stroke: currentColor; stroke-width: 1.5; }
|
||||
|
||||
.nj-charts .nj-charts-c1 { fill: var(--nj-charts-c1); }
|
||||
.nj-charts .nj-charts-c2 { fill: var(--nj-charts-c2); }
|
||||
.nj-charts .nj-charts-c3 { fill: var(--nj-charts-c3); }
|
||||
.nj-charts .nj-charts-c4 { fill: var(--nj-charts-c4); }
|
||||
.nj-charts .nj-charts-c5 { fill: var(--nj-charts-c5); }
|
||||
.nj-charts .nj-charts-c6 { fill: var(--nj-charts-c6); }
|
||||
.nj-charts .nj-charts-dim { fill-opacity: .45; }
|
||||
.nj-charts .nj-charts-clang { fill: var(--nj-charts-clang-c); }
|
||||
.nj-charts .nj-charts-gcc { fill: var(--nj-charts-gcc-c); }
|
||||
.nj-charts polyline.nj-charts-json, .nj-charts line.nj-charts-json { stroke: var(--nj-charts-json-c); stroke-width: 2; fill: none; }
|
||||
.nj-charts polyline.nj-charts-ojson, .nj-charts line.nj-charts-ojson { stroke: var(--nj-charts-ojson-c); stroke-width: 2; fill: none; }
|
||||
.nj-charts .nj-charts-json-dot { fill: var(--nj-charts-json-c); stroke: var(--md-default-bg-color); stroke-width: 2; }
|
||||
.nj-charts .nj-charts-ojson-dot { fill: var(--nj-charts-ojson-c); stroke: var(--md-default-bg-color); stroke-width: 2; }
|
||||
|
||||
/* single wide charts: larger text on phones, where the SVG is scaled down */
|
||||
@media screen and (max-width: 44.9375em) {
|
||||
svg.nj-charts.nj-charts--compile text, svg.nj-charts.nj-charts--scaling text { font-size: 15px; }
|
||||
svg.nj-charts.nj-charts--compile .nj-charts-code { font-size: 14px; }
|
||||
svg.nj-charts:is(.nj-charts--compile, .nj-charts--scaling) :is(.nj-charts-tick, .nj-charts-val, .nj-charts-factor, .nj-charts-note) { font-size: 14px; }
|
||||
}
|
||||
|
||||
/* small multiples: two panels per row, one on narrow screens */
|
||||
.md-typeset .nj-charts-grid-wrap {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr));
|
||||
gap: 1rem 2rem;
|
||||
margin: 1.5rem 0 .5rem;
|
||||
}
|
||||
.md-typeset .nj-charts-grid-wrap > .nj-fig-wrap { margin: 0; }
|
||||
|
||||
/* number literal explorer */
|
||||
.md-typeset .nj-charts-num-ui {
|
||||
margin: 1rem 0 .75rem;
|
||||
padding: .8rem;
|
||||
border: 1px solid var(--md-default-fg-color--lightest);
|
||||
border-radius: 8px;
|
||||
}
|
||||
.md-typeset .nj-charts-num-ui label { display: block; font-weight: 600; font-size: .75rem; margin-bottom: .3rem; }
|
||||
.md-typeset .nj-charts-num-input {
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
min-height: 44px;
|
||||
padding: .4rem .6rem;
|
||||
font-family: var(--md-code-font-family), monospace;
|
||||
font-size: .8rem;
|
||||
color: var(--md-default-fg-color);
|
||||
background: var(--md-code-bg-color);
|
||||
border: 1px solid var(--md-default-fg-color--lighter);
|
||||
border-radius: 6px;
|
||||
}
|
||||
.md-typeset .nj-charts-num-input:focus-visible, .md-typeset .nj-charts-num-chip:focus-visible {
|
||||
outline: 2px solid var(--md-typeset-a-color);
|
||||
outline-offset: 2px;
|
||||
}
|
||||
.md-typeset .nj-charts-num-ui ul.nj-charts-num-chips:not([hidden]) { display: flex; flex-wrap: wrap; gap: .35rem; margin: .6rem 0; padding: 0; list-style: none; }
|
||||
.md-typeset .nj-charts-num-ui ul.nj-charts-num-chips > li { margin: 0; padding: 0; list-style: none; }
|
||||
.md-typeset .nj-charts-num-ui ul.nj-charts-num-chips > li::before, .md-typeset .nj-charts-num-ui ul.nj-charts-num-chips > li::marker { content: none; }
|
||||
.md-typeset .nj-charts-num-chip {
|
||||
min-height: 44px;
|
||||
max-width: 100%;
|
||||
padding: .25rem .6rem;
|
||||
overflow-wrap: anywhere;
|
||||
font-family: var(--md-code-font-family), monospace;
|
||||
font-size: .7rem;
|
||||
color: var(--md-typeset-a-color);
|
||||
background: color-mix(in srgb, var(--md-typeset-a-color) 8%, var(--md-default-bg-color));
|
||||
border: 1px solid color-mix(in srgb, var(--md-typeset-a-color) 35%, var(--md-default-bg-color));
|
||||
border-radius: 6px;
|
||||
cursor: pointer;
|
||||
text-align: left;
|
||||
}
|
||||
.md-typeset .nj-charts-num-chip[aria-pressed="true"] {
|
||||
color: var(--md-default-bg-color);
|
||||
background: var(--md-typeset-a-color);
|
||||
border-color: var(--md-typeset-a-color);
|
||||
}
|
||||
.md-typeset .nj-charts-num-out {
|
||||
display: grid;
|
||||
grid-template-columns: max-content 1fr;
|
||||
gap: .2rem .8rem;
|
||||
margin: 0;
|
||||
font-size: .75rem;
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
.md-typeset .nj-charts-num-out dt { color: var(--md-default-fg-color--light); margin: 0; }
|
||||
.md-typeset .nj-charts-num-out dd { margin: 0; }
|
||||
.md-typeset .nj-charts-num-miss { font-size: .75rem; color: var(--md-default-fg-color--light); margin: 0; }
|
||||
.md-typeset .nj-charts-num tr.nj-charts-num-hit td { background: var(--md-accent-fg-color--transparent); }
|
||||
|
||||
/* direct line labels replace the legend */
|
||||
.nj-charts .nj-charts-name-json { fill: var(--nj-charts-json-c); font-weight: 600; }
|
||||
.nj-charts .nj-charts-name-ojson { fill: var(--nj-charts-ojson-c); font-weight: 600; }
|
||||
@@ -1,75 +0,0 @@
|
||||
/* figures: exceptions (home/exceptions.md exception map, community/quality_assurance.md pipeline) */
|
||||
|
||||
/* the generated SVGs hold a wide and a narrow drawing; show one of them */
|
||||
.md-typeset svg.nj-exceptions-map--wide, .md-typeset svg.nj-exceptions-qa--wide { max-width: 47.5rem; }
|
||||
.md-typeset svg.nj-exceptions-map--narrow, .md-typeset svg.nj-exceptions-qa--narrow { display: none; max-width: 24rem; }
|
||||
@media screen and (max-width: 37.5em) {
|
||||
.md-typeset svg.nj-exceptions-map--wide, .md-typeset svg.nj-exceptions-qa--wide { display: none; }
|
||||
.md-typeset svg.nj-exceptions-map--narrow, .md-typeset svg.nj-exceptions-qa--narrow { display: block; }
|
||||
}
|
||||
|
||||
/* shared */
|
||||
.nj-fig { --nj-exceptions-line: color-mix(in srgb, currentColor 45%, var(--md-default-bg-color)); }
|
||||
.nj-fig .nj-exceptions-edge { stroke: var(--nj-exceptions-line); stroke-width: 1.5; fill: none; }
|
||||
.nj-fig .nj-exceptions-tri { fill: var(--md-default-bg-color); stroke: var(--nj-exceptions-line); stroke-width: 1.3; }
|
||||
.nj-fig .nj-exceptions-box {
|
||||
fill: color-mix(in srgb, currentColor 4%, var(--md-default-bg-color));
|
||||
stroke: color-mix(in srgb, currentColor 30%, var(--md-default-bg-color));
|
||||
stroke-width: 1.5;
|
||||
}
|
||||
.nj-fig .nj-exceptions-box--fam {
|
||||
fill: color-mix(in srgb, var(--md-typeset-a-color) 9%, var(--md-default-bg-color));
|
||||
stroke: color-mix(in srgb, var(--md-typeset-a-color) 55%, var(--md-default-bg-color));
|
||||
}
|
||||
.nj-fig .nj-exceptions-name { fill: currentColor; font-family: var(--md-code-font-family), monospace; font-size: 14px; font-weight: 600; }
|
||||
.nj-fig .nj-exceptions-sub { fill: currentColor; fill-opacity: .68; font-size: 12.5px; }
|
||||
|
||||
/* exception map: id chips are links */
|
||||
.nj-fig .nj-exceptions-chip rect {
|
||||
fill: color-mix(in srgb, var(--md-typeset-a-color) 7%, var(--md-default-bg-color));
|
||||
stroke: color-mix(in srgb, var(--md-typeset-a-color) 40%, var(--md-default-bg-color));
|
||||
stroke-width: 1.2;
|
||||
transition: fill .15s;
|
||||
}
|
||||
.nj-fig .nj-exceptions-chip--named rect {
|
||||
fill: color-mix(in srgb, var(--md-typeset-a-color) 16%, var(--md-default-bg-color));
|
||||
stroke: var(--md-typeset-a-color);
|
||||
}
|
||||
.nj-fig .nj-exceptions-id { fill: var(--md-typeset-a-color); font-family: var(--md-code-font-family), monospace; font-size: 13px; font-weight: 600; }
|
||||
.nj-fig .nj-exceptions-label { fill: currentColor; font-size: 12.5px; font-weight: 500; }
|
||||
.nj-fig a:hover rect, .nj-fig a:focus-visible rect {
|
||||
fill: color-mix(in srgb, var(--md-typeset-a-color) 28%, var(--md-default-bg-color));
|
||||
}
|
||||
.nj-fig a:focus { outline: none; }
|
||||
.nj-fig a:focus-visible rect { stroke: var(--md-typeset-a-color); stroke-width: 2.5; }
|
||||
.nj-fig a:hover .nj-exceptions-name, .nj-fig a:focus-visible .nj-exceptions-name { text-decoration: underline; }
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
.nj-fig .nj-exceptions-chip rect { transition: none; }
|
||||
}
|
||||
|
||||
/* quality assurance pipeline */
|
||||
.nj-fig { --nj-exceptions-push: var(--md-typeset-a-color); --nj-exceptions-sched: #a86400; --nj-exceptions-cont: #1a7f37; }
|
||||
[data-md-color-scheme="slate"] .nj-fig { --nj-exceptions-sched: #e3a33b; --nj-exceptions-cont: #56c46e; }
|
||||
.nj-fig .nj-exceptions-groupbox {
|
||||
fill: color-mix(in srgb, currentColor 2.5%, var(--md-default-bg-color));
|
||||
stroke: color-mix(in srgb, currentColor 22%, var(--md-default-bg-color));
|
||||
stroke-width: 1.2;
|
||||
stroke-dasharray: 5 4;
|
||||
}
|
||||
.nj-fig .nj-exceptions-group { fill: currentColor; fill-opacity: .68; font-size: 13px; font-weight: 600; letter-spacing: .02em; }
|
||||
.nj-fig .nj-exceptions-card .nj-exceptions-box { fill: var(--md-default-bg-color); }
|
||||
.nj-fig .nj-exceptions-ctitle { fill: currentColor; font-size: 15px; font-weight: 700; }
|
||||
.nj-fig .nj-exceptions-line { fill: currentColor; fill-opacity: .8; font-size: 12.5px; }
|
||||
.nj-fig .nj-exceptions-badge { stroke-width: 1.2; }
|
||||
.nj-fig .nj-exceptions-badgetext { font-size: 11px; font-weight: 600; text-anchor: middle; }
|
||||
.nj-fig .nj-exceptions-badge--push { fill: color-mix(in srgb, var(--nj-exceptions-push) 12%, var(--md-default-bg-color)); stroke: var(--nj-exceptions-push); }
|
||||
.nj-fig .nj-exceptions-badge--sched { fill: color-mix(in srgb, var(--nj-exceptions-sched) 12%, var(--md-default-bg-color)); stroke: var(--nj-exceptions-sched); }
|
||||
.nj-fig .nj-exceptions-badge--cont { fill: color-mix(in srgb, var(--nj-exceptions-cont) 12%, var(--md-default-bg-color)); stroke: var(--nj-exceptions-cont); }
|
||||
.nj-fig .nj-exceptions-badgetext--push { fill: var(--nj-exceptions-push); }
|
||||
.nj-fig .nj-exceptions-badgetext--sched { fill: var(--nj-exceptions-sched); }
|
||||
.nj-fig .nj-exceptions-badgetext--cont { fill: var(--nj-exceptions-cont); }
|
||||
.nj-fig .nj-exceptions-stage { fill: var(--md-typeset-a-color); }
|
||||
.nj-fig .nj-exceptions-stagetext { fill: #fff; font-size: 14px; font-weight: 700; text-anchor: middle; }
|
||||
.nj-fig .nj-exceptions-stagesub { fill: #fff; fill-opacity: .85; font-size: 12px; text-anchor: middle; }
|
||||
[data-md-color-scheme="slate"] .nj-fig .nj-exceptions-stage { fill: #1747a6; }
|
||||
.nj-fig .nj-exceptions-qa .fg-head, .nj-exceptions-qa .fg-head { fill: var(--nj-exceptions-line); }
|
||||
@@ -1,176 +0,0 @@
|
||||
/* figures: integration */
|
||||
|
||||
/* namespace name builder (features/namespace.md, js/fig-integration.js) */
|
||||
.md-typeset .nj-integration-ns {
|
||||
--nj-int-line: color-mix(in srgb, currentColor 30%, var(--md-default-bg-color));
|
||||
display: block;
|
||||
width: auto;
|
||||
max-width: none;
|
||||
margin: 1.5rem 0;
|
||||
padding: .9rem 1rem;
|
||||
text-align: left;
|
||||
border: 1px solid var(--nj-int-line);
|
||||
border-radius: 8px;
|
||||
}
|
||||
.md-typeset .nj-integration-ns__strip {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: flex-start;
|
||||
gap: .5rem .15rem;
|
||||
}
|
||||
.md-typeset .nj-integration-ns__seg {
|
||||
display: inline-flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
min-width: 0;
|
||||
}
|
||||
.md-typeset .nj-integration-ns__seg code {
|
||||
padding: .25em .5em;
|
||||
border: 1.5px solid var(--nj-int-line);
|
||||
border-radius: 6px;
|
||||
background: var(--md-default-bg-color);
|
||||
color: var(--md-default-fg-color);
|
||||
font-size: .8rem;
|
||||
font-weight: 600;
|
||||
word-break: normal;
|
||||
}
|
||||
.md-typeset .nj-integration-ns__seg small {
|
||||
max-width: 10rem;
|
||||
margin-top: .25rem;
|
||||
color: var(--md-default-fg-color--light);
|
||||
font-size: .58rem;
|
||||
line-height: 1.25;
|
||||
text-align: center;
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
.md-typeset .nj-integration-ns__seg--sep code {
|
||||
border-color: transparent;
|
||||
padding-inline: .1em;
|
||||
}
|
||||
.md-typeset .nj-integration-ns__seg--abi code {
|
||||
border-color: var(--md-typeset-a-color);
|
||||
background: color-mix(in srgb, var(--md-typeset-a-color) 12%, var(--md-default-bg-color));
|
||||
color: var(--md-typeset-a-color);
|
||||
}
|
||||
.md-typeset .nj-integration-ns__seg--tag code {
|
||||
border-style: dashed;
|
||||
border-color: var(--md-typeset-a-color);
|
||||
color: var(--md-typeset-a-color);
|
||||
}
|
||||
.md-typeset .nj-integration-ns__seg--ver code {
|
||||
background: color-mix(in srgb, currentColor 8%, var(--md-default-bg-color));
|
||||
}
|
||||
.md-typeset .nj-integration-ns figcaption {
|
||||
max-width: none;
|
||||
margin: .8rem 0 0;
|
||||
font-size: .75rem;
|
||||
text-align: left;
|
||||
color: var(--md-default-fg-color--light);
|
||||
}
|
||||
.md-typeset .nj-integration-ns__controls {
|
||||
margin-top: 1rem;
|
||||
padding-top: .8rem;
|
||||
border-top: 1px solid var(--nj-int-line);
|
||||
font-size: .7rem;
|
||||
}
|
||||
.md-typeset .nj-integration-ns__version select {
|
||||
min-height: 2rem;
|
||||
margin-left: .3rem;
|
||||
padding: 0 .4rem;
|
||||
border: 1px solid var(--nj-int-line);
|
||||
border-radius: 6px;
|
||||
background: var(--md-default-bg-color);
|
||||
color: var(--md-default-fg-color);
|
||||
font: inherit;
|
||||
}
|
||||
.md-typeset .nj-integration-ns__list {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(min(100%, 21rem), 1fr));
|
||||
gap: 0 1rem;
|
||||
margin: .7rem 0 0;
|
||||
padding: 0;
|
||||
border: 0;
|
||||
}
|
||||
.md-typeset .nj-integration-ns__list legend {
|
||||
padding: 0;
|
||||
margin-bottom: .3rem;
|
||||
font-weight: 600;
|
||||
}
|
||||
.md-typeset .nj-integration-ns__opt {
|
||||
display: grid;
|
||||
grid-template-columns: 1.1rem 1fr;
|
||||
align-items: center;
|
||||
gap: 0 .55rem;
|
||||
min-height: 2.2rem;
|
||||
padding: .15rem 0;
|
||||
cursor: pointer;
|
||||
}
|
||||
.md-typeset .nj-integration-ns__meta {
|
||||
grid-column: 2;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 0 .45rem;
|
||||
}
|
||||
.md-typeset .nj-integration-ns__opt input {
|
||||
grid-row: 1 / span 2;
|
||||
width: 1.1rem;
|
||||
height: 1.1rem;
|
||||
margin: 0;
|
||||
accent-color: var(--md-typeset-a-color);
|
||||
}
|
||||
.md-typeset .nj-integration-ns__opt input:focus-visible {
|
||||
outline: 2px solid var(--md-accent-fg-color);
|
||||
outline-offset: 2px;
|
||||
}
|
||||
.md-typeset .nj-integration-ns__opt code {
|
||||
font-size: .64rem;
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
.md-typeset .nj-integration-ns__hint {
|
||||
color: var(--md-typeset-a-color);
|
||||
font-family: var(--md-code-font-family);
|
||||
font-size: .64rem;
|
||||
}
|
||||
.md-typeset .nj-integration-ns__since {
|
||||
color: var(--md-default-fg-color--light);
|
||||
font-size: .6rem;
|
||||
}
|
||||
.md-typeset .nj-integration-ns__opt.is-unavailable {
|
||||
cursor: not-allowed;
|
||||
opacity: .5;
|
||||
}
|
||||
@media screen and (max-width: 44.984375em) {
|
||||
.md-typeset .nj-integration-ns__opt {
|
||||
min-height: 2.75rem;
|
||||
}
|
||||
}
|
||||
|
||||
/* roadmap lanes and release timeline (scripts/figures/integration.py, release_timeline.py) */
|
||||
.md-typeset svg.nj-fig--lanes { min-width: 44rem; max-width: 46rem; }
|
||||
.md-typeset svg.nj-fig--timeline { min-width: 44rem; max-width: 52rem; }
|
||||
.nj-fig .nj-int-lane { fill: color-mix(in srgb, var(--md-typeset-a-color) 10%, var(--md-default-bg-color)); stroke: var(--md-typeset-a-color); stroke-width: 1.5; }
|
||||
.nj-fig .nj-int-lane--future { fill: none; stroke-dasharray: 6 4; }
|
||||
.nj-fig .nj-int-lanetext { fill: var(--md-typeset-a-color); font-size: 15px; font-weight: 700; }
|
||||
.nj-fig .nj-int-text { fill: currentColor; font-size: 13px; }
|
||||
.nj-fig .nj-int-mute { fill: currentColor; fill-opacity: .7; font-size: 12.5px; }
|
||||
.nj-fig .nj-int-macro { fill: currentColor; font-family: var(--md-code-font-family), monospace; font-size: 12.5px; }
|
||||
.nj-fig .nj-int-val { fill: currentColor; font-family: var(--md-code-font-family), monospace; font-size: 13px; font-weight: 600; }
|
||||
.nj-fig .nj-int-row { fill: color-mix(in srgb, currentColor 4%, var(--md-default-bg-color)); }
|
||||
.nj-fig .nj-int-track { fill: color-mix(in srgb, currentColor 14%, var(--md-default-bg-color)); stroke: color-mix(in srgb, currentColor 45%, var(--md-default-bg-color)); stroke-width: 1.2; }
|
||||
.nj-fig .nj-int-track--on { fill: var(--md-typeset-a-color); stroke: var(--md-typeset-a-color); }
|
||||
.nj-fig .nj-int-knob { fill: var(--md-default-bg-color); stroke: color-mix(in srgb, currentColor 45%, var(--md-default-bg-color)); stroke-width: 1.2; }
|
||||
.nj-fig .nj-int-knob--on { stroke: var(--md-typeset-a-color); }
|
||||
.nj-fig .nj-int-axis { stroke: color-mix(in srgb, currentColor 45%, var(--md-default-bg-color)); stroke-width: 1.5; }
|
||||
.nj-fig .nj-int-grid { stroke: color-mix(in srgb, currentColor 14%, var(--md-default-bg-color)); stroke-width: 1; }
|
||||
.nj-fig .nj-int-minor { fill: var(--md-typeset-a-color); stroke: var(--md-default-bg-color); stroke-width: 1.5; }
|
||||
.nj-fig .nj-int-patch { fill: var(--md-default-bg-color); stroke: var(--md-typeset-a-color); stroke-width: 1.5; }
|
||||
.nj-fig .nj-int-major { fill: currentColor; fill-opacity: .7; font-size: 13px; font-weight: 600; }
|
||||
.nj-fig .nj-int-label { fill: currentColor; font-size: 12px; font-weight: 600; text-anchor: middle; }
|
||||
.nj-fig .nj-int-year { fill: currentColor; fill-opacity: .7; font-size: 12px; text-anchor: middle; }
|
||||
.nj-fig .nj-int-leader { stroke: color-mix(in srgb, currentColor 30%, var(--md-default-bg-color)); stroke-width: 1; }
|
||||
.nj-fig .nj-int-hit { fill: transparent; }
|
||||
|
||||
/* roadmap: value pills (3.x default -> 4.0 value) */
|
||||
.nj-fig .nj-int-pill { fill: color-mix(in srgb, currentColor 8%, var(--md-default-bg-color)); stroke: color-mix(in srgb, currentColor 35%, var(--md-default-bg-color)); stroke-width: 1.2; }
|
||||
.nj-fig .nj-int-pill--v4 { fill: var(--md-typeset-a-color); stroke: var(--md-typeset-a-color); }
|
||||
.nj-fig .nj-int-val--v4 { fill: var(--md-default-bg-color); }
|
||||
@@ -1,107 +0,0 @@
|
||||
/* figures: jsonview (features/json_view.md; SVGs from scripts/figures/json_view_layout.py, stepper in js/fig-jsonview.js) */
|
||||
|
||||
/* one colour per concept, the same in every figure: structure (object/array, views) blue, keys navy, strings green,
|
||||
numbers orange, decoded strings purple, owned edit storage teal, dangling/invalid red */
|
||||
.nj-jsonview, .nj-jsonview-cmp {
|
||||
--jv-struct: var(--nj-blue);
|
||||
--jv-key: var(--nj-hl-key);
|
||||
--jv-str: var(--nj-hl-string);
|
||||
--jv-num: var(--nj-hl-number);
|
||||
--jv-dec: var(--nj-hl-function);
|
||||
--jv-own: var(--nj-hl-type);
|
||||
--jv-bad: var(--nj-red);
|
||||
--jv-line: color-mix(in srgb, currentColor 55%, var(--md-default-bg-color));
|
||||
}
|
||||
.md-typeset svg.nj-jsonview { min-width: 34rem; max-width: 42rem; }
|
||||
.nj-jsonview .nj-jsonview-c-struct { --c: var(--jv-struct); }
|
||||
.nj-jsonview .nj-jsonview-c-key { --c: var(--jv-key); }
|
||||
.nj-jsonview .nj-jsonview-c-str { --c: var(--jv-str); }
|
||||
.nj-jsonview .nj-jsonview-c-num { --c: var(--jv-num); }
|
||||
.nj-jsonview .nj-jsonview-c-dec { --c: var(--jv-dec); }
|
||||
.nj-jsonview .nj-jsonview-c-own { --c: var(--jv-own); }
|
||||
.nj-jsonview .nj-jsonview-c-bad { --c: var(--jv-bad); }
|
||||
.nj-jsonview .nj-jsonview-c-line { --c: var(--jv-line); }
|
||||
|
||||
.nj-jsonview text { fill: currentColor; font-size: 13px; }
|
||||
.nj-jsonview text[class*="nj-jsonview-c-"] { fill: var(--c); }
|
||||
.nj-jsonview .nj-jsonview-h { font-size: 15px; font-weight: 600; fill-opacity: .85; }
|
||||
.nj-jsonview .nj-jsonview-sm2 { font-size: 14px; }
|
||||
.nj-jsonview .nj-jsonview-note { font-size: 13px; fill-opacity: .75; }
|
||||
.nj-jsonview .nj-jsonview-strong { font-weight: 600; fill-opacity: 1; }
|
||||
.nj-jsonview .nj-jsonview-tiny { font-size: 10.5px; fill-opacity: .7; }
|
||||
.nj-jsonview .nj-jsonview-mono { font-family: var(--md-code-font-family), monospace; font-size: 13px; }
|
||||
.nj-jsonview .nj-jsonview-sm { font-size: 12px; }
|
||||
.nj-jsonview .nj-jsonview-xs { font-size: 11px; }
|
||||
.nj-jsonview .nj-jsonview-muted { fill-opacity: .75; }
|
||||
.nj-jsonview .nj-jsonview-byte { font-size: 12px; }
|
||||
.nj-jsonview .nj-jsonview-kind { font-size: 12.5px; font-weight: 700; }
|
||||
|
||||
.nj-jsonview .nj-jsonview-box { fill: var(--md-default-bg-color); stroke: var(--jv-line); stroke-width: 1.5; }
|
||||
.nj-jsonview .nj-jsonview-heap { fill: color-mix(in srgb, currentColor 7%, var(--md-default-bg-color)); stroke: var(--jv-line); stroke-width: 1.5; stroke-dasharray: 5 3; }
|
||||
.nj-jsonview .nj-jsonview-ribbon { fill: color-mix(in srgb, currentColor 4%, var(--md-default-bg-color)); stroke: var(--jv-line); stroke-width: 1.2; }
|
||||
.nj-jsonview .nj-jsonview-span { fill: color-mix(in srgb, var(--c) 18%, var(--md-default-bg-color)); }
|
||||
.nj-jsonview .nj-jsonview-frame { fill: none; stroke: var(--jv-line); stroke-width: 1.2; stroke-dasharray: 6 4; }
|
||||
.nj-jsonview .nj-jsonview-store { fill: color-mix(in srgb, var(--jv-own) 6%, var(--md-default-bg-color)); stroke: color-mix(in srgb, var(--jv-own) 55%, var(--md-default-bg-color)); stroke-width: 1.2; stroke-dasharray: 6 4; }
|
||||
.nj-jsonview .nj-jsonview-node { fill: color-mix(in srgb, var(--c) 12%, var(--md-default-bg-color)); stroke: var(--c); stroke-width: 1.5; }
|
||||
.nj-jsonview .nj-jsonview-node.nj-jsonview-hot { stroke-width: 3; }
|
||||
.nj-jsonview .nj-jsonview-node.nj-jsonview-gap { fill: var(--md-default-bg-color); stroke: var(--jv-bad); stroke-dasharray: 4 3; }
|
||||
.nj-jsonview .nj-jsonview-node.nj-jsonview-free { fill: none; stroke-dasharray: 3 3; }
|
||||
.nj-jsonview .nj-jsonview-sep { stroke: var(--jv-line); stroke-width: 1; fill: none; }
|
||||
.nj-jsonview .nj-jsonview-arr { stroke: var(--c); stroke-width: 1.5; fill: none; }
|
||||
.nj-jsonview .nj-jsonview-dash { stroke-dasharray: 4 3; }
|
||||
.nj-jsonview .nj-jsonview-head { fill: var(--c); }
|
||||
.nj-jsonview .nj-jsonview-bar { fill: color-mix(in srgb, var(--jv-struct) 30%, var(--md-default-bg-color)); stroke: var(--jv-struct); stroke-width: 1.2; }
|
||||
.nj-jsonview .nj-jsonview-bad {
|
||||
fill: color-mix(in srgb, var(--jv-bad) 20%, var(--md-default-bg-color));
|
||||
stroke: var(--jv-bad); stroke-width: 1.2; stroke-dasharray: 4 2;
|
||||
}
|
||||
.nj-jsonview .nj-jsonview-evt { stroke: var(--jv-bad); stroke-width: 2; fill: none; }
|
||||
.nj-jsonview .nj-jsonview-evt--ok { stroke: var(--jv-struct); stroke-dasharray: 4 3; }
|
||||
.nj-jsonview .nj-jsonview-onbad, .nj-jsonview .nj-jsonview-onok { font-size: 11.5px; fill-opacity: 1; }
|
||||
|
||||
/* the edit stepper: without JS all frames are shown one below the other */
|
||||
.nj-jsonview-steps { margin: 1.5rem 0; }
|
||||
.md-typeset .nj-jsonview-step { display: block; width: 100%; max-width: none; margin: 0 0 1.5rem; }
|
||||
.nj-jsonview-step > figcaption {
|
||||
margin: .25rem 0 0; font-size: .75rem; color: var(--md-default-fg-color--light); text-align: left;
|
||||
max-width: none;
|
||||
}
|
||||
.nj-jsonview-step > figcaption code { font-size: .95em; }
|
||||
.nj-jsonview-step .nj-jsonview-scroll { overflow-x: auto; }
|
||||
.md-typeset .nj-jsonview-steps.is-enhanced .nj-jsonview-step { display: none; margin: 0; }
|
||||
.md-typeset .nj-jsonview-steps.is-enhanced .nj-jsonview-step.is-current { display: block; }
|
||||
.nj-jsonview-controls { display: flex; flex-wrap: wrap; align-items: center; gap: .5rem; margin: 0 0 .6rem; }
|
||||
.nj-jsonview-controls button {
|
||||
min-height: 2.2rem; min-width: 2.2rem; padding: 0 .8rem;
|
||||
font: inherit; font-size: .7rem; font-weight: 600; cursor: pointer;
|
||||
color: var(--md-typeset-a-color); background: var(--md-default-bg-color);
|
||||
border: 1.5px solid var(--md-typeset-a-color); border-radius: .4rem;
|
||||
}
|
||||
.nj-jsonview-controls button:hover:not(:disabled) { background: color-mix(in srgb, var(--md-typeset-a-color) 10%, var(--md-default-bg-color)); }
|
||||
.nj-jsonview-controls button:focus-visible { outline: 2px solid var(--md-accent-fg-color); outline-offset: 2px; }
|
||||
.nj-jsonview-controls button:disabled { opacity: .45; cursor: default; }
|
||||
.nj-jsonview-controls button[aria-current="step"], .nj-jsonview-controls button[aria-current="step"]:hover { color: var(--md-default-bg-color); background: var(--md-typeset-a-color); }
|
||||
.nj-jsonview-controls .nj-jsonview-status { font-size: .7rem; color: var(--md-default-fg-color--light); margin-left: .25rem; }
|
||||
@media (max-width: 44.9375em) {
|
||||
.nj-jsonview-controls button { min-height: 44px; min-width: 44px; }
|
||||
}
|
||||
@media (prefers-reduced-motion: no-preference) {
|
||||
.nj-jsonview-steps.is-enhanced .nj-jsonview-step.is-current { animation: nj-jsonview-fade .25s ease-out; }
|
||||
}
|
||||
@keyframes nj-jsonview-fade { from { opacity: .3; } to { opacity: 1; } }
|
||||
|
||||
/* json vs ordered_json vs editable document */
|
||||
.nj-jsonview-cmp { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: .6rem; margin: 1.2rem 0; }
|
||||
.nj-jsonview-cmp > div {
|
||||
border: 1px solid var(--md-default-fg-color--lightest); border-radius: .4rem; padding: .5rem .6rem .6rem;
|
||||
background: var(--md-code-bg-color); min-width: 0;
|
||||
}
|
||||
.nj-jsonview-cmp > div.nj-jsonview-cmp--best { border-color: var(--jv-struct); }
|
||||
.nj-jsonview-cmp .nj-jsonview-cmp-h { font-size: .7rem; font-weight: 600; margin: 0 0 .1rem; }
|
||||
.nj-jsonview-cmp .nj-jsonview-cmp-v { font-size: .64rem; color: var(--md-default-fg-color--light); margin: 0 0 .4rem; }
|
||||
.md-typeset .nj-jsonview-cmp pre { margin: 0; font-family: var(--md-code-font-family), monospace; font-size: .68rem; line-height: 1.5; white-space: pre; overflow-x: auto; background: none; color: var(--md-code-fg-color); }
|
||||
.nj-jsonview-cmp .nj-jsonview-bad { color: var(--jv-bad); font-weight: 600; text-decoration: underline wavy; text-underline-offset: 3px; }
|
||||
.nj-jsonview-cmp .nj-jsonview-ok { color: var(--jv-own); font-weight: 600; }
|
||||
@media (max-width: 44.9375em) {
|
||||
.nj-jsonview-cmp { grid-template-columns: minmax(0, 1fr); }
|
||||
}
|
||||
@@ -1,98 +0,0 @@
|
||||
/* figures: macro chooser (js/fig-macros.js) on features/arbitrary_types.md; colours come from the brand
|
||||
variables in brand.css, which switch with the light/slate scheme */
|
||||
.nj-macro-chooser {
|
||||
--nj-mc-line: color-mix(in srgb, currentColor 18%, var(--md-default-bg-color));
|
||||
--nj-mc-panel: color-mix(in srgb, currentColor 3%, var(--md-default-bg-color));
|
||||
--nj-mc-ink2: var(--md-default-fg-color--light);
|
||||
margin: 1.2em 0 1.6em;
|
||||
font-size: .74rem;
|
||||
}
|
||||
.md-typeset .nj-macro-chooser .nj-mc-fallback > :first-child { margin-top: 0; }
|
||||
|
||||
.nj-mc-app { border: 1px solid var(--nj-mc-line); border-radius: .3rem; background: var(--nj-mc-panel);
|
||||
padding: .9rem; display: grid; grid-template-columns: minmax(0, 1fr); gap: 1rem; }
|
||||
.nj-mc-form, .nj-mc-out, .nj-mc-editor, .nj-mc-members, .nj-mc-mbody { grid-template-columns: minmax(0, 1fr); }
|
||||
.nj-mc-form { display: grid; gap: 1rem; margin: 0; }
|
||||
|
||||
/* questions as segmented radio groups */
|
||||
.nj-mc-questions { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(14.5rem, 100%), 1fr)); gap: .7rem .9rem; }
|
||||
.nj-mc-q { border: 0; margin: 0; padding: 0; min-width: 0; }
|
||||
.nj-mc-q legend { font-weight: 600; padding: 0; margin-bottom: .3rem; font-size: .7rem; }
|
||||
.nj-mc-seg { display: flex; border: 1px solid var(--nj-mc-line); border-radius: .25rem; overflow: hidden;
|
||||
background: var(--md-default-bg-color); }
|
||||
.nj-mc-seg input { position: absolute; opacity: 0; width: 1px; height: 1px; margin: 0; pointer-events: none; }
|
||||
.nj-mc-seg label { flex: 1 1 0; display: flex; align-items: center; justify-content: center; text-align: center;
|
||||
min-height: 2.1rem; padding: .25rem .5rem; cursor: pointer; line-height: 1.25; font-size: .7rem;
|
||||
color: var(--md-default-fg-color); transition: background-color .15s, color .15s; }
|
||||
.nj-mc-seg label + input + label { border-left: 1px solid var(--nj-mc-line); }
|
||||
.nj-mc-seg label:hover { background: var(--nj-blue-soft); }
|
||||
.nj-mc-seg input:checked + label { background: var(--nj-blue); color: var(--md-default-bg-color); font-weight: 600; }
|
||||
.nj-mc-seg input:focus-visible + label { outline: 2px solid var(--md-accent-fg-color); outline-offset: -3px; }
|
||||
.nj-mc-q:disabled .nj-mc-seg { opacity: .45; }
|
||||
.nj-mc-q:disabled label { cursor: not-allowed; }
|
||||
.nj-mc-q:disabled label:hover { background: transparent; }
|
||||
.md-typeset .nj-mc-qnote { margin: .3rem 0 0; font-size: .64rem; line-height: 1.4; color: var(--nj-mc-ink2); }
|
||||
|
||||
/* type editor */
|
||||
.nj-mc-editor { display: grid; gap: .6rem; border-top: 1px solid var(--nj-mc-line); padding-top: .9rem; }
|
||||
.nj-mc-names { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(11rem, 100%), 1fr)); gap: .6rem .9rem; }
|
||||
.nj-mc-field { display: grid; gap: .2rem; }
|
||||
.nj-mc-field label { font-weight: 600; font-size: .7rem; }
|
||||
.nj-mc-field[hidden] { display: none; }
|
||||
.nj-macro-chooser input[type="text"] { font-family: var(--md-code-font-family), monospace; font-size: .7rem;
|
||||
min-height: 2.1rem; padding: .2rem .45rem; min-width: 0; width: 100%; box-sizing: border-box;
|
||||
border: 1px solid var(--nj-mc-line); border-radius: .2rem; background: var(--md-default-bg-color);
|
||||
color: var(--md-default-fg-color); }
|
||||
.nj-macro-chooser input[type="text"]:focus { outline: 2px solid var(--md-accent-fg-color); outline-offset: 0; border-color: transparent; }
|
||||
|
||||
.nj-mc-members { display: grid; gap: .35rem; }
|
||||
.nj-mc-mbody { display: grid; gap: .35rem; }
|
||||
.nj-mc-mrow { display: grid; grid-template-columns: minmax(0, 1.3fr) minmax(0, 1fr) 2.2rem; gap: .4rem; align-items: center; }
|
||||
.nj-mc-custom .nj-mc-mrow { grid-template-columns: minmax(0, 1.3fr) minmax(0, 1fr) minmax(0, 1fr) 2.2rem; }
|
||||
.nj-mc-mrow .nj-mc-keycol { display: none; }
|
||||
.nj-mc-custom .nj-mc-mrow .nj-mc-keycol { display: block; }
|
||||
.nj-mc-mhead { font-weight: 600; font-size: .66rem; color: var(--nj-mc-ink2); }
|
||||
.nj-mc-mhead .nj-mc-keycol[hidden] { display: none; }
|
||||
|
||||
.nj-macro-chooser button { font: inherit; cursor: pointer; border-radius: .2rem; }
|
||||
.nj-macro-chooser button:focus-visible { outline: 2px solid var(--md-accent-fg-color); outline-offset: 2px; }
|
||||
.nj-mc-rm { width: 2.2rem; height: 2.1rem; border: 1px solid var(--nj-mc-line); background: var(--md-default-bg-color);
|
||||
color: var(--nj-mc-ink2); font-size: 1rem; line-height: 1; padding: 0; }
|
||||
.nj-mc-rm:hover { color: var(--nj-red); border-color: var(--nj-red); }
|
||||
.nj-mc-add, .nj-mc-copy { justify-self: start; min-height: 2.1rem; padding: .2rem .8rem; font-size: .7rem; font-weight: 600;
|
||||
border: 1px solid var(--nj-blue); background: var(--md-default-bg-color); color: var(--nj-blue); }
|
||||
.nj-mc-add:hover, .nj-mc-copy:hover { background: var(--nj-blue-soft); }
|
||||
|
||||
/* output */
|
||||
.nj-mc-out { display: grid; gap: .7rem; }
|
||||
.nj-mc-result { border-left: .2rem solid var(--nj-blue); background: var(--nj-blue-soft); border-radius: 0 .2rem .2rem 0;
|
||||
padding: .55rem .8rem; }
|
||||
.nj-mc-result.nj-mc-bad { border-left-color: var(--nj-red); background: var(--nj-red-soft); }
|
||||
.md-typeset .nj-mc-result p { margin: 0; }
|
||||
.md-typeset .nj-mc-result p + p { margin-top: .3rem; }
|
||||
.md-typeset .nj-mc-label { font-size: .64rem; font-weight: 600; text-transform: uppercase; letter-spacing: .04em; color: var(--nj-mc-ink2); }
|
||||
.md-typeset .nj-mc-macro code { font-size: .8rem; font-weight: 600; background: transparent; padding: 0;
|
||||
overflow-wrap: anywhere; color: var(--md-default-fg-color); }
|
||||
.md-typeset .nj-mc-why { line-height: 1.5; }
|
||||
.md-typeset .nj-mc-hints { margin: 0; padding-left: 1.1rem; font-size: .68rem; color: var(--nj-mc-ink2); }
|
||||
.md-typeset .nj-mc-hints li { margin: 0; }
|
||||
.nj-mc-hints[hidden], .nj-mc-code[hidden] { display: none; }
|
||||
|
||||
.nj-mc-codebar { display: flex; align-items: center; gap: .6rem; margin-bottom: .3rem; }
|
||||
.nj-mc-codetitle { font-weight: 600; font-size: .7rem; margin-right: auto; }
|
||||
.nj-mc-copystatus { font-size: .66rem; color: var(--nj-mc-ink2); }
|
||||
.md-typeset .nj-mc-code .highlight { margin: 0; }
|
||||
.md-typeset .nj-mc-code pre { margin: 0; }
|
||||
.md-typeset .nj-mc-code pre > code { max-height: 34rem; }
|
||||
|
||||
@media (max-width: 44.9375em) {
|
||||
.nj-mc-app { padding: .7rem; }
|
||||
.nj-mc-seg label, .nj-macro-chooser input[type="text"], .nj-mc-add, .nj-mc-copy { min-height: 2.75rem; }
|
||||
.nj-mc-rm { width: 2.75rem; height: 2.75rem; }
|
||||
.nj-mc-mrow, .nj-mc-custom .nj-mc-mrow { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) 2.75rem; }
|
||||
.nj-mc-custom .nj-mc-mrow .nj-mc-keycol { grid-column: 1 / 3; }
|
||||
.nj-mc-custom .nj-mc-mhead { display: none; }
|
||||
}
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
.nj-mc-seg label { transition: none; }
|
||||
}
|
||||
@@ -1,459 +0,0 @@
|
||||
/* figures: pointer (features/json_pointer.md, json_patch.md, merge_patch.md; widgets in js/fig-pointer.js) */
|
||||
|
||||
/* value types: the colours of the code highlighting (brand.css), so a string looks the same everywhere */
|
||||
.nj-pointer-walk, .nj-pointer-fl, .nj-patch {
|
||||
--nj-pointer-s: var(--nj-hl-string);
|
||||
--nj-pointer-n: var(--nj-hl-number);
|
||||
--nj-pointer-b: var(--nj-hl-function);
|
||||
--nj-pointer-line: color-mix(in srgb, var(--md-default-fg-color) 28%, var(--md-default-bg-color));
|
||||
--nj-pointer-ok: #23793a;
|
||||
--nj-pointer-ok-soft: #e6f4ea;
|
||||
}
|
||||
[data-md-color-scheme="slate"] :is(.nj-pointer-walk, .nj-pointer-fl, .nj-patch) {
|
||||
--nj-pointer-ok: #7ed491;
|
||||
--nj-pointer-ok-soft: #14301d;
|
||||
}
|
||||
|
||||
/* ---------- pointer walker ---------- */
|
||||
.md-typeset .nj-pointer-walk {
|
||||
display: grid;
|
||||
grid-template-columns: minmax(0, 1fr);
|
||||
gap: 1rem 1.6rem;
|
||||
margin: 1.5rem 0;
|
||||
padding: 1rem 1.1rem;
|
||||
border: 1px solid var(--md-default-fg-color--lightest);
|
||||
border-radius: 6px;
|
||||
font-size: .75rem;
|
||||
}
|
||||
@media screen and (min-width: 45em) {
|
||||
.md-typeset .nj-pointer-walk--js {
|
||||
grid-template-columns: minmax(0, 1fr) minmax(0, 1.1fr);
|
||||
}
|
||||
.md-typeset .nj-pointer-walk--js .nj-pointer-panel { order: 2; }
|
||||
}
|
||||
.md-typeset .nj-pointer-static {
|
||||
margin: 0;
|
||||
color: var(--md-default-fg-color--light);
|
||||
}
|
||||
.md-typeset .nj-pointer-walk code {
|
||||
font-size: .95em;
|
||||
}
|
||||
|
||||
/* tree: elbow lines drawn by each item (::before up to its row, ::after down to the next sibling) */
|
||||
.md-typeset .nj-pointer-walk ul.nj-pointer-tree,
|
||||
.md-typeset .nj-pointer-walk .nj-pointer-tree ul {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
list-style: none;
|
||||
}
|
||||
.md-typeset .nj-pointer-walk .nj-pointer-tree ul {
|
||||
padding-left: 1.5rem;
|
||||
}
|
||||
.md-typeset .nj-pointer-walk .nj-pointer-tree li {
|
||||
position: relative;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
list-style: none;
|
||||
--nj-pointer-mid: .95rem;
|
||||
}
|
||||
.md-typeset .nj-pointer-walk .nj-pointer-tree li::before,
|
||||
.md-typeset .nj-pointer-walk .nj-pointer-tree li::after {
|
||||
content: none;
|
||||
}
|
||||
.md-typeset .nj-pointer-walk .nj-pointer-tree ul > li::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: -1rem;
|
||||
width: .8rem;
|
||||
height: var(--nj-pointer-mid);
|
||||
border: 0 solid var(--nj-pointer-line);
|
||||
border-width: 0 0 2px 2px;
|
||||
border-bottom-left-radius: 4px;
|
||||
background: none;
|
||||
}
|
||||
.md-typeset .nj-pointer-walk .nj-pointer-tree ul > li:not(:last-child)::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: -1rem;
|
||||
border-left: 2px solid var(--nj-pointer-line);
|
||||
}
|
||||
.md-typeset .nj-pointer-walk .nj-pointer-tree ul > li.is-on::before {
|
||||
z-index: 1;
|
||||
border-color: var(--md-typeset-a-color);
|
||||
}
|
||||
.md-typeset .nj-pointer-walk .nj-pointer-tree ul > li.is-pass::after {
|
||||
z-index: 1;
|
||||
border-left-color: var(--md-typeset-a-color);
|
||||
}
|
||||
|
||||
.md-typeset .nj-pointer-walk .nj-pointer-n {
|
||||
display: inline-block;
|
||||
margin: .15rem 0;
|
||||
padding: .2rem .5rem;
|
||||
border: 1px solid transparent;
|
||||
border-radius: 6px;
|
||||
background: none;
|
||||
color: var(--md-default-fg-color);
|
||||
font: inherit;
|
||||
font-family: var(--md-code-font-family), monospace;
|
||||
font-size: .95em;
|
||||
line-height: 1.5;
|
||||
text-align: left;
|
||||
}
|
||||
.md-typeset .nj-pointer-walk button.nj-pointer-n {
|
||||
cursor: pointer;
|
||||
}
|
||||
.md-typeset .nj-pointer-walk button.nj-pointer-n:hover {
|
||||
border-color: var(--md-default-fg-color--lightest);
|
||||
}
|
||||
.md-typeset .nj-pointer-walk :is(button):focus-visible {
|
||||
outline: 2px solid var(--md-typeset-a-color);
|
||||
outline-offset: 2px;
|
||||
}
|
||||
.nj-pointer-k { color: var(--nj-hl-key); }
|
||||
.nj-pointer-t {
|
||||
color: var(--md-default-fg-color--light);
|
||||
font-family: var(--md-text-font-family), sans-serif;
|
||||
font-size: .88em;
|
||||
font-style: italic;
|
||||
}
|
||||
.nj-pointer-v--s { color: var(--nj-pointer-s); }
|
||||
.nj-pointer-v--n { color: var(--nj-pointer-n); }
|
||||
.nj-pointer-v--b { color: var(--nj-pointer-b); }
|
||||
|
||||
.md-typeset .nj-pointer-walk li.is-on > .nj-pointer-n {
|
||||
border-color: color-mix(in srgb, var(--md-typeset-a-color) 45%, transparent);
|
||||
}
|
||||
.md-typeset .nj-pointer-walk li.is-target > .nj-pointer-n {
|
||||
border-color: var(--md-typeset-a-color);
|
||||
background-color: var(--nj-blue-soft);
|
||||
box-shadow: 0 0 0 1px var(--md-typeset-a-color);
|
||||
}
|
||||
/* the value a container pointer identifies includes its subtree */
|
||||
.md-typeset .nj-pointer-walk li.is-target li > .nj-pointer-n {
|
||||
background-color: var(--nj-blue-soft);
|
||||
}
|
||||
.md-typeset .nj-pointer-walk li.is-miss > .nj-pointer-n {
|
||||
border-color: var(--nj-red);
|
||||
border-style: dashed;
|
||||
}
|
||||
|
||||
/* panel: pointer bar, result, example pointers */
|
||||
.nj-pointer-lbl {
|
||||
margin: 0 0 .35rem;
|
||||
color: var(--md-default-fg-color--light);
|
||||
font-size: .62rem;
|
||||
font-weight: 600;
|
||||
letter-spacing: .04em;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
.nj-pointer-lbl span {
|
||||
font-weight: 500;
|
||||
letter-spacing: 0;
|
||||
text-transform: none;
|
||||
}
|
||||
.nj-pointer-bar {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
margin-bottom: .6rem;
|
||||
}
|
||||
.md-typeset .nj-pointer-seg {
|
||||
margin: 0 -1px 0 0;
|
||||
padding: .3rem .55rem;
|
||||
border: 1px solid var(--md-typeset-a-color);
|
||||
background-color: var(--md-default-bg-color);
|
||||
color: var(--md-typeset-a-color);
|
||||
cursor: pointer;
|
||||
font: inherit;
|
||||
}
|
||||
.md-typeset .nj-pointer-seg:first-child { border-radius: 6px 0 0 6px; }
|
||||
.md-typeset .nj-pointer-seg:last-child { border-radius: 0 6px 6px 0; }
|
||||
.md-typeset .nj-pointer-seg:only-child { border-radius: 6px; }
|
||||
.md-typeset .nj-pointer-seg code { color: inherit; font-size: 1em; }
|
||||
.md-typeset .nj-pointer-seg--root code { color: var(--md-default-fg-color--light); }
|
||||
.md-typeset .nj-pointer-seg.is-after {
|
||||
border-color: var(--md-default-fg-color--lighter);
|
||||
color: var(--md-default-fg-color--light);
|
||||
border-style: dashed;
|
||||
}
|
||||
.md-typeset .nj-pointer-seg[aria-pressed="true"] {
|
||||
position: relative;
|
||||
background-color: var(--md-typeset-a-color);
|
||||
color: var(--md-default-bg-color);
|
||||
}
|
||||
.md-typeset .nj-pointer-seg--root[aria-pressed="true"] code { color: inherit; }
|
||||
.nj-pointer-out {
|
||||
min-height: 3.2em;
|
||||
margin-bottom: .9rem;
|
||||
padding: .5rem .7rem;
|
||||
border-left: 3px solid var(--md-typeset-a-color);
|
||||
border-radius: 0 6px 6px 0;
|
||||
background-color: var(--md-code-bg-color);
|
||||
line-height: 1.6;
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
.md-typeset .nj-pointer-out .nj-pointer-val { color: var(--md-typeset-a-color); font-weight: 600; }
|
||||
.nj-pointer-out .nj-pointer-note { color: var(--md-default-fg-color--light); }
|
||||
.nj-pointer-out .nj-pointer-err { color: var(--nj-red); font-weight: 600; }
|
||||
.nj-pointer-presets {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: .35rem;
|
||||
}
|
||||
.md-typeset .nj-pointer-chip {
|
||||
padding: .2rem .5rem;
|
||||
border: 1px solid var(--md-default-fg-color--lightest);
|
||||
border-radius: 6px;
|
||||
background-color: var(--md-default-bg-color);
|
||||
color: var(--md-default-fg-color);
|
||||
cursor: pointer;
|
||||
font: inherit;
|
||||
}
|
||||
.md-typeset .nj-pointer-chip:hover { border-color: var(--md-typeset-a-color); }
|
||||
.md-typeset .nj-pointer-chip[aria-pressed="true"] {
|
||||
border-color: var(--md-typeset-a-color);
|
||||
background-color: var(--nj-blue-soft);
|
||||
color: var(--md-typeset-a-color);
|
||||
}
|
||||
.md-typeset .nj-pointer-chip code { color: inherit; font-size: 1em; }
|
||||
@media (pointer: coarse), screen and (max-width: 44.984375em) {
|
||||
.md-typeset :is(.nj-pointer-seg, .nj-pointer-chip, .nj-patch-btn) { min-height: 44px; min-width: 44px; }
|
||||
.md-typeset .nj-pointer-walk button.nj-pointer-n { min-height: 40px; }
|
||||
}
|
||||
|
||||
/* ---------- flatten / unflatten figure (scripts/figures/json_pointer_flatten.py) ---------- */
|
||||
.md-typeset svg.nj-pointer-fl { min-width: 28rem; max-width: 44rem; }
|
||||
.nj-pointer-fl .nj-pointer-fl-edge { fill: none; stroke: var(--fg-line); stroke-width: 1.5; }
|
||||
.nj-pointer-fl .nj-pointer-fl-link { fill: none; stroke-width: 1.5; stroke-opacity: .75; }
|
||||
.nj-pointer-fl .nj-pointer-fl-link.nj-pointer-fl--s, .nj-pointer-fl .nj-pointer-fl-dot.nj-pointer-fl--s { stroke: var(--nj-pointer-s); }
|
||||
.nj-pointer-fl .nj-pointer-fl-link.nj-pointer-fl--n, .nj-pointer-fl .nj-pointer-fl-dot.nj-pointer-fl--n { stroke: var(--nj-pointer-n); }
|
||||
.nj-pointer-fl .nj-pointer-fl-link.nj-pointer-fl--b, .nj-pointer-fl .nj-pointer-fl-dot.nj-pointer-fl--b { stroke: var(--nj-pointer-b); }
|
||||
.nj-pointer-fl .nj-pointer-fl-dot { fill: var(--md-default-bg-color); stroke-width: 2; }
|
||||
.nj-pointer-fl tspan.nj-pointer-fl--s { fill: var(--nj-pointer-s); }
|
||||
.nj-pointer-fl tspan.nj-pointer-fl--n { fill: var(--nj-pointer-n); }
|
||||
.nj-pointer-fl tspan.nj-pointer-fl--b { fill: var(--nj-pointer-b); }
|
||||
.nj-pointer-fl .nj-pointer-fl-k, .nj-pointer-fl .nj-pointer-fl-inner, .nj-pointer-fl .nj-pointer-fl-key { fill: var(--nj-hl-key); }
|
||||
.nj-pointer-fl .nj-pointer-fl-op {
|
||||
fill: var(--md-typeset-a-color);
|
||||
font-family: var(--md-code-font-family), monospace;
|
||||
font-size: 15px;
|
||||
font-weight: 600;
|
||||
text-anchor: middle;
|
||||
}
|
||||
|
||||
/* ---------- JSON Patch stepper ---------- */
|
||||
.md-typeset .nj-patch--js .md-typeset__scrollwrap,
|
||||
.md-typeset .nj-patch--js > .md-typeset__table,
|
||||
.md-typeset .nj-patch--js > table {
|
||||
display: none;
|
||||
}
|
||||
.md-typeset .nj-patch-stage {
|
||||
margin: 1.5rem 0;
|
||||
padding: 1rem 1.1rem;
|
||||
border: 1px solid var(--md-default-fg-color--lightest);
|
||||
border-radius: 6px;
|
||||
font-size: .75rem;
|
||||
}
|
||||
.nj-patch-cols {
|
||||
display: grid;
|
||||
grid-template-columns: minmax(0, 1fr);
|
||||
gap: 1rem 1.4rem;
|
||||
}
|
||||
@media screen and (min-width: 50em) {
|
||||
.nj-patch-cols { grid-template-columns: minmax(0, .8fr) minmax(0, 1.2fr); }
|
||||
}
|
||||
.nj-patch-h {
|
||||
margin: 0 0 .35rem;
|
||||
color: var(--md-default-fg-color--light);
|
||||
font-size: .62rem;
|
||||
font-weight: 600;
|
||||
letter-spacing: .04em;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
.nj-patch-doc {
|
||||
--nj-patch-lh: 1.9rem;
|
||||
--nj-patch-pad: .5rem;
|
||||
position: relative;
|
||||
padding: var(--nj-patch-pad) .6rem var(--nj-patch-pad) 2rem;
|
||||
border: 1px solid var(--md-default-fg-color--lightest);
|
||||
border-radius: 6px;
|
||||
background-color: var(--md-code-bg-color);
|
||||
font-family: var(--md-code-font-family), monospace;
|
||||
font-size: .95em;
|
||||
}
|
||||
.nj-patch-line {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
gap: 0 .6rem;
|
||||
min-height: var(--nj-patch-lh);
|
||||
margin: 0 -.3rem;
|
||||
padding: 0 .3rem;
|
||||
border-radius: 4px;
|
||||
white-space: pre;
|
||||
}
|
||||
.nj-patch-code { white-space: pre; }
|
||||
.nj-patch-k { color: var(--nj-hl-key); }
|
||||
.nj-patch-s { color: var(--nj-pointer-s); }
|
||||
.nj-patch-note {
|
||||
padding: 0 .4rem;
|
||||
border-radius: 4px;
|
||||
font-family: var(--md-text-font-family), sans-serif;
|
||||
font-size: .82em;
|
||||
font-weight: 600;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.nj-patch-line--add { background-color: var(--nj-pointer-ok-soft); box-shadow: inset 3px 0 0 var(--nj-pointer-ok); }
|
||||
.nj-patch-line--add .nj-patch-note { color: var(--nj-pointer-ok); }
|
||||
.nj-patch-line--del { background-color: var(--nj-red-soft); box-shadow: inset 3px 0 0 var(--nj-red); }
|
||||
.nj-patch-line--del .nj-patch-code { text-decoration: line-through; text-decoration-color: var(--nj-red); text-decoration-thickness: 2px; opacity: .75; }
|
||||
.nj-patch-line--del .nj-patch-note { color: var(--nj-red); }
|
||||
.nj-patch-line--mod .nj-patch-note { color: var(--nj-pointer-ok); }
|
||||
.nj-patch-line--test { background-color: var(--nj-blue-soft); box-shadow: inset 3px 0 0 var(--md-typeset-a-color); }
|
||||
.nj-patch-line--test .nj-patch-note { color: var(--md-typeset-a-color); }
|
||||
.nj-patch-ins { padding: .05rem .15rem; border-radius: 3px; background-color: var(--nj-pointer-ok-soft); box-shadow: 0 0 0 1.5px var(--nj-pointer-ok); }
|
||||
.nj-patch-src { padding: .05rem .15rem; border-radius: 3px; box-shadow: 0 0 0 1.5px var(--md-typeset-a-color); }
|
||||
|
||||
/* move/copy connector in the left gutter: a bracket from the source line to the target line */
|
||||
.nj-patch-arc {
|
||||
position: absolute;
|
||||
left: .55rem;
|
||||
width: .8rem;
|
||||
border: 2px solid var(--md-typeset-a-color);
|
||||
border-right: 0;
|
||||
border-radius: 6px 0 0 6px;
|
||||
}
|
||||
.nj-patch-arc::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
right: -2px;
|
||||
border: 5px solid transparent;
|
||||
border-left: 7px solid var(--md-typeset-a-color);
|
||||
}
|
||||
.nj-patch-arc--down::after { bottom: -6px; }
|
||||
.nj-patch-arc--up::after { top: -6px; }
|
||||
|
||||
.md-typeset .nj-patch-ops {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
list-style: none;
|
||||
counter-reset: nj-patch;
|
||||
}
|
||||
.md-typeset .nj-patch-ops > li {
|
||||
position: relative;
|
||||
margin: 0 0 .3rem;
|
||||
padding: .35rem .5rem .35rem 2rem;
|
||||
border: 1px solid transparent;
|
||||
border-radius: 6px;
|
||||
counter-increment: nj-patch;
|
||||
line-height: 1.5;
|
||||
}
|
||||
.md-typeset .nj-patch-ops > li::before {
|
||||
content: counter(nj-patch);
|
||||
position: absolute;
|
||||
top: .35rem;
|
||||
left: .6rem;
|
||||
color: var(--md-default-fg-color--lighter);
|
||||
font-weight: 600;
|
||||
font-variant-numeric: tabular-nums;
|
||||
}
|
||||
.md-typeset .nj-patch-ops code { font-size: .9em; overflow-wrap: anywhere; }
|
||||
.md-typeset .nj-patch-ops > li.is-done { opacity: .6; }
|
||||
.md-typeset .nj-patch-ops > li.is-cur {
|
||||
border-color: var(--md-typeset-a-color);
|
||||
background-color: var(--nj-blue-soft);
|
||||
}
|
||||
.md-typeset .nj-patch-ops > li.is-cur::before { color: var(--md-typeset-a-color); }
|
||||
.nj-patch-op { color: var(--nj-hl-keyword); font-weight: 600; }
|
||||
.nj-patch-path { color: var(--nj-pointer-s); }
|
||||
.md-typeset .nj-patch-ops > li.is-cur .nj-patch-path {
|
||||
padding: 0 .15rem;
|
||||
border-radius: 3px;
|
||||
background-color: var(--md-typeset-a-color);
|
||||
color: var(--md-default-bg-color);
|
||||
}
|
||||
.nj-patch-ctrl {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
gap: .4rem;
|
||||
margin-top: .9rem;
|
||||
}
|
||||
.md-typeset .nj-patch-btn {
|
||||
padding: .3rem .9rem;
|
||||
border: 1px solid var(--md-default-fg-color--lighter);
|
||||
border-radius: 6px;
|
||||
background-color: var(--md-default-bg-color);
|
||||
color: var(--md-default-fg-color);
|
||||
cursor: pointer;
|
||||
font: inherit;
|
||||
font-weight: 600;
|
||||
}
|
||||
.md-typeset .nj-patch-btn--primary {
|
||||
border-color: var(--md-typeset-a-color);
|
||||
background-color: var(--md-typeset-a-color);
|
||||
color: var(--md-default-bg-color);
|
||||
}
|
||||
.md-typeset .nj-patch-btn:disabled { opacity: .45; cursor: default; }
|
||||
.md-typeset .nj-patch-btn:focus-visible { outline: 2px solid var(--md-typeset-a-color); outline-offset: 2px; }
|
||||
.nj-patch-count {
|
||||
margin-left: auto;
|
||||
color: var(--md-default-fg-color--light);
|
||||
font-variant-numeric: tabular-nums;
|
||||
}
|
||||
.md-typeset .nj-patch-status {
|
||||
min-height: 3.2em;
|
||||
margin: .6rem 0 0;
|
||||
color: var(--md-default-fg-color--light);
|
||||
}
|
||||
@media (prefers-reduced-motion: no-preference) {
|
||||
.nj-patch-doc--anim :is(.nj-patch-line--add, .nj-patch-line--del, .nj-patch-line--test, .nj-patch-ins, .nj-patch-arc) {
|
||||
animation: nj-patch-in 450ms ease-out;
|
||||
}
|
||||
}
|
||||
@keyframes nj-patch-in {
|
||||
from { opacity: 0; transform: translateX(-.4rem); }
|
||||
to { opacity: 1; transform: none; }
|
||||
}
|
||||
|
||||
/* ---------- merge patch table ---------- */
|
||||
.nj-pointer-mpt {
|
||||
--nj-pointer-mp-set: var(--nj-hl-keyword);
|
||||
--nj-pointer-mp-add: #23793a;
|
||||
--nj-pointer-mp-del: var(--nj-red);
|
||||
--nj-pointer-mp-rec: var(--nj-hl-function);
|
||||
--nj-pointer-mp-arr: var(--nj-hl-number);
|
||||
--nj-pointer-mp-keep: var(--md-default-fg-color--light);
|
||||
}
|
||||
[data-md-color-scheme="slate"] .nj-pointer-mpt { --nj-pointer-mp-add: #7ed491; }
|
||||
.md-typeset .nj-pointer-mpt td { vertical-align: top; }
|
||||
.md-typeset .nj-pointer-mpt td:first-child { white-space: nowrap; }
|
||||
.nj-pointer-mp {
|
||||
display: inline-block;
|
||||
padding: .05rem .5rem;
|
||||
border: 1px solid currentColor;
|
||||
border-radius: 999px;
|
||||
background-color: color-mix(in srgb, currentColor 10%, var(--md-default-bg-color));
|
||||
font-size: .92em;
|
||||
font-weight: 600;
|
||||
line-height: 1.5;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.nj-pointer-mp--set { color: var(--nj-pointer-mp-set); }
|
||||
.nj-pointer-mp--add { color: var(--nj-pointer-mp-add); }
|
||||
.nj-pointer-mp--del { color: var(--nj-pointer-mp-del); }
|
||||
.nj-pointer-mp--rec { color: var(--nj-pointer-mp-rec); }
|
||||
.nj-pointer-mp--arr { color: var(--nj-pointer-mp-arr); }
|
||||
.nj-pointer-mp--keep { color: var(--nj-pointer-mp-keep); }
|
||||
.nj-pointer-mp-none { color: var(--md-default-fg-color--light); font-style: italic; }
|
||||
.md-typeset .nj-pointer-mpt table:not([class]) td code { white-space: normal; }
|
||||
.md-typeset .nj-pointer-mpt table:not([class]) td:nth-child(-n+2) code { white-space: nowrap; }
|
||||
/* the result cell takes a tint of the rule's colour */
|
||||
.md-typeset .nj-pointer-mpt tr:has(.nj-pointer-mp--set) td:last-child { background-color: color-mix(in srgb, var(--nj-pointer-mp-set) 8%, transparent); }
|
||||
.md-typeset .nj-pointer-mpt tr:has(.nj-pointer-mp--add) td:last-child { background-color: color-mix(in srgb, var(--nj-pointer-mp-add) 8%, transparent); }
|
||||
.md-typeset .nj-pointer-mpt tr:has(.nj-pointer-mp--del) td:last-child { background-color: color-mix(in srgb, var(--nj-pointer-mp-del) 8%, transparent); }
|
||||
.md-typeset .nj-pointer-mpt tr:has(.nj-pointer-mp--rec) td:last-child { background-color: color-mix(in srgb, var(--nj-pointer-mp-rec) 8%, transparent); }
|
||||
.md-typeset .nj-pointer-mpt tr:has(.nj-pointer-mp--arr) td:last-child { background-color: color-mix(in srgb, var(--nj-pointer-mp-arr) 8%, transparent); }
|
||||
@@ -1,207 +0,0 @@
|
||||
/* figures: sax (SAX event stepper on features/parsing/sax_interface.md, js/fig-sax.js; memory_over_time.svg and
|
||||
chunk_buffering.svg on features/parsing/large_and_partial_input.md). Event colours are the --cb-* variables of the
|
||||
parser-callback figure in brand.css, which .nj-fig provides. */
|
||||
|
||||
/* ---------- stepper ---------- */
|
||||
.md-typeset .nj-sax {
|
||||
display: grid;
|
||||
grid-template-columns: minmax(0, 1fr);
|
||||
gap: .9rem 1.4rem;
|
||||
margin: 1.5rem 0;
|
||||
padding: 1rem 1.1rem;
|
||||
border: 1px solid var(--md-default-fg-color--lightest);
|
||||
border-radius: 8px;
|
||||
background: var(--md-default-bg-color);
|
||||
font-size: .74rem;
|
||||
}
|
||||
@media screen and (min-width: 45em) {
|
||||
.md-typeset .nj-sax {
|
||||
grid-template-columns: minmax(0, 1fr) minmax(0, 1.15fr);
|
||||
grid-template-areas: "ctl ctl" "text text" "ev state" "status status";
|
||||
}
|
||||
.md-typeset .nj-sax > .nj-sax__controls { grid-area: ctl; }
|
||||
.md-typeset .nj-sax > .nj-sax__lane--text { grid-area: text; }
|
||||
.md-typeset .nj-sax > .nj-sax__lane--events { grid-area: ev; }
|
||||
.md-typeset .nj-sax > .nj-sax__lane--state { grid-area: state; }
|
||||
.md-typeset .nj-sax > .nj-sax__status { grid-area: status; }
|
||||
}
|
||||
.md-typeset .nj-sax p { margin: 0; }
|
||||
.md-typeset .nj-sax .nj-sax__h {
|
||||
margin: 0 0 .45rem;
|
||||
color: var(--md-default-fg-color--light);
|
||||
font-size: .68rem;
|
||||
font-weight: 600;
|
||||
letter-spacing: .02em;
|
||||
}
|
||||
.md-typeset .nj-sax .nj-sax__h code { font-size: .95em; }
|
||||
.md-typeset .nj-sax .nj-sax__text code {
|
||||
display: inline-block;
|
||||
max-width: 100%;
|
||||
overflow-x: auto;
|
||||
padding: .35rem .6rem;
|
||||
font-size: .95rem;
|
||||
white-space: pre;
|
||||
word-break: normal;
|
||||
}
|
||||
.nj-sax .nj-sax-unread { color: var(--md-default-fg-color--light); }
|
||||
.nj-sax .nj-sax-unread--never { color: var(--md-default-fg-color--lighter); text-decoration: line-through; text-decoration-color: var(--md-default-fg-color--lighter); }
|
||||
.nj-sax .nj-sax-read { color: var(--md-code-fg-color); }
|
||||
.nj-sax .nj-sax-tok { border-radius: 3px; box-shadow: inset 0 -3px 0 var(--nj-sax-ev, var(--cb-v)); background: color-mix(in srgb, var(--nj-sax-ev, var(--cb-v)) 22%, transparent); }
|
||||
.nj-sax .nj-sax-tok--os, .nj-sax .nj-sax-ev--os { --nj-sax-ev: var(--cb-os); }
|
||||
.nj-sax .nj-sax-tok--oe, .nj-sax .nj-sax-ev--oe { --nj-sax-ev: var(--cb-oe); }
|
||||
.nj-sax .nj-sax-tok--k, .nj-sax .nj-sax-ev--k { --nj-sax-ev: var(--cb-k); }
|
||||
.nj-sax .nj-sax-tok--as, .nj-sax .nj-sax-ev--as { --nj-sax-ev: var(--cb-as); }
|
||||
.nj-sax .nj-sax-tok--ae, .nj-sax .nj-sax-ev--ae { --nj-sax-ev: var(--cb-ae); }
|
||||
.nj-sax .nj-sax-tok--v, .nj-sax .nj-sax-ev--v { --nj-sax-ev: var(--cb-v); }
|
||||
|
||||
/* event ticker */
|
||||
.md-typeset .nj-sax ol.nj-sax__events {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
list-style: none;
|
||||
counter-reset: nj-sax;
|
||||
}
|
||||
.md-typeset .nj-sax ol.nj-sax__events > li {
|
||||
position: relative;
|
||||
margin: 0 0 .2rem;
|
||||
padding: .12rem .4rem .12rem 2.6rem;
|
||||
border-radius: 5px;
|
||||
counter-increment: nj-sax;
|
||||
line-height: 1.5;
|
||||
}
|
||||
.md-typeset .nj-sax ol.nj-sax__events > li::before {
|
||||
content: counter(nj-sax);
|
||||
position: absolute;
|
||||
left: .35rem;
|
||||
top: .2rem;
|
||||
width: 1.1rem;
|
||||
color: var(--md-default-fg-color--lighter);
|
||||
font-size: .64rem;
|
||||
font-variant-numeric: tabular-nums;
|
||||
text-align: right;
|
||||
}
|
||||
.md-typeset .nj-sax ol.nj-sax__events > li::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
left: 1.75rem;
|
||||
top: 50%;
|
||||
width: .55rem;
|
||||
height: .55rem;
|
||||
margin-top: -.275rem;
|
||||
border-radius: 50%;
|
||||
background: var(--nj-sax-ev);
|
||||
}
|
||||
.md-typeset .nj-sax ol.nj-sax__events code { background: none; padding: 0; font-size: .8rem; }
|
||||
.nj-sax .nj-sax-ev--todo { opacity: .42; }
|
||||
.nj-sax .nj-sax-ev--skip { opacity: .42; text-decoration: line-through; }
|
||||
.nj-sax .nj-sax-ev--skip::after { background: var(--md-default-fg-color--lighter) !important; }
|
||||
.nj-sax .nj-sax-ev--cur { background: color-mix(in srgb, var(--nj-sax-ev) 16%, transparent); }
|
||||
.md-typeset .nj-sax .nj-sax-ev--false > code::after {
|
||||
content: " \2192 false";
|
||||
color: var(--nj-red);
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
/* handler state */
|
||||
.md-typeset .nj-sax pre.nj-sax__tree { margin: 0 0 .6rem; }
|
||||
.md-typeset .nj-sax pre.nj-sax__tree > code { padding: .5rem .7rem; font-size: .76rem; line-height: 1.45; }
|
||||
.nj-sax .nj-sax-hit { border-radius: 3px; background: color-mix(in srgb, var(--nj-blue) 22%, transparent); box-shadow: 0 0 0 1px color-mix(in srgb, var(--nj-blue) 55%, transparent); }
|
||||
.nj-sax .nj-sax-dim { color: var(--md-default-fg-color--lighter); }
|
||||
.md-typeset .nj-sax .nj-sax__stackh { margin: 0 0 .3rem; color: var(--md-default-fg-color--light); font-size: .66rem; font-weight: 600; }
|
||||
.md-typeset .nj-sax ol.nj-sax__stack {
|
||||
display: flex;
|
||||
flex-direction: column-reverse;
|
||||
gap: .25rem;
|
||||
margin: 0 0 .6rem;
|
||||
padding: 0;
|
||||
list-style: none;
|
||||
}
|
||||
.md-typeset .nj-sax ol.nj-sax__stack > li {
|
||||
margin: 0;
|
||||
padding: .2rem .5rem;
|
||||
border: 1px solid var(--md-default-fg-color--lightest);
|
||||
border-left: 3px solid var(--nj-blue);
|
||||
border-radius: 4px;
|
||||
}
|
||||
.md-typeset .nj-sax ol.nj-sax__stack > li.nj-sax-dim { border-left-color: var(--md-default-fg-color--lightest); }
|
||||
.md-typeset .nj-sax ol.nj-sax__stack code { background: none; padding: 0; }
|
||||
.md-typeset .nj-sax .nj-sax__note { color: var(--md-default-fg-color--light); font-size: .75rem; line-height: 1.5; }
|
||||
.md-typeset .nj-sax dl.nj-sax__kv {
|
||||
display: grid;
|
||||
grid-template-columns: auto minmax(0, 1fr);
|
||||
gap: .35rem .8rem;
|
||||
margin: 0 0 .6rem;
|
||||
}
|
||||
.md-typeset .nj-sax dl.nj-sax__kv dt { color: var(--md-default-fg-color--light); font-weight: 600; }
|
||||
.md-typeset .nj-sax dl.nj-sax__kv dd { margin: 0; }
|
||||
|
||||
/* controls */
|
||||
.nj-sax .nj-sax__controls { display: flex; flex-wrap: wrap; gap: .5rem 1rem; align-items: center; }
|
||||
.nj-sax .nj-sax__btns, .nj-sax .nj-sax__modes { display: flex; flex-wrap: wrap; gap: .35rem; }
|
||||
.nj-sax .nj-sax__modes { margin-left: auto; }
|
||||
.md-typeset .nj-sax .nj-sax-btn {
|
||||
min-height: 2.2rem;
|
||||
padding: .3rem .8rem;
|
||||
border: 1px solid color-mix(in srgb, var(--nj-blue) 55%, var(--md-default-bg-color));
|
||||
border-radius: 6px;
|
||||
background: var(--md-default-bg-color);
|
||||
color: var(--nj-blue);
|
||||
font: inherit;
|
||||
font-weight: 600;
|
||||
cursor: pointer;
|
||||
}
|
||||
.md-typeset .nj-sax .nj-sax-btn:hover:not(:disabled) { background: color-mix(in srgb, var(--nj-blue) 10%, var(--md-default-bg-color)); }
|
||||
.md-typeset .nj-sax .nj-sax-btn--main, .md-typeset .nj-sax .nj-sax-btn[aria-pressed="true"] {
|
||||
border-color: var(--nj-band);
|
||||
background: var(--nj-band);
|
||||
color: #fff;
|
||||
}
|
||||
.md-typeset .nj-sax .nj-sax-btn--main:hover:not(:disabled), .md-typeset .nj-sax .nj-sax-btn[aria-pressed="true"]:hover {
|
||||
background: var(--md-primary-fg-color--light);
|
||||
}
|
||||
.md-typeset .nj-sax .nj-sax-btn:disabled { opacity: .4; cursor: default; }
|
||||
.md-typeset .nj-sax .nj-sax-btn:focus-visible, .nj-sax .nj-sax__stop input:focus-visible {
|
||||
outline: 2px solid var(--nj-blue);
|
||||
outline-offset: 2px;
|
||||
}
|
||||
.nj-sax .nj-sax__stop { display: inline-flex; gap: .45rem; align-items: center; min-height: 2.2rem; cursor: pointer; }
|
||||
.nj-sax .nj-sax__stop input { width: 1.05rem; height: 1.05rem; margin: 0; accent-color: var(--nj-red); }
|
||||
.nj-sax .nj-sax__stop:has(input:disabled) { opacity: .45; cursor: default; }
|
||||
.md-typeset .nj-sax .nj-sax__status {
|
||||
padding-top: .6rem;
|
||||
border-top: 1px solid var(--md-default-fg-color--lightest);
|
||||
color: var(--md-default-fg-color--light);
|
||||
font-size: .72rem;
|
||||
min-height: 2.6em;
|
||||
}
|
||||
@media screen and (max-width: 44.984375em) {
|
||||
.md-typeset .nj-sax { padding: .8rem; }
|
||||
.md-typeset .nj-sax .nj-sax-btn { min-height: 44px; min-width: 44px; }
|
||||
.nj-sax .nj-sax__stop { min-height: 44px; }
|
||||
.nj-sax .nj-sax__modes { margin-left: 0; }
|
||||
}
|
||||
@media (prefers-reduced-motion: no-preference) {
|
||||
.nj-sax .nj-sax__events > li { transition: opacity .2s, background-color .2s; }
|
||||
}
|
||||
|
||||
/* ---------- static SVG figures ---------- */
|
||||
.md-typeset svg.nj-fig--sax-mem { min-width: 34rem; max-width: 40rem; }
|
||||
.md-typeset svg.nj-fig--sax-buf { min-width: 36rem; max-width: 42rem; }
|
||||
.nj-fig .nj-sax-axis { fill: none; stroke: var(--fg-line); stroke-width: 1.5; }
|
||||
.nj-fig .nj-sax-illus { font-style: italic; }
|
||||
.nj-fig .nj-sax-curve { fill: none; stroke-width: 3; stroke-linecap: round; stroke-linejoin: round; }
|
||||
.nj-fig .nj-sax-c-dom { --nj-sax-c: var(--nj-red); }
|
||||
.nj-fig .nj-sax-c-doc { --nj-sax-c: var(--nj-hl-type); }
|
||||
.nj-fig .nj-sax-c-cb { --nj-sax-c: var(--nj-hl-number); }
|
||||
.nj-fig .nj-sax-c-sax { --nj-sax-c: var(--nj-blue); }
|
||||
.nj-fig .nj-sax-curve.nj-sax-c-doc { stroke-dasharray: 9 5; }
|
||||
.nj-fig .nj-sax-curve { stroke: var(--nj-sax-c); }
|
||||
.nj-fig .nj-sax-lab { fill: var(--nj-sax-c); font-size: 14.5px; font-weight: 700; }
|
||||
.nj-fig .nj-sax-old { fill: color-mix(in srgb, currentColor 10%, var(--md-default-bg-color)); }
|
||||
.nj-fig .nj-sax-new { fill: color-mix(in srgb, var(--md-typeset-a-color) 18%, var(--md-default-bg-color)); stroke: var(--md-typeset-a-color); stroke-width: 1; }
|
||||
.nj-fig .nj-sax-buf { fill: currentColor; font-family: var(--md-code-font-family), monospace; font-size: 14px; white-space: pre; }
|
||||
.nj-fig .nj-sax-sep { stroke: var(--fg-line); stroke-width: 1; stroke-dasharray: 3 3; }
|
||||
.nj-fig .nj-sax-status { font-size: 14px; font-weight: 600; }
|
||||
.nj-fig .nj-sax-s-wait { fill: var(--nj-blue); }
|
||||
.nj-fig .nj-sax-s-ok { fill: var(--nj-hl-string); }
|
||||
.nj-fig .nj-sax-s-err { fill: var(--nj-red); }
|
||||
@@ -1 +0,0 @@
|
||||
<svg xmlns='http://www.w3.org/2000/svg' width='160' height='160'><g font-family='Menlo,monospace' font-size='26' font-weight='600' fill='#ffffff' fill-opacity='0.10'><text x='14' y='34'>{</text><text x='92' y='22'>]</text><text x='136' y='60'>:</text><text x='52' y='82'>[</text><text x='118' y='112'>,</text><text x='20' y='140'>}</text><text x='78' y='150'>:</text><text x='140' y='158'>{</text></g></svg>
|
||||
|
Before Width: | Height: | Size: 408 B |
@@ -0,0 +1,33 @@
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
using json = nlohmann::json;
|
||||
|
||||
void print_hex(const char* label, const std::vector<std::uint8_t>& v)
|
||||
{
|
||||
std::cout << label << ':';
|
||||
for (auto b : v)
|
||||
{
|
||||
std::cout << ' ' << std::hex << std::setw(2) << std::setfill('0') << static_cast<int>(b);
|
||||
}
|
||||
std::cout << std::dec << std::setfill(' ') << '\n';
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
// a binary value
|
||||
json j = json::binary({0xCA, 0xFE, 0xBA, 0xBE});
|
||||
|
||||
// Draft 2 (the default) writes an array of integers
|
||||
auto v2 = json::to_bjdata(j, true, true, json::bjdata_version_t::draft2);
|
||||
print_hex("draft2", v2);
|
||||
|
||||
// Draft 3 writes an optimized binary array
|
||||
auto v3 = json::to_bjdata(j, true, true, json::bjdata_version_t::draft3);
|
||||
print_hex("draft3", v3);
|
||||
|
||||
// reading yields an array for Draft 2 and a binary value for Draft 3
|
||||
std::cout << json::from_bjdata(v2) << '\n';
|
||||
std::cout << json::from_bjdata(v3) << '\n';
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
draft2: 5b 24 55 23 69 04 ca fe ba be
|
||||
draft3: 5b 24 42 23 69 04 ca fe ba be
|
||||
[202,254,186,190]
|
||||
{"bytes":[202,254,186,190],"subtype":null}
|
||||
@@ -124,28 +124,26 @@ For all the macros, the first parameter is the name of the class/struct. The `DE
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A["choosing a NLOHMANN_DEFINE_* macro"] --> B{{"adding fields to a base class?"}}
|
||||
A["choosing a NLOHMANN_DEFINE_* macro"] --> B{"adding fields to a base class?"}
|
||||
B -->|"yes"| C["...DERIVED_TYPE..."]
|
||||
B -->|"no"| D["...TYPE..."]
|
||||
C --> E{{"need access to private members?"}}
|
||||
C --> E{"need access to private members?"}
|
||||
D --> E
|
||||
E -->|"yes"| F["...INTRUSIVE... (used inside the class)"]
|
||||
E -->|"no"| G["...NON_INTRUSIVE... (used in the namespace)"]
|
||||
F --> H{{"only serializing, never parsing back?"}}
|
||||
F --> H{"only serializing, never parsing back?"}
|
||||
G --> H
|
||||
H -->|"yes"| I["...ONLY_SERIALIZE"]
|
||||
H -->|"no"| J{{"allow missing keys when parsing?"}}
|
||||
H -->|"no"| J{"allow missing keys when parsing?"}
|
||||
J -->|"yes"| K["...WITH_DEFAULT"]
|
||||
J -->|"no"| L["plain (missing keys throw)"]
|
||||
I --> M{{"need custom JSON key names?"}}
|
||||
I --> M{"need custom JSON key names?"}
|
||||
K --> M
|
||||
L --> M
|
||||
M -->|"yes"| N["...WITH_NAMES"]
|
||||
M -->|"no"| O["done"]
|
||||
```
|
||||
|
||||
<p class="nj-caption" markdown>Decision tree for choosing a `NLOHMANN_DEFINE_*` macro: answer the questions from top to bottom; each answer picks one part of the macro name, and the parts are combined in this order. The table below lists the resulting macros.</p>
|
||||
|
||||
| Need access to private members | Need only serialization | Allow missing values when de-serializing | macro |
|
||||
|------------------------------------------------------------------|------------------------------------------------------------------|------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------|
|
||||
| <div style="color: green;">:octicons-check-circle-fill-24:</div> | <div style="color: red;">:octicons-x-circle-fill-24:</div> | <div style="color: red;">:octicons-x-circle-fill-24:</div> | [**NLOHMANN_DEFINE_TYPE_INTRUSIVE**](../api/macros/nlohmann_define_type_intrusive.md) |
|
||||
@@ -155,8 +153,6 @@ flowchart TD
|
||||
| <div style="color: red;">:octicons-x-circle-fill-24:</div> | <div style="color: red;">:octicons-x-circle-fill-24:</div> | <div style="color: green;">:octicons-check-circle-fill-24:</div> | [**NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT**](../api/macros/nlohmann_define_type_non_intrusive.md) |
|
||||
| <div style="color: red;">:octicons-x-circle-fill-24:</div> | <div style="color: green;">:octicons-check-circle-fill-24:</div> | <div style="color: grey;">:octicons-skip-fill-24:</div> | [**NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE**](../api/macros/nlohmann_define_type_non_intrusive.md) |
|
||||
|
||||
<p class="nj-table-caption" markdown>Macros for classes and structs without a base class. A green check means yes, a red cross means no, and a grey skip sign means the column does not apply, as a macro that only serializes never reads values.</p>
|
||||
|
||||
For _derived_ classes and structs, use the following macros
|
||||
|
||||
| Need access to private members | Need only serialization | Allow missing values when de-serializing | macro |
|
||||
@@ -168,33 +164,12 @@ For _derived_ classes and structs, use the following macros
|
||||
| <div style="color: red;">:octicons-x-circle-fill-24:</div> | <div style="color: red;">:octicons-x-circle-fill-24:</div> | <div style="color: green;">:octicons-check-circle-fill-24:</div> | [**NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_WITH_DEFAULT**](../api/macros/nlohmann_define_derived_type.md) |
|
||||
| <div style="color: red;">:octicons-x-circle-fill-24:</div> | <div style="color: green;">:octicons-check-circle-fill-24:</div> | <div style="color: grey;">:octicons-skip-fill-24:</div> | [**NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE**](../api/macros/nlohmann_define_derived_type.md) |
|
||||
|
||||
<p class="nj-table-caption" markdown>Macros for derived classes and structs, read as Table 1.</p>
|
||||
|
||||
!!! info "Implementation limits"
|
||||
|
||||
- The current macro implementations are limited to at most 63 member variables. If you want to serialize/deserialize
|
||||
types with more than 63 member variables, you need to define the `to_json`/`from_json` functions manually.
|
||||
- For the `WITH_NAMES` variants the limit is halved to 31 member variables.
|
||||
|
||||
To pick the macro for your own type and get code to start from, answer the questions below.
|
||||
|
||||
<div class="nj-macro-chooser" data-variant="full" markdown>
|
||||
<div class="nj-mc-fallback" markdown>
|
||||
|
||||
- Members are private: use an `INTRUSIVE` macro inside the class ([reference](../api/macros/nlohmann_define_type_intrusive.md){ data-nj-mc="intrusive" }).
|
||||
- All members are public, or you cannot edit the class: use a `NON_INTRUSIVE` macro in the class's namespace ([reference](../api/macros/nlohmann_define_type_non_intrusive.md){ data-nj-mc="non_intrusive" }).
|
||||
- The class adds members to a serializable base class: use a `DERIVED_TYPE` macro with the base class as second argument ([reference](../api/macros/nlohmann_define_derived_type.md){ data-nj-mc="derived" }).
|
||||
- Missing keys should keep their default values: append `_WITH_DEFAULT`; otherwise a missing key throws.
|
||||
- You only convert to JSON: append `_ONLY_SERIALIZE` instead.
|
||||
- JSON keys differ from the member names: append `_WITH_NAMES` and write `"key", member` pairs ([reference](../api/macros/nlohmann_define_type_with_names.md){ data-nj-mc="with_names" }).
|
||||
- Private members of a class you cannot edit: no macro works; write the conversion by hand ([third-party types](#how-do-i-convert-third-party-types){ data-nj-mc="third_party" }).
|
||||
- The type is not default constructible and is converted in both directions: no macro works; specialize `adl_serializer` with a `from_json` that returns the value, or append `_ONLY_SERIALIZE` if you only convert to JSON ([non-default-constructible types](#how-can-i-use-get-for-non-default-constructiblenon-copyable-types){ data-nj-mc="non_default" }).
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p class="nj-caption" markdown>Macro chooser: each answer selects one part of the macro name; the generated program defines the type, calls the macro and converts a value to JSON and back. Combinations that no macro supports show the alternative instead of code.</p>
|
||||
|
||||
??? example "Example: using the `NLOHMANN_DEFINE_TYPE_*` macros"
|
||||
|
||||
The `to_json`/`from_json` functions for the `person` struct above can be created with:
|
||||
@@ -324,8 +299,6 @@ flowchart LR
|
||||
B -->|"user specialization replaces the default"| E["user's adl_serializer specialization for T"]
|
||||
```
|
||||
|
||||
<p class="nj-caption" markdown>How a conversion between `json` and a type `T` is dispatched: the default `adl_serializer` calls the free `to_json`/`from_json` functions found by argument-dependent lookup, while a user specialization of `adl_serializer` replaces this path.</p>
|
||||
|
||||
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](https://en.cppreference.com/w/cpp/language/adl)).
|
||||
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
|
||||
The [BJData format](https://neurojson.org) was derived from and improved upon
|
||||
[Universal Binary JSON(UBJSON)](https://ubjson.org) 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
|
||||
array container for efficient storage of N-dimensional packed arrays (**ND-arrays**); it also adds four new type markers -
|
||||
`[u] - uint16`, `[m] - uint32`, `[M] - uint64`, and `[h] - float16` - to unambiguously map common binary numeric types
|
||||
(Draft 3 adds `[B] - byte`); furthermore, it uses little-endian (LE) to store all numerics instead of big-endian (BE) as in UBJSON to
|
||||
avoid unnecessary conversions on commonly available platforms.
|
||||
|
||||
Compared to other binary JSON-like formats such as MessagePack and CBOR, both BJData and UBJSON demonstrate a rare
|
||||
@@ -15,11 +15,30 @@ simple processing.
|
||||
|
||||
!!! abstract "References"
|
||||
|
||||
- [BJData Specification](https://neurojson.org/bjdata/draft2)
|
||||
- [BJData Specification (Draft 3)](https://neurojson.org/bjdata/draft3)
|
||||
- [BJData Specification (Draft 2)](https://neurojson.org/bjdata/draft2)
|
||||
|
||||
!!! info "Supported drafts"
|
||||
|
||||
The library supports BJData Draft 2 (the default) and Draft 3, except for column-major N-dimensional arrays (see
|
||||
below). The draft used for writing is selected with the
|
||||
[`version` parameter](../../api/basic_json/bjdata_version_t.md) of
|
||||
[`to_bjdata`](../../api/basic_json/to_bjdata.md); [`from_bjdata`](../../api/basic_json/from_bjdata.md) has no such
|
||||
parameter and reads the markers of both drafts.
|
||||
|
||||
!!! warning "Draft 4 and column-major ND-arrays are not supported"
|
||||
|
||||
BJData Draft 4 (April 2026) adds structure-of-arrays (SoA) containers (`[$` or `{$` followed by a schema object)
|
||||
and the extension type `E`. `from_bjdata` does not implement them and throws
|
||||
[`parse_error.112`](../../home/exceptions.md#jsonexceptionparse_error112) for such input; `to_bjdata` never writes
|
||||
them.
|
||||
|
||||
Likewise, column-major ND-arrays of Draft 3 (the `#` marker followed by an array that wraps the dimension vector)
|
||||
are rejected with [`parse_error.113`](../../home/exceptions.md#jsonexceptionparse_error113).
|
||||
|
||||
## Byte layout
|
||||
|
||||
BJData follows the structure of UBJSON: a one-byte, human-readable ASCII *type marker* followed by the payload of that type, with strings prefixed by a length that is itself an integer value. In contrast to UBJSON, numbers are stored in little-endian byte order, and additional markers cover unsigned 16/32/64-bit integers, half-precision floats, and bytes. Containers can be written unoptimized (opened with `[` or `{`, closed with `]` or `}`) or optimized with a declared element type (`$`) and/or count (`#`). BJData extends the optimized form: the count can be a list of dimensions, which stores an N-dimensional packed array as a flat sequence of values without any per-element markers.
|
||||
BJData follows the structure of UBJSON: a one-byte, human-readable ASCII *type marker* followed by the payload of that type, with strings prefixed by a length that is itself an integer value. In contrast to UBJSON, numbers are stored in little-endian byte order, and additional markers cover unsigned 16/32/64-bit integers, half-precision floats, and bytes. Containers can be written unoptimized (opened with `[` or `{`, closed with `]` or `}`) or optimized with a count (`#`), optionally preceded by a declared element type (`$`). BJData extends the optimized form: the count can be a list of dimensions, which stores an N-dimensional packed array as a flat sequence of values without any per-element markers.
|
||||
|
||||
Consider the following JSON value (shown formatted for readability):
|
||||
|
||||
@@ -54,35 +73,35 @@ Consider the following JSON value (shown formatted for readability):
|
||||
|
||||
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` |
|
||||
| JSON value type | value/range | BJData type | marker |
|
||||
|-----------------|-------------------------------------------|-------------|-------------------------------------------------------------------------|
|
||||
| null | `null` | null | `Z` |
|
||||
| boolean | `true` | true | `T` |
|
||||
| boolean | `false` | false | `F` |
|
||||
| number_integer | -9223372036854775808..-2147483649 | int64 | `L` |
|
||||
| number_integer | -2147483648..-32769 | int32 | `l` |
|
||||
| number_integer | -32768..-129 | int16 | `I` |
|
||||
| number_integer | -128..127 | int8 | `i` |
|
||||
| number_integer | 128..255 | uint8 | `U` |
|
||||
| number_integer | 256..32767 | int16 | `I` |
|
||||
| number_integer | 32768..65535 | uint16 | `u` |
|
||||
| number_integer | 65536..2147483647 | int32 | `l` |
|
||||
| number_integer | 2147483648..4294967295 | uint32 | `m` |
|
||||
| number_integer | 4294967296..9223372036854775807 | int64 | `L` |
|
||||
| number_integer | 9223372036854775808..18446744073709551615 | uint64 | `M` |
|
||||
| number_unsigned | 0..127 | int8 | `i` |
|
||||
| number_unsigned | 128..255 | uint8 | `U` |
|
||||
| number_unsigned | 256..32767 | int16 | `I` |
|
||||
| number_unsigned | 32768..65535 | uint16 | `u` |
|
||||
| number_unsigned | 65536..2147483647 | int32 | `l` |
|
||||
| number_unsigned | 2147483648..4294967295 | uint32 | `m` |
|
||||
| number_unsigned | 4294967296..9223372036854775807 | int64 | `L` |
|
||||
| number_unsigned | 9223372036854775808..18446744073709551615 | uint64 | `M` |
|
||||
| number_float | *any value* | float64 | `D` |
|
||||
| string | *with shortest length indicator* | string | `S` |
|
||||
| array | *see notes on optimized format/ND-array* | array | `[` |
|
||||
| object | *see notes on optimized format* | map | `{` |
|
||||
| binary | *see notes on binary values* | array | `[$B` (Draft 3 with `use_size` and `use_type`), `[U`, or `[B` otherwise |
|
||||
|
||||
!!! success "Complete mapping"
|
||||
|
||||
@@ -107,10 +126,16 @@ The library uses the following mapping from JSON values types to BJData types ac
|
||||
|
||||
!!! info "Unused BJData markers"
|
||||
|
||||
The following markers are not used in the conversion:
|
||||
The following markers are not written:
|
||||
|
||||
- `Z`: no-op values are not created.
|
||||
- `C`: single-byte strings are serialized with `S` markers.
|
||||
- `N`: no-op values are not created (they are skipped when reading).
|
||||
- `C`: single-character strings are serialized with `S` markers (`C` is read, and written for the elements of
|
||||
ND-arrays with `"_ArrayType_": "char"`).
|
||||
- `h`: floating-point numbers are written as `D`, not as float16 (`h` is read).
|
||||
- `B`: only written in Draft 3 mode.
|
||||
- `d` is only written for `single` ND-arrays or if `number_float_t` is `float`; `H` is only written for integers
|
||||
wider than 64 bits (custom `number_integer_t`/`number_unsigned_t`). An unsigned integer above 9223372036854775807
|
||||
is written as `M`.
|
||||
|
||||
!!! info "NaN/infinity handling"
|
||||
|
||||
@@ -142,7 +167,7 @@ The library uses the following mapping from JSON values types to BJData types ac
|
||||
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`.
|
||||
`[$U#[$i#i2 3 2 1 2 3 4 5 6` or `[$U#[i3 i2] 1 2 3 4 5 6`.
|
||||
|
||||
To maintain type and size information, ND-arrays are converted to JSON objects following the **annotated array
|
||||
format** (defined in the [JData specification (Draft 3)][JDataAAFmt]), when parsed using
|
||||
@@ -152,11 +177,14 @@ The library uses the following mapping from JSON values types to BJData types ac
|
||||
```json
|
||||
{
|
||||
"_ArrayType_": "uint8",
|
||||
"_ArraySize_": [2,3],
|
||||
"_ArraySize_": [3,2],
|
||||
"_ArrayData_": [1,2,3,4,5,6]
|
||||
}
|
||||
```
|
||||
|
||||
ND-arrays with the element type `h` (float16) are returned with `"_ArrayType_": "half"`. `to_bjdata` does not pack
|
||||
`"half"` objects; they are written as regular objects, which read back as an equal value.
|
||||
|
||||
Likewise, when a JSON object in the above form is serialized using
|
||||
[`to_bjdata`](../../api/basic_json/to_bjdata.md), it is automatically converted into a compact BJData ND-array.
|
||||
|
||||
@@ -167,34 +195,40 @@ The library uses the following mapping from JSON values types to BJData types ac
|
||||
object; otherwise it is serialized as a regular JSON object, so the annotation is never lost in a round trip. This requires
|
||||
all of the following:
|
||||
|
||||
- the object has exactly the three keys `"_ArrayType_"`, `"_ArraySize_"`, and `"_ArrayData_"` (any other key, e.g.,
|
||||
`"_ArrayOrder_"`, makes it a regular object),
|
||||
- `"_ArrayType_"` is one of `uint8`, `int8`, `uint16`, `int16`, `uint32`, `int32`, `uint64`, `int64`, `single`,
|
||||
`double`, `char`, or `byte`,
|
||||
`double`, `char`, or (only with `version = bjdata_version_t::draft3`, since the `B` marker is not part of Draft 2)
|
||||
`byte`; the names are case-sensitive,
|
||||
- `"_ArraySize_"` is an array, since the dimensions are written as the ND-array header's length,
|
||||
- `"_ArraySize_"` has at least two entries and is not a 1×N row vector (first entry 1), since other shapes are
|
||||
parsed back as a regular array,
|
||||
- `"_ArraySize_"` has at least two entries and is not a two-entry row vector (`[1,N]`), since other shapes are
|
||||
parsed back as a regular array (`[1,2,2]` is packed, `[1,4]` is not),
|
||||
- every entry of `"_ArraySize_"` is a positive integer, and their product is representable as a `std::size_t`,
|
||||
- `"_ArrayData_"` is an array holding exactly that many elements, and
|
||||
- every element of `"_ArrayData_"` is a number of the kind named by `"_ArrayType_"`: for the integer types, 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`).
|
||||
- every element of `"_ArrayData_"` is a number of the kind named by `"_ArrayType_"`: for the integer types, an
|
||||
integer (a floating-point number such as `1.0` does not qualify) that fits the named width (for `char`, 0..127);
|
||||
for `double`, a floating-point number (an integer such as `1` does not qualify); for `single`, a floating-point
|
||||
number that survives narrowing to `float` and back without change (for instance, `0.1` does not, since it is not
|
||||
exactly representable as `float`).
|
||||
|
||||
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.
|
||||
With `ordered_json`, an annotated object read from BJData has its keys in the order `"_ArrayType_"`,
|
||||
`"_ArraySize_"`, `"_ArrayData_"`; with `json`, they are sorted like those of any other object.
|
||||
|
||||
The current version of this library does not yet support automatic detection of and conversion from a nested JSON
|
||||
array input to a BJData ND-array.
|
||||
|
||||
[JDataAAFmt]: https://github.com/NeuroJSON/jdata/blob/master/JData_specification.md#annotated-storage-of-n-d-arrays
|
||||
[JDataAAFmt]: https://github.com/NeuroJSON/jdata/blob/Draft-3/JData_specification.md#annotated-storage-of-n-d-arrays
|
||||
|
||||
!!! info "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
|
||||
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.
|
||||
`UiuImlMLhdDC`, plus `B` since Draft 3 (the reader accepts `B` in both drafts). This also means other variable (`[{SH`) or zero-length types (`TFZN`) can not be used in an
|
||||
optimized array or object in BJData. The library enforces this restriction for both drafts. A `C` (char) element above 127 is rejected on read with
|
||||
[`parse_error.113`](../../home/exceptions.md#jsonexceptionparse_error113), in 1-D and in N-dimensional arrays. With `use_type`, the
|
||||
elements must have the same marker (`[1,200,3]` is not optimized, since it mixes `i` and `U`); booleans, null,
|
||||
strings, arrays, and objects are never optimized with `$`.
|
||||
|
||||
!!! info "Binary values"
|
||||
|
||||
@@ -202,14 +236,16 @@ The library uses the following mapping from JSON values types to BJData types ac
|
||||
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`](../../api/basic_json/to_bjdata.md).
|
||||
To preserve compatibility with BJData Draft 2, the Draft 3 optimized binary array must be explicitly enabled: pass
|
||||
`version = bjdata_version_t::draft3` together with `use_size = true` and `use_type = true` to
|
||||
[`to_bjdata`](../../api/basic_json/to_bjdata.md). With Draft 3 and only `use_size` (or neither), a binary value is
|
||||
written as an array of `B` elements.
|
||||
|
||||
In Draft2 mode (default), if the JSON data contains the binary type, the value stored as a list of integers, as
|
||||
In Draft 2 mode (default), if the JSON data contains the binary type, the value is stored as a list of integers, as
|
||||
suggested by the BJData documentation. In particular, this means that the serialization and the deserialization of
|
||||
JSON containing binary values into BJData and back will result in a different JSON object.
|
||||
|
||||
[BJDataBinArr]: https://github.com/NeuroJSON/bjdata/blob/master/Binary_JData_Specification.md#optimized-binary-array
|
||||
[BJDataBinArr]: https://github.com/NeuroJSON/bjdata/blob/Draft-3/Binary_JData_Specification.md#optimized-binary-array
|
||||
|
||||
??? example "Example: serialize JSON values to BJData, with and without size/type optimization"
|
||||
|
||||
@@ -227,34 +263,46 @@ The library uses the following mapping from JSON values types to BJData types ac
|
||||
|
||||
The library maps BJData types to JSON value types as follows:
|
||||
|
||||
| BJData type | JSON value type | marker |
|
||||
|-------------|------------------------------------------|----------|
|
||||
| no-op | *no value, next value is read* | `N` |
|
||||
| null | `null` | `Z` |
|
||||
| false | `false` | `F` |
|
||||
| true | `true` | `T` |
|
||||
| float16 | number_float | `h` |
|
||||
| float32 | number_float | `d` |
|
||||
| float64 | number_float | `D` |
|
||||
| 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` |
|
||||
| BJData type | JSON value type | marker |
|
||||
|-----------------------|--------------------------------------------------|----------|
|
||||
| no-op | *no value, next value is read* | `N` |
|
||||
| null | `null` | `Z` |
|
||||
| false | `false` | `F` |
|
||||
| true | `true` | `T` |
|
||||
| float16 | number_float | `h` |
|
||||
| float32 | number_float | `d` |
|
||||
| float64 | number_float | `D` |
|
||||
| high-precision number | number_integer, number_unsigned, or number_float | `H` |
|
||||
| uint8 | number_unsigned | `U` |
|
||||
| int8 | number_integer | `i` |
|
||||
| uint16 | number_unsigned | `u` |
|
||||
| int16 | number_integer | `I` |
|
||||
| uint32 | number_unsigned | `m` |
|
||||
| int32 | number_integer | `l` |
|
||||
| uint64 | number_unsigned | `M` |
|
||||
| int64 | number_integer | `L` |
|
||||
| byte | number_unsigned | `B` |
|
||||
| string | string | `S` |
|
||||
| char | string | `C` |
|
||||
| array | array (optimized values are supported) | `[` |
|
||||
| ND-array | object (in JData annotated array format) | `[$.#[.` |
|
||||
| object | object (optimized values are supported) | `{` |
|
||||
| binary | binary (strongly-typed byte array) | `[$B` |
|
||||
|
||||
!!! success "Complete mapping"
|
||||
|
||||
The mapping is **complete** in the sense that any BJData value can be converted to a JSON value.
|
||||
The mapping is **complete** for the BJData types of Draft 2 and Draft 3 with one exception: column-major
|
||||
N-dimensional arrays are rejected with [`parse_error.113`](../../home/exceptions.md#jsonexceptionparse_error113).
|
||||
The Draft 4 constructs (structure-of-arrays containers and the extension type `E`) are not supported either.
|
||||
|
||||
The digits of an `H` value are parsed like a JSON number: integers that fit 64 bits become `number_integer` or
|
||||
`number_unsigned`, anything else a `number_float`; invalid text throws
|
||||
[`parse_error.115`](../../home/exceptions.md#jsonexceptionparse_error115).
|
||||
|
||||
!!! info "Duplicate object keys"
|
||||
|
||||
If an object contains the same key more than once, `from_bjdata` accepts it and keeps the last value; with
|
||||
`ordered_json`, the key keeps the position of its first occurrence.
|
||||
|
||||
!!! warning "Ill-formed UTF-8 in string values and object keys"
|
||||
|
||||
|
||||
@@ -66,7 +66,12 @@ The library uses the following mapping from JSON values types to BSON types:
|
||||
!!! warning "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.
|
||||
Also, keys may not contain U+0000, since they are serialized as zero-terminated C strings.
|
||||
|
||||
!!! info "Order of object members"
|
||||
|
||||
The members of an object are written in the order in which iteration visits them: sorted by key for
|
||||
[`json`](../../api/json.md), in insertion order for [`ordered_json`](../../api/ordered_json.md).
|
||||
|
||||
!!! warning "BSON type 0x11 interoperability"
|
||||
|
||||
@@ -81,6 +86,19 @@ The library uses the following mapping from JSON values types to BSON types:
|
||||
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.
|
||||
|
||||
!!! info "Binary subtype 0x02 (old binary)"
|
||||
|
||||
The BSON specification defines the payload of the "binary (old)" subtype `0x02` as an int32 followed by that many
|
||||
bytes, so the value is preceded by two lengths: the length of the binary element and, as the first four bytes of
|
||||
the payload, the number of bytes that follow. A binary value with subtype `2` is therefore written with the outer
|
||||
length 4 bytes larger than its size and the size as inner length: `binary({1, 2, 3}, 2)` becomes
|
||||
`07 00 00 00 02 03 00 00 00 01 02 03`. When reading, the inner length is checked and removed, so the value
|
||||
contains only the bytes that follow it. `from_bson()` throws
|
||||
[`parse_error.112`](../../home/exceptions.md#jsonexceptionparse_error112) if the outer length is less than 4 or the
|
||||
inner length is not the outer length minus 4. Versions before 3.13.0 did not write the inner length and returned
|
||||
it as part of the payload; BSON data written by those versions with subtype 2 is not readable any more and must be
|
||||
written again.
|
||||
|
||||
??? example "Example: serialize a JSON value to BSON"
|
||||
|
||||
```cpp
|
||||
@@ -135,12 +153,29 @@ The library maps BSON record types to JSON value types as follows:
|
||||
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.
|
||||
- any non-zero byte is accepted as `true` for the boolean type,
|
||||
- the payloads of the binary subtypes `0x03` (UUID, old), `0x04` (UUID), and `0x05` (MD5) are not checked to have
|
||||
16 bytes,
|
||||
- duplicate keys within a document are accepted; the last value wins (`{"a": 1, "a": 2}` is read as `{"a": 2}`),
|
||||
while a SAX handler receives every occurrence,
|
||||
- a `string` value may contain embedded `0x00` bytes, and
|
||||
- with `strict` set to `false`, bytes after the end of the document are ignored.
|
||||
|
||||
If BSON input must be validated for strict specification compliance, validate it separately before passing it to
|
||||
`from_bson()`.
|
||||
|
||||
!!! note "Document size"
|
||||
|
||||
Every document starts with its size. `from_bson()` rejects a document with
|
||||
[`parse_error.112`](../../home/exceptions.md#jsonexceptionparse_error112) if the size is less than 5 (the size prefix and the terminator), if an embedded document does not end before the
|
||||
end of the document that contains it, if the elements do not fit into the declared size, or if the size does not
|
||||
match the number of bytes read when the terminating `0x00` byte is reached. A size that is too small is detected
|
||||
before an element is read whose type byte and name no longer fit; an element that starts inside the declared size
|
||||
but extends past it is read, and reported to a SAX handler, before the mismatch is found at the terminator. A size
|
||||
that is too large is likewise found only at the terminator. Passing `strict` as `false` skips only the check for bytes after
|
||||
the end of the document ([`parse_error.110`](../../home/exceptions.md#jsonexceptionparse_error110)), not the
|
||||
document size checks.
|
||||
|
||||
!!! warning "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
|
||||
@@ -154,8 +189,9 @@ The library maps BSON record types to JSON value types as follows:
|
||||
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`](../../api/macros/json_strict_binary_utf8.md) 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.
|
||||
instead. Element (key) names are treated like string values: with `keep` they are read unchanged, with `strict`,
|
||||
`replace`, or `ignore` they are checked and handled in the same way. `binary` values (type `0x05`) are unaffected,
|
||||
since they are not required to hold text.
|
||||
|
||||
??? example "Example: deserialize a JSON value from BSON"
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ extremely small code sizes, fairly small message size, and extensibility without
|
||||
|
||||
## Byte layout
|
||||
|
||||
CBOR encodes every data item as a *head* followed by optional content. The first byte of the head holds the *major type* in its upper three bits (unsigned integer, negative integer, byte string, text string, array, map, tag, or simple/float) and an *additional information* value in its lower five bits. Additional information below 24 is the argument itself (for example, a small integer or a short length); the values 24 to 27 announce that the argument follows in 1, 2, 4, or 8 big-endian bytes. Strings, arrays, and maps are prefixed with their length (or count of elements/pairs), and content follows directly, so a reader always knows how many items to expect without a terminator.
|
||||
CBOR encodes every data item as a *head* followed by optional content. The first byte of the head holds the *major type* in its upper three bits (unsigned integer, negative integer, byte string, text string, array, map, tag, or simple/float) and an *additional information* value in its lower five bits. Additional information below 24 is the argument itself (for example, a small integer or a short length); the values 24 to 27 announce that the argument follows in 1, 2, 4, or 8 big-endian bytes. Strings, arrays, and maps are prefixed with their length (or count of elements/pairs), and content follows directly. A reader of definite-length items knows how many items to expect without a terminator; indefinite-length items (additional information 31) are instead closed by the "break" byte 0xFF, which `from_cbor` reads but `to_cbor` never writes.
|
||||
|
||||
Consider the following JSON value (shown formatted for readability):
|
||||
|
||||
@@ -52,16 +52,16 @@ The library uses the following mapping from JSON values types to CBOR types acco
|
||||
| null | `null` | Null | 0xF6 |
|
||||
| boolean | `true` | True | 0xF5 |
|
||||
| boolean | `false` | False | 0xF4 |
|
||||
| number_integer | -9223372036854775808..-2147483649 | Negative integer (8 bytes follow) | 0x3B |
|
||||
| number_integer | -2147483648..-32769 | Negative integer (4 bytes follow) | 0x3A |
|
||||
| number_integer | -32768..-129 | Negative integer (2 bytes follow) | 0x39 |
|
||||
| number_integer | -128..-25 | Negative integer (1 byte follow) | 0x38 |
|
||||
| number_integer | -9223372036854775808..-4294967297 | Negative integer (8 bytes follow) | 0x3B |
|
||||
| number_integer | -4294967296..-65537 | Negative integer (4 bytes follow) | 0x3A |
|
||||
| number_integer | -65536..-257 | Negative integer (2 bytes follow) | 0x39 |
|
||||
| number_integer | -256..-25 | Negative integer (1 byte follow) | 0x38 |
|
||||
| number_integer | -24..-1 | Negative integer | 0x20..0x37 |
|
||||
| number_integer | 0..23 | Integer | 0x00..0x17 |
|
||||
| number_integer | 24..255 | Unsigned integer (1 byte follow) | 0x18 |
|
||||
| number_integer | 256..65535 | Unsigned integer (2 bytes follow) | 0x19 |
|
||||
| number_integer | 65536..4294967295 | Unsigned integer (4 bytes follow) | 0x1A |
|
||||
| number_integer | 4294967296..18446744073709551615 | Unsigned integer (8 bytes follow) | 0x1B |
|
||||
| number_integer | 4294967296..9223372036854775807 | Unsigned integer (8 bytes follow) | 0x1B |
|
||||
| number_unsigned | 0..23 | Integer | 0x00..0x17 |
|
||||
| number_unsigned | 24..255 | Unsigned integer (1 byte follow) | 0x18 |
|
||||
| number_unsigned | 256..65535 | Unsigned integer (2 bytes follow) | 0x19 |
|
||||
@@ -95,7 +95,24 @@ see "binary" cells in the table above.
|
||||
|
||||
!!! success "Complete mapping"
|
||||
|
||||
The mapping is **complete** in the sense that any JSON value type can be converted to a CBOR value.
|
||||
The mapping is **complete** in the sense that any JSON value type can be converted to a CBOR value, with one
|
||||
exception: an integer outside the range of CBOR integers (only possible with a number type wider than 64 bits)
|
||||
throws [`out_of_range.407`](../../home/exceptions.md#jsonexceptionout_of_range407).
|
||||
|
||||
!!! info "Not a deterministic encoding"
|
||||
|
||||
`to_cbor` does not produce the deterministic encoding of
|
||||
[RFC 8949, Section 4.2.1](https://www.rfc-editor.org/rfc/rfc8949.html#section-4.2.1), and not always the preferred
|
||||
serialization of Section 4.1:
|
||||
|
||||
- floating-point numbers are written as single precision (0xFA) when that is exact and as double precision (0xFB)
|
||||
otherwise; half precision (0xF9) is used only for `NaN` and `Infinity`/`-Infinity` (`1.0` is `fa 3f 80 00 00`);
|
||||
- a binary subtype 0..23 is written as `d8 xx` instead of the one-byte tag 0xC0..0xD7 (`d8 01 41 01`);
|
||||
- object members are written in the order of `object_t` (for the default `std::map`: sorted by the key string, not
|
||||
by the encoded key bytes).
|
||||
|
||||
Integers and lengths use the shortest form, and indefinite-length items are never written. Decoders must accept all
|
||||
of this; the RFC does not require the preferred serialization.
|
||||
|
||||
!!! info "NaN/infinity handling"
|
||||
|
||||
@@ -105,9 +122,8 @@ see "binary" cells in the table above.
|
||||
|
||||
!!! note
|
||||
|
||||
Prior to version 3.13.0, 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.
|
||||
Prior to version 3.8.0, NaN and Infinity were instead serialized as a CBOR double-precision float (type 0xFB,
|
||||
9 bytes total).
|
||||
|
||||
!!! info "Unused CBOR types"
|
||||
|
||||
@@ -124,7 +140,6 @@ see "binary" cells in the table above.
|
||||
- expected conversions (0xD5..0xD7)
|
||||
- simple values (0xE0..0xF3, 0xF8)
|
||||
- undefined (0xF7)
|
||||
- half-precision floats (0xF9)
|
||||
- break (0xFF)
|
||||
|
||||
!!! info "Tagged items"
|
||||
@@ -226,10 +241,20 @@ string of the same major type, as required by [RFC 8949, Section 3.2.3](https://
|
||||
([RFC 8392](https://www.rfc-editor.org/rfc/rfc8392.html)), cannot be read with this library and need a
|
||||
general-purpose CBOR library instead.
|
||||
|
||||
A tag in front of a text string key is handled like a tag in front of a value: it is skipped with
|
||||
`cbor_tag_handler_t::ignore` or `cbor_tag_handler_t::store` and rejected with the default `error`. A tag does not
|
||||
turn a key of another type into a text string.
|
||||
|
||||
A map with duplicate keys is well-formed, but invalid under
|
||||
[RFC 8949, Section 5.3.1](https://www.rfc-editor.org/rfc/rfc8949.html#section-5.3.1). `from_cbor` accepts it and the
|
||||
last value wins; the [SAX interface](../parsing/sax_interface.md) reports every occurrence.
|
||||
|
||||
!!! warning "Ill-formed UTF-8 in text strings"
|
||||
|
||||
[RFC 8949, Section 3.1](https://www.rfc-editor.org/rfc/rfc8949.html#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
|
||||
type 3) to be valid UTF-8 (a string with ill-formed UTF-8 is "well-formed but invalid"), and
|
||||
[Section 5.3.1](https://www.rfc-editor.org/rfc/rfc8949.html#section-5.3.1) leaves it up to the decoder whether to
|
||||
verify this, so checking is opt-in: with the
|
||||
[`error_handler`](../../api/basic_json/from_cbor.md) 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
|
||||
@@ -242,9 +267,14 @@ string of the same major type, as required by [RFC 8949, Section 3.2.3](https://
|
||||
[`JSON_STRICT_BINARY_UTF8`](../../api/macros/json_strict_binary_utf8.md) is enabled), it throws the same exception
|
||||
instead. Byte strings (major type 2) are unaffected, since they are not required to hold text.
|
||||
|
||||
The chunks of an indefinite-length text string are checked one by one, as required by
|
||||
[RFC 8949, Section 3.2.3](https://www.rfc-editor.org/rfc/rfc8949.html#section-3.2.3): a code point cannot be spread
|
||||
over two chunks. With `error_handler_t::strict` such a string throws `parse_error.113`; `replace` and `ignore`
|
||||
sanitize each chunk on its own.
|
||||
|
||||
!!! warning "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.
|
||||
Tagged items (0xC0..0xDB) will throw a parse error by default. They can be ignored by passing `cbor_tag_handler_t::ignore` to function `from_cbor`, in which case the tag is skipped and the enclosed data item is parsed on its own. Passing `cbor_tag_handler_t::store` to function `from_cbor` stores tagged byte strings (for bytes 0xd8..0xdb) as binary values with the tag as subtype; other tagged values are read as if the tag were ignored. If several tags precede a byte string, only the tag directly in front of it is stored, and only when it has the form 0xD8..0xDB (a tag 0..23 written as 0xC0..0xD7 is skipped); for example, `D8 05 C1 41 AA` yields subtype `null`, whereas `C1 D8 05 41 AA` yields 5. Tags in front of a text string map key are skipped as well. Note that no tag is ever interpreted: for instance, a text string tagged with tag 0 (date/time) stays a string.
|
||||
|
||||
??? example "Example: deserialize a JSON value from CBOR"
|
||||
|
||||
|
||||
@@ -16,25 +16,25 @@ to efficiently encode JSON values to byte vectors and to decode such vectors.
|
||||
|
||||
### Completeness
|
||||
|
||||
| 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 |
|
||||
| Format | Serialization | Deserialization |
|
||||
|-------------|-----------------------------------------------|-----------------------------------------------------------------------|
|
||||
| BJData | complete | incomplete: no column-major ND-arrays, no Draft 4 SoA/extension types |
|
||||
| BON8 | incomplete: no unsigned integers above int64 | complete |
|
||||
| BSON | incomplete: top-level value must be an object | incomplete, but all JSON types are supported |
|
||||
| CBOR | complete | incomplete, but all JSON types are supported |
|
||||
| MessagePack | complete | incomplete, but all JSON types are supported |
|
||||
| UBJSON | complete | complete |
|
||||
|
||||
### Binary values
|
||||
|
||||
| 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 |
|
||||
| Format | Binary values | Binary subtypes |
|
||||
|-------------|--------------------------|-----------------|
|
||||
| BJData | supported (Draft 3 only) | not supported |
|
||||
| BON8 | not supported | not supported |
|
||||
| BSON | supported | supported |
|
||||
| CBOR | supported | supported |
|
||||
| MessagePack | supported | supported |
|
||||
| UBJSON | not supported | not supported |
|
||||
|
||||
See [binary values](../binary_values.md) for more information.
|
||||
|
||||
@@ -53,25 +53,7 @@ See [binary values](../binary_values.md) for more information.
|
||||
| UBJSON (size) | 58.6 % | 92.3 % | 86.8 % | 97.4 % |
|
||||
| UBJSON (size+type) | 55.9 % | 92.3 % | 85.0 % | 95.0 % |
|
||||
|
||||
<p class="nj-table-caption" markdown>Size of each test file in each format, in percent of the minified JSON value; the smallest size per file is printed in bold. The (size) and (size+type) rows are written with the `use_size` and `use_type` options of [`to_bjdata`](../../api/basic_json/to_bjdata.md) and [`to_ubjson`](../../api/basic_json/to_ubjson.md).</p>
|
||||
|
||||
<div class="nj-charts-grid-wrap" markdown>
|
||||
<div class="nj-fig-wrap" markdown>
|
||||
--8<-- "images/binary_sizes_canada.svg"
|
||||
</div>
|
||||
<div class="nj-fig-wrap" markdown>
|
||||
--8<-- "images/binary_sizes_twitter.svg"
|
||||
</div>
|
||||
<div class="nj-fig-wrap" markdown>
|
||||
--8<-- "images/binary_sizes_citm_catalog.svg"
|
||||
</div>
|
||||
<div class="nj-fig-wrap" markdown>
|
||||
--8<-- "images/binary_sizes_jeopardy.svg"
|
||||
</div>
|
||||
</div>
|
||||
<p class="nj-charts-caption" markdown>The table above as charts: size per base format relative to minified JSON (vertical line at
|
||||
100 %); the smallest format per file is drawn in a stronger colour than the others. The size and size+type variants of BJData and UBJSON are
|
||||
omitted here; see the table.</p>
|
||||
Sizes compared to minified JSON value; the smallest size per file is printed in bold.
|
||||
|
||||
## See also
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ extra byte in addition to the strings themselves.
|
||||
|
||||
## Byte layout
|
||||
|
||||
MessagePack encodes each value as a one-byte *format marker*, optionally followed by a length or the payload. The marker range is partitioned to keep common values small: small non-negative integers (0 to 127) and small negative integers (-32 to -1) are the marker byte itself; short strings, arrays, and maps (up to 31 or 15 elements) hide their length in the marker's lower bits. Larger values use dedicated markers that announce the width (8, 16, 32, or 64 bits) of the length or number that follows, in big-endian byte order. Like CBOR, containers are length-prefixed, so no terminator is needed.
|
||||
MessagePack encodes each value as a one-byte *format marker*, optionally followed by a length or the payload. The marker range is partitioned to keep common values small: small non-negative integers (0 to 127) and small negative integers (-32 to -1) are the marker byte itself; short strings, arrays, and maps (up to 31 bytes for strings and up to 15 elements for arrays and maps) hide their length in the marker's lower bits. Larger values use dedicated markers that announce the width (8, 16, 32, or 64 bits) of the length or number that follows, in big-endian byte order. Like CBOR, containers are length-prefixed, so no terminator is needed.
|
||||
|
||||
Consider the following JSON value (shown formatted for readability):
|
||||
|
||||
@@ -109,8 +109,9 @@ specification:
|
||||
!!! note
|
||||
|
||||
Prior to version 3.13.0, 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.
|
||||
total), because the check used to select the smaller float 32 encoding failed for NaN (all comparisons are `false`)
|
||||
and for Infinity and -Infinity (outside the float range checked against `std::numeric_limits<float>::lowest()` and
|
||||
`max()`), so the float 32 path was skipped.
|
||||
|
||||
??? example "Example: serialize a JSON value to MessagePack"
|
||||
|
||||
@@ -135,6 +136,7 @@ The library maps MessagePack types to JSON value types as follows:
|
||||
| fixarray | array | 0x90..0x9F |
|
||||
| fixstr | string | 0xA0..0xBF |
|
||||
| nil | `null` | 0xC0 |
|
||||
| (never used) | – | 0xC1 |
|
||||
| false | `false` | 0xC2 |
|
||||
| true | `true` | 0xC3 |
|
||||
| float 32 | number_float | 0xCA |
|
||||
@@ -167,6 +169,30 @@ The library maps MessagePack types to JSON value types as follows:
|
||||
| fixext 16 | binary | 0xD8 |
|
||||
| negative fixint | number_integer | 0xE0-0xFF |
|
||||
|
||||
The byte 0xC1 is reserved as "never used" by the specification. As a value it is rejected with
|
||||
[`parse_error.112`](../../home/exceptions.md#jsonexceptionparse_error112) (`invalid byte: 0xC1`); as a map key it is
|
||||
rejected with [`parse_error.113`](../../home/exceptions.md#jsonexceptionparse_error113) and the generic "expected length
|
||||
specification" message, because the key is read as a string.
|
||||
|
||||
Duplicate keys in a map are accepted; the last value wins.
|
||||
|
||||
### Extension types (ext, fixext)
|
||||
|
||||
MessagePack ext and fixext values are read as binary values, and the ext type byte is stored as the binary subtype.
|
||||
Although the specification defines the type as a signed 8-bit integer (0 to 127 for applications, -128 to -1 reserved,
|
||||
with -1 being the Timestamp extension), the library reads it as an unsigned byte: a negative ext type `n` becomes
|
||||
subtype `256+n`, so ext type -1 is read as subtype 255 and -128 as subtype 128. The Timestamp extension is not
|
||||
interpreted; it is returned as binary with subtype 255. Use
|
||||
[`has_subtype()`](../../api/byte_container_with_subtype/has_subtype.md) to tell a `bin` value (no subtype) from an ext
|
||||
value (subtype, even if it is 0).
|
||||
|
||||
When serializing, a binary value with a subtype is always written as fixext (1, 2, 4, 8, or 16 bytes) or ext, even
|
||||
for subtype 0 (`d6 00 01 02 03 04`); a binary value without a subtype is written as bin. Subtypes 128 to 255 are
|
||||
written as the reserved negative ext types (255 as -1), so `json::binary({1,2,3,4}, 255)` becomes
|
||||
`d6 ff 01 02 03 04`, which other MessagePack libraries decode as a 32-bit timestamp. A subtype above 255 throws
|
||||
[`out_of_range.415`](../../home/exceptions.md#jsonexceptionout_of_range415). The payload length is limited to
|
||||
4294967295 bytes like all other lengths.
|
||||
|
||||
!!! info
|
||||
|
||||
Any MessagePack output created by `to_msgpack` can be successfully parsed by `from_msgpack`.
|
||||
@@ -177,7 +203,8 @@ The library maps MessagePack types to JSON value types as follows:
|
||||
JSON-compatible [profile](https://github.com/msgpack/msgpack/blob/master/spec.md#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`](../../home/exceptions.md#jsonexceptionparse_error113) exception (or, with
|
||||
`allow_exceptions` set to `false`, a discarded value) naming the type of the key that was found, for instance:
|
||||
`allow_exceptions` set to `false`, a discarded value). For most key types the message names the type that was
|
||||
found, for instance:
|
||||
|
||||
```
|
||||
[json.exception.parse_error.113] parse error at byte 2: syntax error while parsing MessagePack object key: only string keys are supported, but found nil; last byte: 0xC0
|
||||
@@ -189,7 +216,7 @@ The library maps MessagePack types to JSON value types as follows:
|
||||
!!! warning "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.
|
||||
a byte sequence that is not valid UTF-8, and recommends that a deserializer provide a way to obtain the original bytes.
|
||||
This library follows that by default: with its
|
||||
[`error_handler`](../../api/basic_json/from_msgpack.md) parameter left at `keep` (the default),
|
||||
`from_msgpack()` reads `str` bytes (object keys included) as-is, without validating them, so such a value
|
||||
|
||||
@@ -5,11 +5,11 @@ achieve the generality of JSON, combined with being much easier to process than
|
||||
|
||||
!!! abstract "References"
|
||||
|
||||
- [UBJSON Website](http://ubjson.org)
|
||||
- [UBJSON Website](https://ubjson.org)
|
||||
|
||||
## Byte layout
|
||||
|
||||
UBJSON is built from just a one-byte, human-readable ASCII *type marker* (for example, `i` for int8, `S` for string, `[` for array) followed by the payload of that type. Strings and the like are prefixed with their length, which is itself a UBJSON integer value including its marker. Numbers are stored in big-endian byte order. Containers can be written in two ways: as an *unoptimized* container that is opened with `[` or `{` and closed with `]` or `}`, or as an *optimized* container that declares an element type (`$`) and/or a count (`#`) after the opening marker, which saves per-element markers and (for a count) the closing marker.
|
||||
UBJSON is built from just a one-byte, human-readable ASCII *type marker* (for example, `i` for int8, `S` for string, `[` for array) followed by the payload of that type. Strings and the like are prefixed with their length, which is itself a UBJSON integer value including its marker. Numbers are stored in big-endian byte order. Containers can be written in two ways: as an *unoptimized* container that is opened with `[` or `{` and closed with `]` or `}`, or as an *optimized* container that declares a count (`#`) after the opening marker, optionally preceded by an element type (`$`); an element type is only allowed together with a count. An optimized container saves the closing marker and, with a type, the per-element markers.
|
||||
|
||||
Consider the following JSON value (shown formatted for readability):
|
||||
|
||||
@@ -44,29 +44,29 @@ Consider the following JSON value (shown formatted for readability):
|
||||
|
||||
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 | `{` |
|
||||
| JSON value type | value/range | UBJSON type | marker |
|
||||
|-----------------|-------------------------------------------|--------------------------------------------------|-----------|
|
||||
| null | `null` | null | `Z` |
|
||||
| boolean | `true` | true | `T` |
|
||||
| boolean | `false` | false | `F` |
|
||||
| number_integer | -9223372036854775808..-2147483649 | int64 | `L` |
|
||||
| number_integer | -2147483648..-32769 | int32 | `l` |
|
||||
| number_integer | -32768..-129 | int16 | `I` |
|
||||
| number_integer | -128..127 | int8 | `i` |
|
||||
| number_integer | 128..255 | uint8 | `U` |
|
||||
| number_integer | 256..32767 | int16 | `I` |
|
||||
| number_integer | 32768..2147483647 | int32 | `l` |
|
||||
| number_integer | 2147483648..9223372036854775807 | int64 | `L` |
|
||||
| number_unsigned | 0..127 | int8 | `i` |
|
||||
| number_unsigned | 128..255 | uint8 | `U` |
|
||||
| number_unsigned | 256..32767 | int16 | `I` |
|
||||
| number_unsigned | 32768..2147483647 | int32 | `l` |
|
||||
| number_unsigned | 2147483648..9223372036854775807 | int64 | `L` |
|
||||
| number_unsigned | 9223372036854775808..18446744073709551615 | high-precision | `H` |
|
||||
| number_float | *any value* | float64 (float32 if `number_float_t` is `float`) | `D` (`d`) |
|
||||
| string | *with shortest length indicator* | string | `S` |
|
||||
| array | *see notes on optimized format* | array | `[` |
|
||||
| object | *see notes on optimized format* | object | `{` |
|
||||
|
||||
!!! success "Complete mapping"
|
||||
|
||||
@@ -93,20 +93,27 @@ The library uses the following mapping from JSON values types to UBJSON types ac
|
||||
|
||||
The following markers are not used in the conversion:
|
||||
|
||||
- `Z`: no-op values are not created.
|
||||
- `N`: no-op values are never written (they are skipped when reading).
|
||||
- `C`: single-byte strings are serialized with `S` markers.
|
||||
|
||||
!!! info "NaN/infinity handling"
|
||||
|
||||
If NaN or Infinity are stored inside a JSON number, they are serialized properly. This behavior differs from the
|
||||
[`dump()`](../../api/basic_json/dump.md) function which serializes NaN or Infinity to `null`.
|
||||
NaN and infinity are written as IEEE 754 float64 values (`D`) and read back unchanged. This differs from
|
||||
[`dump()`](../../api/basic_json/dump.md), which serializes them to `null`, and from the UBJSON specification, which
|
||||
encodes infinity as `null` (it does not mention NaN); other UBJSON readers may therefore not accept these values.
|
||||
|
||||
!!! info "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`.
|
||||
used together with `use_size = true`: combining `use_type` with `use_size = false` throws
|
||||
[`other_error.502`](../../home/exceptions.md#jsonexceptionother_error502) if the value contains a non-empty array,
|
||||
object, or binary value.
|
||||
|
||||
Two elements have the same type if they are written with the same type marker. For example, `[1, 2]` is written with
|
||||
the type `i`, but `[1, 200]` (`i`, `U`), `[true, false]` (`T`, `F`), and `[1, 2.5]` (`i`, `D`) are not; an empty
|
||||
container is never given a `$` annotation of its own (an array of empty arrays is still typed `[`).
|
||||
|
||||
Note that `use_size = true` alone may result in larger representations - the benefit of this parameter is that the
|
||||
receiving side is immediately informed on the number of elements of the container.
|
||||
@@ -115,8 +122,9 @@ The library uses the following mapping from JSON values types to UBJSON types ac
|
||||
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`](../../home/exceptions.md#jsonexceptionout_of_range408) 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.
|
||||
(`1 << 20`), and `to_ubjson` writes longer arrays of these types in the counted but untyped form: the `$` type marker is
|
||||
dropped, the `#` count is kept, and every element is written with its own marker (`[#l 1048577 Z Z ...`), so any value
|
||||
it produces can be read back. Objects and untyped counted arrays are not subject to this limit.
|
||||
|
||||
!!! info "Binary values"
|
||||
|
||||
@@ -140,27 +148,54 @@ The library uses the following mapping from JSON values types to UBJSON types ac
|
||||
|
||||
The library maps UBJSON types to JSON value types as follows:
|
||||
|
||||
| UBJSON type | JSON value type | marker |
|
||||
|-------------|-----------------------------------------|--------|
|
||||
| no-op | *no value, next value is read* | `N` |
|
||||
| null | `null` | `Z` |
|
||||
| false | `false` | `F` |
|
||||
| true | `true` | `T` |
|
||||
| float32 | number_float | `d` |
|
||||
| float64 | number_float | `D` |
|
||||
| uint8 | number_unsigned | `U` |
|
||||
| int8 | number_integer | `i` |
|
||||
| int16 | number_integer | `I` |
|
||||
| int32 | number_integer | `l` |
|
||||
| int64 | number_integer | `L` |
|
||||
| string | string | `S` |
|
||||
| char | string | `C` |
|
||||
| array | array (optimized values are supported) | `[` |
|
||||
| object | object (optimized values are supported) | `{` |
|
||||
| UBJSON type | JSON value type | marker |
|
||||
|----------------|--------------------------------------------------|--------|
|
||||
| no-op | *no value, next value is read* | `N` |
|
||||
| null | `null` | `Z` |
|
||||
| false | `false` | `F` |
|
||||
| true | `true` | `T` |
|
||||
| float32 | number_float | `d` |
|
||||
| float64 | number_float | `D` |
|
||||
| uint8 | number_unsigned | `U` |
|
||||
| int8 | number_integer | `i` |
|
||||
| int16 | number_integer | `I` |
|
||||
| int32 | number_integer | `l` |
|
||||
| int64 | number_integer | `L` |
|
||||
| string | string | `S` |
|
||||
| char | string | `C` |
|
||||
| high-precision | number_unsigned, number_integer, or number_float | `H` |
|
||||
| array | array (optimized values are supported) | `[` |
|
||||
| object | object (optimized values are supported) | `{` |
|
||||
|
||||
!!! info "High-precision numbers"
|
||||
|
||||
The payload of `H` is a length-prefixed string that is parsed as a JSON number (surrounding whitespace is ignored).
|
||||
Integer text in the range of `number_unsigned_t` (non-negative) or `number_integer_t` (negative) is stored as such;
|
||||
any other valid number text (larger or smaller integers, fractions, and exponents such as `1e2`) is stored as
|
||||
`number_float`, so precision may be lost. Text that is not a valid JSON number raises
|
||||
[`parse_error.115`](../../home/exceptions.md#jsonexceptionparse_error115), a number outside the range of
|
||||
`number_float_t` (`1e999`) raises [`out_of_range.406`](../../home/exceptions.md#jsonexceptionout_of_range406).
|
||||
|
||||
!!! success "Complete mapping"
|
||||
|
||||
The mapping is **complete** in the sense that any UBJSON value can be converted to a JSON value.
|
||||
Every well-formed UBJSON value can be converted to a JSON value, with these exceptions: a high-precision number
|
||||
outside the range of `number_float_t` ([`out_of_range.406`](../../home/exceptions.md#jsonexceptionout_of_range406)),
|
||||
an optimized array of `Z`, `T`, or `F` with more than 1,048,576 elements, and a count that exceeds the capacity of the
|
||||
container ([`out_of_range.408`](../../home/exceptions.md#jsonexceptionout_of_range408)). High-precision numbers that
|
||||
do not fit an integer type are stored as floating-point numbers and may lose precision. Ill-formed input is rejected
|
||||
with a parse error.
|
||||
|
||||
!!! info "Duplicate object keys"
|
||||
|
||||
If an object contains the same key more than once, the last value is kept (the UBJSON specification does not
|
||||
address duplicate keys).
|
||||
|
||||
!!! info "Type marker of optimized containers"
|
||||
|
||||
The type marker after `$` must be one of `Z`, `N`, `T`, `F`, `i`, `U`, `I`, `l`, `L`, `d`, `D`, `H`, `C`, `S`, `[`, or
|
||||
`{`. It is checked even if the count is 0; any other marker raises
|
||||
[`parse_error.112`](../../home/exceptions.md#jsonexceptionparse_error112). A counted object typed `N` (`{$N#i1 ...`)
|
||||
is not supported.
|
||||
|
||||
!!! warning "Ill-formed UTF-8 in string values and object keys"
|
||||
|
||||
|
||||
@@ -25,8 +25,6 @@ class vector ["std::vector<uint8_t>"]
|
||||
vector <|-- binary_t
|
||||
```
|
||||
|
||||
<p class="nj-caption" markdown>Class diagram of `json::binary_t`: it derives from `std::vector<uint8_t>` and adds functions to set, clear, query, and test an optional subtype.</p>
|
||||
|
||||
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`](../api/basic_json/binary_t.md):
|
||||
@@ -134,8 +132,11 @@ is an integer or `null`.
|
||||
|
||||
### BJData
|
||||
|
||||
[BJData](binary_formats/bjdata.md) neither supports binary values nor subtypes and proposes to serialize binary values
|
||||
as an array of uint8 values. The library implements this translation.
|
||||
[BJData](binary_formats/bjdata.md) Draft 3 supports binary values as optimized arrays of `B` (byte) elements, but no
|
||||
subtypes. With `version = bjdata_version_t::draft3` and both `use_size` and `use_type` set, `to_bjdata` writes a binary
|
||||
value as `[$B#...`, and `from_bjdata` reads it back as a binary value (without subtype). In all other cases, including
|
||||
the default Draft 2 mode, the library follows the Draft 2 proposal and writes an array of integers (`U` in Draft 2, `B`
|
||||
in Draft 3), which is read back as an array.
|
||||
|
||||
??? example "Example: serialize a binary value to BJData"
|
||||
|
||||
@@ -173,7 +174,7 @@ as an array of uint8 values. The library implements this translation.
|
||||
|
||||
```c
|
||||
0x7B // '{'
|
||||
0x23 0x69 0x01 // '#' 'i' type of the array elements: unsigned integers
|
||||
0x23 0x69 0x01 // '#' 'i' 1 number of object members
|
||||
0x69 0x06 // i 6 (length of the key)
|
||||
0x62 0x69 0x6E 0x61 0x72 0x79 // "binary"
|
||||
0x5B // '[' array
|
||||
@@ -182,7 +183,7 @@ as an array of uint8 values. The library implements this translation.
|
||||
0xCA 0xFE 0xBA 0xBE // content
|
||||
```
|
||||
|
||||
Note that subtype (42) is **not** serialized and that BJData has **no binary type**, and deserializing `v` would
|
||||
Note that subtype (42) is **not** serialized and that, in Draft 2 mode, BJData has **no binary type**, and deserializing `v` would
|
||||
yield the following value:
|
||||
|
||||
```json
|
||||
@@ -229,7 +230,10 @@ array of integers.
|
||||
### BSON
|
||||
|
||||
[BSON](binary_formats/bson.md) 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.
|
||||
unsigned 8-bit integer; a subtype above 255 throws
|
||||
[`out_of_range.415`](../home/exceptions.md#jsonexceptionout_of_range415). If no subtype is given, the generic binary
|
||||
subtype 0x00 is used. The payload of the "old binary" subtype 0x02 is preceded by a second length, which the library
|
||||
writes and removes again when reading; it is not part of the payload.
|
||||
|
||||
??? example "Example: serialize a binary value to BSON"
|
||||
|
||||
@@ -303,6 +307,8 @@ representation using the length of the byte array.
|
||||
[`json::from_cbor`](../api/basic_json/from_cbor.md) (see
|
||||
[`cbor_tag_handler_t`](../api/basic_json/cbor_tag_handler_t.md)).
|
||||
|
||||
With `ignore`, the subtype is dropped (`"subtype": null`); with `store`, the tag is kept (`"subtype": 42`):
|
||||
|
||||
```json
|
||||
{
|
||||
"binary": {
|
||||
@@ -312,11 +318,21 @@ representation using the length of the byte array.
|
||||
}
|
||||
```
|
||||
|
||||
```json
|
||||
{
|
||||
"binary": {
|
||||
"bytes": [202, 254, 186, 190],
|
||||
"subtype": 42
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### MessagePack
|
||||
|
||||
[MessagePack](binary_formats/messagepack.md) 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.
|
||||
is used. The library will choose the smallest representation among fixext1, fixext2, fixext4, fixext8, fixext16, ext8,
|
||||
ext16, and ext32. The subtype is then written as the signed 8-bit ext type: subtypes 128 to 255 map to the negative
|
||||
(reserved) ext types, and on reading the ext type is exposed as an unsigned subtype from 0 to 255.
|
||||
|
||||
If no subtype is given, the bin family (bin8, bin16, bin32) is used.
|
||||
|
||||
|
||||
@@ -89,5 +89,3 @@ non-existing, an exception is thrown.
|
||||
| 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 |
|
||||
|
||||
<p class="nj-table-caption" markdown>Result of [`at`](../../api/basic_json/at.md) in each scenario, for a non-const and a const value.</p>
|
||||
@@ -12,23 +12,16 @@ Testing whether a key or index exists before accessing it is also possible, with
|
||||
[`contains`](../../api/basic_json/contains.md) or [`find`](../../api/basic_json/find.md) (which returns an iterator to
|
||||
the value, or `end()` if it is not found).
|
||||
|
||||
How do I get a value out? Start at the top and follow the first question that applies:
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A["getting a value out"] --> P{{"nested path such as /server/port?"}}
|
||||
P -->|"yes"| JP["JSON Pointer: at(ptr), value(ptr, default), contains(ptr)"]
|
||||
P -->|"no, one key or index"| T{{"only testing whether it exists?"}}
|
||||
T -->|"yes"| CF["contains() / find()"]
|
||||
T -->|"no"| M{{"may it be missing?"}}
|
||||
M -->|"yes, a fallback is fine"| V["value(key, default)"]
|
||||
M -->|"yes, and missing is an error"| AT["at(): throws out_of_range"]
|
||||
M -->|"no, it exists and its type is known"| OP["operator[] and get#lt;T#gt;()"]
|
||||
OP -.- W["non-const operator[] inserts null for a missing key"]
|
||||
A["accessing a value"] --> B{"must it exist?"}
|
||||
B -->|"yes, missing is an error"| C["at() -- throws"]
|
||||
B -->|"yes, but checking is my job"| D["operator[] -- unchecked"]
|
||||
B -->|"no, a fallback is fine"| E["value() -- default value"]
|
||||
A --> F{"just testing first?"}
|
||||
F -->|"yes"| G["contains() / find()"]
|
||||
```
|
||||
|
||||
<p class="nj-caption" markdown>Decision tree for reading a value: the labels on the arrows are the answers to the questions, and the boxes name the functions to use. The dashed line marks a side effect of the non-const `operator[]`.</p>
|
||||
|
||||
## Does this key exist?
|
||||
|
||||
Use [`contains`](../../api/basic_json/contains.md) to test for a key; it does not modify the value and does not throw:
|
||||
|
||||
@@ -125,5 +125,3 @@ for (int i = 0; i < 1000; ++i) {
|
||||
| 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 `#!json null` value is returned | **undefined behavior**; [runtime assertion](../assertions.md) in debug mode |
|
||||
| access to invalid array index | reference to newly inserted `#!json null` value is returned; any index between previous maximal index and passed index are filled with `#!json null` | **undefined behavior**; [runtime assertion](../assertions.md) in debug mode |
|
||||
|
||||
<p class="nj-table-caption" markdown>Result of [`operator[]`](../../api/basic_json/operator%5B%5D.md) in each scenario, for a non-const and a const value.</p>
|
||||
@@ -9,11 +9,7 @@ As for other containers, [`begin()`](../api/basic_json/begin.md) returns an iter
|
||||
placeholder and cannot be dereferenced. In case of null values, empty arrays, or empty objects, `begin()` will return
|
||||
`end()`.
|
||||
|
||||
<div class="nj-fig-wrap" markdown>
|
||||
--8<-- "images/range-begin-end.svg"
|
||||
</div>
|
||||
|
||||
<p class="nj-caption" markdown>The range of `begin()` and `end()`: `begin()` refers to the first element, `end()` to the position after the last element, which must not be dereferenced.</p>
|
||||

|
||||
|
||||
### Iteration order for objects
|
||||
|
||||
@@ -116,11 +112,7 @@ for (auto& [key, val] : j_object.items())
|
||||
[`rbegin()`](../api/basic_json/rbegin.md) and [`rend()`](../api/basic_json/rend.md) return iterators in the reverse
|
||||
sequence.
|
||||
|
||||
<div class="nj-fig-wrap" markdown>
|
||||
--8<-- "images/range-rbegin-rend.svg"
|
||||
</div>
|
||||
|
||||
<p class="nj-caption" markdown>The range of `rbegin()` and `rend()` over the same elements: `rbegin()` refers to the last element and `rend()` to the position before the first one. Each reverse iterator stores an iterator to the element after the one it refers to.</p>
|
||||

|
||||
|
||||
??? example "Example: reverse iteration with `rbegin()` and `rend()`"
|
||||
|
||||
|
||||
@@ -7,24 +7,6 @@ of operations to apply to a JSON document. Operations address locations in the d
|
||||
[JSON Pointer](json_pointer.md) paths. With the [`patch`](../api/basic_json/patch.md) function, a JSON Patch is applied
|
||||
to the current JSON value by executing all operations from the patch, yielding the patched document as a new value.
|
||||
|
||||
The following steps through one operation of each kind. The first three operations are those of the example below; the
|
||||
other three continue on its result.
|
||||
|
||||
<div class="nj-patch" data-nj-patch markdown>
|
||||
|
||||
| Operation | Before | After |
|
||||
|-------------------------------------------------------------|------------------------------------------------|-------------------------------------------------|
|
||||
| `{"op": "replace", "path": "/baz", "value": "boo"}` | `{"baz": "qux", "foo": "bar"}` | `{"baz": "boo", "foo": "bar"}` |
|
||||
| `{"op": "add", "path": "/hello", "value": ["world"]}` | `{"baz": "boo", "foo": "bar"}` | `{"baz": "boo", "foo": "bar", "hello": ["world"]}` |
|
||||
| `{"op": "remove", "path": "/foo"}` | `{"baz": "boo", "foo": "bar", "hello": ["world"]}` | `{"baz": "boo", "hello": ["world"]}` |
|
||||
| `{"op": "move", "from": "/baz", "path": "/hello/1"}` | `{"baz": "boo", "hello": ["world"]}` | `{"hello": ["world", "boo"]}` |
|
||||
| `{"op": "copy", "from": "/hello/0", "path": "/greeting"}` | `{"hello": ["world", "boo"]}` | `{"greeting": "world", "hello": ["world", "boo"]}` |
|
||||
| `{"op": "test", "path": "/greeting", "value": "world"}` | `{"greeting": "world", "hello": ["world", "boo"]}` | unchanged (a failed test throws) |
|
||||
|
||||
</div>
|
||||
|
||||
<p class="nj-caption" markdown>Stepper through the six operations: *Next* applies the next operation, *Back* undoes it, and *Reset* returns to the original document. The current operation is highlighted in the patch list, and the lines it changes are marked in the document.</p>
|
||||
|
||||
!!! tip "Applying a patch without copying"
|
||||
|
||||
[`patch`](../api/basic_json/patch.md) leaves the original value unchanged and returns the patched result as a copy.
|
||||
@@ -57,8 +39,6 @@ flowchart LR
|
||||
P -.->|"applied to source, yields"| T
|
||||
```
|
||||
|
||||
<p class="nj-caption" markdown>How `diff` and `patch` relate: `diff(source, target)` yields a patch, and applying that patch to the source yields the target.</p>
|
||||
|
||||
!!! success "Invariant"
|
||||
|
||||
For two JSON values *source* and *target*, the following code yields always true:
|
||||
|
||||
@@ -18,40 +18,6 @@ Consider the following JSON document
|
||||
}
|
||||
```
|
||||
|
||||
Select a pointer (or a node of the tree) to walk it through this document; each segment of the pointer goes one level
|
||||
deeper. The table below lists the same pointers.
|
||||
|
||||
<div class="nj-pointer-walk" data-nj-pointer-walk data-doc="{"array":["A","B","C"],"nested":{"one":1,"two":2,"three":[true,false]}}" role="group" aria-label="Pointer walker for the example document">
|
||||
<p class="nj-pointer-static">Highlighted: the path of the pointer <code>/nested/three/1</code>, which identifies <code>false</code>.</p>
|
||||
<ul class="nj-pointer-tree">
|
||||
<li data-p="" class="is-on"><span class="nj-pointer-n"><span class="nj-pointer-k">root</span> <span class="nj-pointer-t">object</span></span>
|
||||
<ul>
|
||||
<li data-p="/array" class="is-pass"><span class="nj-pointer-n"><span class="nj-pointer-k">"array"</span> <span class="nj-pointer-t">array</span></span>
|
||||
<ul>
|
||||
<li data-p="/array/0"><span class="nj-pointer-n"><span class="nj-pointer-k">0</span>: <span class="nj-pointer-v nj-pointer-v--s">"A"</span></span></li>
|
||||
<li data-p="/array/1"><span class="nj-pointer-n"><span class="nj-pointer-k">1</span>: <span class="nj-pointer-v nj-pointer-v--s">"B"</span></span></li>
|
||||
<li data-p="/array/2"><span class="nj-pointer-n"><span class="nj-pointer-k">2</span>: <span class="nj-pointer-v nj-pointer-v--s">"C"</span></span></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li data-p="/nested" class="is-on"><span class="nj-pointer-n"><span class="nj-pointer-k">"nested"</span> <span class="nj-pointer-t">object</span></span>
|
||||
<ul>
|
||||
<li data-p="/nested/one" class="is-pass"><span class="nj-pointer-n"><span class="nj-pointer-k">"one"</span>: <span class="nj-pointer-v nj-pointer-v--n">1</span></span></li>
|
||||
<li data-p="/nested/two" class="is-pass"><span class="nj-pointer-n"><span class="nj-pointer-k">"two"</span>: <span class="nj-pointer-v nj-pointer-v--n">2</span></span></li>
|
||||
<li data-p="/nested/three" class="is-on"><span class="nj-pointer-n"><span class="nj-pointer-k">"three"</span> <span class="nj-pointer-t">array</span></span>
|
||||
<ul>
|
||||
<li data-p="/nested/three/0" class="is-pass"><span class="nj-pointer-n"><span class="nj-pointer-k">0</span>: <span class="nj-pointer-v nj-pointer-v--b">true</span></span></li>
|
||||
<li data-p="/nested/three/1" class="is-on is-target"><span class="nj-pointer-n"><span class="nj-pointer-k">1</span>: <span class="nj-pointer-v nj-pointer-v--b">false</span></span></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<p class="nj-caption" markdown>The highlighted nodes are the path from the root to the selected level, and the line below the tree shows the value the pointer resolves to. Select a segment in the pointer bar to stop at a shallower level, or a node of the tree to select its pointer.</p>
|
||||
|
||||
Then every value inside the JSON document can be identified as follows:
|
||||
|
||||
| JSON Pointer | JSON value |
|
||||
@@ -161,14 +127,6 @@ The reverse function, [`unflatten`](../api/basic_json/unflatten.md) recreates th
|
||||
auto j_original = j_flat.unflatten();
|
||||
```
|
||||
|
||||
Each leaf of the document becomes one key of the flat object, and `unflatten()` reverses the mapping:
|
||||
|
||||
<div class="nj-fig-wrap" markdown>
|
||||
--8<-- "images/json_pointer_flatten.svg"
|
||||
</div>
|
||||
|
||||
<p class="nj-caption" markdown>Left: the example document as a tree; right: the flat object it becomes. `flatten()` converts from left to right, `unflatten()` from right to left.</p>
|
||||
|
||||
## See also
|
||||
|
||||
- Class [`json_pointer`](../api/json_pointer/index.md)
|
||||
|
||||
@@ -33,14 +33,6 @@ index. It gives you the read-only, type-inspection part of the `basic_json` inte
|
||||
actual `basic_json` value for a subtree, [`materialize()`](../api/basic_json_view/materialize.md) builds exactly the
|
||||
one [`parse()`](../api/basic_json/parse.md) would have produced for it.
|
||||
|
||||
The same small text, parsed both ways:
|
||||
|
||||
<div class="nj-fig-wrap" markdown>
|
||||
--8<-- "images/json_view_layout.svg"
|
||||
</div>
|
||||
|
||||
<p class="nj-caption" markdown>Top: the tree of separate heap allocations that `basic_json::parse()` builds. Bottom: `json_document::parse()` keeps the source text and builds one flat index of 16-byte nodes that point back into it, plus a buffer of decoded strings.</p>
|
||||
|
||||
## How to use it
|
||||
|
||||
Include `<nlohmann/json_view.hpp>` in addition to (or instead of) `<nlohmann/json.hpp>`. Parse into a
|
||||
@@ -92,12 +84,6 @@ Moving the `basic_json_document<>` itself is fine and does **not** invalidate it
|
||||
allocation that keeps its address across the move. Take a fresh view from [`root()`](../api/basic_json_document/root.md)
|
||||
whenever any of the other conditions above was not met.
|
||||
|
||||
<div class="nj-fig-wrap" markdown>
|
||||
--8<-- "images/json_view_lifetime.svg"
|
||||
</div>
|
||||
|
||||
<p class="nj-caption" markdown>Four timelines of a document and its views, each bar showing when an object is alive or valid and when it dangles. Destroying the borrowed text, re-parsing, or shrinking the document invalidates the views taken before; moving the document does not.</p>
|
||||
|
||||
A view can dangle, exactly like a `#!cpp std::string_view`: nothing stops you from using it after its document is
|
||||
gone. This is deliberate. A view is two pointers and trivially copyable; making it safe (a `#!cpp std::shared_ptr` in
|
||||
the document and a `#!cpp std::weak_ptr` in each view) would make it larger, add reference counting to every copy,
|
||||
@@ -288,26 +274,6 @@ or `ordered_json` value in place lossy. Say you parse a configuration file, patc
|
||||
- **`ordered_json`** keeps the key order, but still rewrites every number the same way: parsing has already reduced
|
||||
it to a `#!cpp double`/`#!cpp int64_t`, and there is no way back to how it was spelled in the source text.
|
||||
|
||||
The patch of the example below (set `"host"`, add `"retries"`) written back by each of them:
|
||||
|
||||
<div class="nj-jsonview-cmp" role="group" aria-label="The same patch written back by json, ordered_json, and json_editable_document">
|
||||
<div><p class="nj-jsonview-cmp-h"><code>json</code></p><p class="nj-jsonview-cmp-v">keys sorted, numbers rewritten</p><pre>{<span class="nj-jsonview-bad">"host"</span>:"db2",
|
||||
"name":"cache",
|
||||
"port":6379,
|
||||
"price":<span class="nj-jsonview-bad">19.9</span>,
|
||||
"retries":3}</pre></div>
|
||||
<div><p class="nj-jsonview-cmp-h"><code>ordered_json</code></p><p class="nj-jsonview-cmp-v">key order kept, numbers rewritten</p><pre>{"name":"cache",
|
||||
"host":"db2",
|
||||
"port":6379,
|
||||
"price":<span class="nj-jsonview-bad">19.9</span>,
|
||||
"retries":3}</pre></div>
|
||||
<div class="nj-jsonview-cmp--best"><p class="nj-jsonview-cmp-h"><code>json_editable_document</code></p><p class="nj-jsonview-cmp-v">order and spelling kept</p><pre>{"name":"cache",
|
||||
"host":"db2",
|
||||
"port":6379,
|
||||
"price":<span class="nj-jsonview-ok">19.90</span>,
|
||||
"retries":3}</pre></div>
|
||||
</div>
|
||||
|
||||
An editable document keeps both. [`dump()`](../api/basic_json_view/dump.md) of an edited document writes members in
|
||||
document order -- a member [`set`](../api/basic_json_document/set.md) added goes at the end, exactly where it was
|
||||
inserted, and an [`erase`](../api/basic_json_document/erase.md)d member simply leaves a gap: everything around it
|
||||
@@ -335,8 +301,8 @@ parsed into for as long as it is not itself replaced. So every [view](../api/bas
|
||||
an edit, including a previously obtained [`root()`](../api/basic_json_document/root.md), stays valid and, if it
|
||||
still refers to the edited value, sees the edit; a view of a value a later edit drops or replaces just keeps showing
|
||||
what it last held. New values go to storage the document allocates and owns on demand. The one thing an edit does
|
||||
invalidate is the **iterators** taken over an edited array or object: the first time an element is added to it,
|
||||
inserted into it, erased from it, or replaced by a value that spans a different number of nodes, its elements move from the parsed, fixed layout to a growable block of links
|
||||
invalidate is the **iterators** taken over an edited array or object: the first time one of its elements is set,
|
||||
appended to, inserted into, or erased, its elements move from the parsed, fixed layout to a growable block of links
|
||||
so that [`push_back`](../api/basic_json_document/push_back.md) can later grow it in amortized constant time --
|
||||
existing elements are not touched, but an iterator that was walking the old layout no longer matches. A string
|
||||
obtained with
|
||||
@@ -346,43 +312,6 @@ edits. See [`basic_json_document`'s Edits](../api/basic_json_document/index.md#e
|
||||
throws (the *basic* guarantee, not the strong one `dump()` and the read-only functions provide). How edits are kept in
|
||||
the index is described in the [architecture overview](../home/architecture.md#node-index-of-json-views).
|
||||
|
||||
Step through the edits of a small document (the node fields follow the [architecture overview](../home/architecture.md#node-index-of-json-views)):
|
||||
|
||||
<div class="nj-jsonview-steps" data-nj-jsonview-steps>
|
||||
<figure class="nj-jsonview-step" data-label="After parsing">
|
||||
<div class="nj-jsonview-scroll">
|
||||
--8<-- "images/json_view_edit_0.svg"
|
||||
</div>
|
||||
<figcaption>Step 1 of 5. After parsing: nine nodes in the parsed index, no owned storage yet.</figcaption>
|
||||
</figure>
|
||||
<figure class="nj-jsonview-step" data-label="set an existing member">
|
||||
<div class="nj-jsonview-scroll">
|
||||
--8<-- "images/json_view_edit_1.svg"
|
||||
</div>
|
||||
<figcaption>Step 2 of 5. <code>doc.set(doc.root(), "port", 6380)</code> overwrites the node of the integer in place; no member is added or removed, so the object keeps its parsed layout.</figcaption>
|
||||
</figure>
|
||||
<figure class="nj-jsonview-step" data-label="erase an array element">
|
||||
<div class="nj-jsonview-scroll">
|
||||
--8<-- "images/json_view_edit_2.svg"
|
||||
</div>
|
||||
<figcaption>Step 3 of 5. <code>doc.erase(doc.root()["tags"], 0)</code>: the array is edited for the first time, so its elements move to a block of links in owned storage. The node of <code>"eu"</code> stays in the index, but nothing refers to it any more; iterators over the array taken before are invalid.</figcaption>
|
||||
</figure>
|
||||
<figure class="nj-jsonview-step" data-label="push_back onto the array">
|
||||
<div class="nj-jsonview-scroll">
|
||||
--8<-- "images/json_view_edit_3.svg"
|
||||
</div>
|
||||
<figcaption>Step 4 of 5. <code>doc.push_back(doc.root()["tags"], "new")</code>: the new string gets its own node, its text goes to the buffer of edited text, and a link to it is appended to the block of the array.</figcaption>
|
||||
</figure>
|
||||
<figure class="nj-jsonview-step" data-label="set a new member">
|
||||
<div class="nj-jsonview-scroll">
|
||||
--8<-- "images/json_view_edit_4.svg"
|
||||
</div>
|
||||
<figcaption>Step 5 of 5. <code>doc.set(doc.root(), "retries", 3)</code>: a new member, so the object moves to a block too: copies of its keys, links to the values it already had, then the new key and a link to the new integer.</figcaption>
|
||||
</figure>
|
||||
</div>
|
||||
|
||||
<p class="nj-caption" markdown>The node index and the owned storage of the document after each of five edits. Use *Back*, *Next*, or the numbered buttons to switch between the steps; without JavaScript all steps are shown one below the other.</p>
|
||||
|
||||
## Images
|
||||
|
||||
[`save()`](../api/basic_json_document/save.md) writes a document as an *image*: a byte buffer that
|
||||
@@ -444,8 +373,6 @@ either.
|
||||
| **Typical use** | general-purpose JSON handling: config, request/response bodies you build or modify, anything you hold onto | validating or projecting a text into your own data structure without ever holding the whole thing as JSON | large or high-volume input where you only need part of it, or need it repeatedly, and can keep the source text (or a copy) alive for as long as the document lives | a document you read, patch a few fields of, and write back -- a configuration file, for instance -- where the rest of it should come back exactly as it was |
|
||||
| **Caching/reload** | not applicable -- re-parse, or roll your own serialization | not applicable | [`save()`](../api/basic_json_document/save.md)/[`load()`](../api/basic_json_document/load.md): cache the parsed index as an image and reload it without parsing | same, saving the document's current -- possibly edited -- state |
|
||||
|
||||
<p class="nj-table-caption" markdown>Each column is one way to work with JSON in this library, and each row compares one property of them.</p>
|
||||
|
||||
## Version history
|
||||
|
||||
- Added in version 3.13.0.
|
||||
@@ -12,35 +12,6 @@ easier to read and write for object-shaped documents.
|
||||
The function [`merge_diff`](../api/basic_json/merge_diff.md) creates a merge patch that changes one JSON value into
|
||||
another.
|
||||
|
||||
The example below shows every rule in one patch, member by member:
|
||||
|
||||
<div class="nj-pointer-mpt" markdown>
|
||||
|
||||
| Rule | Key | Target | Patch | Result |
|
||||
|------|-----|--------|-------|--------|
|
||||
| <span class="nj-pointer-mp nj-pointer-mp--set">change value</span> | `title` | `#!json "Goodbye!"` | `#!json "Hello!"` | `#!json "Hello!"` |
|
||||
| <span class="nj-pointer-mp nj-pointer-mp--add">add key</span> | `phoneNumber` | <span class="nj-pointer-mp-none">(no key)</span> | `#!json "+01-123-456-7890"` | `#!json "+01-123-456-7890"` |
|
||||
| <span class="nj-pointer-mp nj-pointer-mp--del">null removes key</span> | `author.familyName` | `#!json "Doe"` | `#!json null` | <span class="nj-pointer-mp-none">(removed)</span> |
|
||||
| <span class="nj-pointer-mp nj-pointer-mp--rec">object merges recursively</span> | `author` | `#!json {"givenName": "John", "familyName": "Doe"}` | `#!json {"familyName": null}` | `#!json {"givenName": "John"}` |
|
||||
| <span class="nj-pointer-mp nj-pointer-mp--arr">array replaced whole</span> | `tags` | `#!json ["example", "sample"]` | `#!json ["example"]` | `#!json ["example"]` |
|
||||
| <span class="nj-pointer-mp nj-pointer-mp--keep">unchanged key</span> | `content` | `#!json "This will be unchanged"` | <span class="nj-pointer-mp-none">(no key)</span> | `#!json "This will be unchanged"` |
|
||||
|
||||
</div>
|
||||
|
||||
An array in the patch replaces the array in the target, so a merge patch cannot change a single element. Each member of
|
||||
the patch is applied like this; a patch that is not an object replaces the whole target.
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
M["member of the patch"] --> N{{"value null?"}}
|
||||
N -->|yes| D["delete the key"]
|
||||
N -->|no| O{{"value an object?"}}
|
||||
O -->|yes| R["merge recursively into the target's value"]
|
||||
O -->|no| S["set the key to the value"]
|
||||
```
|
||||
|
||||
<p class="nj-caption" markdown>How one member of a merge patch is applied: a `null` value deletes the key, an object is merged recursively, and any other value replaces the value of the key.</p>
|
||||
|
||||
!!! tip "Not a general deep merge"
|
||||
|
||||
A merge patch is not a general deep merge: a `#!json null` value in the patch deletes the key from the target.
|
||||
|
||||
@@ -4,8 +4,6 @@ This library has experimental support for C++ modules, introduced in C++20. The
|
||||
|
||||
Please be aware that the module is experimental and a full test is outstanding, and the exported symbols are subject to change.
|
||||
|
||||
Importing the module instead of including the header reduces the compile time of every translation unit that uses the library, at the price of building the module once. The [Compile times](../integration/compile_times.md#use-c20-modules) page has measurements and the one-off cost.
|
||||
|
||||
## Requirements
|
||||
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.
|
||||
|
||||
|
||||
@@ -40,22 +40,6 @@ For example, the namespace name for version 3.11.2 with `JSON_DIAGNOSTICS` defin
|
||||
nlohmann::json_abi_diag_v3_11_2
|
||||
```
|
||||
|
||||
The name is assembled from these segments; pick a version and macros to see the resulting name:
|
||||
|
||||
<figure class="nj-integration-ns" data-nj-integration-ns aria-label="How the inline namespace name is assembled from its segments">
|
||||
<div class="nj-integration-ns__strip" aria-live="polite">
|
||||
<span class="nj-integration-ns__seg nj-integration-ns__seg--root"><code>nlohmann</code><small>root namespace</small></span>
|
||||
<span class="nj-integration-ns__seg nj-integration-ns__seg--sep"><code>::</code><small> </small></span>
|
||||
<span class="nj-integration-ns__seg nj-integration-ns__seg--abi"><code>json_abi</code><small>always</small></span>
|
||||
<span class="nj-integration-ns__seg nj-integration-ns__seg--tag"><code>_diag</code><small>JSON_DIAGNOSTICS=1</small></span>
|
||||
<span class="nj-integration-ns__seg nj-integration-ns__seg--ver"><code>_v3_11_2</code><small>version 3.11.2</small></span>
|
||||
</div>
|
||||
<figcaption>Version 3.11.2 with <code>JSON_DIAGNOSTICS</code> defined to <code>1</code>. ABI tags are appended in the order of the
|
||||
list above, the version suffix comes last.</figcaption>
|
||||
</figure>
|
||||
|
||||
<p class="nj-caption" markdown>The name of the inline namespace, assembled from its segments. Select a version and macros to see which ABI tags appear; a tag the chosen version does not have is disabled.</p>
|
||||
|
||||
## Purpose
|
||||
|
||||
Several incompatibilities have been observed. Amongst the most common ones is linking code compiled with different
|
||||
@@ -73,8 +57,6 @@ graph
|
||||
app --> library
|
||||
```
|
||||
|
||||
<p class="nj-caption" markdown>The application uses the library with `JSON_DIAGNOSTICS=1` and links `some library`, which uses the same library version with `JSON_DIAGNOSTICS=0`. Arrows point from a component to what it uses.</p>
|
||||
|
||||
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.
|
||||
|
||||
@@ -13,8 +13,6 @@ flowchart LR
|
||||
A --> V["bool: is the input valid JSON?"]
|
||||
```
|
||||
|
||||
<p class="nj-caption" markdown>The three entry points for parsing: `parse()` builds a `basic_json` value, optionally filtered by a parser callback, `sax_parse()` delivers events to a SAX handler, and `accept()` only checks whether the input is valid.</p>
|
||||
|
||||
## Input
|
||||
|
||||
The [`parse`](../../api/basic_json/parse.md) function reads a JSON value from an input. The input can be
|
||||
|
||||
@@ -17,8 +17,6 @@ flowchart TD
|
||||
H -->|"yes"| I["stop early with SAX, or read through a view"]
|
||||
```
|
||||
|
||||
<p class="nj-caption" markdown>Questions about the input and the approach this page describes for each; an input can match more than one question.</p>
|
||||
|
||||
## Several values in one stream
|
||||
|
||||
For newline-delimited input, read line by line and parse each line, as described in [JSON Lines](json_lines.md). For
|
||||
@@ -82,14 +80,6 @@ exception is one past the buffer size in the first case:
|
||||
The example feeds a document in five chunks. The first four are reported as incomplete, and a syntax error is reported as
|
||||
such, not as missing data.
|
||||
|
||||
The chunks of the example, and the bytes each attempt parses again:
|
||||
|
||||
<div class="nj-fig-wrap" markdown>
|
||||
--8<-- "images/chunk_buffering.svg"
|
||||
</div>
|
||||
|
||||
<p class="nj-caption" markdown>Each row is one parse attempt on the growing buffer: an error at the byte after the end of the buffer means the value is incomplete, an error before the end is a real syntax error. The last line adds up the bytes parsed over all attempts.</p>
|
||||
|
||||
!!! warning "Limits of buffering"
|
||||
|
||||
- The buffer must contain exactly one value. Data that belongs to the next value is a syntax error. Use framing if
|
||||
@@ -103,14 +93,6 @@ The chunks of the example, and the bytes each attempt parses again:
|
||||
|
||||
The input does not have to become one huge `json` value. The two tools below process it piece by piece.
|
||||
|
||||
How the memory use develops while a large array of records is parsed (illustrative, not a measurement):
|
||||
|
||||
<div class="nj-fig-wrap" markdown>
|
||||
--8<-- "images/memory_over_time.svg"
|
||||
</div>
|
||||
|
||||
<p class="nj-caption" markdown>Memory use over the number of records parsed: `parse()` keeps the whole tree, `json_document` the text plus its index, a discarding callback one record at a time, and SAX only what the handler keeps.</p>
|
||||
|
||||
### Handle and discard elements with a callback
|
||||
|
||||
A [parser callback](parser_callbacks.md) is called for every finished value. If it returns `#!cpp false`, the value is
|
||||
|
||||
@@ -29,8 +29,6 @@ class sax_t ["json::sax_t"] {
|
||||
}
|
||||
```
|
||||
|
||||
<p class="nj-caption" markdown>The interface `json::sax_t`: one function per event, each returning `bool`; the functions marked with `*` are pure virtual.</p>
|
||||
|
||||
```cpp
|
||||
// called when null is parsed
|
||||
bool null();
|
||||
@@ -64,34 +62,6 @@ bool parse_error(std::size_t position, const std::string& last_token, const json
|
||||
|
||||
The return value of each function determines whether parsing should proceed.
|
||||
|
||||
## Stepping through the events
|
||||
|
||||
The events for a small input, step by step, and what two different handlers do with them. Press *Play* or step with *Next*:
|
||||
|
||||
<div class="nj-sax nj-fig" id="sax-event-stepper" data-nj-sax role="group" aria-label="SAX events for the input {"a":[1,true],"b":"x"}, and the state of a handler after each event">
|
||||
<div class="nj-sax__lane nj-sax__lane--text"><p class="nj-sax__h">input</p><p class="nj-sax__text"><code class="nj-sax__src">{"a":[1,true],"b":"x"}</code></p></div>
|
||||
<div class="nj-sax__lane nj-sax__lane--events"><p class="nj-sax__h">events, in the order the parser calls them</p><ol class="nj-sax__events">
|
||||
<li class="nj-sax-ev nj-sax-ev--os"><code>start_object(-1)</code></li>
|
||||
<li class="nj-sax-ev nj-sax-ev--k"><code>key("a")</code></li>
|
||||
<li class="nj-sax-ev nj-sax-ev--as"><code>start_array(-1)</code></li>
|
||||
<li class="nj-sax-ev nj-sax-ev--v"><code>number_unsigned(1)</code></li>
|
||||
<li class="nj-sax-ev nj-sax-ev--v"><code>boolean(true)</code></li>
|
||||
<li class="nj-sax-ev nj-sax-ev--ae"><code>end_array()</code></li>
|
||||
<li class="nj-sax-ev nj-sax-ev--k"><code>key("b")</code></li>
|
||||
<li class="nj-sax-ev nj-sax-ev--v"><code>string("x")</code></li>
|
||||
<li class="nj-sax-ev nj-sax-ev--oe"><code>end_object()</code></li>
|
||||
</ol></div>
|
||||
<div class="nj-sax__lane nj-sax__lane--state"><p class="nj-sax__h">handler: build a value tree, as <code>parse</code> does</p><div class="nj-sax__state"><pre class="nj-sax__tree"><code>{
|
||||
"a": [
|
||||
1,
|
||||
true
|
||||
],
|
||||
"b": "x"
|
||||
}</code></pre><p class="nj-sax__note">After <code>end_object()</code> the tree is complete and no container is open. The number of elements is passed as -1: the parser does not know it in advance.</p></div></div>
|
||||
</div>
|
||||
|
||||
<p class="nj-caption" markdown>The three lanes show the input consumed so far, the events called so far, and the state of the selected handler (*build a tree* or *keep only /b*). Check *return false at this event* to stop the parse at the current event and see which events are no longer called.</p>
|
||||
|
||||
To implement your own SAX handler, proceed as follows:
|
||||
|
||||
1. Implement the SAX interface in a class. You can use class `nlohmann::json_sax<json>` as base class, but you can also use any class where the functions described above are implemented and public.
|
||||
|
||||
@@ -96,17 +96,6 @@ comparison for text-heavy documents (63.5%-87.5%), at the cost of an
|
||||
whether it is worth the loss of human readability at all -- depends on the actual data; see the
|
||||
[comparison tables](binary_formats/index.md#comparison) before choosing one.
|
||||
|
||||
<div class="nj-charts-grid-wrap" markdown>
|
||||
<div class="nj-fig-wrap" markdown>
|
||||
--8<-- "images/binary_sizes_canada.svg"
|
||||
</div>
|
||||
<div class="nj-fig-wrap" markdown>
|
||||
--8<-- "images/binary_sizes_jeopardy.svg"
|
||||
</div>
|
||||
</div>
|
||||
<p class="nj-charts-caption" markdown>Two of the four panels from the [size comparison](binary_formats/index.md#sizes);
|
||||
the smallest format per file is drawn in a stronger colour than the others.</p>
|
||||
|
||||
## Object type: `json` vs. `ordered_json`
|
||||
|
||||
The default [`json`](../api/json.md) type stores object keys in a `#!cpp std::map`, giving logarithmic-time lookup,
|
||||
@@ -119,13 +108,6 @@ read. The [measurements on the `ordered_map` page](../api/ordered_map.md#complex
|
||||
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).
|
||||
|
||||
<div class="nj-fig-wrap" markdown>
|
||||
--8<-- "images/ordered_json_scaling.svg"
|
||||
</div>
|
||||
<p class="nj-charts-caption" markdown>Parsing a flat object of `n` keys, measured with `-O2 -DNDEBUG`; all
|
||||
four sizes from the [table on the `ordered_map` page](../api/ordered_map.md#complexity), both
|
||||
axes logarithmic.</p>
|
||||
|
||||
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](types/template_parameters.md#objecttype) can be
|
||||
set to a different container instead: `#!cpp nlohmann::fifo_map` keeps insertion order with a real lookup index
|
||||
|
||||
@@ -64,8 +64,6 @@ basic_json .. json_value
|
||||
basic_json .. value_t
|
||||
```
|
||||
|
||||
<p class="nj-caption" markdown>Storage of a `basic_json` value: the enumeration `value_t` holds the type, and the union `json_value` holds the value, as a pointer for objects, arrays, strings, and binary values and directly for booleans and numbers.</p>
|
||||
|
||||
## Template arguments
|
||||
|
||||
The data types to store a JSON value are derived from the template arguments passed to class `basic_json`:
|
||||
|
||||
@@ -27,11 +27,7 @@ JSON defines the syntax of numbers as follows:
|
||||
|
||||
The following railroad diagram from [json.org](https://json.org) visualizes the number syntax:
|
||||
|
||||
<div class="railroad-wrap" markdown>
|
||||
--8<-- "images/json_syntax_number.svg"
|
||||
</div>
|
||||
|
||||
<p class="nj-caption" markdown>Read the diagram from left to right: every path along the lines spells a valid number, made of an optional minus sign, an integer part, an optional fraction, and an optional exponent.</p>
|
||||

|
||||
|
||||
### Number interoperability
|
||||
|
||||
@@ -73,17 +69,15 @@ otherwise, it uses unsigned integer storage.
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A["number literal"] --> B{{"has a fraction (.) or exponent (e/E)?"}}
|
||||
A["number literal"] --> B{"has a fraction (.) or exponent (e/E)?"}
|
||||
B -->|"yes"| F["number_float_t"]
|
||||
B -->|"no"| C{{"has a leading minus sign?"}}
|
||||
B -->|"no"| C{"has a leading minus sign?"}
|
||||
C -->|"yes"| D["try number_integer_t"]
|
||||
C -->|"no"| E["try number_unsigned_t"]
|
||||
D -->|"overflow"| F
|
||||
E -->|"overflow"| F
|
||||
```
|
||||
|
||||
<p class="nj-caption" markdown>How the parser picks the storage type of a number literal: a fraction or exponent always gives `number_float_t`; otherwise the sign selects the signed or unsigned integer type, and a value that overflows it is stored as `number_float_t`.</p>
|
||||
|
||||
!!! info "Notes"
|
||||
|
||||
- Numbers with a decimal digit or scientific notation are always stored as `#!c double`.
|
||||
@@ -137,32 +131,6 @@ The JSON number grammar allows for different ways to express zero, and this libr
|
||||
|
||||
That is, `-0` is stored as a signed integer, but the serialization does not reproduce the `-`.
|
||||
|
||||
The literals mentioned on this page, parsed with `json::parse` and serialized with `dump()` (checked against the
|
||||
library; pick one or type it to see the row):
|
||||
|
||||
<div class="nj-charts-num" markdown>
|
||||
|
||||
| Literal | Stored as (`type()`) | `dump()` |
|
||||
|---------|----------------------|----------|
|
||||
| `0` | `number_unsigned` (`std::uint64_t`) | `0` |
|
||||
| `-0` | `number_integer` (`std::int64_t`) | `0` |
|
||||
| `-0.0` | `number_float` (`double`) | `-0.0` |
|
||||
| `1E3` | `number_float` (`double`) | `1000.0` |
|
||||
| `-12345678912345789123456789` | `number_float` (`double`) | `-1.2345678912345788e+25` |
|
||||
| `18446744073709551615` | `number_unsigned` (`std::uint64_t`) | `18446744073709551615` |
|
||||
| `18446744073709551616` | `number_float` (`double`) | `1.8446744073709552e+19` |
|
||||
| `-9223372036854775808` | `number_integer` (`std::int64_t`) | `-9223372036854775808` |
|
||||
| `1E400` | exception `out_of_range.406` | (nothing, parsing fails) |
|
||||
| `1E-400` | `number_float` (`double`) | `0.0` |
|
||||
| `3.141592653589793238462643383279` | `number_float` (`double`) | `3.141592653589793` |
|
||||
| `2555.5599999999999` | `number_float` (`double`) | `2555.56` |
|
||||
| `0.0000972439793401814` | `number_float` (`double`) | `9.72439793401814e-05` |
|
||||
| `12345E-5` | `number_float` (`double`) | `0.12345` |
|
||||
|
||||
</div>
|
||||
|
||||
<p class="nj-caption" markdown>Each row shows how a literal is stored and how `dump()` writes it back. The explorer only knows the literals in this list; other input is reported as not in the verified list.</p>
|
||||
|
||||
### Number serialization
|
||||
|
||||
- Integer numbers are serialized as is; that is, no scientific notation is used.
|
||||
@@ -361,8 +329,6 @@ the stored number:
|
||||
| [`type_name()`](../../api/basic_json/type_name.md) | `#!c "number"` | `#!c "number"` | `#!c "number"` | `#!c "string"` |
|
||||
| [`type()`](../../api/basic_json/type.md) | `number_unsigned` | `number_integer` | `number_float` | `string` |
|
||||
|
||||
<p class="nj-table-caption" markdown>Return value of each function for a value that stores an unsigned integer, a signed integer, or a floating-point number, and for a string for comparison.</p>
|
||||
|
||||
### Template number types
|
||||
|
||||
The number types can be changed with template parameters.
|
||||
|
||||
@@ -368,8 +368,7 @@ using array_t = ArrayType<basic_json, AllocatorType<basic_json>>;
|
||||
`#!cpp std::from_chars` is not available or declines the token, and `std::strtold` reads up to the null character. A type whose `data()`
|
||||
is not null-terminated does not fail to compile; with such a `NumberFloatType` it can silently misparse
|
||||
floating-point numbers.
|
||||
- `append(const char*, size_type)`, used by [`dump`](../../api/basic_json/dump.md), and `append(const StringType&)`,
|
||||
used by the CBOR reader for indefinite-length strings. The library's internal string concatenation additionally has
|
||||
- `append(const char*, size_type)`, used by [`dump`](../../api/basic_json/dump.md) and by the binary readers. The library's internal string concatenation additionally has
|
||||
to append a `#!cpp char` and a `#!cpp const char*`; for each it selects between `append(arg)`, `#!cpp operator+=`,
|
||||
`append(first, last)`, and `append(data, size)`.
|
||||
- The comparison operator `==` against another `StringType`, and `<` for use as a key of the chosen
|
||||
@@ -678,8 +677,7 @@ using binary_t = nlohmann::byte_container_with_subtype<BinaryType>;
|
||||
[`StringType`](#stringtype), whose non-`#!cpp const` `data()` is C++17 and later only.
|
||||
- Default-constructible, copy-constructible, and move-constructible.
|
||||
- Member functions `size()`, `empty()`, `data()`, `resize()`, `operator[]`, `back()`, `begin()`, `end()`, `cbegin()`,
|
||||
and `cend()` with random-access iterators, 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.
|
||||
and `cend()` with random-access iterators. `push_back()` is **not** required.
|
||||
- Comparison operators: `==` is used by
|
||||
[`byte_container_with_subtype`](../../api/byte_container_with_subtype/index.md), the relational operators by
|
||||
[`basic_json`'s comparison operators](../../api/basic_json/operator_le.md).
|
||||
|
||||
@@ -32,8 +32,6 @@ flowchart LR
|
||||
oa --> output
|
||||
```
|
||||
|
||||
<p class="nj-caption" markdown>Data flow through the library: input runs left to right through an input adapter and the lexer and parser (JSON text) or the `binary_reader` (binary formats) into SAX events, which build the value tree; the `serializer` or the `binary_writer` writes the tree to an output adapter.</p>
|
||||
|
||||
- **JSON text** is read by an [input adapter](#input-adapters), tokenized by the lexer, and turned into SAX events by
|
||||
the parser.
|
||||
- **Binary formats** (BJData, BON8, BSON, CBOR, MessagePack, UBJSON) are read by an input adapter and turned into the same SAX
|
||||
@@ -194,8 +192,6 @@ packet-beta
|
||||
96-127: "next"
|
||||
```
|
||||
|
||||
<p class="nj-caption" markdown>Layout of one 16-byte node of a JSON view index. Each row is 32 bits wide, and the numbers are the bit offsets of the fields `kind`, `flags`, `extra`, `off`, `len`, and `next`.</p>
|
||||
|
||||
| Bytes | Field | Type | Contents |
|
||||
|-------|---------|------------|-------------------------------------------------------------------------------------------------------------------------------|
|
||||
| 0 | `kind` | `uint8_t` | the type, numbered as [`value_t`](../api/basic_json/value_t.md): 0 null, 1 object, 2 array, 3 string, 4 boolean, 5 signed integer, 6 unsigned integer, 7 float; 10 for a link (see below). There is no node for a discarded value: a [discarded](../api/basic_json_view/is_discarded.md) view has none |
|
||||
@@ -205,8 +201,6 @@ packet-beta
|
||||
| 8-11 | `len` | `uint32_t` | strings: the length after decoding; floats and literals: the length of the token; arrays and objects: the number of elements |
|
||||
| 12-15 | `next` | `uint32_t` | arrays and objects: the number of nodes of the subtree, including the node itself |
|
||||
|
||||
<p class="nj-table-caption" markdown>Fields of a node, by their byte offset within the 16-byte node. Integers use bytes 8-15 differently, see below.</p>
|
||||
|
||||
- **Integers** keep their converted value in bytes 8-15 instead of `len` and `next`; the length of their token follows
|
||||
from the number of digits in `extra` (and the sign). Non-negative integers are unsigned integers, as with
|
||||
[`parse`](../api/basic_json/parse.md).
|
||||
@@ -240,8 +234,6 @@ flowchart LR
|
||||
n2 -. next .-> e
|
||||
```
|
||||
|
||||
<p class="nj-caption" markdown>The five nodes of `#!json {"a": [1, 2.5]}` in document order. Solid arrows lead from each node to the one after it; dotted arrows show where `next` leads from the object and the array, past their subtrees.</p>
|
||||
|
||||
| Node | `kind` | `extra` | `off` | `len` | `next` |
|
||||
|------|----------------------|---------|-------|-------|--------|
|
||||
| 0 | 1 (object) | 0 | 0 | 1 | 5 |
|
||||
@@ -250,8 +242,6 @@ flowchart LR
|
||||
| 3 | 6 (unsigned integer) | 0x0001 | 7 | - | - |
|
||||
| 4 | 7 (float) | 0x0101 | 10 | 3 | 0 |
|
||||
|
||||
<p class="nj-table-caption" markdown>Fields of the five nodes of `#!json {"a": [1, 2.5]}`. `off` is the byte offset in the text, and - marks the bytes 8-15 that hold the integer's value instead of `len` and `next`.</p>
|
||||
|
||||
All `flags` are 0. The integer's bytes 8-15 hold its value, 1; its `extra` says it has one digit. The float's `extra`
|
||||
says it has one integer and one fraction digit, and its `len` is that of the token `2.5`.
|
||||
|
||||
@@ -297,9 +287,8 @@ template<class T>
|
||||
std::size_t get_elements(T* dest, std::size_t count = 1);
|
||||
```
|
||||
|
||||
The lexer detects two optional extensions at compile time. `iterator_input_adapter` provides both, and only for
|
||||
random-access input of single-byte characters. `input_stream_adapter` provides the second one (as a window onto the
|
||||
streambuf's buffer) unless `JSON_DISABLE_STREAM_BULK_SCAN` is defined:
|
||||
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. With `get_read_count()` and
|
||||
@@ -317,40 +306,6 @@ The function `input_adapter` picks the right adapter for the argument passed to
|
||||
- `input_stream_adapter` reads from a `std::istream`.
|
||||
- `file_input_adapter` reads from a `std::FILE*`.
|
||||
|
||||
The adapters have no common base class: the lexer and the parser are templates on the adapter type, and
|
||||
`wide_string_input_adapter` wraps an `iterator_input_adapter`:
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class input_adapter ["input adapter"] {
|
||||
<<concept>>
|
||||
+char_type
|
||||
+get_character() int_type
|
||||
+get_elements(T* dest, size_t count) size_t
|
||||
}
|
||||
class iterator_input_adapter {
|
||||
-IteratorType current
|
||||
-SentinelType end
|
||||
}
|
||||
class wide_string_input_adapter {
|
||||
-BaseInputAdapter base_adapter
|
||||
}
|
||||
class input_stream_adapter {
|
||||
-std::istream* is
|
||||
-std::streambuf* sb
|
||||
}
|
||||
class file_input_adapter {
|
||||
-std::FILE* m_file
|
||||
}
|
||||
input_adapter <|.. iterator_input_adapter
|
||||
input_adapter <|.. wide_string_input_adapter
|
||||
input_adapter <|.. input_stream_adapter
|
||||
input_adapter <|.. file_input_adapter
|
||||
wide_string_input_adapter o-- iterator_input_adapter : converts to UTF-8
|
||||
```
|
||||
|
||||
<p class="nj-caption" markdown>The input adapters as a class diagram. The dotted arrows mean that each adapter implements the input adapter concept; the diamond shows that `wide_string_input_adapter` holds an `iterator_input_adapter`.</p>
|
||||
|
||||
## SAX interface
|
||||
|
||||
The parser does not build values itself. It reports what it reads as events to a [SAX](../features/parsing/sax_interface.md)
|
||||
@@ -366,7 +321,6 @@ The library comes with two consumers in `detail/input/json_sax.hpp`:
|
||||
|
||||
The `binary_reader` emits the same events for binary formats, so [`sax_parse`](../api/basic_json/sax_parse.md) works
|
||||
with a user-defined consumer for JSON and for all binary formats alike.
|
||||
The [SAX event stepper](../features/parsing/sax_interface.md#sax-event-stepper) shows the events for a small input.
|
||||
|
||||
## Output adapters
|
||||
|
||||
@@ -385,36 +339,6 @@ The `serializer` (used by [`dump`](../api/basic_json/dump.md) and [`operator<<`]
|
||||
- `output_stream_adapter` writes to a `std::ostream`.
|
||||
- `output_string_adapter` appends to a string.
|
||||
|
||||
They implement the abstract class `output_adapter_protocol`. The class `output_adapter` creates the one that matches
|
||||
its argument and holds it in a `std::shared_ptr` (`output_adapter_t`):
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class output_adapter_protocol~CharType~ {
|
||||
<<interface>>
|
||||
+write_character(CharType c)*
|
||||
+write_characters(const CharType* s, size_t length)*
|
||||
}
|
||||
class output_vector_adapter {
|
||||
-std::vector& v
|
||||
}
|
||||
class output_stream_adapter {
|
||||
-std::basic_ostream& stream
|
||||
}
|
||||
class output_string_adapter {
|
||||
-StringType& str
|
||||
}
|
||||
class output_adapter {
|
||||
-output_adapter_t oa
|
||||
}
|
||||
output_adapter_protocol <|-- output_vector_adapter
|
||||
output_adapter_protocol <|-- output_stream_adapter
|
||||
output_adapter_protocol <|-- output_string_adapter
|
||||
output_adapter o-- output_adapter_protocol : shared_ptr
|
||||
```
|
||||
|
||||
<p class="nj-caption" markdown>The output adapters as a class diagram. The three adapters derive from `output_adapter_protocol` (solid arrows), and `output_adapter` holds one of them through a `shared_ptr` (diamond).</p>
|
||||
|
||||
The `binary_writer` does not call an adapter for every byte. The `to_*` functions that return a `std::vector` write
|
||||
into the vector through a sink (`output_vector_sink`) that is not virtual. The functions that take an output adapter
|
||||
write through a sink (`output_adapter_sink`) that collects the output in a buffer of one kibibyte and passes it to the
|
||||
|
||||
@@ -6,35 +6,35 @@
|
||||
|
||||
All exceptions inherit from class `json::exception` (which in turn inherits from `std::exception`). It is used as the base class for all exceptions thrown by the `basic_json` class. This class can hence be used as "wildcard" to catch exceptions.
|
||||
|
||||
The map shows the class tree and every exception id documented on this page; click an id to jump to its section.
|
||||
``` mermaid
|
||||
classDiagram
|
||||
direction LR
|
||||
class `std::exception` {
|
||||
<<interface>>
|
||||
}
|
||||
|
||||
<div class="nj-fig-wrap" markdown>
|
||||
--8<-- "images/exception_map.svg"
|
||||
</div>
|
||||
class `json::exception` {
|
||||
+const int id
|
||||
+const char* what() const
|
||||
}
|
||||
|
||||
<p class="nj-caption" markdown>The exception classes from `std::exception` down to the five families, each with the ids it can throw. Every id chip links to the section that describes it.</p>
|
||||
class `json::parse_error` {
|
||||
+const std::size_t byte
|
||||
}
|
||||
|
||||
Which exception an element access throws depends on the function and on the type of the value:
|
||||
class `json::invalid_iterator`
|
||||
class `json::type_error`
|
||||
class `json::out_of_range`
|
||||
class `json::other_error`
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
S{{"which call?"}} -->|"at(key)"| A{{"j is"}}
|
||||
A -->|"object, key missing"| A1["out_of_range.403"]
|
||||
A -->|"array or null"| A2["type_error.304"]
|
||||
S -->|"at(index)"| B{{"j is"}}
|
||||
B -->|"array, index >= size()"| B1["out_of_range.401"]
|
||||
B -->|"object or null"| B2["type_error.304"]
|
||||
S -->|"non-const operator[](key)"| C{{"j is"}}
|
||||
C -->|"object or null"| C1["no exception: a missing key is inserted as null"]
|
||||
C -->|"array"| C2["type_error.305"]
|
||||
S -->|"value(key, default)"| D{{"j is"}}
|
||||
D -->|"object, key missing"| D1["no exception: returns the default"]
|
||||
D -->|"object, incompatible value type"| D2["type_error.302"]
|
||||
D -->|"array or null"| D3["type_error.306"]
|
||||
`std::exception` <|-- `json::exception`
|
||||
`json::exception` <|-- `json::parse_error`
|
||||
`json::exception` <|-- `json::invalid_iterator`
|
||||
`json::exception` <|-- `json::type_error`
|
||||
`json::exception` <|-- `json::out_of_range`
|
||||
`json::exception` <|-- `json::other_error`
|
||||
```
|
||||
|
||||
<p class="nj-caption" markdown>Exceptions thrown by element access. Start at the call on the left, follow the edge that matches the type of `j`, and read the exception id (or "no exception") in the box at the end.</p>
|
||||
|
||||
### Switch off exceptions
|
||||
|
||||
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`](../api/macros/json_noexception.md). In this case, exceptions are replaced by `abort()` calls. You can further control this behavior by defining `JSON_THROW_USER` (overriding `#!cpp throw`), `JSON_TRY_USER` (overriding `#!cpp try`), and `JSON_CATCH_USER` (overriding `#!cpp catch`).
|
||||
@@ -330,7 +330,7 @@ where they cannot be resolved.
|
||||
### json.exception.parse_error.110
|
||||
|
||||
When parsing a [binary format](../features/binary_formats/index.md), the byte vector ends before the complete value has
|
||||
been read.
|
||||
been read, or (with `strict = true`) further bytes follow the value.
|
||||
|
||||
!!! failure "Example messages"
|
||||
|
||||
@@ -418,13 +418,16 @@ The parsing of the corresponding BSON record type is not implemented (yet).
|
||||
|
||||
### json.exception.parse_error.115
|
||||
|
||||
A UBJSON high-precision number could not be parsed.
|
||||
A UBJSON or BJData high-precision number could not be parsed.
|
||||
|
||||
!!! failure "Example message"
|
||||
!!! failure "Example messages"
|
||||
|
||||
```
|
||||
[json.exception.parse_error.115] parse error at byte 5: syntax error while parsing UBJSON high-precision number: invalid number text: 1A
|
||||
```
|
||||
```
|
||||
[json.exception.parse_error.115] parse error at byte 5: syntax error while parsing BJData high-precision number: invalid number text: 1A
|
||||
```
|
||||
|
||||
### json.exception.parse_error.116
|
||||
|
||||
@@ -1025,7 +1028,7 @@ exception, because they serialize integers beyond 64 bits as high-precision numb
|
||||
- Since version 3.12.0, integer numbers beyond int64 are serialized as uint64 BSON numbers.
|
||||
|
||||
Before version 3.13.0, CBOR, MessagePack, and BSON silently truncated integers wider than 64 bits, and BJData
|
||||
truncated unsigned integers wider than 64 bits.
|
||||
truncated unsigned integers wider than 64 bits that were elements of ND-arrays with `"_ArrayType_": "uint64"`.
|
||||
|
||||
!!! failure "Example messages"
|
||||
|
||||
@@ -1045,8 +1048,8 @@ or the encoded length for [CBOR](../features/binary_formats/cbor.md).
|
||||
The exception is also thrown for a [UBJSON](../features/binary_formats/ubjson.md) 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`](../api/basic_json/to_ubjson.md) writes longer arrays of these types without the size and type annotation,
|
||||
so any value it produces can still be read back.
|
||||
[`to_ubjson`](../api/basic_json/to_ubjson.md) writes longer arrays of these types without the `$` type annotation (the `#`
|
||||
count and one marker per element are kept), so any value it produces can still be read back.
|
||||
|
||||
!!! failure "Example messages"
|
||||
|
||||
@@ -1153,14 +1156,18 @@ A JSON Patch `move` operation's `"from"` location is a proper prefix of its `"pa
|
||||
### json.exception.out_of_range.415
|
||||
|
||||
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`](../api/byte_container_with_subtype/index.md) whose subtype exceeds 255.
|
||||
[`byte_container_with_subtype`](../api/byte_container_with_subtype/index.md) whose subtype exceeds 255, the largest value the library can store in that byte.
|
||||
|
||||
!!! failure "Example message"
|
||||
!!! failure "Example messages"
|
||||
|
||||
```
|
||||
[json.exception.out_of_range.415] subtype 70000 is too large for the MessagePack ext type (max 255)
|
||||
```
|
||||
|
||||
```
|
||||
[json.exception.out_of_range.415] subtype 70000 is too large for the BSON binary subtype (max 255)
|
||||
```
|
||||
|
||||
!!! note
|
||||
|
||||
This exception was added in version 3.13.0. Before that, subtypes above 255 were silently truncated modulo 256 instead of raising an error.
|
||||
@@ -1229,7 +1236,9 @@ A JSON Patch operation 'test' failed. The unsuccessful operation is also printed
|
||||
### json.exception.other_error.502
|
||||
|
||||
[`to_ubjson`](../api/basic_json/to_ubjson.md) and [`to_bjdata`](../api/basic_json/to_bjdata.md) were called with
|
||||
`use_type = true` but `use_size = false`. UBJSON requires a size marker (`#`) after a type marker (`$`).
|
||||
`use_type = true` but `use_size = false`, and the value contains a non-empty array or object (or, with BJData Draft 3,
|
||||
any binary value). UBJSON requires a size marker (`#`) after a type marker (`$`); scalars and empty arrays or objects
|
||||
do not throw.
|
||||
|
||||
!!! failure "Example message"
|
||||
|
||||
|
||||
@@ -192,8 +192,6 @@ The value is a `json`, and printing it produces JSON text. Convert it first: `#!
|
||||
|
||||
Use `contains` or `find`. Do not test with the non-const `operator[]`: like `std::map::operator[]`, it inserts a `null`
|
||||
value for a missing key. See [Does this key exist?](../features/element_access/index.md#does-this-key-exist).
|
||||
For choosing between `value`, `contains`/`find`, `at`, `operator[]`, and JSON Pointer, see the decision flow in
|
||||
[Element access](../features/element_access/index.md).
|
||||
|
||||
### Reading a value with a fallback
|
||||
|
||||
|
||||
@@ -14,14 +14,6 @@ changed in it. The API overview is generated from the "Version history" section
|
||||
[API pages](../../api/basic_json/index.md); it is not a change log, but helps to see whether a feature is available in
|
||||
the version you use.
|
||||
|
||||
All releases at a glance (hover a marker for its version and date):
|
||||
|
||||
<div class="nj-fig-wrap" markdown>
|
||||
--8<-- "images/release_timeline.svg"
|
||||
</div>
|
||||
|
||||
<p class="nj-caption" markdown>Releases from 1.0.0 to the latest one, on a time axis by year. Filled dots with a version label are minor or major releases, rings are patch releases.</p>
|
||||
|
||||
## Unreleased
|
||||
|
||||
| Release | Date | Summary |
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
<svg class="nj-fig nj-charts nj-charts--sizes" viewBox="0 0 340 220" role="img" aria-labelledby="nj-charts-bs-canada nj-charts-bs-canada-d" xmlns="http://www.w3.org/2000/svg">
|
||||
<title id="nj-charts-bs-canada">Size of canada.json in each binary format relative to minified J​SON</title>
|
||||
<desc id="nj-charts-bs-canada-d">B​JData 53.2 %; B​ON8 50.5 %; B​SON 85.8 %; C​BOR 50.5 %; MessagePack 50.5 %; U​BJSON 53.2 %. Smallest: B​ON8 and C​BOR and MessagePack.</desc>
|
||||
<text class="nj-charts-panel" x="8" y="18">canada.json</text>
|
||||
<line class="nj-charts-grid" x1="104" y1="40" x2="104" y2="196"/>
|
||||
<text class="nj-charts-tick" x="104" y="211">0 %</text>
|
||||
<line class="nj-charts-grid" x1="186.727" y1="40" x2="186.727" y2="196"/>
|
||||
<text class="nj-charts-tick" x="186.727" y="211">50 %</text>
|
||||
<text class="nj-charts-rowlabel nj-charts-fmt" x="96" y="58.5">B​JData</text>
|
||||
<path class="nj-charts-c1 nj-charts-dim" d="M104 46 H188.022 Q192.022 46 192.022 50 V58 Q192.022 62 188.022 62 H104 Z"><title>canada.json, B​JData: 53.2 % of minified J​SON</title></path>
|
||||
<text class="nj-charts-rowlabel nj-charts-fmt nj-charts-best" x="96" y="84.5">B​ON8</text>
|
||||
<path class="nj-charts-c2" d="M104 72 H183.555 Q187.555 72 187.555 76 V84 Q187.555 88 183.555 88 H104 Z"><title>canada.json, B​ON8: 50.5 % of minified J​SON (smallest)</title></path>
|
||||
<text class="nj-charts-rowlabel nj-charts-fmt" x="96" y="110.5">B​SON</text>
|
||||
<path class="nj-charts-c3 nj-charts-dim" d="M104 98 H241.96 Q245.96 98 245.96 102 V110 Q245.96 114 241.96 114 H104 Z"><title>canada.json, B​SON: 85.8 % of minified J​SON</title></path>
|
||||
<text class="nj-charts-rowlabel nj-charts-fmt nj-charts-best" x="96" y="136.5">C​BOR</text>
|
||||
<path class="nj-charts-c4" d="M104 124 H183.555 Q187.555 124 187.555 128 V136 Q187.555 140 183.555 140 H104 Z"><title>canada.json, C​BOR: 50.5 % of minified J​SON (smallest)</title></path>
|
||||
<text class="nj-charts-rowlabel nj-charts-fmt nj-charts-best" x="96" y="162.5">MessagePack</text>
|
||||
<path class="nj-charts-c5" d="M104 150 H183.555 Q187.555 150 187.555 154 V162 Q187.555 166 183.555 166 H104 Z"><title>canada.json, MessagePack: 50.5 % of minified J​SON (smallest)</title></path>
|
||||
<text class="nj-charts-rowlabel nj-charts-fmt" x="96" y="188.5">U​BJSON</text>
|
||||
<path class="nj-charts-c6 nj-charts-dim" d="M104 176 H188.022 Q192.022 176 192.022 180 V188 Q192.022 192 188.022 192 H104 Z"><title>canada.json, U​BJSON: 53.2 % of minified J​SON</title></path>
|
||||
<line class="nj-charts-ref" x1="269.455" y1="36" x2="269.455" y2="196"/>
|
||||
<text class="nj-charts-tick nj-charts-tick--r" x="271.455" y="32">minified J​SON = 100 %</text>
|
||||
<text class="nj-charts-tick" x="269.455" y="211">100 %</text>
|
||||
<text class="nj-charts-val" x="197.022" y="58.5">53.2 %</text>
|
||||
<text class="nj-charts-val nj-charts-best" x="192.555" y="84.5">50.5 %</text>
|
||||
<text class="nj-charts-val" x="250.96" y="110.5">85.8 %</text>
|
||||
<text class="nj-charts-val nj-charts-best" x="192.555" y="136.5">50.5 %</text>
|
||||
<text class="nj-charts-val nj-charts-best" x="192.555" y="162.5">50.5 %</text>
|
||||
<text class="nj-charts-val" x="197.022" y="188.5">53.2 %</text>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 3.2 KiB |
@@ -1,30 +0,0 @@
|
||||
<svg class="nj-fig nj-charts nj-charts--sizes" viewBox="0 0 340 220" role="img" aria-labelledby="nj-charts-bs-citm_catalog nj-charts-bs-citm_catalog-d" xmlns="http://www.w3.org/2000/svg">
|
||||
<title id="nj-charts-bs-citm_catalog">Size of citm_catalog.json in each binary format relative to minified J​SON</title>
|
||||
<desc id="nj-charts-bs-citm_catalog-d">B​JData 78.1 %; B​ON8 63.5 %; B​SON 95.8 %; C​BOR 68.4 %; MessagePack 68.5 %; U​BJSON 78.2 %. Smallest: B​ON8.</desc>
|
||||
<text class="nj-charts-panel" x="8" y="18">citm_catalog.json</text>
|
||||
<line class="nj-charts-grid" x1="104" y1="40" x2="104" y2="196"/>
|
||||
<text class="nj-charts-tick" x="104" y="211">0 %</text>
|
||||
<line class="nj-charts-grid" x1="186.727" y1="40" x2="186.727" y2="196"/>
|
||||
<text class="nj-charts-tick" x="186.727" y="211">50 %</text>
|
||||
<text class="nj-charts-rowlabel nj-charts-fmt" x="96" y="58.5">B​JData</text>
|
||||
<path class="nj-charts-c1 nj-charts-dim" d="M104 46 H229.22 Q233.22 46 233.22 50 V58 Q233.22 62 229.22 62 H104 Z"><title>citm_catalog.json, B​JData: 78.1 % of minified J​SON</title></path>
|
||||
<text class="nj-charts-rowlabel nj-charts-fmt nj-charts-best" x="96" y="84.5">B​ON8</text>
|
||||
<path class="nj-charts-c2" d="M104 72 H205.064 Q209.064 72 209.064 76 V84 Q209.064 88 205.064 88 H104 Z"><title>citm_catalog.json, B​ON8: 63.5 % of minified J​SON (smallest)</title></path>
|
||||
<text class="nj-charts-rowlabel nj-charts-fmt" x="96" y="110.5">B​SON</text>
|
||||
<path class="nj-charts-c3 nj-charts-dim" d="M104 98 H258.505 Q262.505 98 262.505 102 V110 Q262.505 114 258.505 114 H104 Z"><title>citm_catalog.json, B​SON: 95.8 % of minified J​SON</title></path>
|
||||
<text class="nj-charts-rowlabel nj-charts-fmt" x="96" y="136.5">C​BOR</text>
|
||||
<path class="nj-charts-c4 nj-charts-dim" d="M104 124 H213.171 Q217.171 124 217.171 128 V136 Q217.171 140 213.171 140 H104 Z"><title>citm_catalog.json, C​BOR: 68.4 % of minified J​SON</title></path>
|
||||
<text class="nj-charts-rowlabel nj-charts-fmt" x="96" y="162.5">MessagePack</text>
|
||||
<path class="nj-charts-c5 nj-charts-dim" d="M104 150 H213.336 Q217.336 150 217.336 154 V162 Q217.336 166 213.336 166 H104 Z"><title>citm_catalog.json, MessagePack: 68.5 % of minified J​SON</title></path>
|
||||
<text class="nj-charts-rowlabel nj-charts-fmt" x="96" y="188.5">U​BJSON</text>
|
||||
<path class="nj-charts-c6 nj-charts-dim" d="M104 176 H229.385 Q233.385 176 233.385 180 V188 Q233.385 192 229.385 192 H104 Z"><title>citm_catalog.json, U​BJSON: 78.2 % of minified J​SON</title></path>
|
||||
<line class="nj-charts-ref" x1="269.455" y1="36" x2="269.455" y2="196"/>
|
||||
<text class="nj-charts-tick nj-charts-tick--r" x="271.455" y="32">minified J​SON = 100 %</text>
|
||||
<text class="nj-charts-tick" x="269.455" y="211">100 %</text>
|
||||
<text class="nj-charts-val" x="238.22" y="58.5">78.1 %</text>
|
||||
<text class="nj-charts-val nj-charts-best" x="214.064" y="84.5">63.5 %</text>
|
||||
<text class="nj-charts-val" x="267.505" y="110.5">95.8 %</text>
|
||||
<text class="nj-charts-val" x="222.171" y="136.5">68.4 %</text>
|
||||
<text class="nj-charts-val" x="222.336" y="162.5">68.5 %</text>
|
||||
<text class="nj-charts-val" x="238.385" y="188.5">78.2 %</text>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 3.2 KiB |
@@ -1,30 +0,0 @@
|
||||
<svg class="nj-fig nj-charts nj-charts--sizes" viewBox="0 0 340 220" role="img" aria-labelledby="nj-charts-bs-jeopardy nj-charts-bs-jeopardy-d" xmlns="http://www.w3.org/2000/svg">
|
||||
<title id="nj-charts-bs-jeopardy">Size of jeopardy.json in each binary format relative to minified J​SON</title>
|
||||
<desc id="nj-charts-bs-jeopardy-d">B​JData 96.6 %; B​ON8 87.5 %; B​SON 106.7 %; C​BOR 88 %; MessagePack 87.9 %; U​BJSON 96.6 %. Smallest: B​ON8.</desc>
|
||||
<text class="nj-charts-panel" x="8" y="18">jeopardy.json</text>
|
||||
<line class="nj-charts-grid" x1="104" y1="40" x2="104" y2="196"/>
|
||||
<text class="nj-charts-tick" x="104" y="211">0 %</text>
|
||||
<line class="nj-charts-grid" x1="186.727" y1="40" x2="186.727" y2="196"/>
|
||||
<text class="nj-charts-tick" x="186.727" y="211">50 %</text>
|
||||
<text class="nj-charts-rowlabel nj-charts-fmt" x="96" y="58.5">B​JData</text>
|
||||
<path class="nj-charts-c1 nj-charts-dim" d="M104 46 H259.829 Q263.829 46 263.829 50 V58 Q263.829 62 259.829 62 H104 Z"><title>jeopardy.json, B​JData: 96.6 % of minified J​SON</title></path>
|
||||
<text class="nj-charts-rowlabel nj-charts-fmt nj-charts-best" x="96" y="84.5">B​ON8</text>
|
||||
<path class="nj-charts-c2" d="M104 72 H244.773 Q248.773 72 248.773 76 V84 Q248.773 88 244.773 88 H104 Z"><title>jeopardy.json, B​ON8: 87.5 % of minified J​SON (smallest)</title></path>
|
||||
<text class="nj-charts-rowlabel nj-charts-fmt" x="96" y="110.5">B​SON</text>
|
||||
<path class="nj-charts-c3 nj-charts-dim" d="M104 98 H276.54 Q280.54 98 280.54 102 V110 Q280.54 114 276.54 114 H104 Z"><title>jeopardy.json, B​SON: 106.7 % of minified J​SON</title></path>
|
||||
<text class="nj-charts-rowlabel nj-charts-fmt" x="96" y="136.5">C​BOR</text>
|
||||
<path class="nj-charts-c4 nj-charts-dim" d="M104 124 H245.6 Q249.6 124 249.6 128 V136 Q249.6 140 245.6 140 H104 Z"><title>jeopardy.json, C​BOR: 88 % of minified J​SON</title></path>
|
||||
<text class="nj-charts-rowlabel nj-charts-fmt" x="96" y="162.5">MessagePack</text>
|
||||
<path class="nj-charts-c5 nj-charts-dim" d="M104 150 H245.435 Q249.435 150 249.435 154 V162 Q249.435 166 245.435 166 H104 Z"><title>jeopardy.json, MessagePack: 87.9 % of minified J​SON</title></path>
|
||||
<text class="nj-charts-rowlabel nj-charts-fmt" x="96" y="188.5">U​BJSON</text>
|
||||
<path class="nj-charts-c6 nj-charts-dim" d="M104 176 H259.829 Q263.829 176 263.829 180 V188 Q263.829 192 259.829 192 H104 Z"><title>jeopardy.json, U​BJSON: 96.6 % of minified J​SON</title></path>
|
||||
<line class="nj-charts-ref" x1="269.455" y1="36" x2="269.455" y2="196"/>
|
||||
<text class="nj-charts-tick nj-charts-tick--r" x="271.455" y="32">minified J​SON = 100 %</text>
|
||||
<text class="nj-charts-tick" x="269.455" y="211">100 %</text>
|
||||
<text class="nj-charts-val" x="268.829" y="58.5">96.6 %</text>
|
||||
<text class="nj-charts-val nj-charts-best" x="253.773" y="84.5">87.5 %</text>
|
||||
<text class="nj-charts-val" x="285.54" y="110.5">106.7 %</text>
|
||||
<text class="nj-charts-val" x="254.6" y="136.5">88.0 %</text>
|
||||
<text class="nj-charts-val" x="254.435" y="162.5">87.9 %</text>
|
||||
<text class="nj-charts-val" x="268.829" y="188.5">96.6 %</text>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 3.1 KiB |
@@ -1,30 +0,0 @@
|
||||
<svg class="nj-fig nj-charts nj-charts--sizes" viewBox="0 0 340 220" role="img" aria-labelledby="nj-charts-bs-twitter nj-charts-bs-twitter-d" xmlns="http://www.w3.org/2000/svg">
|
||||
<title id="nj-charts-bs-twitter">Size of twitter.json in each binary format relative to minified J​SON</title>
|
||||
<desc id="nj-charts-bs-twitter-d">B​JData 91.1 %; B​ON8 83.8 %; B​SON 95.2 %; C​BOR 86.3 %; MessagePack 86 %; U​BJSON 91.3 %. Smallest: B​ON8.</desc>
|
||||
<text class="nj-charts-panel" x="8" y="18">twitter.json</text>
|
||||
<line class="nj-charts-grid" x1="104" y1="40" x2="104" y2="196"/>
|
||||
<text class="nj-charts-tick" x="104" y="211">0 %</text>
|
||||
<line class="nj-charts-grid" x1="186.727" y1="40" x2="186.727" y2="196"/>
|
||||
<text class="nj-charts-tick" x="186.727" y="211">50 %</text>
|
||||
<text class="nj-charts-rowlabel nj-charts-fmt" x="96" y="58.5">B​JData</text>
|
||||
<path class="nj-charts-c1 nj-charts-dim" d="M104 46 H250.729 Q254.729 46 254.729 50 V58 Q254.729 62 250.729 62 H104 Z"><title>twitter.json, B​JData: 91.1 % of minified J​SON</title></path>
|
||||
<text class="nj-charts-rowlabel nj-charts-fmt nj-charts-best" x="96" y="84.5">B​ON8</text>
|
||||
<path class="nj-charts-c2" d="M104 72 H238.651 Q242.651 72 242.651 76 V84 Q242.651 88 238.651 88 H104 Z"><title>twitter.json, B​ON8: 83.8 % of minified J​SON (smallest)</title></path>
|
||||
<text class="nj-charts-rowlabel nj-charts-fmt" x="96" y="110.5">B​SON</text>
|
||||
<path class="nj-charts-c3 nj-charts-dim" d="M104 98 H257.513 Q261.513 98 261.513 102 V110 Q261.513 114 257.513 114 H104 Z"><title>twitter.json, B​SON: 95.2 % of minified J​SON</title></path>
|
||||
<text class="nj-charts-rowlabel nj-charts-fmt" x="96" y="136.5">C​BOR</text>
|
||||
<path class="nj-charts-c4 nj-charts-dim" d="M104 124 H242.787 Q246.787 124 246.787 128 V136 Q246.787 140 242.787 140 H104 Z"><title>twitter.json, C​BOR: 86.3 % of minified J​SON</title></path>
|
||||
<text class="nj-charts-rowlabel nj-charts-fmt" x="96" y="162.5">MessagePack</text>
|
||||
<path class="nj-charts-c5 nj-charts-dim" d="M104 150 H242.291 Q246.291 150 246.291 154 V162 Q246.291 166 242.291 166 H104 Z"><title>twitter.json, MessagePack: 86 % of minified J​SON</title></path>
|
||||
<text class="nj-charts-rowlabel nj-charts-fmt" x="96" y="188.5">U​BJSON</text>
|
||||
<path class="nj-charts-c6 nj-charts-dim" d="M104 176 H251.06 Q255.06 176 255.06 180 V188 Q255.06 192 251.06 192 H104 Z"><title>twitter.json, U​BJSON: 91.3 % of minified J​SON</title></path>
|
||||
<line class="nj-charts-ref" x1="269.455" y1="36" x2="269.455" y2="196"/>
|
||||
<text class="nj-charts-tick nj-charts-tick--r" x="271.455" y="32">minified J​SON = 100 %</text>
|
||||
<text class="nj-charts-tick" x="269.455" y="211">100 %</text>
|
||||
<text class="nj-charts-val" x="259.729" y="58.5">91.1 %</text>
|
||||
<text class="nj-charts-val nj-charts-best" x="247.651" y="84.5">83.8 %</text>
|
||||
<text class="nj-charts-val" x="266.513" y="110.5">95.2 %</text>
|
||||
<text class="nj-charts-val" x="251.787" y="136.5">86.3 %</text>
|
||||
<text class="nj-charts-val" x="251.291" y="162.5">86.0 %</text>
|
||||
<text class="nj-charts-val" x="260.06" y="188.5">91.3 %</text>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 3.1 KiB |
|
After Width: | Height: | Size: 45 KiB |
@@ -1,39 +0,0 @@
|
||||
<svg class="nj-fig nj-fig--cb" viewBox="0 0 480 262" role="img" aria-labelledby="fig-cb-title" xmlns="http://www.w3.org/2000/svg">
|
||||
<title id="fig-cb-title">Example of the parse events a callback sees for the J​SON text {"name": "Berlin", "location": [52.519444, 13.406667]}: object_start after the opening brace, key after each key, array_start after the opening bracket, value after each value, array_end after the closing bracket, and object_end after the closing brace. Every array and object also produces a value event when it is complete.</title>
|
||||
<text class="fg-h" x="16" y="28">J​SON to parse</text>
|
||||
<text class="fg-h" x="320" y="28">callback events</text>
|
||||
<text class="fg-code" x="16" y="74" xml:space="preserve">{</text>
|
||||
<circle class="cb-os" cx="35.6" cy="69" r="5.5"/>
|
||||
<text class="fg-code" x="35.2" y="102" xml:space="preserve">"name"</text>
|
||||
<circle class="cb-k" cx="102.8" cy="97" r="5.5"/>
|
||||
<text class="fg-code" x="112.8" y="102" xml:space="preserve">: "Berlin"</text>
|
||||
<circle class="cb-v" cx="218.8" cy="97" r="5.5"/>
|
||||
<text class="fg-code" x="228.8" y="102" xml:space="preserve">,</text>
|
||||
<text class="fg-code" x="35.2" y="130" xml:space="preserve">"location"</text>
|
||||
<circle class="cb-k" cx="141.2" cy="125" r="5.5"/>
|
||||
<text class="fg-code" x="151.2" y="130" xml:space="preserve">: [</text>
|
||||
<circle class="cb-as" cx="190" cy="125" r="5.5"/>
|
||||
<text class="fg-code" x="54.4" y="158" xml:space="preserve">52.519444</text>
|
||||
<circle class="cb-v" cx="150.8" cy="153" r="5.5"/>
|
||||
<text class="fg-code" x="160.8" y="158" xml:space="preserve">,</text>
|
||||
<text class="fg-code" x="54.4" y="186" xml:space="preserve">13.406667</text>
|
||||
<circle class="cb-v" cx="150.8" cy="181" r="5.5"/>
|
||||
<text class="fg-code" x="35.2" y="214" xml:space="preserve">]</text>
|
||||
<circle class="cb-ae" cx="54.8" cy="209" r="5.5"/>
|
||||
<circle class="cb-v" cx="74.8" cy="209" r="5.5"/>
|
||||
<text class="fg-code" x="16" y="242" xml:space="preserve">}</text>
|
||||
<circle class="cb-oe" cx="35.6" cy="237" r="5.5"/>
|
||||
<circle class="cb-v" cx="55.6" cy="237" r="5.5"/>
|
||||
<circle class="cb-os" cx="327" cy="69" r="6"/>
|
||||
<text class="fg-code fg-leg" x="344" y="74">object_start</text>
|
||||
<circle class="cb-k" cx="327" cy="99" r="6"/>
|
||||
<text class="fg-code fg-leg" x="344" y="104">key</text>
|
||||
<circle class="cb-oe" cx="327" cy="129" r="6"/>
|
||||
<text class="fg-code fg-leg" x="344" y="134">object_end</text>
|
||||
<circle class="cb-as" cx="327" cy="159" r="6"/>
|
||||
<text class="fg-code fg-leg" x="344" y="164">array_start</text>
|
||||
<circle class="cb-ae" cx="327" cy="189" r="6"/>
|
||||
<text class="fg-code fg-leg" x="344" y="194">array_end</text>
|
||||
<circle class="cb-v" cx="327" cy="219" r="6"/>
|
||||
<text class="fg-code fg-leg" x="344" y="224">value</text>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 2.7 KiB |
@@ -1,50 +0,0 @@
|
||||
<svg class="nj-fig nj-fig--sax-buf" viewBox="0 0 700 442" role="img" aria-labelledby="fig-sax-buf-title fig-sax-buf-desc" xmlns="http://www.w3.org/2000/svg">
|
||||
<title id="fig-sax-buf-title">Buffering chunks until the value is complete: five chunks of {"name": "Mary", "list": [1, 2, 3]} appended to a buffer.</title>
|
||||
<desc id="fig-sax-buf-desc">After chunks 1 to 4 the buffer has 4, 12, 19, and 30 bytes, and parsing it fails at byte 5, 13, 20, and 31: one past the end, so the input is incomplete and the program waits for more. After chunk 5 the buffer of 35 bytes parses as one complete value. For the input [1, ] of 5 bytes the error is at byte 5, before the end, so it is a real syntax error. Every attempt parses the buffer from byte 1, so 4 + 12 + 19 + 30 + 35 = 100 bytes are parsed for a 35-byte value, and the work grows quadratically.</desc>
|
||||
<text class="fg-h" x="16" y="24">chunk</text>
|
||||
<text class="fg-h" x="96" y="24">buffer, parsed from byte 1 each time</text>
|
||||
<text class="fg-h" x="420" y="24">result</text>
|
||||
<text class="fg-note fg-note--l" x="16" y="67">chunk 1</text>
|
||||
<rect class="nj-sax-new" x="96" y="50" width="36.6" height="24" rx="4"/>
|
||||
<text class="nj-sax-buf" x="96" y="67" xml:space="preserve">{"na</text>
|
||||
<path class="nj-sax-caret nj-sax-s-wait" d="M133.8 76 l-5 8 h10 z"/>
|
||||
<text class="nj-sax-status nj-sax-s-wait" x="420" y="61">error at byte 5 = size + 1</text>
|
||||
<text class="fg-note fg-note--l" x="420" y="77">incomplete: wait for more</text>
|
||||
<text class="fg-note fg-note--l" x="16" y="117">chunk 2</text>
|
||||
<rect class="nj-sax-old" x="93" y="100" width="36.6" height="24" rx="4"/>
|
||||
<rect class="nj-sax-new" x="129.6" y="100" width="70.2" height="24" rx="4"/>
|
||||
<text class="nj-sax-buf" x="96" y="117" xml:space="preserve">{"name": "Ma</text>
|
||||
<path class="nj-sax-caret nj-sax-s-wait" d="M201 126 l-5 8 h10 z"/>
|
||||
<text class="nj-sax-status nj-sax-s-wait" x="420" y="111">error at byte 13 = size + 1</text>
|
||||
<text class="fg-note fg-note--l" x="420" y="127">incomplete: wait for more</text>
|
||||
<text class="fg-note fg-note--l" x="16" y="167">chunk 3</text>
|
||||
<rect class="nj-sax-old" x="93" y="150" width="103.8" height="24" rx="4"/>
|
||||
<rect class="nj-sax-new" x="196.8" y="150" width="61.8" height="24" rx="4"/>
|
||||
<text class="nj-sax-buf" x="96" y="167" xml:space="preserve">{"name": "Mary", "l</text>
|
||||
<path class="nj-sax-caret nj-sax-s-wait" d="M259.8 176 l-5 8 h10 z"/>
|
||||
<text class="nj-sax-status nj-sax-s-wait" x="420" y="161">error at byte 20 = size + 1</text>
|
||||
<text class="fg-note fg-note--l" x="420" y="177">incomplete: wait for more</text>
|
||||
<text class="fg-note fg-note--l" x="16" y="217">chunk 4</text>
|
||||
<rect class="nj-sax-old" x="93" y="200" width="162.6" height="24" rx="4"/>
|
||||
<rect class="nj-sax-new" x="255.6" y="200" width="95.4" height="24" rx="4"/>
|
||||
<text class="nj-sax-buf" x="96" y="217" xml:space="preserve">{"name": "Mary", "list": [1, 2</text>
|
||||
<path class="nj-sax-caret nj-sax-s-wait" d="M352.2 226 l-5 8 h10 z"/>
|
||||
<text class="nj-sax-status nj-sax-s-wait" x="420" y="211">error at byte 31 = size + 1</text>
|
||||
<text class="fg-note fg-note--l" x="420" y="227">incomplete: wait for more</text>
|
||||
<text class="fg-note fg-note--l" x="16" y="267">chunk 5</text>
|
||||
<rect class="nj-sax-old" x="93" y="250" width="255" height="24" rx="4"/>
|
||||
<rect class="nj-sax-new" x="348" y="250" width="45" height="24" rx="4"/>
|
||||
<text class="nj-sax-buf" x="96" y="267" xml:space="preserve">{"name": "Mary", "list": [1, 2, 3]}</text>
|
||||
<text class="nj-sax-status nj-sax-s-ok" x="420" y="261">parsed, size 35</text>
|
||||
<text class="fg-note fg-note--l" x="420" y="277">complete: one value</text>
|
||||
<path class="nj-sax-sep" d="M16 290 H684"/>
|
||||
<text class="fg-note fg-note--l" x="16" y="325">other input</text>
|
||||
<rect class="nj-sax-new" x="96" y="308" width="45" height="24" rx="4"/>
|
||||
<text class="nj-sax-buf" x="96" y="325" xml:space="preserve">[1, ]</text>
|
||||
<path class="nj-sax-caret nj-sax-s-err" d="M133.8 334 l-5 8 h10 z"/>
|
||||
<text class="nj-sax-status nj-sax-s-err" x="420" y="319">error at byte 5, size 5</text>
|
||||
<text class="fg-note fg-note--l" x="420" y="335">before the end: a real error</text>
|
||||
<text class="fg-note fg-note--l" x="16" y="366">Bytes parsed: 4 + 12 + 19 + 30 + 35 = 100 for a value of 35 bytes.</text>
|
||||
<text class="fg-note fg-note--l" x="16" y="386">Every attempt starts again at byte 1, so the total work grows</text>
|
||||
<text class="fg-note fg-note--l" x="16" y="406">quadratically with the size of the value.</text>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 4.5 KiB |
@@ -1,60 +0,0 @@
|
||||
<svg class="nj-fig nj-charts nj-charts--compile" viewBox="0 0 470 516" role="img" aria-labelledby="nj-charts-ct nj-charts-ct-d" xmlns="http://www.w3.org/2000/svg">
|
||||
<title id="nj-charts-ct">Change in compile time against the default configuration at -O0, Apple clang and G​CC 16</title>
|
||||
<desc id="nj-charts-ct-d">Grouped horizontal bars, negative is faster. json_fwd.hpp instead of json.hpp on a header-only translation unit: Apple clang -62 %, G​CC 16 -82 %; extern template on a parsing translation unit: Apple clang -7 %, G​CC 16 -21 %; JSON_NO_AUTOMATIC_UDLS on a model translation unit: Apple clang -11 %, G​CC 16 -11 %; JSON_NO_AUTOMATIC_UDLS on a parsing translation unit: Apple clang -1 %, G​CC 16 -2 %; JSON_HAS_FILESYSTEM=0 + JSON_NO_IO on a model translation unit: Apple clang -8 %, G​CC 16 -11 %; JSON_HAS_FILESYSTEM=0 on a model translation unit: Apple clang -5 %, G​CC 16 -9 %; JSON_NO_IO on a model translation unit: Apple clang -2 %, G​CC 16 -2 %; JSON_USE_GLOBAL_UDLS=0 on a model translation unit: Apple clang 0 %, G​CC 16 -1 %.</desc>
|
||||
<rect class="nj-charts-clang" x="8" y="10" width="12" height="12" rx="3"/>
|
||||
<text class="nj-charts-leg" x="26" y="20.5">Apple clang</text>
|
||||
<rect class="nj-charts-gcc" x="126" y="10" width="12" height="12" rx="3"/>
|
||||
<text class="nj-charts-leg" x="144" y="20.5">G​CC 16</text>
|
||||
<line class="nj-charts-grid" x1="47.4" y1="58" x2="47.4" y2="472"/>
|
||||
<text class="nj-charts-tick" x="47.4" y="488">−80 %</text>
|
||||
<line class="nj-charts-grid" x1="126.2" y1="58" x2="126.2" y2="472"/>
|
||||
<text class="nj-charts-tick" x="126.2" y="488">−60 %</text>
|
||||
<line class="nj-charts-grid" x1="205" y1="58" x2="205" y2="472"/>
|
||||
<text class="nj-charts-tick" x="205" y="488">−40 %</text>
|
||||
<line class="nj-charts-grid" x1="283.8" y1="58" x2="283.8" y2="472"/>
|
||||
<text class="nj-charts-tick" x="283.8" y="488">−20 %</text>
|
||||
<text class="nj-charts-tick" x="362.6" y="488">0 %</text>
|
||||
<text class="nj-charts-tick nj-charts-tick--l" x="8" y="506">← faster</text>
|
||||
<text class="nj-charts-tick nj-charts-tick--r" x="462" y="506">slower →</text>
|
||||
<text class="nj-charts-rowlabel" x="8" y="62"><tspan class="nj-charts-code">json_fwd.hpp instead of json.hpp</tspan><tspan class="nj-charts-sub"> · header-only TU</tspan></text>
|
||||
<path class="nj-charts-clang" d="M362.6 70 H122.32 Q118.32 70 118.32 74 V78 Q118.32 82 122.32 82 H362.6 Z"><title>json_fwd.hpp instead of json.hpp, header-only TU (Apple clang): −62 %</title></path>
|
||||
<text class="nj-charts-val" x="367.6" y="80.5">−62 %</text>
|
||||
<path class="nj-charts-gcc" d="M362.6 84 H43.52 Q39.52 84 39.52 88 V92 Q39.52 96 43.52 96 H362.6 Z"><title>json_fwd.hpp instead of json.hpp, header-only TU (G​CC 16): −82 %</title></path>
|
||||
<text class="nj-charts-val" x="367.6" y="94.5">−82 %</text>
|
||||
<text class="nj-charts-rowlabel" x="8" y="114"><tspan class="nj-charts-code">extern template</tspan><tspan class="nj-charts-sub"> · parsing TU</tspan></text>
|
||||
<path class="nj-charts-clang" d="M362.6 122 H339.02 Q335.02 122 335.02 126 V130 Q335.02 134 339.02 134 H362.6 Z"><title>extern template, parsing TU (Apple clang): −7 %</title></path>
|
||||
<text class="nj-charts-val" x="367.6" y="132.5">−7 %</text>
|
||||
<path class="nj-charts-gcc" d="M362.6 136 H283.86 Q279.86 136 279.86 140 V144 Q279.86 148 283.86 148 H362.6 Z"><title>extern template, parsing TU (G​CC 16): −21 %</title></path>
|
||||
<text class="nj-charts-val" x="367.6" y="146.5">−21 %</text>
|
||||
<text class="nj-charts-rowlabel" x="8" y="166"><tspan class="nj-charts-code">JSON_NO_AUTOMATIC_UDLS</tspan><tspan class="nj-charts-sub"> · model TU</tspan></text>
|
||||
<path class="nj-charts-clang" d="M362.6 174 H323.26 Q319.26 174 319.26 178 V182 Q319.26 186 323.26 186 H362.6 Z"><title>JSON_NO_AUTOMATIC_UDLS, model TU (Apple clang): −11 %</title></path>
|
||||
<text class="nj-charts-val" x="367.6" y="184.5">−11 %</text>
|
||||
<path class="nj-charts-gcc" d="M362.6 188 H323.26 Q319.26 188 319.26 192 V196 Q319.26 200 323.26 200 H362.6 Z"><title>JSON_NO_AUTOMATIC_UDLS, model TU (G​CC 16): −11 %</title></path>
|
||||
<text class="nj-charts-val" x="367.6" y="198.5">−11 %</text>
|
||||
<text class="nj-charts-rowlabel" x="8" y="218"><tspan class="nj-charts-code">JSON_NO_AUTOMATIC_UDLS</tspan><tspan class="nj-charts-sub"> · parsing TU</tspan></text>
|
||||
<path class="nj-charts-clang" d="M362.6 226 H362.6 Q358.66 226 358.66 229.94 V234.06 Q358.66 238 362.6 238 H362.6 Z"><title>JSON_NO_AUTOMATIC_UDLS, parsing TU (Apple clang): −1 %</title></path>
|
||||
<text class="nj-charts-val" x="367.6" y="236.5">−1 %</text>
|
||||
<path class="nj-charts-gcc" d="M362.6 240 H358.72 Q354.72 240 354.72 244 V248 Q354.72 252 358.72 252 H362.6 Z"><title>JSON_NO_AUTOMATIC_UDLS, parsing TU (G​CC 16): −2 %</title></path>
|
||||
<text class="nj-charts-val" x="367.6" y="250.5">−2 %</text>
|
||||
<text class="nj-charts-rowlabel" x="8" y="270"><tspan class="nj-charts-code">JSON_HAS_FILESYSTEM=0 + JSON_NO_IO</tspan><tspan class="nj-charts-sub"> · model TU</tspan></text>
|
||||
<path class="nj-charts-clang" d="M362.6 278 H335.08 Q331.08 278 331.08 282 V286 Q331.08 290 335.08 290 H362.6 Z"><title>JSON_HAS_FILESYSTEM=0 + JSON_NO_IO, model TU (Apple clang): −8 %</title></path>
|
||||
<text class="nj-charts-val" x="367.6" y="288.5">−8 %</text>
|
||||
<path class="nj-charts-gcc" d="M362.6 292 H323.26 Q319.26 292 319.26 296 V300 Q319.26 304 323.26 304 H362.6 Z"><title>JSON_HAS_FILESYSTEM=0 + JSON_NO_IO, model TU (G​CC 16): −11 %</title></path>
|
||||
<text class="nj-charts-val" x="367.6" y="302.5">−11 %</text>
|
||||
<text class="nj-charts-rowlabel" x="8" y="322"><tspan class="nj-charts-code">JSON_HAS_FILESYSTEM=0</tspan><tspan class="nj-charts-sub"> · model TU</tspan></text>
|
||||
<path class="nj-charts-clang" d="M362.6 330 H346.9 Q342.9 330 342.9 334 V338 Q342.9 342 346.9 342 H362.6 Z"><title>JSON_HAS_FILESYSTEM=0, model TU (Apple clang): −5 %</title></path>
|
||||
<text class="nj-charts-val" x="367.6" y="340.5">−5 %</text>
|
||||
<path class="nj-charts-gcc" d="M362.6 344 H331.14 Q327.14 344 327.14 348 V352 Q327.14 356 331.14 356 H362.6 Z"><title>JSON_HAS_FILESYSTEM=0, model TU (G​CC 16): −9 %</title></path>
|
||||
<text class="nj-charts-val" x="367.6" y="354.5">−9 %</text>
|
||||
<text class="nj-charts-rowlabel" x="8" y="374"><tspan class="nj-charts-code">JSON_NO_IO</tspan><tspan class="nj-charts-sub"> · model TU*</tspan></text>
|
||||
<path class="nj-charts-clang" d="M362.6 382 H358.72 Q354.72 382 354.72 386 V390 Q354.72 394 358.72 394 H362.6 Z"><title>JSON_NO_IO, model TU (Apple clang): −2 %</title></path>
|
||||
<text class="nj-charts-val" x="367.6" y="392.5">−2 %</text>
|
||||
<path class="nj-charts-gcc" d="M362.6 396 H358.72 Q354.72 396 354.72 400 V404 Q354.72 408 358.72 408 H362.6 Z"><title>JSON_NO_IO, model TU (G​CC 16): −2 %</title></path>
|
||||
<text class="nj-charts-val" x="367.6" y="406.5">−2 %</text>
|
||||
<text class="nj-charts-rowlabel" x="8" y="426"><tspan class="nj-charts-code">JSON_USE_GLOBAL_UDLS=0</tspan><tspan class="nj-charts-sub"> · model TU*</tspan></text>
|
||||
<path class="nj-charts-clang" d="M362.6 434 h0.5 v12 h-0.5 Z"><title>JSON_USE_GLOBAL_UDLS=0, model TU (Apple clang): 0 %</title></path>
|
||||
<text class="nj-charts-val" x="367.6" y="444.5">0 %</text>
|
||||
<path class="nj-charts-gcc" d="M362.6 448 H362.6 Q358.66 448 358.66 451.94 V456.06 Q358.66 460 362.6 460 H362.6 Z"><title>JSON_USE_GLOBAL_UDLS=0, model TU (G​CC 16): −1 %</title></path>
|
||||
<text class="nj-charts-val" x="367.6" y="458.5">−1 %</text>
|
||||
<line class="nj-charts-zero" x1="362.6" y1="58" x2="362.6" y2="472"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 7.5 KiB |
@@ -1,30 +0,0 @@
|
||||
<svg class="nj-fig nj-charts nj-charts--compile" viewBox="0 0 440 282" role="img" aria-labelledby="nj-charts-mod nj-charts-mod-d" xmlns="http://www.w3.org/2000/svg">
|
||||
<title id="nj-charts-mod">Compile time per translation unit with import nlohmann.json at -O0, and the one-off cost of the module</title>
|
||||
<desc id="nj-charts-mod-d">Horizontal bars, negative is faster, medians of nine runs, -std=c++20 for both. model TU, Apple clang: -48 % (1311 ms to 680 ms); model TU, G​CC 16: -47 % (2156 ms to 1153 ms); parsing TU, Apple clang: -42 % (1387 ms to 800 ms); parsing TU, G​CC 16: -36 % (2838 ms to 1810 ms); one-off build, Apple clang: 1630 ms; one-off build, G​CC 16: 2538 ms.</desc>
|
||||
<rect class="nj-charts-clang" x="8" y="10" width="12" height="12" rx="3"/>
|
||||
<text class="nj-charts-leg" x="26" y="20.5">Apple clang</text>
|
||||
<rect class="nj-charts-gcc" x="126" y="10" width="12" height="12" rx="3"/>
|
||||
<text class="nj-charts-leg" x="144" y="20.5">G​CC 16</text>
|
||||
<line class="nj-charts-grid" x1="68.6667" y1="58" x2="68.6667" y2="160"/>
|
||||
<text class="nj-charts-tick" x="68.6667" y="176">−50 %</text>
|
||||
<line class="nj-charts-grid" x1="220.333" y1="58" x2="220.333" y2="160"/>
|
||||
<text class="nj-charts-tick" x="220.333" y="176">−25 %</text>
|
||||
<text class="nj-charts-tick" x="372" y="176">0 %</text>
|
||||
<text class="nj-charts-tick nj-charts-tick--l" x="8" y="194">← faster per TU</text>
|
||||
<text class="nj-charts-rowlabel" x="8" y="62">model TU<tspan class="nj-charts-sub"> · import nlohmann.json</tspan></text>
|
||||
<path class="nj-charts-clang" d="M372 70 H84.8 Q80.8 70 80.8 74 V78 Q80.8 82 84.8 82 H372 Z"><title>model TU, Apple clang: 1311 ms by default, 680 ms import nlohmann.json (−48 %)</title></path>
|
||||
<text class="nj-charts-val" x="377" y="80.5">−48 %</text>
|
||||
<path class="nj-charts-gcc" d="M372 84 H90.8667 Q86.8667 84 86.8667 88 V92 Q86.8667 96 90.8667 96 H372 Z"><title>model TU, G​CC 16: 2156 ms by default, 1153 ms import nlohmann.json (−47 %)</title></path>
|
||||
<text class="nj-charts-val" x="377" y="94.5">−47 %</text>
|
||||
<text class="nj-charts-rowlabel" x="8" y="114">parsing TU<tspan class="nj-charts-sub"> · import nlohmann.json</tspan></text>
|
||||
<path class="nj-charts-clang" d="M372 122 H121.2 Q117.2 122 117.2 126 V130 Q117.2 134 121.2 134 H372 Z"><title>parsing TU, Apple clang: 1387 ms by default, 800 ms import nlohmann.json (−42 %)</title></path>
|
||||
<text class="nj-charts-val" x="377" y="132.5">−42 %</text>
|
||||
<path class="nj-charts-gcc" d="M372 136 H157.6 Q153.6 136 153.6 140 V144 Q153.6 148 157.6 148 H372 Z"><title>parsing TU, G​CC 16: 2838 ms by default, 1810 ms import nlohmann.json (−36 %)</title></path>
|
||||
<text class="nj-charts-val" x="377" y="146.5">−36 %</text>
|
||||
<line class="nj-charts-zero" x1="372" y1="58" x2="372" y2="160"/>
|
||||
<text class="nj-charts-rowlabel" x="8" y="222">One-off cost<tspan class="nj-charts-sub"> · built once, reused by every TU</tspan></text>
|
||||
<rect class="nj-charts-clang" x="8" y="232.5" width="10" height="10" rx="2.5"/>
|
||||
<text class="nj-charts-val" x="24" y="242">Apple clang: 1630 ms once, saves 587 to 631 ms per TU</text>
|
||||
<rect class="nj-charts-gcc" x="8" y="252.5" width="10" height="10" rx="2.5"/>
|
||||
<text class="nj-charts-val" x="24" y="262">G​CC 16: 2538 ms once, saves 1003 to 1028 ms per TU</text>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 3.3 KiB |
@@ -1,30 +0,0 @@
|
||||
<svg class="nj-fig nj-charts nj-charts--compile" viewBox="0 0 440 282" role="img" aria-labelledby="nj-charts-pch nj-charts-pch-d" xmlns="http://www.w3.org/2000/svg">
|
||||
<title id="nj-charts-pch">Compile time per translation unit with a precompiled json.hpp at -O0, and the one-off cost of the PCH</title>
|
||||
<desc id="nj-charts-pch-d">Horizontal bars, negative is faster, medians of nine runs, -std=c++17. model TU, Apple clang: -43 % (1045 ms to 594 ms); model TU, G​CC 16: -41 % (1789 ms to 1060 ms); parsing TU, Apple clang: -38 % (1148 ms to 714 ms); parsing TU, G​CC 16: -25 % (2498 ms to 1884 ms); one-off build, Apple clang: 771 ms; one-off build, G​CC 16: 2254 ms.</desc>
|
||||
<rect class="nj-charts-clang" x="8" y="10" width="12" height="12" rx="3"/>
|
||||
<text class="nj-charts-leg" x="26" y="20.5">Apple clang</text>
|
||||
<rect class="nj-charts-gcc" x="126" y="10" width="12" height="12" rx="3"/>
|
||||
<text class="nj-charts-leg" x="144" y="20.5">G​CC 16</text>
|
||||
<line class="nj-charts-grid" x1="68.6667" y1="58" x2="68.6667" y2="160"/>
|
||||
<text class="nj-charts-tick" x="68.6667" y="176">−50 %</text>
|
||||
<line class="nj-charts-grid" x1="220.333" y1="58" x2="220.333" y2="160"/>
|
||||
<text class="nj-charts-tick" x="220.333" y="176">−25 %</text>
|
||||
<text class="nj-charts-tick" x="372" y="176">0 %</text>
|
||||
<text class="nj-charts-tick nj-charts-tick--l" x="8" y="194">← faster per TU</text>
|
||||
<text class="nj-charts-rowlabel" x="8" y="62">model TU<tspan class="nj-charts-sub"> · with PCH</tspan></text>
|
||||
<path class="nj-charts-clang" d="M372 70 H115.133 Q111.133 70 111.133 74 V78 Q111.133 82 115.133 82 H372 Z"><title>model TU, Apple clang: 1045 ms by default, 594 ms with PCH (−43 %)</title></path>
|
||||
<text class="nj-charts-val" x="377" y="80.5">−43 %</text>
|
||||
<path class="nj-charts-gcc" d="M372 84 H127.267 Q123.267 84 123.267 88 V92 Q123.267 96 127.267 96 H372 Z"><title>model TU, G​CC 16: 1789 ms by default, 1060 ms with PCH (−41 %)</title></path>
|
||||
<text class="nj-charts-val" x="377" y="94.5">−41 %</text>
|
||||
<text class="nj-charts-rowlabel" x="8" y="114">parsing TU<tspan class="nj-charts-sub"> · with PCH</tspan></text>
|
||||
<path class="nj-charts-clang" d="M372 122 H145.467 Q141.467 122 141.467 126 V130 Q141.467 134 145.467 134 H372 Z"><title>parsing TU, Apple clang: 1148 ms by default, 714 ms with PCH (−38 %)</title></path>
|
||||
<text class="nj-charts-val" x="377" y="132.5">−38 %</text>
|
||||
<path class="nj-charts-gcc" d="M372 136 H224.333 Q220.333 136 220.333 140 V144 Q220.333 148 224.333 148 H372 Z"><title>parsing TU, G​CC 16: 2498 ms by default, 1884 ms with PCH (−25 %)</title></path>
|
||||
<text class="nj-charts-val" x="377" y="146.5">−25 %</text>
|
||||
<line class="nj-charts-zero" x1="372" y1="58" x2="372" y2="160"/>
|
||||
<text class="nj-charts-rowlabel" x="8" y="222">One-off cost<tspan class="nj-charts-sub"> · built once, reused by every TU</tspan></text>
|
||||
<rect class="nj-charts-clang" x="8" y="232.5" width="10" height="10" rx="2.5"/>
|
||||
<text class="nj-charts-val" x="24" y="242">Apple clang: 771 ms once, saves 434 to 451 ms per TU</text>
|
||||
<rect class="nj-charts-gcc" x="8" y="252.5" width="10" height="10" rx="2.5"/>
|
||||
<text class="nj-charts-val" x="24" y="262">G​CC 16: 2254 ms once, saves 614 to 729 ms per TU</text>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 3.2 KiB |
@@ -1,174 +0,0 @@
|
||||
<svg class="nj-fig nj-exceptions-map nj-exceptions-map--wide" viewBox="0 0 760 694" aria-labelledby="nj-exc-map-title-w nj-exc-map-desc-w" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<title id="nj-exc-map-title-w">Exception id map</title>
|
||||
<desc id="nj-exc-map-desc-w">Class tree: std::exception is the base of json::exception, which is the base of the five exception families parse_error (ids 1xx), invalid_iterator (2xx), type_error (3xx), out_of_range (4xx) and other_error (5xx). Each family lists the ids documented on this page, 68 in total; every id links to its section.</desc>
|
||||
<defs><marker id="nj-exc-tri-w" viewBox="0 0 12 12" refX="11" refY="6" markerWidth="11" markerHeight="11" orient="auto"><path class="nj-exceptions-tri" d="M1 1 L11 6 L1 11 z"/></marker></defs>
|
||||
<line class="nj-exceptions-edge" x1="34" y1="656" x2="34" y2="158" marker-end="url(#nj-exc-tri-w)"/>
|
||||
<rect class="nj-exceptions-box" x="12" y="12" width="200" height="52" rx="7"/><text class="nj-exceptions-name" x="24" y="34">std::exception</text><text class="nj-exceptions-sub" x="24" y="53">C++ standard library base</text>
|
||||
<line class="nj-exceptions-edge" x1="34" y1="104" x2="34" y2="66" marker-end="url(#nj-exc-tri-w)"/>
|
||||
<rect class="nj-exceptions-box" x="12" y="104" width="300" height="52" rx="7"/><text class="nj-exceptions-name" x="24" y="126">json::exception</text><text class="nj-exceptions-sub" x="24" y="145">id, what() · catch-all</text>
|
||||
<line class="nj-exceptions-edge" x1="34" y1="222" x2="64" y2="222"/>
|
||||
<a class="nj-exceptions-fam" xlink:href="#parse-errors" aria-label="json::parse_error, 1xx · 15 ids · adds member byte"><rect class="nj-exceptions-box nj-exceptions-box--fam" x="64" y="196" width="214" height="52" rx="7"/><text class="nj-exceptions-name" x="76" y="218">json::parse_error</text><text class="nj-exceptions-sub" x="76" y="237">1xx · 15 ids · adds member byte</text></a>
|
||||
<a class="nj-exceptions-chip" xlink:href="#jsonexceptionparse_error101" aria-label="json.exception.parse_error.101"><rect x="294" y="208" width="41.7" height="28" rx="6"/><text class="nj-exceptions-id" x="303" y="226.5">101</text></a>
|
||||
<a class="nj-exceptions-chip" xlink:href="#jsonexceptionparse_error102" aria-label="json.exception.parse_error.102"><rect x="341.7" y="208" width="41.7" height="28" rx="6"/><text class="nj-exceptions-id" x="350.7" y="226.5">102</text></a>
|
||||
<a class="nj-exceptions-chip" xlink:href="#jsonexceptionparse_error103" aria-label="json.exception.parse_error.103"><rect x="389.4" y="208" width="41.7" height="28" rx="6"/><text class="nj-exceptions-id" x="398.4" y="226.5">103</text></a>
|
||||
<a class="nj-exceptions-chip" xlink:href="#jsonexceptionparse_error104" aria-label="json.exception.parse_error.104"><rect x="437.1" y="208" width="41.7" height="28" rx="6"/><text class="nj-exceptions-id" x="446.1" y="226.5">104</text></a>
|
||||
<a class="nj-exceptions-chip" xlink:href="#jsonexceptionparse_error105" aria-label="json.exception.parse_error.105"><rect x="484.8" y="208" width="41.7" height="28" rx="6"/><text class="nj-exceptions-id" x="493.8" y="226.5">105</text></a>
|
||||
<a class="nj-exceptions-chip" xlink:href="#jsonexceptionparse_error106" aria-label="json.exception.parse_error.106"><rect x="532.5" y="208" width="41.7" height="28" rx="6"/><text class="nj-exceptions-id" x="541.5" y="226.5">106</text></a>
|
||||
<a class="nj-exceptions-chip" xlink:href="#jsonexceptionparse_error107" aria-label="json.exception.parse_error.107"><rect x="580.2" y="208" width="41.7" height="28" rx="6"/><text class="nj-exceptions-id" x="589.2" y="226.5">107</text></a>
|
||||
<a class="nj-exceptions-chip" xlink:href="#jsonexceptionparse_error108" aria-label="json.exception.parse_error.108"><rect x="627.9" y="208" width="41.7" height="28" rx="6"/><text class="nj-exceptions-id" x="636.9" y="226.5">108</text></a>
|
||||
<a class="nj-exceptions-chip" xlink:href="#jsonexceptionparse_error109" aria-label="json.exception.parse_error.109"><rect x="675.6" y="208" width="41.7" height="28" rx="6"/><text class="nj-exceptions-id" x="684.6" y="226.5">109</text></a>
|
||||
<a class="nj-exceptions-chip" xlink:href="#jsonexceptionparse_error110" aria-label="json.exception.parse_error.110"><rect x="294" y="242" width="41.7" height="28" rx="6"/><text class="nj-exceptions-id" x="303" y="260.5">110</text></a>
|
||||
<a class="nj-exceptions-chip" xlink:href="#jsonexceptionparse_error112" aria-label="json.exception.parse_error.112"><rect x="341.7" y="242" width="41.7" height="28" rx="6"/><text class="nj-exceptions-id" x="350.7" y="260.5">112</text></a>
|
||||
<a class="nj-exceptions-chip" xlink:href="#jsonexceptionparse_error113" aria-label="json.exception.parse_error.113"><rect x="389.4" y="242" width="41.7" height="28" rx="6"/><text class="nj-exceptions-id" x="398.4" y="260.5">113</text></a>
|
||||
<a class="nj-exceptions-chip" xlink:href="#jsonexceptionparse_error114" aria-label="json.exception.parse_error.114"><rect x="437.1" y="242" width="41.7" height="28" rx="6"/><text class="nj-exceptions-id" x="446.1" y="260.5">114</text></a>
|
||||
<a class="nj-exceptions-chip" xlink:href="#jsonexceptionparse_error115" aria-label="json.exception.parse_error.115"><rect x="484.8" y="242" width="41.7" height="28" rx="6"/><text class="nj-exceptions-id" x="493.8" y="260.5">115</text></a>
|
||||
<a class="nj-exceptions-chip" xlink:href="#jsonexceptionparse_error116" aria-label="json.exception.parse_error.116"><rect x="532.5" y="242" width="41.7" height="28" rx="6"/><text class="nj-exceptions-id" x="541.5" y="260.5">116</text></a>
|
||||
<line class="nj-exceptions-edge" x1="34" y1="322" x2="64" y2="322"/>
|
||||
<a class="nj-exceptions-fam" xlink:href="#iterator-errors" aria-label="json::invalid_iterator, 2xx · 14 ids"><rect class="nj-exceptions-box nj-exceptions-box--fam" x="64" y="296" width="214" height="52" rx="7"/><text class="nj-exceptions-name" x="76" y="318">json::invalid_iterator</text><text class="nj-exceptions-sub" x="76" y="337">2xx · 14 ids</text></a>
|
||||
<a class="nj-exceptions-chip" xlink:href="#jsonexceptioninvalid_iterator201" aria-label="json.exception.invalid_iterator.201"><rect x="294" y="308" width="41.7" height="28" rx="6"/><text class="nj-exceptions-id" x="303" y="326.5">201</text></a>
|
||||
<a class="nj-exceptions-chip" xlink:href="#jsonexceptioninvalid_iterator202" aria-label="json.exception.invalid_iterator.202"><rect x="341.7" y="308" width="41.7" height="28" rx="6"/><text class="nj-exceptions-id" x="350.7" y="326.5">202</text></a>
|
||||
<a class="nj-exceptions-chip" xlink:href="#jsonexceptioninvalid_iterator203" aria-label="json.exception.invalid_iterator.203"><rect x="389.4" y="308" width="41.7" height="28" rx="6"/><text class="nj-exceptions-id" x="398.4" y="326.5">203</text></a>
|
||||
<a class="nj-exceptions-chip" xlink:href="#jsonexceptioninvalid_iterator204" aria-label="json.exception.invalid_iterator.204"><rect x="437.1" y="308" width="41.7" height="28" rx="6"/><text class="nj-exceptions-id" x="446.1" y="326.5">204</text></a>
|
||||
<a class="nj-exceptions-chip" xlink:href="#jsonexceptioninvalid_iterator205" aria-label="json.exception.invalid_iterator.205"><rect x="484.8" y="308" width="41.7" height="28" rx="6"/><text class="nj-exceptions-id" x="493.8" y="326.5">205</text></a>
|
||||
<a class="nj-exceptions-chip" xlink:href="#jsonexceptioninvalid_iterator206" aria-label="json.exception.invalid_iterator.206"><rect x="532.5" y="308" width="41.7" height="28" rx="6"/><text class="nj-exceptions-id" x="541.5" y="326.5">206</text></a>
|
||||
<a class="nj-exceptions-chip" xlink:href="#jsonexceptioninvalid_iterator207" aria-label="json.exception.invalid_iterator.207"><rect x="580.2" y="308" width="41.7" height="28" rx="6"/><text class="nj-exceptions-id" x="589.2" y="326.5">207</text></a>
|
||||
<a class="nj-exceptions-chip" xlink:href="#jsonexceptioninvalid_iterator208" aria-label="json.exception.invalid_iterator.208"><rect x="627.9" y="308" width="41.7" height="28" rx="6"/><text class="nj-exceptions-id" x="636.9" y="326.5">208</text></a>
|
||||
<a class="nj-exceptions-chip" xlink:href="#jsonexceptioninvalid_iterator209" aria-label="json.exception.invalid_iterator.209"><rect x="675.6" y="308" width="41.7" height="28" rx="6"/><text class="nj-exceptions-id" x="684.6" y="326.5">209</text></a>
|
||||
<a class="nj-exceptions-chip" xlink:href="#jsonexceptioninvalid_iterator210" aria-label="json.exception.invalid_iterator.210"><rect x="294" y="342" width="41.7" height="28" rx="6"/><text class="nj-exceptions-id" x="303" y="360.5">210</text></a>
|
||||
<a class="nj-exceptions-chip" xlink:href="#jsonexceptioninvalid_iterator211" aria-label="json.exception.invalid_iterator.211"><rect x="341.7" y="342" width="41.7" height="28" rx="6"/><text class="nj-exceptions-id" x="350.7" y="360.5">211</text></a>
|
||||
<a class="nj-exceptions-chip" xlink:href="#jsonexceptioninvalid_iterator212" aria-label="json.exception.invalid_iterator.212"><rect x="389.4" y="342" width="41.7" height="28" rx="6"/><text class="nj-exceptions-id" x="398.4" y="360.5">212</text></a>
|
||||
<a class="nj-exceptions-chip" xlink:href="#jsonexceptioninvalid_iterator213" aria-label="json.exception.invalid_iterator.213"><rect x="437.1" y="342" width="41.7" height="28" rx="6"/><text class="nj-exceptions-id" x="446.1" y="360.5">213</text></a>
|
||||
<a class="nj-exceptions-chip" xlink:href="#jsonexceptioninvalid_iterator214" aria-label="json.exception.invalid_iterator.214"><rect x="484.8" y="342" width="41.7" height="28" rx="6"/><text class="nj-exceptions-id" x="493.8" y="360.5">214</text></a>
|
||||
<line class="nj-exceptions-edge" x1="34" y1="422" x2="64" y2="422"/>
|
||||
<a class="nj-exceptions-fam" xlink:href="#type-errors" aria-label="json::type_error, 3xx · 21 ids"><rect class="nj-exceptions-box nj-exceptions-box--fam" x="64" y="396" width="214" height="52" rx="7"/><text class="nj-exceptions-name" x="76" y="418">json::type_error</text><text class="nj-exceptions-sub" x="76" y="437">3xx · 21 ids</text></a>
|
||||
<a class="nj-exceptions-chip" xlink:href="#jsonexceptiontype_error301" aria-label="json.exception.type_error.301"><rect x="294" y="408" width="41.7" height="28" rx="6"/><text class="nj-exceptions-id" x="303" y="426.5">301</text></a>
|
||||
<a class="nj-exceptions-chip" xlink:href="#jsonexceptiontype_error302" aria-label="json.exception.type_error.302"><rect x="341.7" y="408" width="41.7" height="28" rx="6"/><text class="nj-exceptions-id" x="350.7" y="426.5">302</text></a>
|
||||
<a class="nj-exceptions-chip" xlink:href="#jsonexceptiontype_error303" aria-label="json.exception.type_error.303"><rect x="389.4" y="408" width="41.7" height="28" rx="6"/><text class="nj-exceptions-id" x="398.4" y="426.5">303</text></a>
|
||||
<a class="nj-exceptions-chip" xlink:href="#jsonexceptiontype_error304" aria-label="json.exception.type_error.304"><rect x="437.1" y="408" width="41.7" height="28" rx="6"/><text class="nj-exceptions-id" x="446.1" y="426.5">304</text></a>
|
||||
<a class="nj-exceptions-chip" xlink:href="#jsonexceptiontype_error305" aria-label="json.exception.type_error.305"><rect x="484.8" y="408" width="41.7" height="28" rx="6"/><text class="nj-exceptions-id" x="493.8" y="426.5">305</text></a>
|
||||
<a class="nj-exceptions-chip" xlink:href="#jsonexceptiontype_error306" aria-label="json.exception.type_error.306"><rect x="532.5" y="408" width="41.7" height="28" rx="6"/><text class="nj-exceptions-id" x="541.5" y="426.5">306</text></a>
|
||||
<a class="nj-exceptions-chip" xlink:href="#jsonexceptiontype_error307" aria-label="json.exception.type_error.307"><rect x="580.2" y="408" width="41.7" height="28" rx="6"/><text class="nj-exceptions-id" x="589.2" y="426.5">307</text></a>
|
||||
<a class="nj-exceptions-chip" xlink:href="#jsonexceptiontype_error308" aria-label="json.exception.type_error.308"><rect x="627.9" y="408" width="41.7" height="28" rx="6"/><text class="nj-exceptions-id" x="636.9" y="426.5">308</text></a>
|
||||
<a class="nj-exceptions-chip" xlink:href="#jsonexceptiontype_error309" aria-label="json.exception.type_error.309"><rect x="675.6" y="408" width="41.7" height="28" rx="6"/><text class="nj-exceptions-id" x="684.6" y="426.5">309</text></a>
|
||||
<a class="nj-exceptions-chip" xlink:href="#jsonexceptiontype_error310" aria-label="json.exception.type_error.310"><rect x="294" y="442" width="41.7" height="28" rx="6"/><text class="nj-exceptions-id" x="303" y="460.5">310</text></a>
|
||||
<a class="nj-exceptions-chip" xlink:href="#jsonexceptiontype_error311" aria-label="json.exception.type_error.311"><rect x="341.7" y="442" width="41.7" height="28" rx="6"/><text class="nj-exceptions-id" x="350.7" y="460.5">311</text></a>
|
||||
<a class="nj-exceptions-chip" xlink:href="#jsonexceptiontype_error312" aria-label="json.exception.type_error.312"><rect x="389.4" y="442" width="41.7" height="28" rx="6"/><text class="nj-exceptions-id" x="398.4" y="460.5">312</text></a>
|
||||
<a class="nj-exceptions-chip" xlink:href="#jsonexceptiontype_error313" aria-label="json.exception.type_error.313"><rect x="437.1" y="442" width="41.7" height="28" rx="6"/><text class="nj-exceptions-id" x="446.1" y="460.5">313</text></a>
|
||||
<a class="nj-exceptions-chip" xlink:href="#jsonexceptiontype_error314" aria-label="json.exception.type_error.314"><rect x="484.8" y="442" width="41.7" height="28" rx="6"/><text class="nj-exceptions-id" x="493.8" y="460.5">314</text></a>
|
||||
<a class="nj-exceptions-chip" xlink:href="#jsonexceptiontype_error315" aria-label="json.exception.type_error.315"><rect x="532.5" y="442" width="41.7" height="28" rx="6"/><text class="nj-exceptions-id" x="541.5" y="460.5">315</text></a>
|
||||
<a class="nj-exceptions-chip" xlink:href="#jsonexceptiontype_error316" aria-label="json.exception.type_error.316"><rect x="580.2" y="442" width="41.7" height="28" rx="6"/><text class="nj-exceptions-id" x="589.2" y="460.5">316</text></a>
|
||||
<a class="nj-exceptions-chip" xlink:href="#jsonexceptiontype_error317" aria-label="json.exception.type_error.317"><rect x="627.9" y="442" width="41.7" height="28" rx="6"/><text class="nj-exceptions-id" x="636.9" y="460.5">317</text></a>
|
||||
<a class="nj-exceptions-chip" xlink:href="#jsonexceptiontype_error318" aria-label="json.exception.type_error.318"><rect x="675.6" y="442" width="41.7" height="28" rx="6"/><text class="nj-exceptions-id" x="684.6" y="460.5">318</text></a>
|
||||
<a class="nj-exceptions-chip" xlink:href="#jsonexceptiontype_error319" aria-label="json.exception.type_error.319"><rect x="294" y="476" width="41.7" height="28" rx="6"/><text class="nj-exceptions-id" x="303" y="494.5">319</text></a>
|
||||
<a class="nj-exceptions-chip" xlink:href="#jsonexceptiontype_error320" aria-label="json.exception.type_error.320"><rect x="341.7" y="476" width="41.7" height="28" rx="6"/><text class="nj-exceptions-id" x="350.7" y="494.5">320</text></a>
|
||||
<a class="nj-exceptions-chip" xlink:href="#jsonexceptiontype_error321" aria-label="json.exception.type_error.321"><rect x="389.4" y="476" width="41.7" height="28" rx="6"/><text class="nj-exceptions-id" x="398.4" y="494.5">321</text></a>
|
||||
<line class="nj-exceptions-edge" x1="34" y1="556" x2="64" y2="556"/>
|
||||
<a class="nj-exceptions-fam" xlink:href="#out-of-range" aria-label="json::out_of_range, 4xx · 16 ids"><rect class="nj-exceptions-box nj-exceptions-box--fam" x="64" y="530" width="214" height="52" rx="7"/><text class="nj-exceptions-name" x="76" y="552">json::out_of_range</text><text class="nj-exceptions-sub" x="76" y="571">4xx · 16 ids</text></a>
|
||||
<a class="nj-exceptions-chip" xlink:href="#jsonexceptionout_of_range401" aria-label="json.exception.out_of_range.401"><rect x="294" y="542" width="41.7" height="28" rx="6"/><text class="nj-exceptions-id" x="303" y="560.5">401</text></a>
|
||||
<a class="nj-exceptions-chip" xlink:href="#jsonexceptionout_of_range402" aria-label="json.exception.out_of_range.402"><rect x="341.7" y="542" width="41.7" height="28" rx="6"/><text class="nj-exceptions-id" x="350.7" y="560.5">402</text></a>
|
||||
<a class="nj-exceptions-chip" xlink:href="#jsonexceptionout_of_range403" aria-label="json.exception.out_of_range.403"><rect x="389.4" y="542" width="41.7" height="28" rx="6"/><text class="nj-exceptions-id" x="398.4" y="560.5">403</text></a>
|
||||
<a class="nj-exceptions-chip" xlink:href="#jsonexceptionout_of_range404" aria-label="json.exception.out_of_range.404"><rect x="437.1" y="542" width="41.7" height="28" rx="6"/><text class="nj-exceptions-id" x="446.1" y="560.5">404</text></a>
|
||||
<a class="nj-exceptions-chip" xlink:href="#jsonexceptionout_of_range405" aria-label="json.exception.out_of_range.405"><rect x="484.8" y="542" width="41.7" height="28" rx="6"/><text class="nj-exceptions-id" x="493.8" y="560.5">405</text></a>
|
||||
<a class="nj-exceptions-chip" xlink:href="#jsonexceptionout_of_range406" aria-label="json.exception.out_of_range.406"><rect x="532.5" y="542" width="41.7" height="28" rx="6"/><text class="nj-exceptions-id" x="541.5" y="560.5">406</text></a>
|
||||
<a class="nj-exceptions-chip" xlink:href="#jsonexceptionout_of_range407" aria-label="json.exception.out_of_range.407"><rect x="580.2" y="542" width="41.7" height="28" rx="6"/><text class="nj-exceptions-id" x="589.2" y="560.5">407</text></a>
|
||||
<a class="nj-exceptions-chip" xlink:href="#jsonexceptionout_of_range408" aria-label="json.exception.out_of_range.408"><rect x="627.9" y="542" width="41.7" height="28" rx="6"/><text class="nj-exceptions-id" x="636.9" y="560.5">408</text></a>
|
||||
<a class="nj-exceptions-chip" xlink:href="#jsonexceptionout_of_range409" aria-label="json.exception.out_of_range.409"><rect x="675.6" y="542" width="41.7" height="28" rx="6"/><text class="nj-exceptions-id" x="684.6" y="560.5">409</text></a>
|
||||
<a class="nj-exceptions-chip" xlink:href="#jsonexceptionout_of_range410" aria-label="json.exception.out_of_range.410"><rect x="294" y="576" width="41.7" height="28" rx="6"/><text class="nj-exceptions-id" x="303" y="594.5">410</text></a>
|
||||
<a class="nj-exceptions-chip" xlink:href="#jsonexceptionout_of_range411" aria-label="json.exception.out_of_range.411"><rect x="341.7" y="576" width="41.7" height="28" rx="6"/><text class="nj-exceptions-id" x="350.7" y="594.5">411</text></a>
|
||||
<a class="nj-exceptions-chip" xlink:href="#jsonexceptionout_of_range412" aria-label="json.exception.out_of_range.412"><rect x="389.4" y="576" width="41.7" height="28" rx="6"/><text class="nj-exceptions-id" x="398.4" y="594.5">412</text></a>
|
||||
<a class="nj-exceptions-chip" xlink:href="#jsonexceptionout_of_range413" aria-label="json.exception.out_of_range.413"><rect x="437.1" y="576" width="41.7" height="28" rx="6"/><text class="nj-exceptions-id" x="446.1" y="594.5">413</text></a>
|
||||
<a class="nj-exceptions-chip" xlink:href="#jsonexceptionout_of_range414" aria-label="json.exception.out_of_range.414"><rect x="484.8" y="576" width="41.7" height="28" rx="6"/><text class="nj-exceptions-id" x="493.8" y="594.5">414</text></a>
|
||||
<a class="nj-exceptions-chip" xlink:href="#jsonexceptionout_of_range415" aria-label="json.exception.out_of_range.415"><rect x="532.5" y="576" width="41.7" height="28" rx="6"/><text class="nj-exceptions-id" x="541.5" y="594.5">415</text></a>
|
||||
<a class="nj-exceptions-chip" xlink:href="#jsonexceptionout_of_range416" aria-label="json.exception.out_of_range.416"><rect x="580.2" y="576" width="41.7" height="28" rx="6"/><text class="nj-exceptions-id" x="589.2" y="594.5">416</text></a>
|
||||
<line class="nj-exceptions-edge" x1="34" y1="656" x2="64" y2="656"/>
|
||||
<a class="nj-exceptions-fam" xlink:href="#further-exceptions" aria-label="json::other_error, 5xx · 2 ids"><rect class="nj-exceptions-box nj-exceptions-box--fam" x="64" y="630" width="214" height="52" rx="7"/><text class="nj-exceptions-name" x="76" y="652">json::other_error</text><text class="nj-exceptions-sub" x="76" y="671">5xx · 2 ids</text></a>
|
||||
<a class="nj-exceptions-chip" xlink:href="#jsonexceptionother_error501" aria-label="json.exception.other_error.501"><rect x="294" y="642" width="41.7" height="28" rx="6"/><text class="nj-exceptions-id" x="303" y="660.5">501</text></a>
|
||||
<a class="nj-exceptions-chip" xlink:href="#jsonexceptionother_error502" aria-label="json.exception.other_error.502"><rect x="341.7" y="642" width="41.7" height="28" rx="6"/><text class="nj-exceptions-id" x="350.7" y="660.5">502</text></a>
|
||||
</svg>
|
||||
<svg class="nj-fig nj-exceptions-map nj-exceptions-map--narrow" viewBox="0 0 360 1152" aria-labelledby="nj-exc-map-title-n nj-exc-map-desc-n" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<title id="nj-exc-map-title-n">Exception id map</title>
|
||||
<desc id="nj-exc-map-desc-n">Class tree: std::exception is the base of json::exception, which is the base of the five exception families parse_error (ids 1xx), invalid_iterator (2xx), type_error (3xx), out_of_range (4xx) and other_error (5xx). Each family lists the ids documented on this page, 68 in total; every id links to its section.</desc>
|
||||
<defs><marker id="nj-exc-tri-n" viewBox="0 0 12 12" refX="11" refY="6" markerWidth="11" markerHeight="11" orient="auto"><path class="nj-exceptions-tri" d="M1 1 L11 6 L1 11 z"/></marker></defs>
|
||||
<line class="nj-exceptions-edge" x1="34" y1="1070" x2="34" y2="158" marker-end="url(#nj-exc-tri-n)"/>
|
||||
<rect class="nj-exceptions-box" x="12" y="12" width="190" height="52" rx="7"/><text class="nj-exceptions-name" x="24" y="34">std::exception</text><text class="nj-exceptions-sub" x="24" y="53">C++ standard library base</text>
|
||||
<line class="nj-exceptions-edge" x1="34" y1="104" x2="34" y2="66" marker-end="url(#nj-exc-tri-n)"/>
|
||||
<rect class="nj-exceptions-box" x="12" y="104" width="250" height="52" rx="7"/><text class="nj-exceptions-name" x="24" y="126">json::exception</text><text class="nj-exceptions-sub" x="24" y="145">id, what() · catch-all</text>
|
||||
<line class="nj-exceptions-edge" x1="34" y1="222" x2="64" y2="222"/>
|
||||
<a class="nj-exceptions-fam" xlink:href="#parse-errors" aria-label="json::parse_error, 1xx · 15 ids · adds member byte"><rect class="nj-exceptions-box nj-exceptions-box--fam" x="64" y="196" width="284" height="52" rx="7"/><text class="nj-exceptions-name" x="76" y="218">json::parse_error</text><text class="nj-exceptions-sub" x="76" y="237">1xx · 15 ids · adds member byte</text></a>
|
||||
<a class="nj-exceptions-chip" xlink:href="#jsonexceptionparse_error101" aria-label="json.exception.parse_error.101"><rect x="64" y="258" width="41.7" height="34" rx="6"/><text class="nj-exceptions-id" x="73" y="279.5">101</text></a>
|
||||
<a class="nj-exceptions-chip" xlink:href="#jsonexceptionparse_error102" aria-label="json.exception.parse_error.102"><rect x="111.7" y="258" width="41.7" height="34" rx="6"/><text class="nj-exceptions-id" x="120.7" y="279.5">102</text></a>
|
||||
<a class="nj-exceptions-chip" xlink:href="#jsonexceptionparse_error103" aria-label="json.exception.parse_error.103"><rect x="159.4" y="258" width="41.7" height="34" rx="6"/><text class="nj-exceptions-id" x="168.4" y="279.5">103</text></a>
|
||||
<a class="nj-exceptions-chip" xlink:href="#jsonexceptionparse_error104" aria-label="json.exception.parse_error.104"><rect x="207.1" y="258" width="41.7" height="34" rx="6"/><text class="nj-exceptions-id" x="216.1" y="279.5">104</text></a>
|
||||
<a class="nj-exceptions-chip" xlink:href="#jsonexceptionparse_error105" aria-label="json.exception.parse_error.105"><rect x="254.8" y="258" width="41.7" height="34" rx="6"/><text class="nj-exceptions-id" x="263.8" y="279.5">105</text></a>
|
||||
<a class="nj-exceptions-chip" xlink:href="#jsonexceptionparse_error106" aria-label="json.exception.parse_error.106"><rect x="302.5" y="258" width="41.7" height="34" rx="6"/><text class="nj-exceptions-id" x="311.5" y="279.5">106</text></a>
|
||||
<a class="nj-exceptions-chip" xlink:href="#jsonexceptionparse_error107" aria-label="json.exception.parse_error.107"><rect x="64" y="298" width="41.7" height="34" rx="6"/><text class="nj-exceptions-id" x="73" y="319.5">107</text></a>
|
||||
<a class="nj-exceptions-chip" xlink:href="#jsonexceptionparse_error108" aria-label="json.exception.parse_error.108"><rect x="111.7" y="298" width="41.7" height="34" rx="6"/><text class="nj-exceptions-id" x="120.7" y="319.5">108</text></a>
|
||||
<a class="nj-exceptions-chip" xlink:href="#jsonexceptionparse_error109" aria-label="json.exception.parse_error.109"><rect x="159.4" y="298" width="41.7" height="34" rx="6"/><text class="nj-exceptions-id" x="168.4" y="319.5">109</text></a>
|
||||
<a class="nj-exceptions-chip" xlink:href="#jsonexceptionparse_error110" aria-label="json.exception.parse_error.110"><rect x="207.1" y="298" width="41.7" height="34" rx="6"/><text class="nj-exceptions-id" x="216.1" y="319.5">110</text></a>
|
||||
<a class="nj-exceptions-chip" xlink:href="#jsonexceptionparse_error112" aria-label="json.exception.parse_error.112"><rect x="254.8" y="298" width="41.7" height="34" rx="6"/><text class="nj-exceptions-id" x="263.8" y="319.5">112</text></a>
|
||||
<a class="nj-exceptions-chip" xlink:href="#jsonexceptionparse_error113" aria-label="json.exception.parse_error.113"><rect x="302.5" y="298" width="41.7" height="34" rx="6"/><text class="nj-exceptions-id" x="311.5" y="319.5">113</text></a>
|
||||
<a class="nj-exceptions-chip" xlink:href="#jsonexceptionparse_error114" aria-label="json.exception.parse_error.114"><rect x="64" y="338" width="41.7" height="34" rx="6"/><text class="nj-exceptions-id" x="73" y="359.5">114</text></a>
|
||||
<a class="nj-exceptions-chip" xlink:href="#jsonexceptionparse_error115" aria-label="json.exception.parse_error.115"><rect x="111.7" y="338" width="41.7" height="34" rx="6"/><text class="nj-exceptions-id" x="120.7" y="359.5">115</text></a>
|
||||
<a class="nj-exceptions-chip" xlink:href="#jsonexceptionparse_error116" aria-label="json.exception.parse_error.116"><rect x="159.4" y="338" width="41.7" height="34" rx="6"/><text class="nj-exceptions-id" x="168.4" y="359.5">116</text></a>
|
||||
<line class="nj-exceptions-edge" x1="34" y1="424" x2="64" y2="424"/>
|
||||
<a class="nj-exceptions-fam" xlink:href="#iterator-errors" aria-label="json::invalid_iterator, 2xx · 14 ids"><rect class="nj-exceptions-box nj-exceptions-box--fam" x="64" y="398" width="284" height="52" rx="7"/><text class="nj-exceptions-name" x="76" y="420">json::invalid_iterator</text><text class="nj-exceptions-sub" x="76" y="439">2xx · 14 ids</text></a>
|
||||
<a class="nj-exceptions-chip" xlink:href="#jsonexceptioninvalid_iterator201" aria-label="json.exception.invalid_iterator.201"><rect x="64" y="460" width="41.7" height="34" rx="6"/><text class="nj-exceptions-id" x="73" y="481.5">201</text></a>
|
||||
<a class="nj-exceptions-chip" xlink:href="#jsonexceptioninvalid_iterator202" aria-label="json.exception.invalid_iterator.202"><rect x="111.7" y="460" width="41.7" height="34" rx="6"/><text class="nj-exceptions-id" x="120.7" y="481.5">202</text></a>
|
||||
<a class="nj-exceptions-chip" xlink:href="#jsonexceptioninvalid_iterator203" aria-label="json.exception.invalid_iterator.203"><rect x="159.4" y="460" width="41.7" height="34" rx="6"/><text class="nj-exceptions-id" x="168.4" y="481.5">203</text></a>
|
||||
<a class="nj-exceptions-chip" xlink:href="#jsonexceptioninvalid_iterator204" aria-label="json.exception.invalid_iterator.204"><rect x="207.1" y="460" width="41.7" height="34" rx="6"/><text class="nj-exceptions-id" x="216.1" y="481.5">204</text></a>
|
||||
<a class="nj-exceptions-chip" xlink:href="#jsonexceptioninvalid_iterator205" aria-label="json.exception.invalid_iterator.205"><rect x="254.8" y="460" width="41.7" height="34" rx="6"/><text class="nj-exceptions-id" x="263.8" y="481.5">205</text></a>
|
||||
<a class="nj-exceptions-chip" xlink:href="#jsonexceptioninvalid_iterator206" aria-label="json.exception.invalid_iterator.206"><rect x="302.5" y="460" width="41.7" height="34" rx="6"/><text class="nj-exceptions-id" x="311.5" y="481.5">206</text></a>
|
||||
<a class="nj-exceptions-chip" xlink:href="#jsonexceptioninvalid_iterator207" aria-label="json.exception.invalid_iterator.207"><rect x="64" y="500" width="41.7" height="34" rx="6"/><text class="nj-exceptions-id" x="73" y="521.5">207</text></a>
|
||||
<a class="nj-exceptions-chip" xlink:href="#jsonexceptioninvalid_iterator208" aria-label="json.exception.invalid_iterator.208"><rect x="111.7" y="500" width="41.7" height="34" rx="6"/><text class="nj-exceptions-id" x="120.7" y="521.5">208</text></a>
|
||||
<a class="nj-exceptions-chip" xlink:href="#jsonexceptioninvalid_iterator209" aria-label="json.exception.invalid_iterator.209"><rect x="159.4" y="500" width="41.7" height="34" rx="6"/><text class="nj-exceptions-id" x="168.4" y="521.5">209</text></a>
|
||||
<a class="nj-exceptions-chip" xlink:href="#jsonexceptioninvalid_iterator210" aria-label="json.exception.invalid_iterator.210"><rect x="207.1" y="500" width="41.7" height="34" rx="6"/><text class="nj-exceptions-id" x="216.1" y="521.5">210</text></a>
|
||||
<a class="nj-exceptions-chip" xlink:href="#jsonexceptioninvalid_iterator211" aria-label="json.exception.invalid_iterator.211"><rect x="254.8" y="500" width="41.7" height="34" rx="6"/><text class="nj-exceptions-id" x="263.8" y="521.5">211</text></a>
|
||||
<a class="nj-exceptions-chip" xlink:href="#jsonexceptioninvalid_iterator212" aria-label="json.exception.invalid_iterator.212"><rect x="302.5" y="500" width="41.7" height="34" rx="6"/><text class="nj-exceptions-id" x="311.5" y="521.5">212</text></a>
|
||||
<a class="nj-exceptions-chip" xlink:href="#jsonexceptioninvalid_iterator213" aria-label="json.exception.invalid_iterator.213"><rect x="64" y="540" width="41.7" height="34" rx="6"/><text class="nj-exceptions-id" x="73" y="561.5">213</text></a>
|
||||
<a class="nj-exceptions-chip" xlink:href="#jsonexceptioninvalid_iterator214" aria-label="json.exception.invalid_iterator.214"><rect x="111.7" y="540" width="41.7" height="34" rx="6"/><text class="nj-exceptions-id" x="120.7" y="561.5">214</text></a>
|
||||
<line class="nj-exceptions-edge" x1="34" y1="626" x2="64" y2="626"/>
|
||||
<a class="nj-exceptions-fam" xlink:href="#type-errors" aria-label="json::type_error, 3xx · 21 ids"><rect class="nj-exceptions-box nj-exceptions-box--fam" x="64" y="600" width="284" height="52" rx="7"/><text class="nj-exceptions-name" x="76" y="622">json::type_error</text><text class="nj-exceptions-sub" x="76" y="641">3xx · 21 ids</text></a>
|
||||
<a class="nj-exceptions-chip" xlink:href="#jsonexceptiontype_error301" aria-label="json.exception.type_error.301"><rect x="64" y="662" width="41.7" height="34" rx="6"/><text class="nj-exceptions-id" x="73" y="683.5">301</text></a>
|
||||
<a class="nj-exceptions-chip" xlink:href="#jsonexceptiontype_error302" aria-label="json.exception.type_error.302"><rect x="111.7" y="662" width="41.7" height="34" rx="6"/><text class="nj-exceptions-id" x="120.7" y="683.5">302</text></a>
|
||||
<a class="nj-exceptions-chip" xlink:href="#jsonexceptiontype_error303" aria-label="json.exception.type_error.303"><rect x="159.4" y="662" width="41.7" height="34" rx="6"/><text class="nj-exceptions-id" x="168.4" y="683.5">303</text></a>
|
||||
<a class="nj-exceptions-chip" xlink:href="#jsonexceptiontype_error304" aria-label="json.exception.type_error.304"><rect x="207.1" y="662" width="41.7" height="34" rx="6"/><text class="nj-exceptions-id" x="216.1" y="683.5">304</text></a>
|
||||
<a class="nj-exceptions-chip" xlink:href="#jsonexceptiontype_error305" aria-label="json.exception.type_error.305"><rect x="254.8" y="662" width="41.7" height="34" rx="6"/><text class="nj-exceptions-id" x="263.8" y="683.5">305</text></a>
|
||||
<a class="nj-exceptions-chip" xlink:href="#jsonexceptiontype_error306" aria-label="json.exception.type_error.306"><rect x="302.5" y="662" width="41.7" height="34" rx="6"/><text class="nj-exceptions-id" x="311.5" y="683.5">306</text></a>
|
||||
<a class="nj-exceptions-chip" xlink:href="#jsonexceptiontype_error307" aria-label="json.exception.type_error.307"><rect x="64" y="702" width="41.7" height="34" rx="6"/><text class="nj-exceptions-id" x="73" y="723.5">307</text></a>
|
||||
<a class="nj-exceptions-chip" xlink:href="#jsonexceptiontype_error308" aria-label="json.exception.type_error.308"><rect x="111.7" y="702" width="41.7" height="34" rx="6"/><text class="nj-exceptions-id" x="120.7" y="723.5">308</text></a>
|
||||
<a class="nj-exceptions-chip" xlink:href="#jsonexceptiontype_error309" aria-label="json.exception.type_error.309"><rect x="159.4" y="702" width="41.7" height="34" rx="6"/><text class="nj-exceptions-id" x="168.4" y="723.5">309</text></a>
|
||||
<a class="nj-exceptions-chip" xlink:href="#jsonexceptiontype_error310" aria-label="json.exception.type_error.310"><rect x="207.1" y="702" width="41.7" height="34" rx="6"/><text class="nj-exceptions-id" x="216.1" y="723.5">310</text></a>
|
||||
<a class="nj-exceptions-chip" xlink:href="#jsonexceptiontype_error311" aria-label="json.exception.type_error.311"><rect x="254.8" y="702" width="41.7" height="34" rx="6"/><text class="nj-exceptions-id" x="263.8" y="723.5">311</text></a>
|
||||
<a class="nj-exceptions-chip" xlink:href="#jsonexceptiontype_error312" aria-label="json.exception.type_error.312"><rect x="302.5" y="702" width="41.7" height="34" rx="6"/><text class="nj-exceptions-id" x="311.5" y="723.5">312</text></a>
|
||||
<a class="nj-exceptions-chip" xlink:href="#jsonexceptiontype_error313" aria-label="json.exception.type_error.313"><rect x="64" y="742" width="41.7" height="34" rx="6"/><text class="nj-exceptions-id" x="73" y="763.5">313</text></a>
|
||||
<a class="nj-exceptions-chip" xlink:href="#jsonexceptiontype_error314" aria-label="json.exception.type_error.314"><rect x="111.7" y="742" width="41.7" height="34" rx="6"/><text class="nj-exceptions-id" x="120.7" y="763.5">314</text></a>
|
||||
<a class="nj-exceptions-chip" xlink:href="#jsonexceptiontype_error315" aria-label="json.exception.type_error.315"><rect x="159.4" y="742" width="41.7" height="34" rx="6"/><text class="nj-exceptions-id" x="168.4" y="763.5">315</text></a>
|
||||
<a class="nj-exceptions-chip" xlink:href="#jsonexceptiontype_error316" aria-label="json.exception.type_error.316"><rect x="207.1" y="742" width="41.7" height="34" rx="6"/><text class="nj-exceptions-id" x="216.1" y="763.5">316</text></a>
|
||||
<a class="nj-exceptions-chip" xlink:href="#jsonexceptiontype_error317" aria-label="json.exception.type_error.317"><rect x="254.8" y="742" width="41.7" height="34" rx="6"/><text class="nj-exceptions-id" x="263.8" y="763.5">317</text></a>
|
||||
<a class="nj-exceptions-chip" xlink:href="#jsonexceptiontype_error318" aria-label="json.exception.type_error.318"><rect x="302.5" y="742" width="41.7" height="34" rx="6"/><text class="nj-exceptions-id" x="311.5" y="763.5">318</text></a>
|
||||
<a class="nj-exceptions-chip" xlink:href="#jsonexceptiontype_error319" aria-label="json.exception.type_error.319"><rect x="64" y="782" width="41.7" height="34" rx="6"/><text class="nj-exceptions-id" x="73" y="803.5">319</text></a>
|
||||
<a class="nj-exceptions-chip" xlink:href="#jsonexceptiontype_error320" aria-label="json.exception.type_error.320"><rect x="111.7" y="782" width="41.7" height="34" rx="6"/><text class="nj-exceptions-id" x="120.7" y="803.5">320</text></a>
|
||||
<a class="nj-exceptions-chip" xlink:href="#jsonexceptiontype_error321" aria-label="json.exception.type_error.321"><rect x="159.4" y="782" width="41.7" height="34" rx="6"/><text class="nj-exceptions-id" x="168.4" y="803.5">321</text></a>
|
||||
<line class="nj-exceptions-edge" x1="34" y1="868" x2="64" y2="868"/>
|
||||
<a class="nj-exceptions-fam" xlink:href="#out-of-range" aria-label="json::out_of_range, 4xx · 16 ids"><rect class="nj-exceptions-box nj-exceptions-box--fam" x="64" y="842" width="284" height="52" rx="7"/><text class="nj-exceptions-name" x="76" y="864">json::out_of_range</text><text class="nj-exceptions-sub" x="76" y="883">4xx · 16 ids</text></a>
|
||||
<a class="nj-exceptions-chip" xlink:href="#jsonexceptionout_of_range401" aria-label="json.exception.out_of_range.401"><rect x="64" y="904" width="41.7" height="34" rx="6"/><text class="nj-exceptions-id" x="73" y="925.5">401</text></a>
|
||||
<a class="nj-exceptions-chip" xlink:href="#jsonexceptionout_of_range402" aria-label="json.exception.out_of_range.402"><rect x="111.7" y="904" width="41.7" height="34" rx="6"/><text class="nj-exceptions-id" x="120.7" y="925.5">402</text></a>
|
||||
<a class="nj-exceptions-chip" xlink:href="#jsonexceptionout_of_range403" aria-label="json.exception.out_of_range.403"><rect x="159.4" y="904" width="41.7" height="34" rx="6"/><text class="nj-exceptions-id" x="168.4" y="925.5">403</text></a>
|
||||
<a class="nj-exceptions-chip" xlink:href="#jsonexceptionout_of_range404" aria-label="json.exception.out_of_range.404"><rect x="207.1" y="904" width="41.7" height="34" rx="6"/><text class="nj-exceptions-id" x="216.1" y="925.5">404</text></a>
|
||||
<a class="nj-exceptions-chip" xlink:href="#jsonexceptionout_of_range405" aria-label="json.exception.out_of_range.405"><rect x="254.8" y="904" width="41.7" height="34" rx="6"/><text class="nj-exceptions-id" x="263.8" y="925.5">405</text></a>
|
||||
<a class="nj-exceptions-chip" xlink:href="#jsonexceptionout_of_range406" aria-label="json.exception.out_of_range.406"><rect x="302.5" y="904" width="41.7" height="34" rx="6"/><text class="nj-exceptions-id" x="311.5" y="925.5">406</text></a>
|
||||
<a class="nj-exceptions-chip" xlink:href="#jsonexceptionout_of_range407" aria-label="json.exception.out_of_range.407"><rect x="64" y="944" width="41.7" height="34" rx="6"/><text class="nj-exceptions-id" x="73" y="965.5">407</text></a>
|
||||
<a class="nj-exceptions-chip" xlink:href="#jsonexceptionout_of_range408" aria-label="json.exception.out_of_range.408"><rect x="111.7" y="944" width="41.7" height="34" rx="6"/><text class="nj-exceptions-id" x="120.7" y="965.5">408</text></a>
|
||||
<a class="nj-exceptions-chip" xlink:href="#jsonexceptionout_of_range409" aria-label="json.exception.out_of_range.409"><rect x="159.4" y="944" width="41.7" height="34" rx="6"/><text class="nj-exceptions-id" x="168.4" y="965.5">409</text></a>
|
||||
<a class="nj-exceptions-chip" xlink:href="#jsonexceptionout_of_range410" aria-label="json.exception.out_of_range.410"><rect x="207.1" y="944" width="41.7" height="34" rx="6"/><text class="nj-exceptions-id" x="216.1" y="965.5">410</text></a>
|
||||
<a class="nj-exceptions-chip" xlink:href="#jsonexceptionout_of_range411" aria-label="json.exception.out_of_range.411"><rect x="254.8" y="944" width="41.7" height="34" rx="6"/><text class="nj-exceptions-id" x="263.8" y="965.5">411</text></a>
|
||||
<a class="nj-exceptions-chip" xlink:href="#jsonexceptionout_of_range412" aria-label="json.exception.out_of_range.412"><rect x="302.5" y="944" width="41.7" height="34" rx="6"/><text class="nj-exceptions-id" x="311.5" y="965.5">412</text></a>
|
||||
<a class="nj-exceptions-chip" xlink:href="#jsonexceptionout_of_range413" aria-label="json.exception.out_of_range.413"><rect x="64" y="984" width="41.7" height="34" rx="6"/><text class="nj-exceptions-id" x="73" y="1005.5">413</text></a>
|
||||
<a class="nj-exceptions-chip" xlink:href="#jsonexceptionout_of_range414" aria-label="json.exception.out_of_range.414"><rect x="111.7" y="984" width="41.7" height="34" rx="6"/><text class="nj-exceptions-id" x="120.7" y="1005.5">414</text></a>
|
||||
<a class="nj-exceptions-chip" xlink:href="#jsonexceptionout_of_range415" aria-label="json.exception.out_of_range.415"><rect x="159.4" y="984" width="41.7" height="34" rx="6"/><text class="nj-exceptions-id" x="168.4" y="1005.5">415</text></a>
|
||||
<a class="nj-exceptions-chip" xlink:href="#jsonexceptionout_of_range416" aria-label="json.exception.out_of_range.416"><rect x="207.1" y="984" width="41.7" height="34" rx="6"/><text class="nj-exceptions-id" x="216.1" y="1005.5">416</text></a>
|
||||
<line class="nj-exceptions-edge" x1="34" y1="1070" x2="64" y2="1070"/>
|
||||
<a class="nj-exceptions-fam" xlink:href="#further-exceptions" aria-label="json::other_error, 5xx · 2 ids"><rect class="nj-exceptions-box nj-exceptions-box--fam" x="64" y="1044" width="284" height="52" rx="7"/><text class="nj-exceptions-name" x="76" y="1066">json::other_error</text><text class="nj-exceptions-sub" x="76" y="1085">5xx · 2 ids</text></a>
|
||||
<a class="nj-exceptions-chip" xlink:href="#jsonexceptionother_error501" aria-label="json.exception.other_error.501"><rect x="64" y="1106" width="41.7" height="34" rx="6"/><text class="nj-exceptions-id" x="73" y="1127.5">501</text></a>
|
||||
<a class="nj-exceptions-chip" xlink:href="#jsonexceptionother_error502" aria-label="json.exception.other_error.502"><rect x="111.7" y="1106" width="41.7" height="34" rx="6"/><text class="nj-exceptions-id" x="120.7" y="1127.5">502</text></a>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 39 KiB |
@@ -1 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 1200 675" width="1200" height="675" role="img"><title>JSON for Modern C++: feature slideshow (animated, 20 slides, 15 s each)</title><style>.bg{fill:#fff} .tx{fill:#0f1419} .tx2{fill:#3d444f} .tx3{fill:#8a919c} .com{fill:#646d7a}.bl{fill:#1747a6} .blk{fill:#1747a6} .kw{fill:#1747a6} .ty{fill:#0d6e72} .fn{fill:#6b3fb8} .str{fill:#23793a} .num{fill:#b04a07} .pp{fill:#a3247a}.panel{fill:#f5f7fa;stroke:#e3e6eb;stroke-width:1} .rule{stroke:#e3e6eb;stroke-width:1}.wm-a{fill:#0f1419} .wm-s{fill:#1747a6}.on-a,.on-tx{fill:#fff} .red{fill:#d93a3f} .on-panel{fill:#fff;fill-opacity:.08;stroke:#fff;stroke-opacity:.16} .on-s{fill:#bcd3fb} .w70{fill:#fff;fill-opacity:.7} .on-tx2{fill:#dbe6fb} .chip{fill:#fff;fill-opacity:.14}.pat{fill:#fff;fill-opacity:.09}.h1{stop-color:#1d55c4} .h2{stop-color:#123a8a}.seg{fill:#e3e6eb} .seg-on{fill:#1747a6}.seg.on-band{fill:#fff;fill-opacity:.25} .seg-on.on-band{fill:#fff;fill-opacity:1}.bg{fill:#0f1218} .tx,.wm-a{fill:#f2f4f7} .tx2{fill:#c3c8d1} .tx3{fill:#7b828e} .com{fill:#8b929e}.bl,.blk,.wm-s,.seg-on,.kw{fill:#7aa7f5} .ty{fill:#4fd1c5} .fn{fill:#c4a3ff} .str{fill:#7ed491} .num{fill:#f5a65b} .pp{fill:#f48fc8}.panel{fill:#171b23;stroke:#272c36} .rule{stroke:#272c36} .seg{fill:#272c36}.red{fill:#c8383d} .h1{stop-color:#163f93} .h2{stop-color:#0c2556}.s{opacity:0;animation:show 300s linear infinite backwards}.fill{transform-box:fill-box;transform-origin:left;animation:fill 300s linear infinite backwards;animation-delay:inherit}.s0{animation-name:show0} .sl{animation-name:showl}@keyframes show{0%{opacity:0;animation-timing-function:cubic-bezier(.2,.6,.2,1)} 0.2000%{opacity:1} 5.2000%{opacity:1} 5.2100%{opacity:0} 100%{opacity:0}}@keyframes show0{0%{opacity:1} 5.2000%{opacity:1} 5.2100%{opacity:0} 100%{opacity:0}}@keyframes showl{0%{opacity:0;animation-timing-function:cubic-bezier(.2,.6,.2,1)} 0.2000%{opacity:1} 5.0000%{opacity:1} 5.2000%{opacity:0} 100%{opacity:0}}@keyframes fill{0%{transform:scaleX(0)} 5.0000%{transform:scaleX(1)} 100%{transform:scaleX(1)}}@media (prefers-reduced-motion:reduce){.s,.fill{animation:none} .s:first-of-type{opacity:1}}</style><defs><path id="g0" d="M233 0 46 730H148L269 238Q281 191 289 148Q298 105 302 81Q306 105 315 148Q324 191 335 239L452 730H554L366 0H233Z"/><path id="g1" d="M97 0V730H522V641H195V424H487V337H195V89H522V0H97Z"/><path id="g2" d="M89 0V730H315Q382 730 432 703Q483 677 510 629Q538 582 538 518Q538 445 501 391Q463 338 401 316L548 0H439L300 305H187V0H89ZM187 393H315Q370 393 403 427Q436 461 436 517Q436 574 403 608Q370 642 315 642H187V393Z"/><path id="g3" d="M304 -10Q233 -10 179 15Q126 41 97 88Q68 136 68 202H167Q167 144 204 111Q242 78 304 78Q364 78 399 112Q435 146 435 201Q435 243 412 274Q390 306 347 317L239 346Q168 366 126 419Q85 471 85 543Q85 602 112 646Q138 691 186 715Q234 740 297 740Q361 740 409 715Q457 691 485 647Q512 603 512 545H414Q414 593 381 623Q348 653 297 653Q245 653 214 623Q182 593 182 545Q182 507 203 480Q224 453 262 442L373 412Q448 392 490 336Q532 279 532 201Q532 137 504 89Q476 42 424 16Q373 -10 304 -10Z"/><path id="g4" d="M101 0V90H250V640H101V730H499V640H350V90H499V0H101Z"/><path id="g5" d="M300 -10Q200 -10 142 48Q84 106 84 212V518Q84 625 142 682Q200 740 300 740Q400 740 458 682Q516 625 516 519V212Q516 106 458 48Q400 -10 300 -10ZM300 78Q357 78 387 110Q417 142 417 202V528Q417 588 387 620Q357 652 300 652Q244 652 213 620Q183 588 183 528V202Q183 142 213 110Q244 78 300 78Z"/><path id="g6" d="M85 0V730H214L432 114Q429 141 427 179Q424 217 422 259Q421 301 421 337V730H515V0H386L170 616Q172 591 174 553Q176 516 178 474Q179 433 179 396V0H85Z"/><path id="g8" d="M290 -10Q187 -10 127 46Q67 103 67 200H166Q166 143 200 110Q233 78 291 78Q348 78 382 110Q415 143 415 200V251Q415 308 382 341Q349 375 291 375H209V458L385 641H89V730H496V640L291 428L293 462Q395 462 455 405Q515 349 515 251V200Q515 103 454 46Q394 -10 290 -10Z"/><path id="g9" d="M300 -10Q262 -10 238 13Q215 36 215 72Q215 111 238 134Q262 158 300 158Q338 158 362 134Q385 111 385 72Q385 36 362 13Q338 -10 300 -10Z"/><path id="ga" d="M88 0V90H284V641L88 495V607L254 730H383V90H543V0H88Z"/><path id="gb" d="M300 -10Q232 -10 182 17Q132 43 104 92Q77 141 77 206V524Q77 590 104 638Q132 687 182 713Q232 740 300 740Q369 740 419 713Q468 687 496 638Q523 590 523 524V206Q523 141 496 92Q468 43 418 17Q368 -10 300 -10ZM300 75Q358 75 393 111Q428 148 428 206V524Q428 582 393 619Q358 655 300 655Q242 655 207 619Q172 582 172 524V206Q172 148 207 111Q242 75 300 75ZM300 309Q272 309 255 324Q238 339 238 368Q238 396 255 411Q272 425 300 425Q328 425 345 411Q362 396 362 368Q362 339 345 324Q328 309 300 309Z"/><path id="gc" d="M180 688V0H134V1056H180V816H168Q204 944 310 1008Q417 1072 544 1072Q659 1072 746 1024Q834 975 884 889Q934 803 934 688V0H888V688Q888 840 792 933Q696 1026 544 1026Q440 1026 358 982Q275 939 228 862Q180 786 180 688Z"/><path id="gd" d="M180 1490V0H134V1490H180Z"/><path id="ge" d="M530 -16Q394 -16 289 54Q184 125 125 248Q66 371 6Line truncated
|
||||
|
Before Width: | Height: | Size: 395 KiB |
@@ -1 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 1200 675" width="1200" height="675" role="img"><title>JSON for Modern C++: feature slideshow (animated, 20 slides, 15 s each)</title><style>.bg{fill:#fff} .tx{fill:#0f1419} .tx2{fill:#3d444f} .tx3{fill:#8a919c} .com{fill:#646d7a}.bl{fill:#1747a6} .blk{fill:#1747a6} .kw{fill:#1747a6} .ty{fill:#0d6e72} .fn{fill:#6b3fb8} .str{fill:#23793a} .num{fill:#b04a07} .pp{fill:#a3247a}.panel{fill:#f5f7fa;stroke:#e3e6eb;stroke-width:1} .rule{stroke:#e3e6eb;stroke-width:1}.wm-a{fill:#0f1419} .wm-s{fill:#1747a6}.on-a,.on-tx{fill:#fff} .red{fill:#d93a3f} .on-panel{fill:#fff;fill-opacity:.08;stroke:#fff;stroke-opacity:.16} .on-s{fill:#bcd3fb} .w70{fill:#fff;fill-opacity:.7} .on-tx2{fill:#dbe6fb} .chip{fill:#fff;fill-opacity:.14}.pat{fill:#fff;fill-opacity:.09}.h1{stop-color:#1d55c4} .h2{stop-color:#123a8a}.seg{fill:#e3e6eb} .seg-on{fill:#1747a6}.seg.on-band{fill:#fff;fill-opacity:.25} .seg-on.on-band{fill:#fff;fill-opacity:1}.s{opacity:0;animation:show 300s linear infinite backwards}.fill{transform-box:fill-box;transform-origin:left;animation:fill 300s linear infinite backwards;animation-delay:inherit}.s0{animation-name:show0} .sl{animation-name:showl}@keyframes show{0%{opacity:0;animation-timing-function:cubic-bezier(.2,.6,.2,1)} 0.2000%{opacity:1} 5.2000%{opacity:1} 5.2100%{opacity:0} 100%{opacity:0}}@keyframes show0{0%{opacity:1} 5.2000%{opacity:1} 5.2100%{opacity:0} 100%{opacity:0}}@keyframes showl{0%{opacity:0;animation-timing-function:cubic-bezier(.2,.6,.2,1)} 0.2000%{opacity:1} 5.0000%{opacity:1} 5.2000%{opacity:0} 100%{opacity:0}}@keyframes fill{0%{transform:scaleX(0)} 5.0000%{transform:scaleX(1)} 100%{transform:scaleX(1)}}@media (prefers-reduced-motion:reduce){.s,.fill{animation:none} .s:first-of-type{opacity:1}}</style><defs><path id="g0" d="M233 0 46 730H148L269 238Q281 191 289 148Q298 105 302 81Q306 105 315 148Q324 191 335 239L452 730H554L366 0H233Z"/><path id="g1" d="M97 0V730H522V641H195V424H487V337H195V89H522V0H97Z"/><path id="g2" d="M89 0V730H315Q382 730 432 703Q483 677 510 629Q538 582 538 518Q538 445 501 391Q463 338 401 316L548 0H439L300 305H187V0H89ZM187 393H315Q370 393 403 427Q436 461 436 517Q436 574 403 608Q370 642 315 642H187V393Z"/><path id="g3" d="M304 -10Q233 -10 179 15Q126 41 97 88Q68 136 68 202H167Q167 144 204 111Q242 78 304 78Q364 78 399 112Q435 146 435 201Q435 243 412 274Q390 306 347 317L239 346Q168 366 126 419Q85 471 85 543Q85 602 112 646Q138 691 186 715Q234 740 297 740Q361 740 409 715Q457 691 485 647Q512 603 512 545H414Q414 593 381 623Q348 653 297 653Q245 653 214 623Q182 593 182 545Q182 507 203 480Q224 453 262 442L373 412Q448 392 490 336Q532 279 532 201Q532 137 504 89Q476 42 424 16Q373 -10 304 -10Z"/><path id="g4" d="M101 0V90H250V640H101V730H499V640H350V90H499V0H101Z"/><path id="g5" d="M300 -10Q200 -10 142 48Q84 106 84 212V518Q84 625 142 682Q200 740 300 740Q400 740 458 682Q516 625 516 519V212Q516 106 458 48Q400 -10 300 -10ZM300 78Q357 78 387 110Q417 142 417 202V528Q417 588 387 620Q357 652 300 652Q244 652 213 620Q183 588 183 528V202Q183 142 213 110Q244 78 300 78Z"/><path id="g6" d="M85 0V730H214L432 114Q429 141 427 179Q424 217 422 259Q421 301 421 337V730H515V0H386L170 616Q172 591 174 553Q176 516 178 474Q179 433 179 396V0H85Z"/><path id="g8" d="M290 -10Q187 -10 127 46Q67 103 67 200H166Q166 143 200 110Q233 78 291 78Q348 78 382 110Q415 143 415 200V251Q415 308 382 341Q349 375 291 375H209V458L385 641H89V730H496V640L291 428L293 462Q395 462 455 405Q515 349 515 251V200Q515 103 454 46Q394 -10 290 -10Z"/><path id="g9" d="M300 -10Q262 -10 238 13Q215 36 215 72Q215 111 238 134Q262 158 300 158Q338 158 362 134Q385 111 385 72Q385 36 362 13Q338 -10 300 -10Z"/><path id="ga" d="M88 0V90H284V641L88 495V607L254 730H383V90H543V0H88Z"/><path id="gb" d="M300 -10Q232 -10 182 17Q132 43 104 92Q77 141 77 206V524Q77 590 104 638Q132 687 182 713Q232 740 300 740Q369 740 419 713Q468 687 496 638Q523 590 523 524V206Q523 141 496 92Q468 43 418 17Q368 -10 300 -10ZM300 75Q358 75 393 111Q428 148 428 206V524Q428 582 393 619Q358 655 300 655Q242 655 207 619Q172 582 172 524V206Q172 148 207 111Q242 75 300 75ZM300 309Q272 309 255 324Q238 339 238 368Q238 396 255 411Q272 425 300 425Q328 425 345 411Q362 396 362 368Q362 339 345 324Q328 309 300 309Z"/><path id="gc" d="M180 688V0H134V1056H180V816H168Q204 944 310 1008Q417 1072 544 1072Q659 1072 746 1024Q834 975 884 889Q934 803 934 688V0H888V688Q888 840 792 933Q696 1026 544 1026Q440 1026 358 982Q275 939 228 862Q180 786 180 688Z"/><path id="gd" d="M180 1490V0H134V1490H180Z"/><path id="ge" d="M530 -16Q394 -16 289 54Q184 125 125 248Q66 371 66 528Q66 686 125 808Q184 931 289 1002Q394 1072 530 1072Q666 1072 770 1002Q874 931 933 808Q992 686 992 528Q992 371 933 248Q874 125 770 54Q666 -16 530 -16ZM530 30Q652 30 746 94Q840 157 893 270Q946 382 946 528Q946 674 893 786Q840 899 746 962Q652 1026 530 1026Q408 1026 314 962Q219 899 166 786Q112 674 112 528Q112 382 166 270Q219 157 314 94Q408 30 530 30Z"/><path id="gf" d="MLine truncated
|
||||
|
Before Width: | Height: | Size: 394 KiB |
@@ -1,52 +0,0 @@
|
||||
<svg class="nj-fig nj-pointer-fl" viewBox="0 0 760 442" role="img" aria-labelledby="fig-flat-title" xmlns="http://www.w3.org/2000/svg">
|
||||
<title id="fig-flat-title">flatten() turns the nested example document into a flat object, and unflatten() turns it back. Left, the document as a tree: array with the elements A, B, C, and nested with one = 1, two = 2, and three with the elements true and false. Right, the flat object with one key per leaf: /array/0 = A, /array/1 = B, /array/2 = C, /nested/one = 1, /nested/two = 2, /nested/three/0 = true, /nested/three/1 = false. Each leaf is joined to its key by a line.</title>
|
||||
<defs><marker id="fig-flat-arrow" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="7" markerHeight="7" orient="auto"><path class="fg-head" d="M0 1 L10 5 L0 9 z"/></marker></defs>
|
||||
<text class="fg-h" x="20" y="26">nested value</text>
|
||||
<text class="fg-h" x="470" y="26">flat object: key = J​SON Pointer</text>
|
||||
<line class="fg-arrow" x1="250" y1="52" x2="450" y2="52" marker-end="url(#fig-flat-arrow)"/>
|
||||
<text class="nj-pointer-fl-op" x="350" y="44">flatten()</text>
|
||||
<line class="fg-arrow" x1="450" y1="420" x2="250" y2="420" marker-end="url(#fig-flat-arrow)"/>
|
||||
<text class="nj-pointer-fl-op" x="350" y="412">unflatten()</text>
|
||||
<path class="nj-pointer-fl-edge" d="M25 99 V115 H42"/>
|
||||
<path class="nj-pointer-fl-edge" d="M51 127 V143 H68"/>
|
||||
<path class="nj-pointer-fl-edge" d="M51 127 V171 H68"/>
|
||||
<path class="nj-pointer-fl-edge" d="M51 127 V199 H68"/>
|
||||
<path class="nj-pointer-fl-edge" d="M25 99 V227 H42"/>
|
||||
<path class="nj-pointer-fl-edge" d="M51 239 V255 H68"/>
|
||||
<path class="nj-pointer-fl-edge" d="M51 239 V283 H68"/>
|
||||
<path class="nj-pointer-fl-edge" d="M51 239 V311 H68"/>
|
||||
<path class="nj-pointer-fl-edge" d="M77 323 V339 H94"/>
|
||||
<path class="nj-pointer-fl-edge" d="M77 323 V367 H94"/>
|
||||
<path class="nj-pointer-fl-link nj-pointer-fl--s" d="M139.6 143 C259.6 143 340 171 460 171"/>
|
||||
<circle class="nj-pointer-fl-dot nj-pointer-fl--s" cx="139.6" cy="143" r="3.5"/>
|
||||
<text class="fg-code" x="470" y="176" xml:space="preserve"><tspan class="nj-pointer-fl-key">"/array/0"</tspan>: <tspan class="nj-pointer-fl-v nj-pointer-fl--s">"A"</tspan></text>
|
||||
<path class="nj-pointer-fl-link nj-pointer-fl--s" d="M139.6 171 C259.6 171 340 199 460 199"/>
|
||||
<circle class="nj-pointer-fl-dot nj-pointer-fl--s" cx="139.6" cy="171" r="3.5"/>
|
||||
<text class="fg-code" x="470" y="204" xml:space="preserve"><tspan class="nj-pointer-fl-key">"/array/1"</tspan>: <tspan class="nj-pointer-fl-v nj-pointer-fl--s">"B"</tspan></text>
|
||||
<path class="nj-pointer-fl-link nj-pointer-fl--s" d="M139.6 199 C259.6 199 340 227 460 227"/>
|
||||
<circle class="nj-pointer-fl-dot nj-pointer-fl--s" cx="139.6" cy="199" r="3.5"/>
|
||||
<text class="fg-code" x="470" y="232" xml:space="preserve"><tspan class="nj-pointer-fl-key">"/array/2"</tspan>: <tspan class="nj-pointer-fl-v nj-pointer-fl--s">"C"</tspan></text>
|
||||
<path class="nj-pointer-fl-link nj-pointer-fl--n" d="M158.8 255 C278.8 255 340 255 460 255"/>
|
||||
<circle class="nj-pointer-fl-dot nj-pointer-fl--n" cx="158.8" cy="255" r="3.5"/>
|
||||
<text class="fg-code" x="470" y="260" xml:space="preserve"><tspan class="nj-pointer-fl-key">"/nested/one"</tspan>: <tspan class="nj-pointer-fl-v nj-pointer-fl--n">1</tspan></text>
|
||||
<path class="nj-pointer-fl-link nj-pointer-fl--n" d="M158.8 283 C278.8 283 340 283 460 283"/>
|
||||
<circle class="nj-pointer-fl-dot nj-pointer-fl--n" cx="158.8" cy="283" r="3.5"/>
|
||||
<text class="fg-code" x="470" y="288" xml:space="preserve"><tspan class="nj-pointer-fl-key">"/nested/two"</tspan>: <tspan class="nj-pointer-fl-v nj-pointer-fl--n">2</tspan></text>
|
||||
<path class="nj-pointer-fl-link nj-pointer-fl--b" d="M175.2 339 C295.2 339 340 311 460 311"/>
|
||||
<circle class="nj-pointer-fl-dot nj-pointer-fl--b" cx="175.2" cy="339" r="3.5"/>
|
||||
<text class="fg-code" x="470" y="316" xml:space="preserve"><tspan class="nj-pointer-fl-key">"/nested/three/0"</tspan>: <tspan class="nj-pointer-fl-v nj-pointer-fl--b">true</tspan></text>
|
||||
<path class="nj-pointer-fl-link nj-pointer-fl--b" d="M184.8 367 C304.8 367 340 339 460 339"/>
|
||||
<circle class="nj-pointer-fl-dot nj-pointer-fl--b" cx="184.8" cy="367" r="3.5"/>
|
||||
<text class="fg-code" x="470" y="344" xml:space="preserve"><tspan class="nj-pointer-fl-key">"/nested/three/1"</tspan>: <tspan class="nj-pointer-fl-v nj-pointer-fl--b">false</tspan></text>
|
||||
<text class="fg-h" x="20" y="92">root</text>
|
||||
<text class="fg-code nj-pointer-fl-inner" x="46" y="120">"array"</text>
|
||||
<text class="fg-code" x="72" y="148" xml:space="preserve"><tspan class="nj-pointer-fl-k">0</tspan>: <tspan class="nj-pointer-fl-v nj-pointer-fl--s">"A"</tspan></text>
|
||||
<text class="fg-code" x="72" y="176" xml:space="preserve"><tspan class="nj-pointer-fl-k">1</tspan>: <tspan class="nj-pointer-fl-v nj-pointer-fl--s">"B"</tspan></text>
|
||||
<text class="fg-code" x="72" y="204" xml:space="preserve"><tspan class="nj-pointer-fl-k">2</tspan>: <tspan class="nj-pointer-fl-v nj-pointer-fl--s">"C"</tspan></text>
|
||||
<text class="fg-code nj-pointer-fl-inner" x="46" y="232">"nested"</text>
|
||||
<text class="fg-code" x="72" y="260" xml:space="preserve"><tspan class="nj-pointer-fl-k">"one"</tspan>: <tspan class="nj-pointer-fl-v nj-pointer-fl--n">1</tspan></text>
|
||||
<text class="fg-code" x="72" y="288" xml:space="preserve"><tspan class="nj-pointer-fl-k">"two"</tspan>: <tspan class="nj-pointer-fl-v nj-pointer-fl--n">2</tspan></text>
|
||||
<text class="fg-code nj-pointer-fl-inner" x="72" y="316">"three"</text>
|
||||
<text class="fg-code" x="98" y="344" xml:space="preserve"><tspan class="nj-pointer-fl-k">0</tspan>: <tspan class="nj-pointer-fl-v nj-pointer-fl--b">true</tspan></text>
|
||||
<text class="fg-code" x="98" y="372" xml:space="preserve"><tspan class="nj-pointer-fl-k">1</tspan>: <tspan class="nj-pointer-fl-v nj-pointer-fl--b">false</tspan></text>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 5.6 KiB |
|
After Width: | Height: | Size: 36 KiB |
@@ -1,66 +0,0 @@
|
||||
<svg class="railroad" viewBox="0 0 860 214" role="img" aria-labelledby="rr-title" xmlns="http://www.w3.org/2000/svg">
|
||||
<title id="rr-title">Railroad diagram of the J​SON number syntax: optional minus, then 0 or a digit from 1 to 9 followed by digits, then an optional fraction (a dot and digits) and an optional exponent (e or E, an optional sign, and digits).</title>
|
||||
<g class="rr-track" fill="none" stroke="currentColor" stroke-opacity=".6" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M8 44 L850 44"/>
|
||||
<path d="M24 44 L31 44 Q38 44 38 51 L38 82 Q38 92 48 92 L59 92"/>
|
||||
<path d="M85 92 L96 92 Q106 92 106 82 L106 51 Q106 44 113 44 L120 44"/>
|
||||
<path d="M120 44 L127 44 Q134 44 134 51 L134 82 Q134 92 144 92 L160 92"/>
|
||||
<path d="M242 92 L370 92 Q380 92 380 82 L380 52 Q380 44 388 44 L396 44"/>
|
||||
<path d="M242 92 L250 92 Q258 92 258 100 L258 126 Q258 136 268 136 L278 136"/>
|
||||
<path d="M332 136 L340 136 Q348 136 348 128 L348 92"/>
|
||||
<path d="M340 136 L340 160 Q340 170 330 170 L280 170 Q270 170 270 160 L270 136"/>
|
||||
<path d="M396 44 L403 44 Q410 44 410 51 L410 84.5 Q410 92 417.5 92 L425 92"/>
|
||||
<path d="M451 92 L462 92"/>
|
||||
<path d="M524 92 L524 116 Q524 126 514 126 L466 126 Q456 126 456 116 L456 92"/>
|
||||
<path d="M516 92 L523 92 Q530 92 530 85 L530 52 Q530 44 538 44 L546 44"/>
|
||||
<path d="M546 44 L553 44 Q560 44 560 51 L560 83.5 Q560 92 568.5 92 L577 92"/>
|
||||
<path d="M546 44 L553 44 Q560 44 560 51 L560 127.5 Q560 136 568.5 136 L577 136"/>
|
||||
<path d="M603 92 L728 92"/>
|
||||
<path d="M603 136 L611.5 136 Q620 136 620 127.5 L620 92"/>
|
||||
<path d="M640 92 L647 92 Q654 92 654 99 L654 128 Q654 136 662 136 L670 136"/>
|
||||
<path d="M640 92 L647 92 Q654 92 654 99 L654 172 Q654 180 662 180 L670 180"/>
|
||||
<path d="M696 136 L704 136 Q712 136 712 128 L712 92"/>
|
||||
<path d="M696 180 L704 180 Q712 180 712 172 L712 92"/>
|
||||
<path d="M728 92 L746 92"/>
|
||||
<path d="M808 92 L808 116 Q808 126 798 126 L748 126 Q738 126 738 116 L738 92"/>
|
||||
<path d="M800 92 L808 92 Q816 92 816 84 L816 52 Q816 44 824 44 L832 44"/>
|
||||
</g>
|
||||
<polygon class="rr-arrow" points="2,38 12,44 2,50"/>
|
||||
<polygon class="rr-arrow" points="846,38 858,44 846,50"/>
|
||||
<circle class="rr-bg" cx="72" cy="92" r="13"/>
|
||||
<circle class="rr-t" cx="72" cy="92" r="13"/>
|
||||
<circle class="rr-bg" cx="257" cy="44" r="13"/>
|
||||
<circle class="rr-t" cx="257" cy="44" r="13"/>
|
||||
<rect class="rr-bg" x="160" y="78" width="82" height="28" rx="6"/>
|
||||
<rect class="rr-n" x="160" y="78" width="82" height="28" rx="6"/>
|
||||
<rect class="rr-bg" x="278" y="122" width="54" height="28" rx="6"/>
|
||||
<rect class="rr-n" x="278" y="122" width="54" height="28" rx="6"/>
|
||||
<circle class="rr-bg" cx="438" cy="92" r="13"/>
|
||||
<circle class="rr-t" cx="438" cy="92" r="13"/>
|
||||
<rect class="rr-bg" x="462" y="78" width="54" height="28" rx="6"/>
|
||||
<rect class="rr-n" x="462" y="78" width="54" height="28" rx="6"/>
|
||||
<circle class="rr-bg" cx="590" cy="92" r="13"/>
|
||||
<circle class="rr-t" cx="590" cy="92" r="13"/>
|
||||
<circle class="rr-bg" cx="590" cy="136" r="13"/>
|
||||
<circle class="rr-t" cx="590" cy="136" r="13"/>
|
||||
<circle class="rr-bg" cx="683" cy="136" r="13"/>
|
||||
<circle class="rr-t" cx="683" cy="136" r="13"/>
|
||||
<circle class="rr-bg" cx="683" cy="180" r="13"/>
|
||||
<circle class="rr-t" cx="683" cy="180" r="13"/>
|
||||
<rect class="rr-bg" x="746" y="78" width="54" height="28" rx="6"/>
|
||||
<rect class="rr-n" x="746" y="78" width="54" height="28" rx="6"/>
|
||||
<text class="rr-c" x="72" y="97">−</text>
|
||||
<text class="rr-c" x="257" y="49">0</text>
|
||||
<text class="rr-b" x="201" y="97">digit 1–9</text>
|
||||
<text class="rr-b" x="305" y="141">digit</text>
|
||||
<text class="rr-c" x="438" y="97">.</text>
|
||||
<text class="rr-b" x="489" y="97">digit</text>
|
||||
<text class="rr-c" x="590" y="97">e</text>
|
||||
<text class="rr-c" x="590" y="141">E</text>
|
||||
<text class="rr-c" x="683" y="141">−</text>
|
||||
<text class="rr-c" x="683" y="185">+</text>
|
||||
<text class="rr-b" x="773" y="97">digit</text>
|
||||
<text class="rr-l rr-name" x="24" y="32">number</text>
|
||||
<text class="rr-l" x="420" y="32">fraction</text>
|
||||
<text class="rr-l" x="580" y="32">exponent</text>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 3.9 KiB |
@@ -1,57 +0,0 @@
|
||||
<svg class="nj-fig nj-jsonview nj-jsonview-editfig" viewBox="0 0 840 372" role="img" aria-labelledby="fig-jve0-title fig-jve0-title-d" xmlns="http://www.w3.org/2000/svg">
|
||||
<title id="fig-jve0-title">Step 1 of 5: parsed</title>
|
||||
<desc id="fig-jve0-title-d">After parse: nine nodes, nothing owned yet. The dump with number_format::source is {"port":6379,"price":19.90,"tags":["eu","a\"b"]}.</desc>
|
||||
<defs>
|
||||
<marker id="jve0-line" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="6.5" markerHeight="6.5" orient="auto-start-reverse"><path class="nj-jsonview-c-line nj-jsonview-head" d="M0 1 L10 5 L0 9 z"/></marker>
|
||||
<marker id="jve0-own" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="6.5" markerHeight="6.5" orient="auto-start-reverse"><path class="nj-jsonview-c-own nj-jsonview-head" d="M0 1 L10 5 L0 9 z"/></marker>
|
||||
<marker id="jve0-struct" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="6.5" markerHeight="6.5" orient="auto-start-reverse"><path class="nj-jsonview-c-struct nj-jsonview-head" d="M0 1 L10 5 L0 9 z"/></marker>
|
||||
<marker id="jve0-bad" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="6.5" markerHeight="6.5" orient="auto-start-reverse"><path class="nj-jsonview-c-bad nj-jsonview-head" d="M0 1 L10 5 L0 9 z"/></marker>
|
||||
</defs>
|
||||
<text class="nj-jsonview-note nj-jsonview-strong" x="16" y="22" xml:space="preserve">parsed index: fixed, never moves</text>
|
||||
<text class="nj-jsonview-note" x="824" y="22" text-anchor="end" xml:space="preserve">the source text is never written</text>
|
||||
<rect class="nj-jsonview-node nj-jsonview-c-struct" x="36" y="34" width="84" height="50" rx="5"/>
|
||||
<text class="nj-jsonview-tiny" x="42" y="47" xml:space="preserve">0</text>
|
||||
<text class="nj-jsonview-kind nj-jsonview-xs nj-jsonview-c-struct" x="78" y="61" text-anchor="middle" xml:space="preserve">object</text>
|
||||
<text class="nj-jsonview-mono nj-jsonview-sm" x="78" y="77" text-anchor="middle" xml:space="preserve">{ } 3</text>
|
||||
<rect class="nj-jsonview-node nj-jsonview-c-key" x="124" y="34" width="84" height="50" rx="5"/>
|
||||
<text class="nj-jsonview-tiny" x="130" y="47" xml:space="preserve">1</text>
|
||||
<text class="nj-jsonview-kind nj-jsonview-xs nj-jsonview-c-key" x="166" y="61" text-anchor="middle" xml:space="preserve">key</text>
|
||||
<text class="nj-jsonview-mono nj-jsonview-sm" x="166" y="77" text-anchor="middle" xml:space="preserve">port</text>
|
||||
<rect class="nj-jsonview-node nj-jsonview-c-num" x="212" y="34" width="84" height="50" rx="5"/>
|
||||
<text class="nj-jsonview-tiny" x="218" y="47" xml:space="preserve">2</text>
|
||||
<text class="nj-jsonview-kind nj-jsonview-xs nj-jsonview-c-num" x="254" y="61" text-anchor="middle" xml:space="preserve">uint</text>
|
||||
<text class="nj-jsonview-mono nj-jsonview-sm" x="254" y="77" text-anchor="middle" xml:space="preserve">6379</text>
|
||||
<rect class="nj-jsonview-node nj-jsonview-c-key" x="300" y="34" width="84" height="50" rx="5"/>
|
||||
<text class="nj-jsonview-tiny" x="306" y="47" xml:space="preserve">3</text>
|
||||
<text class="nj-jsonview-kind nj-jsonview-xs nj-jsonview-c-key" x="342" y="61" text-anchor="middle" xml:space="preserve">key</text>
|
||||
<text class="nj-jsonview-mono nj-jsonview-sm" x="342" y="77" text-anchor="middle" xml:space="preserve">price</text>
|
||||
<rect class="nj-jsonview-node nj-jsonview-c-num" x="388" y="34" width="84" height="50" rx="5"/>
|
||||
<text class="nj-jsonview-tiny" x="394" y="47" xml:space="preserve">4</text>
|
||||
<text class="nj-jsonview-kind nj-jsonview-xs nj-jsonview-c-num" x="430" y="61" text-anchor="middle" xml:space="preserve">float</text>
|
||||
<text class="nj-jsonview-mono nj-jsonview-sm" x="430" y="77" text-anchor="middle" xml:space="preserve">19.90</text>
|
||||
<rect class="nj-jsonview-node nj-jsonview-c-key" x="476" y="34" width="84" height="50" rx="5"/>
|
||||
<text class="nj-jsonview-tiny" x="482" y="47" xml:space="preserve">5</text>
|
||||
<text class="nj-jsonview-kind nj-jsonview-xs nj-jsonview-c-key" x="518" y="61" text-anchor="middle" xml:space="preserve">key</text>
|
||||
<text class="nj-jsonview-mono nj-jsonview-sm" x="518" y="77" text-anchor="middle" xml:space="preserve">tags</text>
|
||||
<rect class="nj-jsonview-node nj-jsonview-c-struct" x="564" y="34" width="84" height="50" rx="5"/>
|
||||
<text class="nj-jsonview-tiny" x="570" y="47" xml:space="preserve">6</text>
|
||||
<text class="nj-jsonview-kind nj-jsonview-xs nj-jsonview-c-struct" x="606" y="61" text-anchor="middle" xml:space="preserve">array</text>
|
||||
<text class="nj-jsonview-mono nj-jsonview-sm" x="606" y="77" text-anchor="middle" xml:space="preserve">[ ] 2</text>
|
||||
<rect class="nj-jsonview-node nj-jsonview-c-str" x="652" y="34" width="84" height="50" rx="5"/>
|
||||
<text class="nj-jsonview-tiny" x="658" y="47" xml:space="preserve">7</text>
|
||||
<text class="nj-jsonview-kind nj-jsonview-xs nj-jsonview-c-str" x="694" y="61" text-anchor="middle" xml:space="preserve">string</text>
|
||||
<text class="nj-jsonview-mono nj-jsonview-sm" x="694" y="77" text-anchor="middle" xml:space="preserve">"eu"</text>
|
||||
<rect class="nj-jsonview-node nj-jsonview-c-dec" x="740" y="34" width="84" height="50" rx="5"/>
|
||||
<text class="nj-jsonview-tiny" x="746" y="47" xml:space="preserve">8</text>
|
||||
<text class="nj-jsonview-kind nj-jsonview-xs nj-jsonview-c-dec" x="782" y="61" text-anchor="middle" xml:space="preserve">string</text>
|
||||
<text class="nj-jsonview-mono nj-jsonview-sm" x="782" y="77" text-anchor="middle" xml:space="preserve">a"b</text>
|
||||
<text class="nj-jsonview-note nj-jsonview-strong nj-jsonview-c-own" x="16" y="288" xml:space="preserve">owned storage: allocated on demand, never moves</text>
|
||||
<rect class="nj-jsonview-store" x="10" y="192" width="820" height="54" rx="8"/>
|
||||
<text class="nj-jsonview-note" x="26" y="224" xml:space="preserve">empty: a read-only json_document has none of this</text>
|
||||
<path class="nj-jsonview-sep" d="M16 300 H824"/>
|
||||
<text class="nj-jsonview-mono nj-jsonview-xs" x="16" y="318" xml:space="preserve">view v = root()["tags"] (taken after parse):</text>
|
||||
<text class="nj-jsonview-note nj-jsonview-c-struct nj-jsonview-strong" x="320" y="318" xml:space="preserve">valid, sees every edit</text>
|
||||
<text class="nj-jsonview-mono nj-jsonview-xs" x="16" y="338" xml:space="preserve">iterator over tags (taken after parse):</text>
|
||||
<text class="nj-jsonview-note nj-jsonview-c-struct nj-jsonview-strong" x="320" y="338" xml:space="preserve">valid</text>
|
||||
<text class="nj-jsonview-mono nj-jsonview-xs nj-jsonview-muted" x="16" y="360" xml:space="preserve">dump(): {"port":6379,"price":19.90,"tags":["eu","a\"b"]}</text>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 6.4 KiB |
@@ -1,57 +0,0 @@
|
||||
<svg class="nj-fig nj-jsonview nj-jsonview-editfig" viewBox="0 0 840 372" role="img" aria-labelledby="fig-jve1-title fig-jve1-title-d" xmlns="http://www.w3.org/2000/svg">
|
||||
<title id="fig-jve1-title">Step 2 of 5: doc.set(doc.root(), "port", 6380)</title>
|
||||
<desc id="fig-jve1-title-d">set: the node of the integer is overwritten in place. The dump with number_format::source is {"port":6380,"price":19.90,"tags":["eu","a\"b"]}.</desc>
|
||||
<defs>
|
||||
<marker id="jve1-line" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="6.5" markerHeight="6.5" orient="auto-start-reverse"><path class="nj-jsonview-c-line nj-jsonview-head" d="M0 1 L10 5 L0 9 z"/></marker>
|
||||
<marker id="jve1-own" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="6.5" markerHeight="6.5" orient="auto-start-reverse"><path class="nj-jsonview-c-own nj-jsonview-head" d="M0 1 L10 5 L0 9 z"/></marker>
|
||||
<marker id="jve1-struct" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="6.5" markerHeight="6.5" orient="auto-start-reverse"><path class="nj-jsonview-c-struct nj-jsonview-head" d="M0 1 L10 5 L0 9 z"/></marker>
|
||||
<marker id="jve1-bad" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="6.5" markerHeight="6.5" orient="auto-start-reverse"><path class="nj-jsonview-c-bad nj-jsonview-head" d="M0 1 L10 5 L0 9 z"/></marker>
|
||||
</defs>
|
||||
<text class="nj-jsonview-note nj-jsonview-strong" x="16" y="22" xml:space="preserve">parsed index: fixed, never moves</text>
|
||||
<text class="nj-jsonview-note" x="824" y="22" text-anchor="end" xml:space="preserve">the source text is never written</text>
|
||||
<rect class="nj-jsonview-node nj-jsonview-c-struct" x="36" y="34" width="84" height="50" rx="5"/>
|
||||
<text class="nj-jsonview-tiny" x="42" y="47" xml:space="preserve">0</text>
|
||||
<text class="nj-jsonview-kind nj-jsonview-xs nj-jsonview-c-struct" x="78" y="61" text-anchor="middle" xml:space="preserve">object</text>
|
||||
<text class="nj-jsonview-mono nj-jsonview-sm" x="78" y="77" text-anchor="middle" xml:space="preserve">{ } 3</text>
|
||||
<rect class="nj-jsonview-node nj-jsonview-c-key" x="124" y="34" width="84" height="50" rx="5"/>
|
||||
<text class="nj-jsonview-tiny" x="130" y="47" xml:space="preserve">1</text>
|
||||
<text class="nj-jsonview-kind nj-jsonview-xs nj-jsonview-c-key" x="166" y="61" text-anchor="middle" xml:space="preserve">key</text>
|
||||
<text class="nj-jsonview-mono nj-jsonview-sm" x="166" y="77" text-anchor="middle" xml:space="preserve">port</text>
|
||||
<rect class="nj-jsonview-node nj-jsonview-hot nj-jsonview-c-num" x="212" y="34" width="84" height="50" rx="5"/>
|
||||
<text class="nj-jsonview-tiny" x="218" y="47" xml:space="preserve">2</text>
|
||||
<text class="nj-jsonview-kind nj-jsonview-xs nj-jsonview-c-num" x="254" y="61" text-anchor="middle" xml:space="preserve">uint</text>
|
||||
<text class="nj-jsonview-mono nj-jsonview-sm" x="254" y="77" text-anchor="middle" xml:space="preserve">6380</text>
|
||||
<rect class="nj-jsonview-node nj-jsonview-c-key" x="300" y="34" width="84" height="50" rx="5"/>
|
||||
<text class="nj-jsonview-tiny" x="306" y="47" xml:space="preserve">3</text>
|
||||
<text class="nj-jsonview-kind nj-jsonview-xs nj-jsonview-c-key" x="342" y="61" text-anchor="middle" xml:space="preserve">key</text>
|
||||
<text class="nj-jsonview-mono nj-jsonview-sm" x="342" y="77" text-anchor="middle" xml:space="preserve">price</text>
|
||||
<rect class="nj-jsonview-node nj-jsonview-c-num" x="388" y="34" width="84" height="50" rx="5"/>
|
||||
<text class="nj-jsonview-tiny" x="394" y="47" xml:space="preserve">4</text>
|
||||
<text class="nj-jsonview-kind nj-jsonview-xs nj-jsonview-c-num" x="430" y="61" text-anchor="middle" xml:space="preserve">float</text>
|
||||
<text class="nj-jsonview-mono nj-jsonview-sm" x="430" y="77" text-anchor="middle" xml:space="preserve">19.90</text>
|
||||
<rect class="nj-jsonview-node nj-jsonview-c-key" x="476" y="34" width="84" height="50" rx="5"/>
|
||||
<text class="nj-jsonview-tiny" x="482" y="47" xml:space="preserve">5</text>
|
||||
<text class="nj-jsonview-kind nj-jsonview-xs nj-jsonview-c-key" x="518" y="61" text-anchor="middle" xml:space="preserve">key</text>
|
||||
<text class="nj-jsonview-mono nj-jsonview-sm" x="518" y="77" text-anchor="middle" xml:space="preserve">tags</text>
|
||||
<rect class="nj-jsonview-node nj-jsonview-c-struct" x="564" y="34" width="84" height="50" rx="5"/>
|
||||
<text class="nj-jsonview-tiny" x="570" y="47" xml:space="preserve">6</text>
|
||||
<text class="nj-jsonview-kind nj-jsonview-xs nj-jsonview-c-struct" x="606" y="61" text-anchor="middle" xml:space="preserve">array</text>
|
||||
<text class="nj-jsonview-mono nj-jsonview-sm" x="606" y="77" text-anchor="middle" xml:space="preserve">[ ] 2</text>
|
||||
<rect class="nj-jsonview-node nj-jsonview-c-str" x="652" y="34" width="84" height="50" rx="5"/>
|
||||
<text class="nj-jsonview-tiny" x="658" y="47" xml:space="preserve">7</text>
|
||||
<text class="nj-jsonview-kind nj-jsonview-xs nj-jsonview-c-str" x="694" y="61" text-anchor="middle" xml:space="preserve">string</text>
|
||||
<text class="nj-jsonview-mono nj-jsonview-sm" x="694" y="77" text-anchor="middle" xml:space="preserve">"eu"</text>
|
||||
<rect class="nj-jsonview-node nj-jsonview-c-dec" x="740" y="34" width="84" height="50" rx="5"/>
|
||||
<text class="nj-jsonview-tiny" x="746" y="47" xml:space="preserve">8</text>
|
||||
<text class="nj-jsonview-kind nj-jsonview-xs nj-jsonview-c-dec" x="782" y="61" text-anchor="middle" xml:space="preserve">string</text>
|
||||
<text class="nj-jsonview-mono nj-jsonview-sm" x="782" y="77" text-anchor="middle" xml:space="preserve">a"b</text>
|
||||
<text class="nj-jsonview-note nj-jsonview-strong nj-jsonview-c-own" x="16" y="288" xml:space="preserve">owned storage: allocated on demand, never moves</text>
|
||||
<rect class="nj-jsonview-store" x="10" y="192" width="820" height="54" rx="8"/>
|
||||
<text class="nj-jsonview-note" x="26" y="224" xml:space="preserve">empty: a read-only json_document has none of this</text>
|
||||
<path class="nj-jsonview-sep" d="M16 300 H824"/>
|
||||
<text class="nj-jsonview-mono nj-jsonview-xs" x="16" y="318" xml:space="preserve">view v = root()["tags"] (taken after parse):</text>
|
||||
<text class="nj-jsonview-note nj-jsonview-c-struct nj-jsonview-strong" x="320" y="318" xml:space="preserve">valid, sees every edit</text>
|
||||
<text class="nj-jsonview-mono nj-jsonview-xs" x="16" y="338" xml:space="preserve">iterator over tags (taken after parse):</text>
|
||||
<text class="nj-jsonview-note nj-jsonview-c-struct nj-jsonview-strong" x="320" y="338" xml:space="preserve">valid</text>
|
||||
<text class="nj-jsonview-mono nj-jsonview-xs nj-jsonview-muted" x="16" y="360" xml:space="preserve">dump(): {"port":6380,"price":19.90,"tags":["eu","a\"b"]}</text>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 6.4 KiB |
@@ -1,70 +0,0 @@
|
||||
<svg class="nj-fig nj-jsonview nj-jsonview-editfig" viewBox="0 0 840 372" role="img" aria-labelledby="fig-jve2-title fig-jve2-title-d" xmlns="http://www.w3.org/2000/svg">
|
||||
<title id="fig-jve2-title">Step 3 of 5: doc.erase(doc.root()["tags"], 0)</title>
|
||||
<desc id="fig-jve2-title-d">erase: the array moves to a block of links in owned storage. The dump with number_format::source is {"port":6380,"price":19.90,"tags":["a\"b"]}.</desc>
|
||||
<defs>
|
||||
<marker id="jve2-line" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="6.5" markerHeight="6.5" orient="auto-start-reverse"><path class="nj-jsonview-c-line nj-jsonview-head" d="M0 1 L10 5 L0 9 z"/></marker>
|
||||
<marker id="jve2-own" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="6.5" markerHeight="6.5" orient="auto-start-reverse"><path class="nj-jsonview-c-own nj-jsonview-head" d="M0 1 L10 5 L0 9 z"/></marker>
|
||||
<marker id="jve2-struct" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="6.5" markerHeight="6.5" orient="auto-start-reverse"><path class="nj-jsonview-c-struct nj-jsonview-head" d="M0 1 L10 5 L0 9 z"/></marker>
|
||||
<marker id="jve2-bad" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="6.5" markerHeight="6.5" orient="auto-start-reverse"><path class="nj-jsonview-c-bad nj-jsonview-head" d="M0 1 L10 5 L0 9 z"/></marker>
|
||||
</defs>
|
||||
<text class="nj-jsonview-note nj-jsonview-strong" x="16" y="22" xml:space="preserve">parsed index: fixed, never moves</text>
|
||||
<text class="nj-jsonview-note" x="824" y="22" text-anchor="end" xml:space="preserve">the source text is never written</text>
|
||||
<rect class="nj-jsonview-node nj-jsonview-c-struct" x="36" y="34" width="84" height="50" rx="5"/>
|
||||
<text class="nj-jsonview-tiny" x="42" y="47" xml:space="preserve">0</text>
|
||||
<text class="nj-jsonview-kind nj-jsonview-xs nj-jsonview-c-struct" x="78" y="61" text-anchor="middle" xml:space="preserve">object</text>
|
||||
<text class="nj-jsonview-mono nj-jsonview-sm" x="78" y="77" text-anchor="middle" xml:space="preserve">{ } 3</text>
|
||||
<rect class="nj-jsonview-node nj-jsonview-c-key" x="124" y="34" width="84" height="50" rx="5"/>
|
||||
<text class="nj-jsonview-tiny" x="130" y="47" xml:space="preserve">1</text>
|
||||
<text class="nj-jsonview-kind nj-jsonview-xs nj-jsonview-c-key" x="166" y="61" text-anchor="middle" xml:space="preserve">key</text>
|
||||
<text class="nj-jsonview-mono nj-jsonview-sm" x="166" y="77" text-anchor="middle" xml:space="preserve">port</text>
|
||||
<rect class="nj-jsonview-node nj-jsonview-c-num" x="212" y="34" width="84" height="50" rx="5"/>
|
||||
<text class="nj-jsonview-tiny" x="218" y="47" xml:space="preserve">2</text>
|
||||
<text class="nj-jsonview-kind nj-jsonview-xs nj-jsonview-c-num" x="254" y="61" text-anchor="middle" xml:space="preserve">uint</text>
|
||||
<text class="nj-jsonview-mono nj-jsonview-sm" x="254" y="77" text-anchor="middle" xml:space="preserve">6380</text>
|
||||
<rect class="nj-jsonview-node nj-jsonview-c-key" x="300" y="34" width="84" height="50" rx="5"/>
|
||||
<text class="nj-jsonview-tiny" x="306" y="47" xml:space="preserve">3</text>
|
||||
<text class="nj-jsonview-kind nj-jsonview-xs nj-jsonview-c-key" x="342" y="61" text-anchor="middle" xml:space="preserve">key</text>
|
||||
<text class="nj-jsonview-mono nj-jsonview-sm" x="342" y="77" text-anchor="middle" xml:space="preserve">price</text>
|
||||
<rect class="nj-jsonview-node nj-jsonview-c-num" x="388" y="34" width="84" height="50" rx="5"/>
|
||||
<text class="nj-jsonview-tiny" x="394" y="47" xml:space="preserve">4</text>
|
||||
<text class="nj-jsonview-kind nj-jsonview-xs nj-jsonview-c-num" x="430" y="61" text-anchor="middle" xml:space="preserve">float</text>
|
||||
<text class="nj-jsonview-mono nj-jsonview-sm" x="430" y="77" text-anchor="middle" xml:space="preserve">19.90</text>
|
||||
<rect class="nj-jsonview-node nj-jsonview-c-key" x="476" y="34" width="84" height="50" rx="5"/>
|
||||
<text class="nj-jsonview-tiny" x="482" y="47" xml:space="preserve">5</text>
|
||||
<text class="nj-jsonview-kind nj-jsonview-xs nj-jsonview-c-key" x="518" y="61" text-anchor="middle" xml:space="preserve">key</text>
|
||||
<text class="nj-jsonview-mono nj-jsonview-sm" x="518" y="77" text-anchor="middle" xml:space="preserve">tags</text>
|
||||
<rect class="nj-jsonview-node nj-jsonview-c-struct" x="564" y="34" width="84" height="50" rx="5"/>
|
||||
<text class="nj-jsonview-tiny" x="570" y="47" xml:space="preserve">6</text>
|
||||
<text class="nj-jsonview-kind nj-jsonview-xs nj-jsonview-c-struct" x="606" y="61" text-anchor="middle" xml:space="preserve">array</text>
|
||||
<text class="nj-jsonview-tiny nj-jsonview-c-struct nj-jsonview-strong" x="643" y="47" text-anchor="end" xml:space="preserve">moved</text>
|
||||
<text class="nj-jsonview-mono nj-jsonview-sm" x="606" y="77" text-anchor="middle" xml:space="preserve">[ ] 2</text>
|
||||
<rect class="nj-jsonview-node nj-jsonview-gap nj-jsonview-c-str" x="652" y="34" width="84" height="50" rx="5"/>
|
||||
<text class="nj-jsonview-tiny" x="658" y="47" xml:space="preserve">7</text>
|
||||
<text class="nj-jsonview-kind nj-jsonview-xs nj-jsonview-c-str" x="694" y="61" text-anchor="middle" xml:space="preserve">string</text>
|
||||
<text class="nj-jsonview-mono nj-jsonview-sm" x="694" y="77" text-anchor="middle" xml:space="preserve">"eu"</text>
|
||||
<text class="nj-jsonview-tiny nj-jsonview-c-bad" x="694" y="98" text-anchor="middle" xml:space="preserve">unreferenced</text>
|
||||
<rect class="nj-jsonview-node nj-jsonview-c-dec" x="740" y="34" width="84" height="50" rx="5"/>
|
||||
<text class="nj-jsonview-tiny" x="746" y="47" xml:space="preserve">8</text>
|
||||
<text class="nj-jsonview-kind nj-jsonview-xs nj-jsonview-c-dec" x="782" y="61" text-anchor="middle" xml:space="preserve">string</text>
|
||||
<text class="nj-jsonview-mono nj-jsonview-sm" x="782" y="77" text-anchor="middle" xml:space="preserve">a"b</text>
|
||||
<text class="nj-jsonview-note nj-jsonview-strong nj-jsonview-c-own" x="16" y="288" xml:space="preserve">owned storage: allocated on demand, never moves</text>
|
||||
<rect class="nj-jsonview-store" x="10" y="192" width="820" height="54" rx="8"/>
|
||||
<rect class="nj-jsonview-node nj-jsonview-hot nj-jsonview-c-struct" x="16" y="196" width="54" height="46" rx="5"/>
|
||||
<text class="nj-jsonview-tiny" x="66" y="207" text-anchor="end" xml:space="preserve">0'</text>
|
||||
<text class="nj-jsonview-kind nj-jsonview-xs nj-jsonview-c-struct" x="43" y="220" text-anchor="middle" xml:space="preserve">header</text>
|
||||
<text class="nj-jsonview-mono nj-jsonview-xs" x="43" y="235" text-anchor="middle" xml:space="preserve">[ ] 1</text>
|
||||
<rect class="nj-jsonview-node nj-jsonview-hot nj-jsonview-c-own" x="73" y="196" width="54" height="46" rx="5"/>
|
||||
<text class="nj-jsonview-tiny" x="123" y="207" text-anchor="end" xml:space="preserve">1'</text>
|
||||
<text class="nj-jsonview-kind nj-jsonview-xs nj-jsonview-c-own" x="100" y="220" text-anchor="middle" xml:space="preserve">link</text>
|
||||
<text class="nj-jsonview-mono nj-jsonview-xs" x="100" y="235" text-anchor="middle" xml:space="preserve">→ 8</text>
|
||||
<path class="nj-jsonview-arr nj-jsonview-c-own" d="M100 196 C100 140 782 140 782 84" marker-end="url(#jve2-own)"/>
|
||||
<rect class="nj-jsonview-node nj-jsonview-free nj-jsonview-c-own" x="130" y="196" width="54" height="46" rx="5"/>
|
||||
<text class="nj-jsonview-tiny" x="157" y="224" text-anchor="middle" xml:space="preserve">free</text>
|
||||
<path class="nj-jsonview-arr nj-jsonview-c-struct nj-jsonview-dash" d="M598 84 C598 140 43 140 43 196" marker-end="url(#jve2-struct)"/>
|
||||
<path class="nj-jsonview-sep" d="M16 300 H824"/>
|
||||
<text class="nj-jsonview-mono nj-jsonview-xs" x="16" y="318" xml:space="preserve">view v = root()["tags"] (taken after parse):</text>
|
||||
<text class="nj-jsonview-note nj-jsonview-c-struct nj-jsonview-strong" x="320" y="318" xml:space="preserve">valid, sees every edit</text>
|
||||
<text class="nj-jsonview-mono nj-jsonview-xs" x="16" y="338" xml:space="preserve">iterator over tags (taken after parse):</text>
|
||||
<text class="nj-jsonview-note nj-jsonview-c-bad nj-jsonview-strong" x="320" y="338" xml:space="preserve">invalid: tags no longer uses the parsed layout</text>
|
||||
<text class="nj-jsonview-mono nj-jsonview-xs nj-jsonview-muted" x="16" y="360" xml:space="preserve">dump(): {"port":6380,"price":19.90,"tags":["a\"b"]}</text>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 8.0 KiB |
@@ -1,80 +0,0 @@
|
||||
<svg class="nj-fig nj-jsonview nj-jsonview-editfig" viewBox="0 0 840 372" role="img" aria-labelledby="fig-jve3-title fig-jve3-title-d" xmlns="http://www.w3.org/2000/svg">
|
||||
<title id="fig-jve3-title">Step 4 of 5: doc.push_back(doc.root()["tags"], "new")</title>
|
||||
<desc id="fig-jve3-title-d">push_back: a new node, and a link appended to the block. The dump with number_format::source is {"port":6380,"price":19.90,"tags":["a\"b","new"]}.</desc>
|
||||
<defs>
|
||||
<marker id="jve3-line" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="6.5" markerHeight="6.5" orient="auto-start-reverse"><path class="nj-jsonview-c-line nj-jsonview-head" d="M0 1 L10 5 L0 9 z"/></marker>
|
||||
<marker id="jve3-own" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="6.5" markerHeight="6.5" orient="auto-start-reverse"><path class="nj-jsonview-c-own nj-jsonview-head" d="M0 1 L10 5 L0 9 z"/></marker>
|
||||
<marker id="jve3-struct" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="6.5" markerHeight="6.5" orient="auto-start-reverse"><path class="nj-jsonview-c-struct nj-jsonview-head" d="M0 1 L10 5 L0 9 z"/></marker>
|
||||
<marker id="jve3-bad" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="6.5" markerHeight="6.5" orient="auto-start-reverse"><path class="nj-jsonview-c-bad nj-jsonview-head" d="M0 1 L10 5 L0 9 z"/></marker>
|
||||
</defs>
|
||||
<text class="nj-jsonview-note nj-jsonview-strong" x="16" y="22" xml:space="preserve">parsed index: fixed, never moves</text>
|
||||
<text class="nj-jsonview-note" x="824" y="22" text-anchor="end" xml:space="preserve">the source text is never written</text>
|
||||
<rect class="nj-jsonview-node nj-jsonview-c-struct" x="36" y="34" width="84" height="50" rx="5"/>
|
||||
<text class="nj-jsonview-tiny" x="42" y="47" xml:space="preserve">0</text>
|
||||
<text class="nj-jsonview-kind nj-jsonview-xs nj-jsonview-c-struct" x="78" y="61" text-anchor="middle" xml:space="preserve">object</text>
|
||||
<text class="nj-jsonview-mono nj-jsonview-sm" x="78" y="77" text-anchor="middle" xml:space="preserve">{ } 3</text>
|
||||
<rect class="nj-jsonview-node nj-jsonview-c-key" x="124" y="34" width="84" height="50" rx="5"/>
|
||||
<text class="nj-jsonview-tiny" x="130" y="47" xml:space="preserve">1</text>
|
||||
<text class="nj-jsonview-kind nj-jsonview-xs nj-jsonview-c-key" x="166" y="61" text-anchor="middle" xml:space="preserve">key</text>
|
||||
<text class="nj-jsonview-mono nj-jsonview-sm" x="166" y="77" text-anchor="middle" xml:space="preserve">port</text>
|
||||
<rect class="nj-jsonview-node nj-jsonview-c-num" x="212" y="34" width="84" height="50" rx="5"/>
|
||||
<text class="nj-jsonview-tiny" x="218" y="47" xml:space="preserve">2</text>
|
||||
<text class="nj-jsonview-kind nj-jsonview-xs nj-jsonview-c-num" x="254" y="61" text-anchor="middle" xml:space="preserve">uint</text>
|
||||
<text class="nj-jsonview-mono nj-jsonview-sm" x="254" y="77" text-anchor="middle" xml:space="preserve">6380</text>
|
||||
<rect class="nj-jsonview-node nj-jsonview-c-key" x="300" y="34" width="84" height="50" rx="5"/>
|
||||
<text class="nj-jsonview-tiny" x="306" y="47" xml:space="preserve">3</text>
|
||||
<text class="nj-jsonview-kind nj-jsonview-xs nj-jsonview-c-key" x="342" y="61" text-anchor="middle" xml:space="preserve">key</text>
|
||||
<text class="nj-jsonview-mono nj-jsonview-sm" x="342" y="77" text-anchor="middle" xml:space="preserve">price</text>
|
||||
<rect class="nj-jsonview-node nj-jsonview-c-num" x="388" y="34" width="84" height="50" rx="5"/>
|
||||
<text class="nj-jsonview-tiny" x="394" y="47" xml:space="preserve">4</text>
|
||||
<text class="nj-jsonview-kind nj-jsonview-xs nj-jsonview-c-num" x="430" y="61" text-anchor="middle" xml:space="preserve">float</text>
|
||||
<text class="nj-jsonview-mono nj-jsonview-sm" x="430" y="77" text-anchor="middle" xml:space="preserve">19.90</text>
|
||||
<rect class="nj-jsonview-node nj-jsonview-c-key" x="476" y="34" width="84" height="50" rx="5"/>
|
||||
<text class="nj-jsonview-tiny" x="482" y="47" xml:space="preserve">5</text>
|
||||
<text class="nj-jsonview-kind nj-jsonview-xs nj-jsonview-c-key" x="518" y="61" text-anchor="middle" xml:space="preserve">key</text>
|
||||
<text class="nj-jsonview-mono nj-jsonview-sm" x="518" y="77" text-anchor="middle" xml:space="preserve">tags</text>
|
||||
<rect class="nj-jsonview-node nj-jsonview-c-struct" x="564" y="34" width="84" height="50" rx="5"/>
|
||||
<text class="nj-jsonview-tiny" x="570" y="47" xml:space="preserve">6</text>
|
||||
<text class="nj-jsonview-kind nj-jsonview-xs nj-jsonview-c-struct" x="606" y="61" text-anchor="middle" xml:space="preserve">array</text>
|
||||
<text class="nj-jsonview-tiny nj-jsonview-c-struct nj-jsonview-strong" x="643" y="47" text-anchor="end" xml:space="preserve">moved</text>
|
||||
<text class="nj-jsonview-mono nj-jsonview-sm" x="606" y="77" text-anchor="middle" xml:space="preserve">[ ] 2</text>
|
||||
<rect class="nj-jsonview-node nj-jsonview-gap nj-jsonview-c-str" x="652" y="34" width="84" height="50" rx="5"/>
|
||||
<text class="nj-jsonview-tiny" x="658" y="47" xml:space="preserve">7</text>
|
||||
<text class="nj-jsonview-kind nj-jsonview-xs nj-jsonview-c-str" x="694" y="61" text-anchor="middle" xml:space="preserve">string</text>
|
||||
<text class="nj-jsonview-mono nj-jsonview-sm" x="694" y="77" text-anchor="middle" xml:space="preserve">"eu"</text>
|
||||
<text class="nj-jsonview-tiny nj-jsonview-c-bad" x="694" y="98" text-anchor="middle" xml:space="preserve">unreferenced</text>
|
||||
<rect class="nj-jsonview-node nj-jsonview-c-dec" x="740" y="34" width="84" height="50" rx="5"/>
|
||||
<text class="nj-jsonview-tiny" x="746" y="47" xml:space="preserve">8</text>
|
||||
<text class="nj-jsonview-kind nj-jsonview-xs nj-jsonview-c-dec" x="782" y="61" text-anchor="middle" xml:space="preserve">string</text>
|
||||
<text class="nj-jsonview-mono nj-jsonview-sm" x="782" y="77" text-anchor="middle" xml:space="preserve">a"b</text>
|
||||
<text class="nj-jsonview-note nj-jsonview-strong nj-jsonview-c-own" x="16" y="288" xml:space="preserve">owned storage: allocated on demand, never moves</text>
|
||||
<rect class="nj-jsonview-store" x="10" y="192" width="820" height="54" rx="8"/>
|
||||
<rect class="nj-jsonview-node nj-jsonview-c-struct" x="16" y="196" width="54" height="46" rx="5"/>
|
||||
<text class="nj-jsonview-tiny" x="66" y="207" text-anchor="end" xml:space="preserve">0'</text>
|
||||
<text class="nj-jsonview-kind nj-jsonview-xs nj-jsonview-c-struct" x="43" y="220" text-anchor="middle" xml:space="preserve">header</text>
|
||||
<text class="nj-jsonview-mono nj-jsonview-xs" x="43" y="235" text-anchor="middle" xml:space="preserve">[ ] 2</text>
|
||||
<rect class="nj-jsonview-node nj-jsonview-c-own" x="73" y="196" width="54" height="46" rx="5"/>
|
||||
<text class="nj-jsonview-tiny" x="123" y="207" text-anchor="end" xml:space="preserve">1'</text>
|
||||
<text class="nj-jsonview-kind nj-jsonview-xs nj-jsonview-c-own" x="100" y="220" text-anchor="middle" xml:space="preserve">link</text>
|
||||
<text class="nj-jsonview-mono nj-jsonview-xs" x="100" y="235" text-anchor="middle" xml:space="preserve">→ 8</text>
|
||||
<path class="nj-jsonview-arr nj-jsonview-c-own" d="M100 196 C100 140 782 140 782 84" marker-end="url(#jve3-own)"/>
|
||||
<rect class="nj-jsonview-node nj-jsonview-hot nj-jsonview-c-own" x="130" y="196" width="54" height="46" rx="5"/>
|
||||
<text class="nj-jsonview-tiny" x="180" y="207" text-anchor="end" xml:space="preserve">2'</text>
|
||||
<text class="nj-jsonview-kind nj-jsonview-xs nj-jsonview-c-own" x="157" y="220" text-anchor="middle" xml:space="preserve">link</text>
|
||||
<text class="nj-jsonview-mono nj-jsonview-xs" x="157" y="235" text-anchor="middle" xml:space="preserve">→ 3'</text>
|
||||
<path class="nj-jsonview-arr nj-jsonview-c-own" d="M157 242 C157 268 214 268 214 244" marker-end="url(#jve3-own)"/>
|
||||
<rect class="nj-jsonview-node nj-jsonview-hot nj-jsonview-c-str" x="187" y="196" width="54" height="46" rx="5"/>
|
||||
<text class="nj-jsonview-tiny" x="237" y="207" text-anchor="end" xml:space="preserve">3'</text>
|
||||
<text class="nj-jsonview-kind nj-jsonview-xs nj-jsonview-c-str" x="214" y="220" text-anchor="middle" xml:space="preserve">string</text>
|
||||
<text class="nj-jsonview-mono nj-jsonview-xs" x="214" y="235" text-anchor="middle" xml:space="preserve">"new"</text>
|
||||
<path class="nj-jsonview-arr nj-jsonview-c-struct nj-jsonview-dash" d="M598 84 C598 140 43 140 43 196" marker-end="url(#jve3-struct)"/>
|
||||
<text class="nj-jsonview-note" x="588" y="282" text-anchor="end" xml:space="preserve">edited text</text>
|
||||
<rect class="nj-jsonview-node nj-jsonview-c-str" x="596" y="264" width="42" height="26" rx="4"/>
|
||||
<text class="nj-jsonview-mono nj-jsonview-sm" x="602" y="282" xml:space="preserve">new</text>
|
||||
<path class="nj-jsonview-sep" d="M16 300 H824"/>
|
||||
<text class="nj-jsonview-mono nj-jsonview-xs" x="16" y="318" xml:space="preserve">view v = root()["tags"] (taken after parse):</text>
|
||||
<text class="nj-jsonview-note nj-jsonview-c-struct nj-jsonview-strong" x="320" y="318" xml:space="preserve">valid, sees every edit</text>
|
||||
<text class="nj-jsonview-mono nj-jsonview-xs" x="16" y="338" xml:space="preserve">iterator over tags (taken after parse):</text>
|
||||
<text class="nj-jsonview-note nj-jsonview-c-bad nj-jsonview-strong" x="320" y="338" xml:space="preserve">invalid: tags no longer uses the parsed layout</text>
|
||||
<text class="nj-jsonview-mono nj-jsonview-xs nj-jsonview-muted" x="16" y="360" xml:space="preserve">dump(): {"port":6380,"price":19.90,"tags":["a\"b","new"]}</text>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 9.1 KiB |