mirror of
https://github.com/nlohmann/json.git
synced 2026-10-05 14:10:31 +00:00
Document element access, lookup, and iteration of json_view
- API pages for operator[], at, front, back, find, contains, count, begin, end, cbegin, cend, items, and type_name of basic_json_view, linked both ways with the basic_json pages - the feature page and size() describe document order and duplicate keys - the examples show when the view helps: reading a few fields of a large text, probing optional members, and members in source order Signed-off-by: Niels Lohmann <mail@nlohmann.me>
This commit is contained in:
@@ -143,7 +143,17 @@ INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_document::shrink_t
|
|||||||
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_document::source', 'Method', 'api/basic_json_document/source/index.html');
|
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_document::source', 'Method', 'api/basic_json_document/source/index.html');
|
||||||
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_view', 'Class', 'api/basic_json_view/index.html');
|
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_view', 'Class', 'api/basic_json_view/index.html');
|
||||||
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_view::basic_json_view', 'Constructor', 'api/basic_json_view/basic_json_view/index.html');
|
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_view::basic_json_view', 'Constructor', 'api/basic_json_view/basic_json_view/index.html');
|
||||||
|
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_view::at', 'Method', 'api/basic_json_view/at/index.html');
|
||||||
|
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_view::back', 'Method', 'api/basic_json_view/back/index.html');
|
||||||
|
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_view::begin', 'Method', 'api/basic_json_view/begin/index.html');
|
||||||
|
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_view::cbegin', 'Method', 'api/basic_json_view/cbegin/index.html');
|
||||||
|
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_view::cend', 'Method', 'api/basic_json_view/cend/index.html');
|
||||||
|
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_view::contains', 'Method', 'api/basic_json_view/contains/index.html');
|
||||||
|
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_view::count', 'Method', 'api/basic_json_view/count/index.html');
|
||||||
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_view::empty', 'Method', 'api/basic_json_view/empty/index.html');
|
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_view::empty', 'Method', 'api/basic_json_view/empty/index.html');
|
||||||
|
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_view::end', 'Method', 'api/basic_json_view/end/index.html');
|
||||||
|
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_view::find', 'Method', 'api/basic_json_view/find/index.html');
|
||||||
|
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_view::front', 'Method', 'api/basic_json_view/front/index.html');
|
||||||
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_view::is_array', 'Method', 'api/basic_json_view/is_array/index.html');
|
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_view::is_array', 'Method', 'api/basic_json_view/is_array/index.html');
|
||||||
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_view::is_binary', 'Method', 'api/basic_json_view/is_binary/index.html');
|
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_view::is_binary', 'Method', 'api/basic_json_view/is_binary/index.html');
|
||||||
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_view::is_boolean', 'Method', 'api/basic_json_view/is_boolean/index.html');
|
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_view::is_boolean', 'Method', 'api/basic_json_view/is_boolean/index.html');
|
||||||
@@ -157,11 +167,14 @@ INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_view::is_object',
|
|||||||
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_view::is_primitive', 'Method', 'api/basic_json_view/is_primitive/index.html');
|
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_view::is_primitive', 'Method', 'api/basic_json_view/is_primitive/index.html');
|
||||||
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_view::is_string', 'Method', 'api/basic_json_view/is_string/index.html');
|
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_view::is_string', 'Method', 'api/basic_json_view/is_string/index.html');
|
||||||
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_view::is_structured', 'Method', 'api/basic_json_view/is_structured/index.html');
|
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_view::is_structured', 'Method', 'api/basic_json_view/is_structured/index.html');
|
||||||
|
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_view::items', 'Method', 'api/basic_json_view/items/index.html');
|
||||||
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_view::materialize', 'Method', 'api/basic_json_view/materialize/index.html');
|
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_view::materialize', 'Method', 'api/basic_json_view/materialize/index.html');
|
||||||
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_view::operator bool', 'Method', 'api/basic_json_view/operator_bool/index.html');
|
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_view::operator bool', 'Method', 'api/basic_json_view/operator_bool/index.html');
|
||||||
|
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_view::operator[]', 'Operator', 'api/basic_json_view/operator[]/index.html');
|
||||||
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_view::size', 'Method', 'api/basic_json_view/size/index.html');
|
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_view::size', 'Method', 'api/basic_json_view/size/index.html');
|
||||||
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_view::source_offset', 'Method', 'api/basic_json_view/source_offset/index.html');
|
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_view::source_offset', 'Method', 'api/basic_json_view/source_offset/index.html');
|
||||||
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_view::type', 'Method', 'api/basic_json_view/type/index.html');
|
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_view::type', 'Method', 'api/basic_json_view/type/index.html');
|
||||||
|
INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_view::type_name', 'Method', 'api/basic_json_view/type_name/index.html');
|
||||||
INSERT INTO searchIndex(name, type, path) VALUES ('json', 'Class', 'api/json/index.html');
|
INSERT INTO searchIndex(name, type, path) VALUES ('json', 'Class', 'api/json/index.html');
|
||||||
INSERT INTO searchIndex(name, type, path) VALUES ('json_document', 'Class', 'api/json_document/index.html');
|
INSERT INTO searchIndex(name, type, path) VALUES ('json_document', 'Class', 'api/json_document/index.html');
|
||||||
INSERT INTO searchIndex(name, type, path) VALUES ('json_view', 'Class', 'api/json_view/index.html');
|
INSERT INTO searchIndex(name, type, path) VALUES ('json_view', 'Class', 'api/json_view/index.html');
|
||||||
|
|||||||
@@ -219,6 +219,7 @@ Strong exception safety: if an exception occurs, the original value stays intact
|
|||||||
- documentation on [checked access](../../features/element_access/checked_access.md)
|
- documentation on [checked access](../../features/element_access/checked_access.md)
|
||||||
- [`operator[]`](operator%5B%5D.md) for unchecked access by reference
|
- [`operator[]`](operator%5B%5D.md) for unchecked access by reference
|
||||||
- [`value`](value.md) for access with default value
|
- [`value`](value.md) for access with default value
|
||||||
|
- [basic_json_view::at](../basic_json_view/at.md) - the same access on a zero-copy view
|
||||||
|
|
||||||
## Version history
|
## Version history
|
||||||
|
|
||||||
|
|||||||
@@ -58,6 +58,7 @@ Constant.
|
|||||||
## See also
|
## See also
|
||||||
|
|
||||||
- [front](front.md) to access the first element
|
- [front](front.md) to access the first element
|
||||||
|
- [basic_json_view::back](../basic_json_view/back.md) - the same access on a zero-copy view
|
||||||
|
|
||||||
## Version history
|
## Version history
|
||||||
|
|
||||||
|
|||||||
@@ -37,6 +37,12 @@ Constant.
|
|||||||
--8<-- "examples/begin.output"
|
--8<-- "examples/begin.output"
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## See also
|
||||||
|
|
||||||
|
- [end](end.md) - returns an iterator to one past the last element
|
||||||
|
- [basic_json_view::begin](../basic_json_view/begin.md) - the same iteration on a zero-copy view (in document order,
|
||||||
|
not sorted by key)
|
||||||
|
|
||||||
## Version history
|
## Version history
|
||||||
|
|
||||||
- Added in version 1.0.0.
|
- Added in version 1.0.0.
|
||||||
|
|||||||
@@ -36,6 +36,11 @@ Constant.
|
|||||||
--8<-- "examples/cbegin.output"
|
--8<-- "examples/cbegin.output"
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## See also
|
||||||
|
|
||||||
|
- [cend](cend.md) - returns a const iterator to one past the last element
|
||||||
|
- [basic_json_view::cbegin](../basic_json_view/cbegin.md) - the same iteration on a zero-copy view
|
||||||
|
|
||||||
## Version history
|
## Version history
|
||||||
|
|
||||||
- Added in version 1.0.0.
|
- Added in version 1.0.0.
|
||||||
|
|||||||
@@ -36,6 +36,11 @@ Constant.
|
|||||||
--8<-- "examples/cend.output"
|
--8<-- "examples/cend.output"
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## See also
|
||||||
|
|
||||||
|
- [cbegin](cbegin.md) - returns a const iterator to the first element
|
||||||
|
- [basic_json_view::cend](../basic_json_view/cend.md) - the same iteration on a zero-copy view
|
||||||
|
|
||||||
## Version history
|
## Version history
|
||||||
|
|
||||||
- Added in version 1.0.0.
|
- Added in version 1.0.0.
|
||||||
|
|||||||
@@ -115,6 +115,7 @@ Logarithmic in the size of the JSON object.
|
|||||||
|
|
||||||
- [find](find.md) find a value in an object
|
- [find](find.md) find a value in an object
|
||||||
- [count](count.md) returns the number of occurrences of a key
|
- [count](count.md) returns the number of occurrences of a key
|
||||||
|
- [basic_json_view::contains](../basic_json_view/contains.md) - the same check on a zero-copy view
|
||||||
|
|
||||||
## Version history
|
## Version history
|
||||||
|
|
||||||
|
|||||||
@@ -80,6 +80,7 @@ Logarithmic in the size of the JSON object.
|
|||||||
|
|
||||||
- [find](find.md) find a value in an object
|
- [find](find.md) find a value in an object
|
||||||
- [contains](contains.md) checks whether a key exists
|
- [contains](contains.md) checks whether a key exists
|
||||||
|
- [basic_json_view::count](../basic_json_view/count.md) - the same check on a zero-copy view
|
||||||
|
|
||||||
## Version history
|
## Version history
|
||||||
|
|
||||||
|
|||||||
@@ -37,6 +37,11 @@ Constant.
|
|||||||
--8<-- "examples/end.output"
|
--8<-- "examples/end.output"
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## See also
|
||||||
|
|
||||||
|
- [begin](begin.md) - returns an iterator to the first element
|
||||||
|
- [basic_json_view::end](../basic_json_view/end.md) - the same iteration on a zero-copy view
|
||||||
|
|
||||||
## Version history
|
## Version history
|
||||||
|
|
||||||
- Added in version 1.0.0.
|
- Added in version 1.0.0.
|
||||||
|
|||||||
@@ -84,6 +84,7 @@ Logarithmic in the size of the JSON object.
|
|||||||
|
|
||||||
- [count](count.md) returns the number of occurrences of a key
|
- [count](count.md) returns the number of occurrences of a key
|
||||||
- [contains](contains.md) checks whether a key exists
|
- [contains](contains.md) checks whether a key exists
|
||||||
|
- [basic_json_view::find](../basic_json_view/find.md) - the same lookup on a zero-copy view
|
||||||
|
|
||||||
## Version history
|
## Version history
|
||||||
|
|
||||||
|
|||||||
@@ -51,6 +51,7 @@ Constant.
|
|||||||
## See also
|
## See also
|
||||||
|
|
||||||
- [back](back.md) to access the last element
|
- [back](back.md) to access the last element
|
||||||
|
- [basic_json_view::front](../basic_json_view/front.md) - the same access on a zero-copy view
|
||||||
|
|
||||||
## Version history
|
## Version history
|
||||||
|
|
||||||
|
|||||||
@@ -99,6 +99,8 @@ When iterating over an array, `key()` will return the index of the element as st
|
|||||||
|
|
||||||
- [begin](begin.md) returns an iterator to the first element
|
- [begin](begin.md) returns an iterator to the first element
|
||||||
- [end](end.md) returns an iterator to one past the last element
|
- [end](end.md) returns an iterator to one past the last element
|
||||||
|
- [basic_json_view::items](../basic_json_view/items.md) - the same range on a zero-copy view (`#!cpp const auto`,
|
||||||
|
not `#!cpp const auto&`: items are produced on the fly)
|
||||||
|
|
||||||
## Version history
|
## Version history
|
||||||
|
|
||||||
|
|||||||
@@ -257,6 +257,8 @@ Strong exception safety: if an exception occurs, the original value stays intact
|
|||||||
- documentation on [runtime assertions](../../features/assertions.md)
|
- documentation on [runtime assertions](../../features/assertions.md)
|
||||||
- see [`at`](at.md) for access by reference with range checking
|
- see [`at`](at.md) for access by reference with range checking
|
||||||
- see [`value`](value.md) for access with default value
|
- see [`value`](value.md) for access with default value
|
||||||
|
- [basic_json_view::operator[]](../basic_json_view/operator%5B%5D.md) - the same access on a zero-copy view (always
|
||||||
|
returns a discarded view instead of assuming undefined behavior)
|
||||||
|
|
||||||
## Version history
|
## Version history
|
||||||
|
|
||||||
|
|||||||
@@ -52,6 +52,11 @@ Constant.
|
|||||||
--8<-- "examples/type_name.output"
|
--8<-- "examples/type_name.output"
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## See also
|
||||||
|
|
||||||
|
- [type](type.md) - return the type of the JSON value
|
||||||
|
- [basic_json_view::type_name](../basic_json_view/type_name.md) - the same function on a zero-copy view
|
||||||
|
|
||||||
## Version history
|
## Version history
|
||||||
|
|
||||||
- Added in version 1.0.0.
|
- Added in version 1.0.0.
|
||||||
|
|||||||
@@ -0,0 +1,90 @@
|
|||||||
|
# <small>nlohmann::basic_json_view::</small>at
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
// (1)
|
||||||
|
basic_json_view at(string_view_t key) const;
|
||||||
|
basic_json_view at(const char* key) const;
|
||||||
|
basic_json_view at(const string_t& key) const;
|
||||||
|
|
||||||
|
// (2)
|
||||||
|
basic_json_view at(size_type idx) const;
|
||||||
|
basic_json_view at(int idx) const;
|
||||||
|
```
|
||||||
|
|
||||||
|
1. Returns the value of the object member with key `key` -- the first one, should the key occur more than once (see
|
||||||
|
[Notes on duplicate keys](operator[].md#notes)).
|
||||||
|
2. Returns the array element at index `idx`.
|
||||||
|
|
||||||
|
## Parameters
|
||||||
|
|
||||||
|
`key` (in)
|
||||||
|
: object key of the element to access
|
||||||
|
|
||||||
|
`idx` (in)
|
||||||
|
: index of the element to access
|
||||||
|
|
||||||
|
## Return value
|
||||||
|
|
||||||
|
1. the value of the first member with key `key`
|
||||||
|
2. the element at index `idx`
|
||||||
|
|
||||||
|
## Exception safety
|
||||||
|
|
||||||
|
Strong exception safety: if an exception is thrown, there are no changes to the view or the document it refers to.
|
||||||
|
|
||||||
|
## Exceptions
|
||||||
|
|
||||||
|
1. The function can throw the following exceptions, both with the same message as the corresponding call to
|
||||||
|
[`BasicJsonType::at`](../basic_json/at.md):
|
||||||
|
- Throws [`type_error.304`](../../home/exceptions.md#jsonexceptiontype_error304) if the value is not an object.
|
||||||
|
- Throws [`out_of_range.403`](../../home/exceptions.md#jsonexceptionout_of_range403) if no member has key `key`.
|
||||||
|
2. The function can throw the following exceptions, both with the same message as the corresponding call to
|
||||||
|
[`BasicJsonType::at`](../basic_json/at.md):
|
||||||
|
- Throws [`type_error.304`](../../home/exceptions.md#jsonexceptiontype_error304) if the value is not an array.
|
||||||
|
- Throws [`out_of_range.401`](../../home/exceptions.md#jsonexceptionout_of_range401) if `#!cpp idx >= size()`.
|
||||||
|
|
||||||
|
None of these exceptions carry a [`JSON_DIAGNOSTICS`](../macros/json_diagnostics.md) path: the view has no
|
||||||
|
`BasicJsonType` value to point at, so the exception is created without one, even if `BasicJsonType` was built with
|
||||||
|
`JSON_DIAGNOSTICS` enabled.
|
||||||
|
|
||||||
|
## Complexity
|
||||||
|
|
||||||
|
1. Linear in the number of members: as for [`ordered_json`](../ordered_json.md), members are compared one after
|
||||||
|
another, in document order, stopping at the first match. Each comparison first checks the key's length --
|
||||||
|
already known from the index, without reading the key bytes -- before comparing its content.
|
||||||
|
2. Linear in `idx`: elements are skipped one at a time from the first one, since they are not a fixed size in the
|
||||||
|
index (unlike `BasicJsonType`'s array, which is random-access).
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
|
||||||
|
Unlike [`operator[]`](operator[].md), which returns a [discarded](is_discarded.md) view for a missing key or an
|
||||||
|
out-of-range index, `at` always throws -- exactly as `BasicJsonType::at` does, and with the same messages, so
|
||||||
|
existing error handling written against `BasicJsonType::at` keeps working unchanged when switched to a view.
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
??? example
|
||||||
|
|
||||||
|
The example below reads required fields out of a service configuration with `at`, and shows that the exceptions
|
||||||
|
it throws -- for a wrong type and for a missing key -- carry the same messages
|
||||||
|
[`BasicJsonType::at`](../basic_json/at.md) would produce for the same JSON text.
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
--8<-- "examples/basic_json_view__at.cpp"
|
||||||
|
```
|
||||||
|
|
||||||
|
Output:
|
||||||
|
|
||||||
|
```json
|
||||||
|
--8<-- "examples/basic_json_view__at.output"
|
||||||
|
```
|
||||||
|
|
||||||
|
## See also
|
||||||
|
|
||||||
|
- [operator[]](operator[].md) - access specified element (returns a discarded view instead of throwing)
|
||||||
|
- [front](front.md), [back](back.md) - access the first or last element
|
||||||
|
- [`BasicJsonType::at`](../basic_json/at.md) - the corresponding function of `basic_json`
|
||||||
|
|
||||||
|
## Version history
|
||||||
|
|
||||||
|
- Added in version 3.13.0.
|
||||||
@@ -0,0 +1,64 @@
|
|||||||
|
# <small>nlohmann::basic_json_view::</small>back
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
basic_json_view back() const;
|
||||||
|
```
|
||||||
|
|
||||||
|
Returns the last element of an array, the last member value of an object, or the value itself if it is primitive
|
||||||
|
(as for [`BasicJsonType::back()`](../basic_json/back.md), a primitive value is a range of one element).
|
||||||
|
|
||||||
|
## Return value
|
||||||
|
|
||||||
|
The last element or member value. For a primitive value (number, string, boolean), the value itself.
|
||||||
|
|
||||||
|
## Exception safety
|
||||||
|
|
||||||
|
Strong exception safety: if an exception is thrown, there are no changes to the view or the document it refers to.
|
||||||
|
|
||||||
|
## Exceptions
|
||||||
|
|
||||||
|
Throws [`invalid_iterator.214`](../../home/exceptions.md#jsonexceptioninvalid_iterator214) if the view is
|
||||||
|
[null](is_null.md) or [discarded](is_discarded.md), or if it is an empty array or object.
|
||||||
|
|
||||||
|
This exception does not carry a [`JSON_DIAGNOSTICS`](../macros/json_diagnostics.md) path: the view has no
|
||||||
|
`BasicJsonType` value to point at, so the exception is created without one, even if `BasicJsonType` was built with
|
||||||
|
`JSON_DIAGNOSTICS` enabled.
|
||||||
|
|
||||||
|
## Complexity
|
||||||
|
|
||||||
|
Linear in the size of the array or object: unlike [`front()`](front.md), which only ever looks at the first
|
||||||
|
element, `back()` has to walk every element to find where they end, since elements are not a fixed size in the
|
||||||
|
index.
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
|
||||||
|
Unlike [`BasicJsonType::back()`](../basic_json/back.md), which has undefined behavior for an empty array or object,
|
||||||
|
`back()` throws `invalid_iterator.214` in that case -- the same way it already does for `#!json null` and for a
|
||||||
|
discarded view, where `BasicJsonType::back()` also throws.
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
??? example
|
||||||
|
|
||||||
|
The example below reads only the final status of a build log with `back()`. Even though `back()` is linear in
|
||||||
|
the number of events (unlike [`front()`](front.md), which is constant), it still avoids building a
|
||||||
|
`BasicJsonType` value for the events that are not needed.
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
--8<-- "examples/basic_json_view__back.cpp"
|
||||||
|
```
|
||||||
|
|
||||||
|
Output:
|
||||||
|
|
||||||
|
```json
|
||||||
|
--8<-- "examples/basic_json_view__back.output"
|
||||||
|
```
|
||||||
|
|
||||||
|
## See also
|
||||||
|
|
||||||
|
- [front](front.md) - access the first element
|
||||||
|
- [`BasicJsonType::back`](../basic_json/back.md) - the corresponding function of `basic_json`
|
||||||
|
|
||||||
|
## Version history
|
||||||
|
|
||||||
|
- Added in version 3.13.0.
|
||||||
@@ -8,8 +8,9 @@ Creates an invalid (discarded) view: [`type()`](type.md) is `#!cpp value_t::disc
|
|||||||
[`is_discarded()`](is_discarded.md) is `#!cpp true`, and `#!cpp explicit operator bool()` is `#!cpp false`.
|
[`is_discarded()`](is_discarded.md) is `#!cpp true`, and `#!cpp explicit operator bool()` is `#!cpp false`.
|
||||||
|
|
||||||
This is the only constructor a caller can use directly. Every other view is obtained from a
|
This is the only constructor a caller can use directly. Every other view is obtained from a
|
||||||
[`basic_json_document`](../basic_json_document/index.md), via [`root()`](../basic_json_document/root.md) or (once
|
[`basic_json_document`](../basic_json_document/index.md), via [`root()`](../basic_json_document/root.md) or by
|
||||||
element access is added) from navigating into a container.
|
navigating into a container with [`operator[]`](operator[].md), [`at`](at.md), [`front`](front.md), [`back`](back.md),
|
||||||
|
[`find`](find.md), or iteration.
|
||||||
|
|
||||||
## Exception safety
|
## Exception safety
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,61 @@
|
|||||||
|
# <small>nlohmann::basic_json_view::</small>begin
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
iterator begin() const noexcept;
|
||||||
|
```
|
||||||
|
|
||||||
|
Returns an iterator to the first element of an array, or the first member value of an object, in **document order**
|
||||||
|
-- the order the values appear in the source text, not sorted by key. A primitive value iterates as a range of one
|
||||||
|
element (itself); `#!json null` and a [discarded](is_discarded.md) view iterate as an empty range.
|
||||||
|
|
||||||
|
## Return value
|
||||||
|
|
||||||
|
Iterator to the first element.
|
||||||
|
|
||||||
|
## Exception safety
|
||||||
|
|
||||||
|
No-throw guarantee: this function never throws exceptions.
|
||||||
|
|
||||||
|
## Complexity
|
||||||
|
|
||||||
|
Constant.
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
|
||||||
|
For an object, iteration visits **every** member, including all occurrences of a duplicate key -- unlike
|
||||||
|
[`operator[]`](operator[].md), [`at`](at.md), [`find`](find.md), [`contains`](contains.md), and [`count`](count.md),
|
||||||
|
which all resolve to the *first* member with a given key. See the
|
||||||
|
[Notes on duplicate keys](operator[].md#notes) of `operator[]`.
|
||||||
|
|
||||||
|
Because objects are iterated in document order rather than sorted by key, the order seen here can differ from what
|
||||||
|
iterating the [`materialize()`](materialize.md)d `BasicJsonType` value would produce: a `#!cpp basic_json` object
|
||||||
|
(`std::map`-backed by default) sorts its keys, while a view does not.
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
??? example
|
||||||
|
|
||||||
|
The example below iterates a log record's members with `begin()`/[`end()`](end.md) and prints them in the order
|
||||||
|
they were written. Materializing the record into a `BasicJsonType` object and iterating that would instead print
|
||||||
|
the members sorted by key.
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
--8<-- "examples/basic_json_view__begin.cpp"
|
||||||
|
```
|
||||||
|
|
||||||
|
Output:
|
||||||
|
|
||||||
|
```json
|
||||||
|
--8<-- "examples/basic_json_view__begin.output"
|
||||||
|
```
|
||||||
|
|
||||||
|
## See also
|
||||||
|
|
||||||
|
- [end](end.md) - returns an iterator to one past the last element
|
||||||
|
- [cbegin](cbegin.md) - returns a const iterator to the first element
|
||||||
|
- [items](items.md) - access iterator member functions in range-based for
|
||||||
|
- [`BasicJsonType::begin`](../basic_json/begin.md) - the corresponding function of `basic_json`
|
||||||
|
|
||||||
|
## Version history
|
||||||
|
|
||||||
|
- Added in version 3.13.0.
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
# <small>nlohmann::basic_json_view::</small>cbegin
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
iterator cbegin() const noexcept;
|
||||||
|
```
|
||||||
|
|
||||||
|
Returns an iterator to the first element, in [document order](begin.md). Equivalent to [`begin()`](begin.md): a view
|
||||||
|
is always read-only, so `#!cpp const_iterator` and `#!cpp iterator` are the same type, and `cbegin()` exists only so
|
||||||
|
that generic code that expects a `cbegin()`/`cend()` pair works with a view too.
|
||||||
|
|
||||||
|
## Return value
|
||||||
|
|
||||||
|
Iterator to the first element; identical to what [`begin()`](begin.md) returns.
|
||||||
|
|
||||||
|
## Exception safety
|
||||||
|
|
||||||
|
No-throw guarantee: this function never throws exceptions.
|
||||||
|
|
||||||
|
## Complexity
|
||||||
|
|
||||||
|
Constant.
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
??? example
|
||||||
|
|
||||||
|
The example below sums many measurements with `std::accumulate`, using `cbegin()`/[`cend()`](cend.md) as the
|
||||||
|
range -- the same way it would for any standard container -- without ever materializing the whole array into a
|
||||||
|
`BasicJsonType` value.
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
--8<-- "examples/basic_json_view__cbegin.cpp"
|
||||||
|
```
|
||||||
|
|
||||||
|
Output:
|
||||||
|
|
||||||
|
```json
|
||||||
|
--8<-- "examples/basic_json_view__cbegin.output"
|
||||||
|
```
|
||||||
|
|
||||||
|
## See also
|
||||||
|
|
||||||
|
- [begin](begin.md) - returns an iterator to the first element
|
||||||
|
- [cend](cend.md) - returns a const iterator to one past the last element
|
||||||
|
- [`BasicJsonType::cbegin`](../basic_json/cbegin.md) - the corresponding function of `basic_json`
|
||||||
|
|
||||||
|
## Version history
|
||||||
|
|
||||||
|
- Added in version 3.13.0.
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
# <small>nlohmann::basic_json_view::</small>cend
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
iterator cend() const noexcept;
|
||||||
|
```
|
||||||
|
|
||||||
|
Returns an iterator to one past the last element, in [document order](begin.md). Equivalent to [`end()`](end.md): a
|
||||||
|
view is always read-only, so `#!cpp const_iterator` and `#!cpp iterator` are the same type, and `cend()` exists only
|
||||||
|
so that generic code that expects a `cbegin()`/`cend()` pair works with a view too.
|
||||||
|
|
||||||
|
## Return value
|
||||||
|
|
||||||
|
Iterator one past the last element; identical to what [`end()`](end.md) returns.
|
||||||
|
|
||||||
|
## Exception safety
|
||||||
|
|
||||||
|
No-throw guarantee: this function never throws exceptions.
|
||||||
|
|
||||||
|
## Complexity
|
||||||
|
|
||||||
|
Constant.
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
??? example
|
||||||
|
|
||||||
|
The example below checks that every record of a batch is an object with `std::all_of`, using
|
||||||
|
[`cbegin()`](cbegin.md)/`cend()` as the range -- the same way it would for any standard container -- before
|
||||||
|
materializing any record of the batch.
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
--8<-- "examples/basic_json_view__cend.cpp"
|
||||||
|
```
|
||||||
|
|
||||||
|
Output:
|
||||||
|
|
||||||
|
```json
|
||||||
|
--8<-- "examples/basic_json_view__cend.output"
|
||||||
|
```
|
||||||
|
|
||||||
|
## See also
|
||||||
|
|
||||||
|
- [end](end.md) - returns an iterator to one past the last element
|
||||||
|
- [cbegin](cbegin.md) - returns a const iterator to the first element
|
||||||
|
- [`BasicJsonType::cend`](../basic_json/cend.md) - the corresponding function of `basic_json`
|
||||||
|
|
||||||
|
## Version history
|
||||||
|
|
||||||
|
- Added in version 3.13.0.
|
||||||
@@ -0,0 +1,64 @@
|
|||||||
|
# <small>nlohmann::basic_json_view::</small>contains
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
bool contains(string_view_t key) const;
|
||||||
|
bool contains(const char* key) const;
|
||||||
|
bool contains(const string_t& key) const;
|
||||||
|
```
|
||||||
|
|
||||||
|
Checks whether the value is an object with a member with key `key`.
|
||||||
|
|
||||||
|
## Parameters
|
||||||
|
|
||||||
|
`key` (in)
|
||||||
|
: key value to check its existence
|
||||||
|
|
||||||
|
## Return value
|
||||||
|
|
||||||
|
`#!cpp true` if the value is an object and has a member with key `key`, `#!cpp false` otherwise.
|
||||||
|
|
||||||
|
## Exception safety
|
||||||
|
|
||||||
|
No-throw guarantee: this function never throws exceptions.
|
||||||
|
|
||||||
|
## Complexity
|
||||||
|
|
||||||
|
Linear in the number of members: as for [`ordered_json`](../ordered_json.md), members are compared one after
|
||||||
|
another, in document order, stopping at the first match. Each comparison first checks the key's length -- already
|
||||||
|
known from the index, without reading the key bytes -- before comparing its content.
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
|
||||||
|
This method always returns `#!cpp false` when the value is not an object -- including a [discarded](is_discarded.md)
|
||||||
|
view.
|
||||||
|
|
||||||
|
!!! info "Postconditions"
|
||||||
|
|
||||||
|
If `#!cpp v.contains(key)` returns `#!cpp true`, then `#!cpp v[key]` is not [discarded](is_discarded.md).
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
??? example
|
||||||
|
|
||||||
|
The example below counts how many of a batch of records carry an optional `retry_of` field, using `contains()`
|
||||||
|
to check without ever materializing a single record of the batch.
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
--8<-- "examples/basic_json_view__contains.cpp"
|
||||||
|
```
|
||||||
|
|
||||||
|
Output:
|
||||||
|
|
||||||
|
```json
|
||||||
|
--8<-- "examples/basic_json_view__contains.output"
|
||||||
|
```
|
||||||
|
|
||||||
|
## See also
|
||||||
|
|
||||||
|
- [find](find.md) - find a value in an object
|
||||||
|
- [count](count.md) - returns the number of occurrences of a key
|
||||||
|
- [`BasicJsonType::contains`](../basic_json/contains.md) - the corresponding function of `basic_json`
|
||||||
|
|
||||||
|
## Version history
|
||||||
|
|
||||||
|
- Added in version 3.13.0.
|
||||||
@@ -0,0 +1,66 @@
|
|||||||
|
# <small>nlohmann::basic_json_view::</small>count
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
size_type count(string_view_t key) const;
|
||||||
|
size_type count(const char* key) const;
|
||||||
|
size_type count(const string_t& key) const;
|
||||||
|
```
|
||||||
|
|
||||||
|
Returns `#!cpp 1` if the value is an object with a member with key `key`, `#!cpp 0` otherwise.
|
||||||
|
|
||||||
|
## Parameters
|
||||||
|
|
||||||
|
`key` (in)
|
||||||
|
: key value of the element to count
|
||||||
|
|
||||||
|
## Return value
|
||||||
|
|
||||||
|
`#!cpp 1` if the value is an object and has a member with key `key`, `#!cpp 0` otherwise.
|
||||||
|
|
||||||
|
## Exception safety
|
||||||
|
|
||||||
|
No-throw guarantee: this function never throws exceptions.
|
||||||
|
|
||||||
|
## Complexity
|
||||||
|
|
||||||
|
Linear in the number of members: as for [`ordered_json`](../ordered_json.md), members are compared one after
|
||||||
|
another, in document order, stopping at the first match. Each comparison first checks the key's length -- already
|
||||||
|
known from the index, without reading the key bytes -- before comparing its content.
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
|
||||||
|
This method always returns `#!cpp 0` when the value is not an object -- including a [discarded](is_discarded.md)
|
||||||
|
view.
|
||||||
|
|
||||||
|
Unlike [`BasicJsonType::count()`](../basic_json/count.md), whose return value can in principle exceed `#!cpp 1` for
|
||||||
|
an `ObjectType` that allows multiple entries per key, `count()` here never does: it is exactly
|
||||||
|
[`contains()`](contains.md) as `#!cpp 0`/`#!cpp 1`. This holds even if the source text has a duplicate key -- see the
|
||||||
|
[Notes on duplicate keys](operator[].md#notes) of `operator[]` -- because a `#!cpp count() > 1` result would require
|
||||||
|
counting every member with a matching key, not just finding the first one.
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
??? example
|
||||||
|
|
||||||
|
The example below validates that every transaction of a batch carries a mandatory `amount` field, using
|
||||||
|
`count()` before deciding whether to materialize a transaction at all.
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
--8<-- "examples/basic_json_view__count.cpp"
|
||||||
|
```
|
||||||
|
|
||||||
|
Output:
|
||||||
|
|
||||||
|
```json
|
||||||
|
--8<-- "examples/basic_json_view__count.output"
|
||||||
|
```
|
||||||
|
|
||||||
|
## See also
|
||||||
|
|
||||||
|
- [find](find.md) - find a value in an object
|
||||||
|
- [contains](contains.md) - checks whether a key exists
|
||||||
|
- [`BasicJsonType::count`](../basic_json/count.md) - the corresponding function of `basic_json`
|
||||||
|
|
||||||
|
## Version history
|
||||||
|
|
||||||
|
- Added in version 3.13.0.
|
||||||
@@ -0,0 +1,54 @@
|
|||||||
|
# <small>nlohmann::basic_json_view::</small>end
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
iterator end() const noexcept;
|
||||||
|
```
|
||||||
|
|
||||||
|
Returns an iterator to one past the last element of an array, one past the last member value of an object, in
|
||||||
|
**document order** -- see [`begin()`](begin.md). A primitive value iterates as a range of one element (itself);
|
||||||
|
`#!json null` and a [discarded](is_discarded.md) view iterate as an empty range, so `#!cpp begin() == end()` for
|
||||||
|
them.
|
||||||
|
|
||||||
|
## Return value
|
||||||
|
|
||||||
|
Iterator one past the last element.
|
||||||
|
|
||||||
|
## Exception safety
|
||||||
|
|
||||||
|
No-throw guarantee: this function never throws exceptions.
|
||||||
|
|
||||||
|
## Complexity
|
||||||
|
|
||||||
|
Constant.
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
|
||||||
|
`#!cpp iterator` is a forward iterator: unlike `BasicJsonType::iterator`, it cannot be decremented, so there is no
|
||||||
|
way to reach the last element by stepping back from `end()`. Use [`back()`](back.md) instead.
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
??? example
|
||||||
|
|
||||||
|
The example below scans a (possibly large) array of readings for the first one over a threshold, stopping the
|
||||||
|
loop at `end()` as soon as one is found. Only the matching reading, if any, is ever materialized.
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
--8<-- "examples/basic_json_view__end.cpp"
|
||||||
|
```
|
||||||
|
|
||||||
|
Output:
|
||||||
|
|
||||||
|
```json
|
||||||
|
--8<-- "examples/basic_json_view__end.output"
|
||||||
|
```
|
||||||
|
|
||||||
|
## See also
|
||||||
|
|
||||||
|
- [begin](begin.md) - returns an iterator to the first element
|
||||||
|
- [cend](cend.md) - returns a const iterator to one past the last element
|
||||||
|
- [`BasicJsonType::end`](../basic_json/end.md) - the corresponding function of `basic_json`
|
||||||
|
|
||||||
|
## Version history
|
||||||
|
|
||||||
|
- Added in version 3.13.0.
|
||||||
@@ -0,0 +1,63 @@
|
|||||||
|
# <small>nlohmann::basic_json_view::</small>find
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
iterator find(string_view_t key) const;
|
||||||
|
iterator find(const char* key) const;
|
||||||
|
iterator find(const string_t& key) const;
|
||||||
|
```
|
||||||
|
|
||||||
|
Finds a member with key `key` -- the first one, should the key occur more than once (see
|
||||||
|
[Notes on duplicate keys](operator[].md#notes)). If the value is not an object, or no member has this key,
|
||||||
|
[`end()`](end.md) is returned.
|
||||||
|
|
||||||
|
## Parameters
|
||||||
|
|
||||||
|
`key` (in)
|
||||||
|
: key value of the element to search for
|
||||||
|
|
||||||
|
## Return value
|
||||||
|
|
||||||
|
An iterator to the member with key `key`, or [`end()`](end.md) if there is none or the value is not an object.
|
||||||
|
|
||||||
|
## Exception safety
|
||||||
|
|
||||||
|
No-throw guarantee: this function never throws exceptions.
|
||||||
|
|
||||||
|
## Complexity
|
||||||
|
|
||||||
|
Linear in the number of members: as for [`ordered_json`](../ordered_json.md), members are compared one after
|
||||||
|
another, in document order, stopping at the first match. Each comparison first checks the key's length -- already
|
||||||
|
known from the index, without reading the key bytes -- before comparing its content.
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
|
||||||
|
Unlike [`BasicJsonType::find`](../basic_json/find.md), which always returns `#!cpp end()` for a non-object type, this
|
||||||
|
also does so for a [discarded](is_discarded.md) view -- there is no separate "invalid" iterator to return.
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
??? example
|
||||||
|
|
||||||
|
The example below scans a batch of events for those that carry an optional `user_id` field, using `find()`
|
||||||
|
instead of [`operator[]`](operator[].md) (which would throw for the events that are not objects at all) or
|
||||||
|
[`contains()`](contains.md) followed by a second lookup. Events without a match are never materialized.
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
--8<-- "examples/basic_json_view__find.cpp"
|
||||||
|
```
|
||||||
|
|
||||||
|
Output:
|
||||||
|
|
||||||
|
```json
|
||||||
|
--8<-- "examples/basic_json_view__find.output"
|
||||||
|
```
|
||||||
|
|
||||||
|
## See also
|
||||||
|
|
||||||
|
- [count](count.md) - returns the number of occurrences of a key
|
||||||
|
- [contains](contains.md) - checks whether a key exists
|
||||||
|
- [`BasicJsonType::find`](../basic_json/find.md) - the corresponding function of `basic_json`
|
||||||
|
|
||||||
|
## Version history
|
||||||
|
|
||||||
|
- Added in version 3.13.0.
|
||||||
@@ -0,0 +1,61 @@
|
|||||||
|
# <small>nlohmann::basic_json_view::</small>front
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
basic_json_view front() const;
|
||||||
|
```
|
||||||
|
|
||||||
|
Returns the first element of an array, the first member value of an object, or the value itself if it is primitive
|
||||||
|
(as for [`BasicJsonType::front()`](../basic_json/front.md), a primitive value is a range of one element).
|
||||||
|
|
||||||
|
## Return value
|
||||||
|
|
||||||
|
The first element or member value. For a primitive value (number, string, boolean), the value itself.
|
||||||
|
|
||||||
|
## Exception safety
|
||||||
|
|
||||||
|
Strong exception safety: if an exception is thrown, there are no changes to the view or the document it refers to.
|
||||||
|
|
||||||
|
## Exceptions
|
||||||
|
|
||||||
|
Throws [`invalid_iterator.214`](../../home/exceptions.md#jsonexceptioninvalid_iterator214) if the view is
|
||||||
|
[null](is_null.md) or [discarded](is_discarded.md), or if it is an empty array or object.
|
||||||
|
|
||||||
|
This exception does not carry a [`JSON_DIAGNOSTICS`](../macros/json_diagnostics.md) path: the view has no
|
||||||
|
`BasicJsonType` value to point at, so the exception is created without one, even if `BasicJsonType` was built with
|
||||||
|
`JSON_DIAGNOSTICS` enabled.
|
||||||
|
|
||||||
|
## Complexity
|
||||||
|
|
||||||
|
Constant.
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
|
||||||
|
Unlike [`BasicJsonType::front()`](../basic_json/front.md), which has undefined behavior for an empty array or
|
||||||
|
object, `front()` throws `invalid_iterator.214` in that case -- the same way it already does for `#!json null` and
|
||||||
|
for a discarded view, where `BasicJsonType::front()` also throws.
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
??? example
|
||||||
|
|
||||||
|
The example below reads only the earliest entry of a build log with `front()`, without materializing the rest
|
||||||
|
of the (possibly long) log.
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
--8<-- "examples/basic_json_view__front.cpp"
|
||||||
|
```
|
||||||
|
|
||||||
|
Output:
|
||||||
|
|
||||||
|
```json
|
||||||
|
--8<-- "examples/basic_json_view__front.output"
|
||||||
|
```
|
||||||
|
|
||||||
|
## See also
|
||||||
|
|
||||||
|
- [back](back.md) - access the last element
|
||||||
|
- [`BasicJsonType::front`](../basic_json/front.md) - the corresponding function of `basic_json`
|
||||||
|
|
||||||
|
## Version history
|
||||||
|
|
||||||
|
- Added in version 3.13.0.
|
||||||
@@ -19,9 +19,9 @@ to the document and a pointer into its index), trivially copyable. A view is val
|
|||||||
Moving the document itself does not invalidate its views: the index is heap-allocated independently of the
|
Moving the document itself does not invalidate its views: the index is heap-allocated independently of the
|
||||||
`basic_json_document` object.
|
`basic_json_document` object.
|
||||||
|
|
||||||
`basic_json_view` provides the read-only part of the `BasicJsonType` interface: the type-inspection functions, and
|
`basic_json_view` provides the read-only part of the `BasicJsonType` interface: the type-inspection functions, element
|
||||||
[`materialize()`](materialize.md) to build the `BasicJsonType` value of a subtree on demand. It does not (yet) provide
|
access, lookup, iteration, and [`materialize()`](materialize.md) to build the `BasicJsonType` value of a subtree on
|
||||||
element access, iteration, `get<T>()`, JSON Pointer support, `dump()`, or comparison.
|
demand. It does not (yet) provide `get<T>()`, JSON Pointer support, `dump()`, or comparison.
|
||||||
|
|
||||||
## Template parameters
|
## Template parameters
|
||||||
|
|
||||||
@@ -41,6 +41,9 @@ element access, iteration, `get<T>()`, JSON Pointer support, `dump()`, or compar
|
|||||||
member types of `BasicJsonType`
|
member types of `BasicJsonType`
|
||||||
- **size_type** - `#!cpp std::size_t`
|
- **size_type** - `#!cpp std::size_t`
|
||||||
- **string_view_t** - `#!cpp std::string_view` on C++17 and newer, a minimal internal substitute otherwise
|
- **string_view_t** - `#!cpp std::string_view` on C++17 and newer, a minimal internal substitute otherwise
|
||||||
|
- **iterator**, **const_iterator** - a forward iterator over the elements of an array or the member values of an
|
||||||
|
object, in document order; both names refer to the same type, since a view is always read-only
|
||||||
|
- **item** - a (key, value) pair produced by [`items()`](items.md)
|
||||||
|
|
||||||
## Member functions
|
## Member functions
|
||||||
|
|
||||||
@@ -49,6 +52,7 @@ element access, iteration, `get<T>()`, JSON Pointer support, `dump()`, or compar
|
|||||||
### Object inspection
|
### Object inspection
|
||||||
|
|
||||||
- [**type**](type.md) - return the type of the value
|
- [**type**](type.md) - return the type of the value
|
||||||
|
- [**type_name**](type_name.md) - return the type as string
|
||||||
- [**is_null**](is_null.md) - return whether the value is null
|
- [**is_null**](is_null.md) - return whether the value is null
|
||||||
- [**is_boolean**](is_boolean.md) - return whether the value is a boolean
|
- [**is_boolean**](is_boolean.md) - return whether the value is a boolean
|
||||||
- [**is_number**](is_number.md) - return whether the value is a number
|
- [**is_number**](is_number.md) - return whether the value is a number
|
||||||
@@ -64,6 +68,27 @@ element access, iteration, `get<T>()`, JSON Pointer support, `dump()`, or compar
|
|||||||
- [**is_discarded**](is_discarded.md) - return whether the view is invalid
|
- [**is_discarded**](is_discarded.md) - return whether the view is invalid
|
||||||
- [**operator bool**](operator_bool.md) - return whether the view refers to a value
|
- [**operator bool**](operator_bool.md) - return whether the view refers to a value
|
||||||
|
|
||||||
|
### Element access
|
||||||
|
|
||||||
|
- [**at**](at.md) - access specified element with bounds checking
|
||||||
|
- [**operator[]**](operator[].md) - access specified element
|
||||||
|
- [**front**](front.md) - access the first element
|
||||||
|
- [**back**](back.md) - access the last element
|
||||||
|
|
||||||
|
### Lookup
|
||||||
|
|
||||||
|
- [**find**](find.md) - find an element in an object
|
||||||
|
- [**count**](count.md) - returns the number of occurrences of a key in an object
|
||||||
|
- [**contains**](contains.md) - check the existence of an element in an object
|
||||||
|
|
||||||
|
### Iterators
|
||||||
|
|
||||||
|
- [**begin**](begin.md) - returns an iterator to the first element
|
||||||
|
- [**cbegin**](cbegin.md) - returns a const iterator to the first element
|
||||||
|
- [**end**](end.md) - returns an iterator to one past the last element
|
||||||
|
- [**cend**](cend.md) - returns a const iterator to one past the last element
|
||||||
|
- [**items**](items.md) - wrapper to access iterator member functions in range-based for
|
||||||
|
|
||||||
### Capacity
|
### Capacity
|
||||||
|
|
||||||
- [**size**](size.md) - return the number of elements
|
- [**size**](size.md) - return the number of elements
|
||||||
|
|||||||
@@ -0,0 +1,86 @@
|
|||||||
|
# <small>nlohmann::basic_json_view::</small>items
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
/* unspecified */ items() const noexcept;
|
||||||
|
```
|
||||||
|
|
||||||
|
Returns a range of [`item`](index.md#member-types) values -- (key, value) pairs -- for use in range-based for loops.
|
||||||
|
The key of an array element is its index, converted to a string, as for
|
||||||
|
[`BasicJsonType::items()`](../basic_json/items.md).
|
||||||
|
|
||||||
|
The returned type is not part of the public API and may change between versions; use a range-based for loop (see the
|
||||||
|
example), or `#!cpp decltype(v.items())` if you need to name it.
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
for (const auto& item : v.items())
|
||||||
|
{
|
||||||
|
std::cout << "key: " << item.key() << ", value: " << item.value() << '\n';
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
On C++17, `item` also supports [structured bindings](https://en.cppreference.com/w/cpp/language/structured_binding):
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
for (const auto [key, value] : v.items())
|
||||||
|
{
|
||||||
|
std::cout << "key: " << key << ", value: " << value << '\n';
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Note the `#!cpp const auto` (by value), not `#!cpp const auto&`: unlike `BasicJsonType::items()`, whose elements are
|
||||||
|
references into an existing object, a view's `item` is produced on the fly for each step of the iteration, so there
|
||||||
|
is nothing for a reference to bind to.
|
||||||
|
|
||||||
|
## Return value
|
||||||
|
|
||||||
|
A range whose iterators dereference to [`item`](index.md#member-types) and whose `#!cpp begin()`/`#!cpp end()` are
|
||||||
|
equivalent to [`basic_json_view::begin()`](begin.md)/[`end()`](end.md), in document order.
|
||||||
|
|
||||||
|
## Exception safety
|
||||||
|
|
||||||
|
No-throw guarantee: this function never throws exceptions.
|
||||||
|
|
||||||
|
## Complexity
|
||||||
|
|
||||||
|
Constant.
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
|
||||||
|
As for [`begin()`](begin.md)/[`end()`](end.md), `items()` visits **every** member of an object, including all
|
||||||
|
occurrences of a duplicate key -- unlike [`operator[]`](operator[].md), [`at`](at.md), [`find`](find.md),
|
||||||
|
[`contains`](contains.md), and [`count`](count.md), which resolve to the *first* member with a given key. See the
|
||||||
|
[Notes on duplicate keys](operator[].md#notes) of `operator[]`.
|
||||||
|
|
||||||
|
!!! danger "Lifetime issues"
|
||||||
|
|
||||||
|
As for `BasicJsonType::items()`, calling `items()` on a temporary view (or a temporary document) is dangerous:
|
||||||
|
the range refers back to the document, so the document must outlive the loop. See
|
||||||
|
[#2040](https://github.com/nlohmann/json/issues/2040) for the `BasicJsonType` background.
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
??? example
|
||||||
|
|
||||||
|
The example below shows a settings object whose source text records every update to a key as a duplicate
|
||||||
|
member, in the order they happened. `items()` walks all of them, so the update history is visible, while
|
||||||
|
[`operator[]`](operator[].md) only ever sees the *first* one and [`materialize()`](materialize.md) -- like
|
||||||
|
[`BasicJsonType::parse()`](../basic_json/parse.md) -- keeps only the *last*.
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
--8<-- "examples/basic_json_view__items.cpp"
|
||||||
|
```
|
||||||
|
|
||||||
|
Output:
|
||||||
|
|
||||||
|
```json
|
||||||
|
--8<-- "examples/basic_json_view__items.output"
|
||||||
|
```
|
||||||
|
|
||||||
|
## See also
|
||||||
|
|
||||||
|
- [begin](begin.md), [end](end.md) - the iterators `items()` is built on
|
||||||
|
- [`BasicJsonType::items`](../basic_json/items.md) - the corresponding function of `basic_json`
|
||||||
|
|
||||||
|
## Version history
|
||||||
|
|
||||||
|
- Added in version 3.13.0.
|
||||||
@@ -0,0 +1,105 @@
|
|||||||
|
# <small>nlohmann::basic_json_view::</small>operator[]
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
// (1)
|
||||||
|
basic_json_view operator[](string_view_t key) const;
|
||||||
|
basic_json_view operator[](const char* key) const;
|
||||||
|
basic_json_view operator[](const string_t& key) const;
|
||||||
|
|
||||||
|
// (2)
|
||||||
|
basic_json_view operator[](size_type idx) const;
|
||||||
|
basic_json_view operator[](int idx) const;
|
||||||
|
```
|
||||||
|
|
||||||
|
1. Returns the value of the object member with key `key` -- the first one, should the key occur more than once (see
|
||||||
|
the [Notes](#notes) below) -- or a [discarded](is_discarded.md) view if there is no such member.
|
||||||
|
2. Returns the array element at index `idx`, or a [discarded](is_discarded.md) view if `idx` is out of range. (The
|
||||||
|
`#!cpp int` overload only exists so that an integer literal is not ambiguous between this overload and 1.)
|
||||||
|
|
||||||
|
## Parameters
|
||||||
|
|
||||||
|
`key` (in)
|
||||||
|
: object key of the element to access
|
||||||
|
|
||||||
|
`idx` (in)
|
||||||
|
: index of the element to access
|
||||||
|
|
||||||
|
## Return value
|
||||||
|
|
||||||
|
1. the value of the first member with key `key`, or a discarded view if `#!cpp is_object()` is `#!cpp false` or no
|
||||||
|
member has this key
|
||||||
|
2. the element at index `idx`, or a discarded view if `#!cpp is_array()` is `#!cpp false` or `#!cpp idx >= size()`
|
||||||
|
|
||||||
|
## Exception safety
|
||||||
|
|
||||||
|
Strong exception safety: if an exception is thrown, there are no changes to the view or the document it refers to.
|
||||||
|
|
||||||
|
## Exceptions
|
||||||
|
|
||||||
|
1. Throws [`type_error.305`](../../home/exceptions.md#jsonexceptiontype_error305) if the value is not an object --
|
||||||
|
the same exception, with the same message, that the **const** overload of
|
||||||
|
[`BasicJsonType::operator[]`](../basic_json/operator%5B%5D.md) throws for a string argument on a non-object value.
|
||||||
|
2. Throws [`type_error.305`](../../home/exceptions.md#jsonexceptiontype_error305) if the value is not an array --
|
||||||
|
the same exception, with the same message, that the **const** overload of
|
||||||
|
[`BasicJsonType::operator[]`](../basic_json/operator%5B%5D.md) throws for a numeric argument on a non-array value.
|
||||||
|
|
||||||
|
Neither exception carries a [`JSON_DIAGNOSTICS`](../macros/json_diagnostics.md) path: the view has no `BasicJsonType`
|
||||||
|
value to point at, so the exception is created without one, even if `BasicJsonType` was built with
|
||||||
|
`JSON_DIAGNOSTICS` enabled.
|
||||||
|
|
||||||
|
## Complexity
|
||||||
|
|
||||||
|
1. Linear in the number of members: as for [`ordered_json`](../ordered_json.md), members are compared one after
|
||||||
|
another, in document order, stopping at the first match. Each comparison first checks the key's length --
|
||||||
|
already known from the index, without reading the key bytes -- before comparing its content, so a key of a
|
||||||
|
different length than `key` is rejected without touching the source text.
|
||||||
|
2. Linear in `idx`: elements are skipped one at a time from the first one, since they are not a fixed size in the
|
||||||
|
index (unlike `BasicJsonType`'s array, which is random-access).
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
|
||||||
|
Unlike `BasicJsonType::operator[]`, which is undefined behavior (guarded by a
|
||||||
|
[runtime assertion](../../features/assertions.md)) for a missing key on a **const** value, this operator always
|
||||||
|
returns a safe, testable result: a [discarded](is_discarded.md) view, which is `#!cpp false` in a boolean context.
|
||||||
|
There is also no non-const overload that inserts a missing key or extends an array -- a view never modifies the
|
||||||
|
document.
|
||||||
|
|
||||||
|
!!! info "Duplicate keys"
|
||||||
|
|
||||||
|
If the source text has an object with a duplicate key, `#!cpp operator[]` (and [`at`](at.md), [`find`](find.md),
|
||||||
|
[`contains`](contains.md), [`count`](count.md)) all resolve to the *first* member with that key, because a
|
||||||
|
lookup can stop as soon as it finds a match. This is different from
|
||||||
|
[`materialize()`](materialize.md) (and [`BasicJsonType::parse()`](../basic_json/parse.md)), which replay every
|
||||||
|
member in order and so end up keeping the *last* value for a repeated key -- there is no reason for them to stop
|
||||||
|
early. [`begin()`](begin.md)/[`end()`](end.md) and [`items()`](items.md) iterate over *all* members, including
|
||||||
|
duplicates, in document order. See the example below and [`size()`](size.md#notes).
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
??? example
|
||||||
|
|
||||||
|
The example below reads a couple of fields out of a batch of user records without ever materializing a full
|
||||||
|
`BasicJsonType` value for the batch. `operator[]` is used both to look up an optional object member and to index
|
||||||
|
into an array -- in both cases, a missing value comes back as a discarded view that can be tested with a plain
|
||||||
|
`#!cpp if`, instead of relying on undefined behavior.
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
--8<-- "examples/basic_json_view__operator[].cpp"
|
||||||
|
```
|
||||||
|
|
||||||
|
Output:
|
||||||
|
|
||||||
|
```json
|
||||||
|
--8<-- "examples/basic_json_view__operator[].output"
|
||||||
|
```
|
||||||
|
|
||||||
|
## See also
|
||||||
|
|
||||||
|
- [at](at.md) - access specified element with bounds checking (throws instead of returning a discarded view)
|
||||||
|
- [front](front.md), [back](back.md) - access the first or last element
|
||||||
|
- [find](find.md), [contains](contains.md) - look up a member without throwing
|
||||||
|
- [`BasicJsonType::operator[]`](../basic_json/operator%5B%5D.md) - the corresponding function of `basic_json`
|
||||||
|
|
||||||
|
## Version history
|
||||||
|
|
||||||
|
- Added in version 3.13.0.
|
||||||
@@ -33,6 +33,12 @@ Constant: for an object or array, the element count is stored in the index, not
|
|||||||
As for [`BasicJsonType::size()`](../basic_json/size.md), this does not return the length of a string value -- it is
|
As for [`BasicJsonType::size()`](../basic_json/size.md), this does not return the length of a string value -- it is
|
||||||
`1` for a string, regardless of its length.
|
`1` for a string, regardless of its length.
|
||||||
|
|
||||||
|
If the source text has an object with a duplicate key, every occurrence counts towards its `size()` -- unlike
|
||||||
|
[`materialize()`](materialize.md) (and [`BasicJsonType::parse()`](../basic_json/parse.md)), which keeps only the last
|
||||||
|
value for a repeated key. This means `#!cpp v.size()` can be larger than `#!cpp v.materialize().size()`. See the
|
||||||
|
[Notes on duplicate keys](operator[].md#notes) of `operator[]` for why lookups and iteration disagree on how many
|
||||||
|
members there are.
|
||||||
|
|
||||||
## Examples
|
## Examples
|
||||||
|
|
||||||
??? example
|
??? example
|
||||||
|
|||||||
@@ -0,0 +1,63 @@
|
|||||||
|
# <small>nlohmann::basic_json_view::</small>type_name
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
const char* type_name() const noexcept;
|
||||||
|
```
|
||||||
|
|
||||||
|
Returns the type name as string to be used in error messages -- usually to indicate that a function was called on a
|
||||||
|
wrong JSON type. Identical to [`BasicJsonType::type_name()`](../basic_json/type_name.md), including the extra
|
||||||
|
`#!cpp "discarded"` return value for a [discarded](is_discarded.md) view (`BasicJsonType::type_name()` produces the
|
||||||
|
same string for a discarded `BasicJsonType` value).
|
||||||
|
|
||||||
|
## Return value
|
||||||
|
|
||||||
|
a string representation of the type ([`value_t`](../basic_json/value_t.md)):
|
||||||
|
|
||||||
|
| Value type | return value |
|
||||||
|
|-----------------------------------------------------|---------------|
|
||||||
|
| `#!json null` | `"null"` |
|
||||||
|
| boolean | `"boolean"` |
|
||||||
|
| string | `"string"` |
|
||||||
|
| number (integer, unsigned integer, floating-point) | `"number"` |
|
||||||
|
| object | `"object"` |
|
||||||
|
| array | `"array"` |
|
||||||
|
| discarded | `"discarded"` |
|
||||||
|
|
||||||
|
`type_name()` never returns `#!cpp "binary"`, since a JSON text has no binary values (see
|
||||||
|
[`is_binary()`](is_binary.md)); it also never returns `#!cpp "invalid"`, since a view's `#!cpp kind` always comes
|
||||||
|
from a value the parser actually produced.
|
||||||
|
|
||||||
|
## Exception safety
|
||||||
|
|
||||||
|
No-throw guarantee: this function never throws exceptions.
|
||||||
|
|
||||||
|
## Complexity
|
||||||
|
|
||||||
|
Constant.
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
??? example
|
||||||
|
|
||||||
|
The example below reports why some parsed messages were rejected, using only `type_name()` -- no
|
||||||
|
`BasicJsonType` value is ever built for the ones that are wrong, and the message text matches what
|
||||||
|
[`BasicJsonType::type_name()`](../basic_json/type_name.md) would produce for the same value.
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
--8<-- "examples/basic_json_view__type_name.cpp"
|
||||||
|
```
|
||||||
|
|
||||||
|
Output:
|
||||||
|
|
||||||
|
```json
|
||||||
|
--8<-- "examples/basic_json_view__type_name.output"
|
||||||
|
```
|
||||||
|
|
||||||
|
## See also
|
||||||
|
|
||||||
|
- [type](type.md) - return the type of the value
|
||||||
|
- [`BasicJsonType::type_name`](../basic_json/type_name.md) - the corresponding function of `basic_json`
|
||||||
|
|
||||||
|
## Version history
|
||||||
|
|
||||||
|
- Added in version 3.13.0.
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
#include <iostream>
|
||||||
|
#include <nlohmann/json_view.hpp>
|
||||||
|
|
||||||
|
using json_document = nlohmann::json_document;
|
||||||
|
using json_view = nlohmann::json_view;
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
// required fields of a service configuration -- at() reports a missing
|
||||||
|
// or wrong-typed field with the very same exception basic_json::at()
|
||||||
|
// would throw for the equivalent nlohmann::json value, so error
|
||||||
|
// handling written against basic_json::at() keeps working unchanged
|
||||||
|
json_document config = json_document::parse(R"({"name": "cache", "port": "6379"})");
|
||||||
|
const json_view service = config.root();
|
||||||
|
|
||||||
|
std::cout << service.at("port").materialize().dump() << '\n';
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// "port" is a string, not an array
|
||||||
|
static_cast<void>(service.at("port").at(0));
|
||||||
|
}
|
||||||
|
catch (const nlohmann::json::type_error& e)
|
||||||
|
{
|
||||||
|
std::cout << e.what() << '\n';
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
static_cast<void>(service.at("timeout"));
|
||||||
|
}
|
||||||
|
catch (const nlohmann::json::out_of_range& e)
|
||||||
|
{
|
||||||
|
std::cout << e.what() << '\n';
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
"6379"
|
||||||
|
[json.exception.type_error.304] cannot use at() with string
|
||||||
|
[json.exception.out_of_range.403] key 'timeout' not found
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
#include <iostream>
|
||||||
|
#include <nlohmann/json_view.hpp>
|
||||||
|
|
||||||
|
using json_document = nlohmann::json_document;
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
// the same build log; back() reads only the final status. It is linear
|
||||||
|
// in the number of events (unlike front(), which is constant), but
|
||||||
|
// still far less work than materializing the whole array
|
||||||
|
json_document log = json_document::parse(R"(["queued", "started", "compiling", "linking", "done"])");
|
||||||
|
std::cout << log.root().back().materialize().dump() << '\n';
|
||||||
|
|
||||||
|
// an empty log -- back() throws instead of the undefined behavior
|
||||||
|
// basic_json::back() has for an empty array
|
||||||
|
json_document empty_log = json_document::parse("[]");
|
||||||
|
try
|
||||||
|
{
|
||||||
|
static_cast<void>(empty_log.root().back());
|
||||||
|
}
|
||||||
|
catch (const nlohmann::json::invalid_iterator& e)
|
||||||
|
{
|
||||||
|
std::cout << e.what() << '\n';
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
"done"
|
||||||
|
[json.exception.invalid_iterator.214] cannot get value
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
#include <iostream>
|
||||||
|
#include <nlohmann/json_view.hpp>
|
||||||
|
|
||||||
|
using json_document = nlohmann::json_document;
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
// a log record: the fields matter in the order they were written, e.g.
|
||||||
|
// to reproduce the record as it was logged. A nlohmann::json object
|
||||||
|
// sorts its keys, so materializing and iterating it would instead print
|
||||||
|
// them alphabetically ("level", "message", "time")
|
||||||
|
json_document record = json_document::parse(R"({"time": "10:00:01", "level": "info", "message": "started"})");
|
||||||
|
|
||||||
|
for (auto it = record.root().begin(); it != record.root().end(); ++it)
|
||||||
|
{
|
||||||
|
std::cout << it.key() << '=' << it->materialize().dump() << '\n';
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
time="10:00:01"
|
||||||
|
level="info"
|
||||||
|
message="started"
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
#include <iostream>
|
||||||
|
#include <numeric>
|
||||||
|
#include <nlohmann/json_view.hpp>
|
||||||
|
|
||||||
|
using json_document = nlohmann::json_document;
|
||||||
|
using json_view = nlohmann::json_view;
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
// sum many measurements with std::accumulate; cbegin()/cend() (identical
|
||||||
|
// to begin()/end() here -- the view is always read-only) let the view be
|
||||||
|
// used with standard algorithms without ever materializing the whole
|
||||||
|
// array into a nlohmann::json value
|
||||||
|
json_document measurements = json_document::parse("[3, 1, 4, 1, 5, 9, 2, 6]");
|
||||||
|
const auto values = measurements.root();
|
||||||
|
|
||||||
|
const int sum = std::accumulate(values.cbegin(), values.cend(), 0,
|
||||||
|
[](int total, const json_view & v)
|
||||||
|
{
|
||||||
|
return total + v.materialize().get<int>();
|
||||||
|
});
|
||||||
|
|
||||||
|
std::cout << sum << '\n';
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
31
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
#include <algorithm>
|
||||||
|
#include <iostream>
|
||||||
|
#include <nlohmann/json_view.hpp>
|
||||||
|
|
||||||
|
using json_document = nlohmann::json_document;
|
||||||
|
using json_view = nlohmann::json_view;
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
// check that every element of a (possibly large) batch is an object,
|
||||||
|
// before materializing any of them -- cbegin()/cend() (identical to
|
||||||
|
// begin()/end() here) work as the range for std::all_of like they would
|
||||||
|
// for any standard container
|
||||||
|
json_document batch = json_document::parse(R"([{"id": 1}, {"id": 2}, {"id": 3}])");
|
||||||
|
const auto records = batch.root();
|
||||||
|
|
||||||
|
const bool all_objects = std::all_of(records.cbegin(), records.cend(),
|
||||||
|
[](const json_view & v)
|
||||||
|
{
|
||||||
|
return v.is_object();
|
||||||
|
});
|
||||||
|
|
||||||
|
std::cout << std::boolalpha << all_objects << '\n';
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
true
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
#include <iostream>
|
||||||
|
#include <nlohmann/json_view.hpp>
|
||||||
|
|
||||||
|
using json_document = nlohmann::json_document;
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
// count how many of many incoming records carry an optional "retry_of"
|
||||||
|
// field -- contains() only walks the flat index, so scanning a large
|
||||||
|
// batch like this never builds a single nlohmann::json value
|
||||||
|
json_document batch = json_document::parse(R"(
|
||||||
|
[
|
||||||
|
{"id": 1},
|
||||||
|
{"id": 2, "retry_of": 1},
|
||||||
|
{"id": 3},
|
||||||
|
{"id": 4, "retry_of": 3}
|
||||||
|
]
|
||||||
|
)");
|
||||||
|
|
||||||
|
const auto records = batch.root();
|
||||||
|
std::size_t retries = 0;
|
||||||
|
for (std::size_t i = 0; i < records.size(); ++i)
|
||||||
|
{
|
||||||
|
if (records[i].contains("retry_of"))
|
||||||
|
{
|
||||||
|
++retries;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
std::cout << retries << " of " << records.size() << " records are retries\n";
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
2 of 4 records are retries
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
#include <iostream>
|
||||||
|
#include <nlohmann/json_view.hpp>
|
||||||
|
|
||||||
|
using json_document = nlohmann::json_document;
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
// validate that every transaction of a batch carries a mandatory
|
||||||
|
// "amount" field before materializing any of them into a nlohmann::json
|
||||||
|
// value -- count() returns 0 or 1 for an object
|
||||||
|
json_document batch = json_document::parse(R"(
|
||||||
|
[
|
||||||
|
{"id": 1, "amount": 9.99},
|
||||||
|
{"id": 2}
|
||||||
|
]
|
||||||
|
)");
|
||||||
|
|
||||||
|
const auto transactions = batch.root();
|
||||||
|
for (std::size_t i = 0; i < transactions.size(); ++i)
|
||||||
|
{
|
||||||
|
const auto transaction = transactions[i];
|
||||||
|
if (transaction.count("amount") == 0)
|
||||||
|
{
|
||||||
|
std::cout << "transaction " << i << " is missing \"amount\"\n";
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
std::cout << "transaction " << i << ": " << transaction["amount"].materialize().dump() << '\n';
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
transaction 0: 9.99
|
||||||
|
transaction 1 is missing "amount"
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
#include <iostream>
|
||||||
|
#include <nlohmann/json_view.hpp>
|
||||||
|
|
||||||
|
using json_document = nlohmann::json_document;
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
// scan a (possibly large) array of readings for the first one over a
|
||||||
|
// threshold; the loop stops at end() as soon as one is found, and only
|
||||||
|
// the matching reading is ever materialized
|
||||||
|
json_document readings = json_document::parse("[12, 18, 25, 31, 9]");
|
||||||
|
const auto values = readings.root();
|
||||||
|
|
||||||
|
auto it = values.begin();
|
||||||
|
for (; it != values.end(); ++it)
|
||||||
|
{
|
||||||
|
if (it->materialize().get<int>() > 20)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (it != values.end())
|
||||||
|
{
|
||||||
|
std::cout << "first reading over 20: " << it->materialize().dump() << '\n';
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
first reading over 20: 25
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
#include <iostream>
|
||||||
|
#include <nlohmann/json_view.hpp>
|
||||||
|
|
||||||
|
using json_document = nlohmann::json_document;
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
// a batch of incoming events; only some carry a "user_id" -- find()
|
||||||
|
// locates it without throwing for the events that turn out to not be
|
||||||
|
// objects, and without materializing an event that does not match
|
||||||
|
json_document batch = json_document::parse(R"(
|
||||||
|
[
|
||||||
|
{"type": "click", "user_id": 42},
|
||||||
|
{"type": "ping"},
|
||||||
|
{"type": "click", "user_id": 7}
|
||||||
|
]
|
||||||
|
)");
|
||||||
|
|
||||||
|
const auto events = batch.root();
|
||||||
|
for (std::size_t i = 0; i < events.size(); ++i)
|
||||||
|
{
|
||||||
|
const auto event = events[i];
|
||||||
|
const auto it = event.find("user_id");
|
||||||
|
if (it != event.end())
|
||||||
|
{
|
||||||
|
std::cout << "user " << it->materialize().dump() << '\n';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
user 42
|
||||||
|
user 7
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
#include <iostream>
|
||||||
|
#include <nlohmann/json_view.hpp>
|
||||||
|
|
||||||
|
using json_document = nlohmann::json_document;
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
// the build log of a running job; front() reads just the earliest event
|
||||||
|
// without materializing the (possibly long) rest of the log
|
||||||
|
json_document log = json_document::parse(R"(["queued", "started", "compiling", "linking", "done"])");
|
||||||
|
std::cout << log.root().front().materialize().dump() << '\n';
|
||||||
|
|
||||||
|
// an empty log -- front() throws instead of the undefined behavior
|
||||||
|
// basic_json::front() has for an empty array
|
||||||
|
json_document empty_log = json_document::parse("[]");
|
||||||
|
try
|
||||||
|
{
|
||||||
|
static_cast<void>(empty_log.root().front());
|
||||||
|
}
|
||||||
|
catch (const nlohmann::json::invalid_iterator& e)
|
||||||
|
{
|
||||||
|
std::cout << e.what() << '\n';
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
"queued"
|
||||||
|
[json.exception.invalid_iterator.214] cannot get value
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
#include <iostream>
|
||||||
|
#include <nlohmann/json_view.hpp>
|
||||||
|
|
||||||
|
using json_document = nlohmann::json_document;
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
// a settings object whose source text records every update to a key as
|
||||||
|
// a duplicate member. items() visits all of them, in document order, so
|
||||||
|
// the update history is visible; operator[] only ever sees the first
|
||||||
|
// one, and materialize() -- like basic_json::parse() -- keeps the last
|
||||||
|
json_document updates = json_document::parse(R"({"retries": 1, "timeout": 30, "retries": 5})");
|
||||||
|
const auto settings = updates.root();
|
||||||
|
|
||||||
|
for (const auto& item : settings.items())
|
||||||
|
{
|
||||||
|
std::cout << item.key() << '=' << item.value().materialize().dump() << '\n';
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cout << "first \"retries\" seen by operator[]: " << settings["retries"].materialize().dump() << '\n';
|
||||||
|
std::cout << "last \"retries\" kept by materialize(): " << settings.materialize()["retries"].dump() << '\n';
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
retries=1
|
||||||
|
timeout=30
|
||||||
|
retries=5
|
||||||
|
first "retries" seen by operator[]: 1
|
||||||
|
last "retries" kept by materialize(): 5
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
#include <iostream>
|
||||||
|
#include <nlohmann/json_view.hpp>
|
||||||
|
|
||||||
|
using json_document = nlohmann::json_document;
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
// two user records from a large API response; only the fields that are
|
||||||
|
// actually read are ever touched, and no nlohmann::json tree is built
|
||||||
|
// for the batch
|
||||||
|
json_document batch = json_document::parse(R"(
|
||||||
|
[
|
||||||
|
{"name": "Alice", "email": "alice@example.com", "tags": ["admin", "ops"]},
|
||||||
|
{"name": "Bob", "tags": []}
|
||||||
|
]
|
||||||
|
)");
|
||||||
|
|
||||||
|
const auto users = batch.root();
|
||||||
|
for (std::size_t i = 0; i < users.size(); ++i)
|
||||||
|
{
|
||||||
|
const auto user = users[i];
|
||||||
|
std::cout << user["name"].materialize().dump();
|
||||||
|
|
||||||
|
// operator[] on a missing object key gives a discarded view -- test
|
||||||
|
// it with a plain "if". The const overload of json::operator[]
|
||||||
|
// would instead be undefined behavior (guarded by an assertion) for
|
||||||
|
// a missing key
|
||||||
|
if (const auto email = user["email"])
|
||||||
|
{
|
||||||
|
std::cout << " <" << email.materialize().dump() << ">";
|
||||||
|
}
|
||||||
|
|
||||||
|
// the same holds for an array index past the end: a discarded view,
|
||||||
|
// not undefined behavior
|
||||||
|
if (const auto first_tag = user["tags"][0])
|
||||||
|
{
|
||||||
|
std::cout << " #" << first_tag.materialize().dump();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cout << '\n';
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
"Alice" <"alice@example.com"> #"admin"
|
||||||
|
"Bob"
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
#include <iostream>
|
||||||
|
#include <nlohmann/json_view.hpp>
|
||||||
|
|
||||||
|
using json_document = nlohmann::json_document;
|
||||||
|
using json_view = nlohmann::json_view;
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
// report why some parsed messages were rejected, using only
|
||||||
|
// type_name() -- no nlohmann::json value is built for the ones that
|
||||||
|
// are wrong
|
||||||
|
json_document good = json_document::parse(R"({"id": 1})");
|
||||||
|
json_document bad = json_document::parse("[1, 2, 3]");
|
||||||
|
json_document failed = json_document::parse("not json", /* allow_exceptions */ false);
|
||||||
|
|
||||||
|
for (const json_view v : { good.root(), bad.root(), failed.root() })
|
||||||
|
{
|
||||||
|
if (v.is_object())
|
||||||
|
{
|
||||||
|
std::cout << "ok\n";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::cout << "expected an object, got " << v.type_name() << '\n';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
ok
|
||||||
|
expected an object, got array
|
||||||
|
expected an object, got discarded
|
||||||
@@ -22,10 +22,15 @@ actually needed (for a string, only if it contains escape sequences, into one sh
|
|||||||
[`basic_json_view`](../api/basic_json_view/index.md) is a small, trivially copyable handle (two pointers) into that
|
[`basic_json_view`](../api/basic_json_view/index.md) is a small, trivially copyable handle (two pointers) into that
|
||||||
index. It gives you the read-only, type-inspection part of the `basic_json` interface --
|
index. It gives you the read-only, type-inspection part of the `basic_json` interface --
|
||||||
[`type()`](../api/basic_json_view/type.md) and the `is_*()` predicates,
|
[`type()`](../api/basic_json_view/type.md) and the `is_*()` predicates,
|
||||||
[`size()`](../api/basic_json_view/size.md)/[`empty()`](../api/basic_json_view/empty.md) -- without ever allocating a
|
[`size()`](../api/basic_json_view/size.md)/[`empty()`](../api/basic_json_view/empty.md) -- as well as element access
|
||||||
`basic_json` value. When you do need an actual `basic_json` value for a subtree,
|
([`operator[]`](../api/basic_json_view/operator%5B%5D.md), [`at`](../api/basic_json_view/at.md),
|
||||||
[`materialize()`](../api/basic_json_view/materialize.md) builds exactly the one
|
[`front`](../api/basic_json_view/front.md)/[`back`](../api/basic_json_view/back.md)), lookup
|
||||||
[`parse()`](../api/basic_json/parse.md) would have produced for it.
|
([`find`](../api/basic_json_view/find.md), [`contains`](../api/basic_json_view/contains.md),
|
||||||
|
[`count`](../api/basic_json_view/count.md)), and iteration
|
||||||
|
([`begin`](../api/basic_json_view/begin.md)/[`end`](../api/basic_json_view/end.md),
|
||||||
|
[`items`](../api/basic_json_view/items.md)) -- without ever allocating a `basic_json` value. When you do need an
|
||||||
|
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.
|
||||||
|
|
||||||
## How to use it
|
## How to use it
|
||||||
|
|
||||||
@@ -116,9 +121,26 @@ whenever any of the other conditions above was not met.
|
|||||||
[`JSON_DIAGNOSTIC_POSITIONS`](../api/macros/json_diagnostic_positions.md) enabled,
|
[`JSON_DIAGNOSTIC_POSITIONS`](../api/macros/json_diagnostic_positions.md) enabled,
|
||||||
[`materialize()`](../api/basic_json_view/materialize.md) does not set them: there is no lexer run during the
|
[`materialize()`](../api/basic_json_view/materialize.md) does not set them: there is no lexer run during the
|
||||||
replay to record them.
|
replay to record them.
|
||||||
- **Element access, iteration, `get<T>()`, JSON Pointer, `dump()`, and comparison are not (yet) provided** by
|
- **Objects iterate in document order.** [`begin()`](../api/basic_json_view/begin.md)/
|
||||||
`basic_json_view`. For now, [`materialize()`](../api/basic_json_view/materialize.md) is the way to get a value you
|
[`end()`](../api/basic_json_view/end.md) and [`items()`](../api/basic_json_view/items.md) visit an object's
|
||||||
can do those things with.
|
members in the order they appear in the source text. `basic_json`'s default `object_t` is a `std::map`, which
|
||||||
|
sorts by key, so iterating a [`materialize()`](../api/basic_json_view/materialize.md)d value can print members in
|
||||||
|
a different order than iterating the view they came from.
|
||||||
|
- **Duplicate keys are visible.** If an object in the source text repeats a key,
|
||||||
|
[`begin()`](../api/basic_json_view/begin.md)/[`end()`](../api/basic_json_view/end.md) and
|
||||||
|
[`items()`](../api/basic_json_view/items.md) visit *every* occurrence (and [`size()`](../api/basic_json_view/size.md)
|
||||||
|
counts all of them), while [`operator[]`](../api/basic_json_view/operator%5B%5D.md),
|
||||||
|
[`at`](../api/basic_json_view/at.md), [`find`](../api/basic_json_view/find.md),
|
||||||
|
[`contains`](../api/basic_json_view/contains.md), and [`count`](../api/basic_json_view/count.md) resolve to the
|
||||||
|
*first* occurrence, since a lookup can stop as soon as it finds a match. `basic_json::parse()` (and so
|
||||||
|
[`materialize()`](../api/basic_json_view/materialize.md)) instead keeps only the *last* value for a repeated key.
|
||||||
|
See the [Notes on duplicate keys](../api/basic_json_view/operator%5B%5D.md#notes) of `operator[]`.
|
||||||
|
- **No [`JSON_DIAGNOSTICS`](../api/macros/json_diagnostics.md) path.** Exceptions thrown by `basic_json_view`'s own
|
||||||
|
element access and lookup functions never carry the JSON Pointer path `JSON_DIAGNOSTICS` would otherwise add: the
|
||||||
|
view has no `basic_json` value to point at, so the exception is created without one, regardless of how
|
||||||
|
`BasicJsonType` was built.
|
||||||
|
- **`get<T>()`, JSON Pointer, `dump()`, and comparison are not (yet) provided** by `basic_json_view`. For now,
|
||||||
|
[`materialize()`](../api/basic_json_view/materialize.md) is the way to get a value you can do those things with.
|
||||||
|
|
||||||
## Choosing between `json`, `ordered_json`, the SAX interface, and `json_view`
|
## Choosing between `json`, `ordered_json`, the SAX interface, and `json_view`
|
||||||
|
|
||||||
|
|||||||
@@ -246,7 +246,17 @@ nav:
|
|||||||
- basic_json_view:
|
- basic_json_view:
|
||||||
- 'Overview': api/basic_json_view/index.md
|
- 'Overview': api/basic_json_view/index.md
|
||||||
- '(Constructor)': api/basic_json_view/basic_json_view.md
|
- '(Constructor)': api/basic_json_view/basic_json_view.md
|
||||||
|
- 'at': api/basic_json_view/at.md
|
||||||
|
- 'back': api/basic_json_view/back.md
|
||||||
|
- 'begin': api/basic_json_view/begin.md
|
||||||
|
- 'cbegin': api/basic_json_view/cbegin.md
|
||||||
|
- 'cend': api/basic_json_view/cend.md
|
||||||
|
- 'contains': api/basic_json_view/contains.md
|
||||||
|
- 'count': api/basic_json_view/count.md
|
||||||
- 'empty': api/basic_json_view/empty.md
|
- 'empty': api/basic_json_view/empty.md
|
||||||
|
- 'end': api/basic_json_view/end.md
|
||||||
|
- 'find': api/basic_json_view/find.md
|
||||||
|
- 'front': api/basic_json_view/front.md
|
||||||
- 'is_array': api/basic_json_view/is_array.md
|
- 'is_array': api/basic_json_view/is_array.md
|
||||||
- 'is_binary': api/basic_json_view/is_binary.md
|
- 'is_binary': api/basic_json_view/is_binary.md
|
||||||
- 'is_boolean': api/basic_json_view/is_boolean.md
|
- 'is_boolean': api/basic_json_view/is_boolean.md
|
||||||
@@ -260,11 +270,14 @@ nav:
|
|||||||
- 'is_primitive': api/basic_json_view/is_primitive.md
|
- 'is_primitive': api/basic_json_view/is_primitive.md
|
||||||
- 'is_string': api/basic_json_view/is_string.md
|
- 'is_string': api/basic_json_view/is_string.md
|
||||||
- 'is_structured': api/basic_json_view/is_structured.md
|
- 'is_structured': api/basic_json_view/is_structured.md
|
||||||
|
- 'items': api/basic_json_view/items.md
|
||||||
- 'materialize': api/basic_json_view/materialize.md
|
- 'materialize': api/basic_json_view/materialize.md
|
||||||
- 'operator bool': api/basic_json_view/operator_bool.md
|
- 'operator bool': api/basic_json_view/operator_bool.md
|
||||||
|
- 'operator[]': api/basic_json_view/operator[].md
|
||||||
- 'size': api/basic_json_view/size.md
|
- 'size': api/basic_json_view/size.md
|
||||||
- 'source_offset': api/basic_json_view/source_offset.md
|
- 'source_offset': api/basic_json_view/source_offset.md
|
||||||
- 'type': api/basic_json_view/type.md
|
- 'type': api/basic_json_view/type.md
|
||||||
|
- 'type_name': api/basic_json_view/type_name.md
|
||||||
- byte_container_with_subtype:
|
- byte_container_with_subtype:
|
||||||
- 'Overview': api/byte_container_with_subtype/index.md
|
- 'Overview': api/byte_container_with_subtype/index.md
|
||||||
- '(constructor)': api/byte_container_with_subtype/byte_container_with_subtype.md
|
- '(constructor)': api/byte_container_with_subtype/byte_container_with_subtype.md
|
||||||
|
|||||||
Reference in New Issue
Block a user