From 54455afa40909b496ade21d6e6cfea3737242544 Mon Sep 17 00:00:00 2001 From: Niels Lohmann Date: Mon, 28 Sep 2026 22:05:08 +0200 Subject: [PATCH] Document json_document and json_view - API pages for basic_json_document and basic_json_view, one per member, and for the four aliases, each with an example - features/json_view.md: the problem the view solves, ownership and lifetime, what matches basic_json::parse() and what differs, and when to choose json, ordered_json, SAX, or the view - the examples show why one would use the view, not only how: borrowed vs. owned input, reading a few fields and materializing one subtree, reusing a document across many messages - registered in the mkdocs navigation, llms.txt, the docset, the exceptions page (out_of_range.416), architecture.md, the integration page, and the README; the yyjson credit is added to the README and license.md Signed-off-by: Niels Lohmann --- README.md | 9 ++ docs/docset/docSet.sql | 39 +++++ docs/mkdocs/docs/api/basic_json/empty.md | 4 + docs/mkdocs/docs/api/basic_json/is_array.md | 4 + docs/mkdocs/docs/api/basic_json/is_binary.md | 4 + docs/mkdocs/docs/api/basic_json/is_boolean.md | 4 + .../docs/api/basic_json/is_discarded.md | 5 + docs/mkdocs/docs/api/basic_json/is_null.md | 4 + docs/mkdocs/docs/api/basic_json/is_number.md | 1 + .../docs/api/basic_json/is_number_float.md | 1 + .../docs/api/basic_json/is_number_integer.md | 1 + .../docs/api/basic_json/is_number_unsigned.md | 1 + docs/mkdocs/docs/api/basic_json/is_object.md | 4 + .../docs/api/basic_json/is_primitive.md | 1 + docs/mkdocs/docs/api/basic_json/is_string.md | 4 + .../docs/api/basic_json/is_structured.md | 1 + docs/mkdocs/docs/api/basic_json/size.md | 4 + docs/mkdocs/docs/api/basic_json/type.md | 4 + .../docs/api/basic_json_document/accept.md | 67 +++++++++ .../basic_json_document.md | 58 ++++++++ .../docs/api/basic_json_document/index.md | 55 +++++++ .../api/basic_json_document/is_discarded.md | 49 ++++++ .../api/basic_json_document/memory_usage.md | 50 +++++++ .../api/basic_json_document/node_count.md | 48 ++++++ .../api/basic_json_document/owns_source.md | 49 ++++++ .../docs/api/basic_json_document/parse.md | 139 ++++++++++++++++++ .../api/basic_json_document/parse_copy.md | 77 ++++++++++ .../docs/api/basic_json_document/read.md | 76 ++++++++++ .../docs/api/basic_json_document/root.md | 50 +++++++ .../api/basic_json_document/shrink_to_fit.md | 58 ++++++++ .../docs/api/basic_json_document/source.md | 48 ++++++ .../api/basic_json_view/basic_json_view.md | 51 +++++++ docs/mkdocs/docs/api/basic_json_view/empty.md | 61 ++++++++ docs/mkdocs/docs/api/basic_json_view/index.md | 82 +++++++++++ .../docs/api/basic_json_view/is_array.md | 46 ++++++ .../docs/api/basic_json_view/is_binary.md | 46 ++++++ .../docs/api/basic_json_view/is_boolean.md | 45 ++++++ .../docs/api/basic_json_view/is_discarded.md | 55 +++++++ .../docs/api/basic_json_view/is_null.md | 45 ++++++ .../docs/api/basic_json_view/is_number.md | 47 ++++++ .../api/basic_json_view/is_number_float.md | 51 +++++++ .../api/basic_json_view/is_number_integer.md | 51 +++++++ .../api/basic_json_view/is_number_unsigned.md | 45 ++++++ .../docs/api/basic_json_view/is_object.md | 46 ++++++ .../docs/api/basic_json_view/is_primitive.md | 46 ++++++ .../docs/api/basic_json_view/is_string.md | 45 ++++++ .../docs/api/basic_json_view/is_structured.md | 46 ++++++ .../docs/api/basic_json_view/materialize.md | 69 +++++++++ .../docs/api/basic_json_view/operator_bool.md | 46 ++++++ docs/mkdocs/docs/api/basic_json_view/size.md | 60 ++++++++ .../docs/api/basic_json_view/source_offset.md | 55 +++++++ docs/mkdocs/docs/api/basic_json_view/type.md | 53 +++++++ docs/mkdocs/docs/api/json_document.md | 35 +++++ docs/mkdocs/docs/api/json_view.md | 34 +++++ docs/mkdocs/docs/api/ordered_json_document.md | 38 +++++ docs/mkdocs/docs/api/ordered_json_view.md | 35 +++++ .../examples/basic_json_document__accept.cpp | 19 +++ .../basic_json_document__accept.output | 4 + ...sic_json_document__basic_json_document.cpp | 23 +++ ..._json_document__basic_json_document.output | 2 + .../basic_json_document__is_discarded.cpp | 19 +++ .../basic_json_document__is_discarded.output | 3 + .../basic_json_document__memory_usage.cpp | 28 ++++ .../basic_json_document__memory_usage.output | 2 + .../basic_json_document__node_count.cpp | 15 ++ .../basic_json_document__node_count.output | 2 + .../basic_json_document__owns_source.cpp | 24 +++ .../basic_json_document__owns_source.output | 3 + .../examples/basic_json_document__parse.cpp | 33 +++++ .../basic_json_document__parse.output | 3 + .../basic_json_document__parse_copy.cpp | 22 +++ .../basic_json_document__parse_copy.output | 2 + ...sic_json_document__parse_iterator_pair.cpp | 22 +++ ..._json_document__parse_iterator_pair.output | 2 + .../examples/basic_json_document__read.cpp | 31 ++++ .../examples/basic_json_document__read.output | 2 + .../examples/basic_json_document__root.cpp | 19 +++ .../examples/basic_json_document__root.output | 3 + .../basic_json_document__shrink_to_fit.cpp | 44 ++++++ .../basic_json_document__shrink_to_fit.output | 3 + .../examples/basic_json_document__source.cpp | 20 +++ .../basic_json_document__source.output | 3 + .../basic_json_view__basic_json_view.cpp | 17 +++ .../basic_json_view__basic_json_view.output | 2 + .../examples/basic_json_view__materialize.cpp | 33 +++++ .../basic_json_view__materialize.output | 3 + .../examples/basic_json_view__size_empty.cpp | 22 +++ .../basic_json_view__size_empty.output | 3 + .../basic_json_view__source_offset.cpp | 33 +++++ .../basic_json_view__source_offset.output | 4 + .../basic_json_view__type_predicates.cpp | 43 ++++++ .../basic_json_view__type_predicates.output | 12 ++ docs/mkdocs/docs/examples/json_document.cpp | 16 ++ .../mkdocs/docs/examples/json_document.output | 2 + docs/mkdocs/docs/examples/json_view.cpp | 14 ++ docs/mkdocs/docs/examples/json_view.output | 1 + .../docs/examples/json_view_ownership.cpp | 33 +++++ .../docs/examples/json_view_ownership.output | 4 + .../docs/examples/ordered_json_document.cpp | 13 ++ .../examples/ordered_json_document.output | 1 + .../docs/examples/ordered_json_view.cpp | 10 ++ .../docs/examples/ordered_json_view.output | 1 + docs/mkdocs/docs/features/index.md | 2 + docs/mkdocs/docs/features/json_view.md | 134 +++++++++++++++++ docs/mkdocs/docs/home/architecture.md | 9 +- docs/mkdocs/docs/home/exceptions.md | 17 +++ docs/mkdocs/docs/home/license.md | 2 + docs/mkdocs/docs/integration/index.md | 5 + docs/mkdocs/mkdocs.yml | 43 ++++++ 109 files changed, 2983 insertions(+), 1 deletion(-) create mode 100644 docs/mkdocs/docs/api/basic_json_document/accept.md create mode 100644 docs/mkdocs/docs/api/basic_json_document/basic_json_document.md create mode 100644 docs/mkdocs/docs/api/basic_json_document/index.md create mode 100644 docs/mkdocs/docs/api/basic_json_document/is_discarded.md create mode 100644 docs/mkdocs/docs/api/basic_json_document/memory_usage.md create mode 100644 docs/mkdocs/docs/api/basic_json_document/node_count.md create mode 100644 docs/mkdocs/docs/api/basic_json_document/owns_source.md create mode 100644 docs/mkdocs/docs/api/basic_json_document/parse.md create mode 100644 docs/mkdocs/docs/api/basic_json_document/parse_copy.md create mode 100644 docs/mkdocs/docs/api/basic_json_document/read.md create mode 100644 docs/mkdocs/docs/api/basic_json_document/root.md create mode 100644 docs/mkdocs/docs/api/basic_json_document/shrink_to_fit.md create mode 100644 docs/mkdocs/docs/api/basic_json_document/source.md create mode 100644 docs/mkdocs/docs/api/basic_json_view/basic_json_view.md create mode 100644 docs/mkdocs/docs/api/basic_json_view/empty.md create mode 100644 docs/mkdocs/docs/api/basic_json_view/index.md create mode 100644 docs/mkdocs/docs/api/basic_json_view/is_array.md create mode 100644 docs/mkdocs/docs/api/basic_json_view/is_binary.md create mode 100644 docs/mkdocs/docs/api/basic_json_view/is_boolean.md create mode 100644 docs/mkdocs/docs/api/basic_json_view/is_discarded.md create mode 100644 docs/mkdocs/docs/api/basic_json_view/is_null.md create mode 100644 docs/mkdocs/docs/api/basic_json_view/is_number.md create mode 100644 docs/mkdocs/docs/api/basic_json_view/is_number_float.md create mode 100644 docs/mkdocs/docs/api/basic_json_view/is_number_integer.md create mode 100644 docs/mkdocs/docs/api/basic_json_view/is_number_unsigned.md create mode 100644 docs/mkdocs/docs/api/basic_json_view/is_object.md create mode 100644 docs/mkdocs/docs/api/basic_json_view/is_primitive.md create mode 100644 docs/mkdocs/docs/api/basic_json_view/is_string.md create mode 100644 docs/mkdocs/docs/api/basic_json_view/is_structured.md create mode 100644 docs/mkdocs/docs/api/basic_json_view/materialize.md create mode 100644 docs/mkdocs/docs/api/basic_json_view/operator_bool.md create mode 100644 docs/mkdocs/docs/api/basic_json_view/size.md create mode 100644 docs/mkdocs/docs/api/basic_json_view/source_offset.md create mode 100644 docs/mkdocs/docs/api/basic_json_view/type.md create mode 100644 docs/mkdocs/docs/api/json_document.md create mode 100644 docs/mkdocs/docs/api/json_view.md create mode 100644 docs/mkdocs/docs/api/ordered_json_document.md create mode 100644 docs/mkdocs/docs/api/ordered_json_view.md create mode 100644 docs/mkdocs/docs/examples/basic_json_document__accept.cpp create mode 100644 docs/mkdocs/docs/examples/basic_json_document__accept.output create mode 100644 docs/mkdocs/docs/examples/basic_json_document__basic_json_document.cpp create mode 100644 docs/mkdocs/docs/examples/basic_json_document__basic_json_document.output create mode 100644 docs/mkdocs/docs/examples/basic_json_document__is_discarded.cpp create mode 100644 docs/mkdocs/docs/examples/basic_json_document__is_discarded.output create mode 100644 docs/mkdocs/docs/examples/basic_json_document__memory_usage.cpp create mode 100644 docs/mkdocs/docs/examples/basic_json_document__memory_usage.output create mode 100644 docs/mkdocs/docs/examples/basic_json_document__node_count.cpp create mode 100644 docs/mkdocs/docs/examples/basic_json_document__node_count.output create mode 100644 docs/mkdocs/docs/examples/basic_json_document__owns_source.cpp create mode 100644 docs/mkdocs/docs/examples/basic_json_document__owns_source.output create mode 100644 docs/mkdocs/docs/examples/basic_json_document__parse.cpp create mode 100644 docs/mkdocs/docs/examples/basic_json_document__parse.output create mode 100644 docs/mkdocs/docs/examples/basic_json_document__parse_copy.cpp create mode 100644 docs/mkdocs/docs/examples/basic_json_document__parse_copy.output create mode 100644 docs/mkdocs/docs/examples/basic_json_document__parse_iterator_pair.cpp create mode 100644 docs/mkdocs/docs/examples/basic_json_document__parse_iterator_pair.output create mode 100644 docs/mkdocs/docs/examples/basic_json_document__read.cpp create mode 100644 docs/mkdocs/docs/examples/basic_json_document__read.output create mode 100644 docs/mkdocs/docs/examples/basic_json_document__root.cpp create mode 100644 docs/mkdocs/docs/examples/basic_json_document__root.output create mode 100644 docs/mkdocs/docs/examples/basic_json_document__shrink_to_fit.cpp create mode 100644 docs/mkdocs/docs/examples/basic_json_document__shrink_to_fit.output create mode 100644 docs/mkdocs/docs/examples/basic_json_document__source.cpp create mode 100644 docs/mkdocs/docs/examples/basic_json_document__source.output create mode 100644 docs/mkdocs/docs/examples/basic_json_view__basic_json_view.cpp create mode 100644 docs/mkdocs/docs/examples/basic_json_view__basic_json_view.output create mode 100644 docs/mkdocs/docs/examples/basic_json_view__materialize.cpp create mode 100644 docs/mkdocs/docs/examples/basic_json_view__materialize.output create mode 100644 docs/mkdocs/docs/examples/basic_json_view__size_empty.cpp create mode 100644 docs/mkdocs/docs/examples/basic_json_view__size_empty.output create mode 100644 docs/mkdocs/docs/examples/basic_json_view__source_offset.cpp create mode 100644 docs/mkdocs/docs/examples/basic_json_view__source_offset.output create mode 100644 docs/mkdocs/docs/examples/basic_json_view__type_predicates.cpp create mode 100644 docs/mkdocs/docs/examples/basic_json_view__type_predicates.output create mode 100644 docs/mkdocs/docs/examples/json_document.cpp create mode 100644 docs/mkdocs/docs/examples/json_document.output create mode 100644 docs/mkdocs/docs/examples/json_view.cpp create mode 100644 docs/mkdocs/docs/examples/json_view.output create mode 100644 docs/mkdocs/docs/examples/json_view_ownership.cpp create mode 100644 docs/mkdocs/docs/examples/json_view_ownership.output create mode 100644 docs/mkdocs/docs/examples/ordered_json_document.cpp create mode 100644 docs/mkdocs/docs/examples/ordered_json_document.output create mode 100644 docs/mkdocs/docs/examples/ordered_json_view.cpp create mode 100644 docs/mkdocs/docs/examples/ordered_json_view.output create mode 100644 docs/mkdocs/docs/features/json_view.md diff --git a/README.md b/README.md index 9fd3f71fc..487e9ce55 100644 --- a/README.md +++ b/README.md @@ -1189,6 +1189,14 @@ binary.set_subtype(0x10); auto cbor = json::to_msgpack(j); // 0xD5 (fixext2), 0x10, 0xCA, 0xFE ``` +### Zero-copy views + +Header `` adds `json_document`/`json_view`, a read-only, non-owning way to look at a parsed +JSON text: parsing builds a flat index (16 bytes per value) instead of a tree, strings and numbers stay in the source +text, and `materialize()` builds a `json` value for a subtree only when you actually need one. See +[Zero-copy JSON views](https://json.nlohmann.me/features/json_view/) for the details, including which inputs are +borrowed and which are copied. + ## Customers The library is used in multiple projects, applications, operating systems, etc. The list below is not exhaustive, but the result of an internet search. If you know further customers of the library, please let me know, see [contact](#contact). @@ -1396,6 +1404,7 @@ THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR I - The class contains a copy of [Hedley](https://nemequ.github.io/hedley/) from Evan Nemerson which is licensed as [CC0-1.0](https://creativecommons.org/publicdomain/zero/1.0/). - The class contains parts of [Google Abseil](https://github.com/abseil/abseil-cpp) which is licensed under the [Apache 2.0 License](https://opensource.org/licenses/Apache-2.0). - The class contains an adapted version of the Eisel-Lemire algorithm and its table of powers of five from [fast_float](https://github.com/fastfloat/fast_float) by Daniel Lemire and contributors, which is available under the [MIT License](https://opensource.org/licenses/MIT) (used here), the Apache 2.0 License, and the Boost Software License. Copyright © 2021 The fast_float authors +- The view's parser (``) contains techniques and code adapted from [yyjson](https://github.com/ibireme/yyjson) by YaoYuan, which is licensed under the [MIT License](https://opensource.org/licenses/MIT) (see above): table-driven decoding of `\u` escapes and fixed-offset unrolled checks. REUSE Software diff --git a/docs/docset/docSet.sql b/docs/docset/docSet.sql index 3a97e405f..7a8184eae 100644 --- a/docs/docset/docSet.sql +++ b/docs/docset/docSet.sql @@ -128,7 +128,43 @@ INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::to_ubjson', 'Func INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::value', 'Method', 'api/basic_json/value/index.html'); INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::value_t', 'Enum', 'api/basic_json/value_t/index.html'); INSERT INTO searchIndex(name, type, path) VALUES ('basic_json::~basic_json', 'Method', 'api/basic_json/~basic_json/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_document', 'Class', 'api/basic_json_document/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_document::basic_json_document', 'Constructor', 'api/basic_json_document/basic_json_document/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_document::accept', 'Function', 'api/basic_json_document/accept/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_document::is_discarded', 'Method', 'api/basic_json_document/is_discarded/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_document::memory_usage', 'Method', 'api/basic_json_document/memory_usage/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_document::node_count', 'Method', 'api/basic_json_document/node_count/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_document::owns_source', 'Method', 'api/basic_json_document/owns_source/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_document::parse', 'Function', 'api/basic_json_document/parse/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_document::parse_copy', 'Function', 'api/basic_json_document/parse_copy/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_document::read', 'Method', 'api/basic_json_document/read/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_document::root', 'Method', 'api/basic_json_document/root/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_document::shrink_to_fit', 'Method', 'api/basic_json_document/shrink_to_fit/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::basic_json_view', 'Constructor', 'api/basic_json_view/basic_json_view/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::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_boolean', 'Method', 'api/basic_json_view/is_boolean/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_view::is_discarded', 'Method', 'api/basic_json_view/is_discarded/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_view::is_null', 'Method', 'api/basic_json_view/is_null/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_view::is_number', 'Method', 'api/basic_json_view/is_number/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_view::is_number_float', 'Method', 'api/basic_json_view/is_number_float/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_view::is_number_integer', 'Method', 'api/basic_json_view/is_number_integer/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_view::is_number_unsigned', 'Method', 'api/basic_json_view/is_number_unsigned/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('basic_json_view::is_object', 'Method', 'api/basic_json_view/is_object/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_structured', 'Method', 'api/basic_json_view/is_structured/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::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::type', 'Method', 'api/basic_json_view/type/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_view', 'Class', 'api/json_view/index.html'); INSERT INTO searchIndex(name, type, path) VALUES ('json_pointer', 'Class', 'api/json_pointer/index.html'); INSERT INTO searchIndex(name, type, path) VALUES ('json_pointer::back', 'Method', 'api/json_pointer/back/index.html'); INSERT INTO searchIndex(name, type, path) VALUES ('json_pointer::empty', 'Method', 'api/json_pointer/empty/index.html'); @@ -162,6 +198,8 @@ INSERT INTO searchIndex(name, type, path) VALUES ('operator""_json_pointer', 'Li INSERT INTO searchIndex(name, type, path) VALUES ('operator<<', 'Operator', 'api/operator_ltlt/index.html'); INSERT INTO searchIndex(name, type, path) VALUES ('operator>>', 'Operator', 'api/operator_gtgt/index.html'); INSERT INTO searchIndex(name, type, path) VALUES ('ordered_json', 'Class', 'api/ordered_json/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('ordered_json_document', 'Class', 'api/ordered_json_document/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('ordered_json_view', 'Class', 'api/ordered_json_view/index.html'); INSERT INTO searchIndex(name, type, path) VALUES ('ordered_map', 'Class', 'api/ordered_map/index.html'); INSERT INTO searchIndex(name, type, path) VALUES ('std::hash', 'Class', 'api/basic_json/std_hash/index.html'); INSERT INTO searchIndex(name, type, path) VALUES ('std::swap', 'Function', 'api/basic_json/std_swap/index.html'); @@ -191,6 +229,7 @@ INSERT INTO searchIndex(name, type, path) VALUES ('Iterators', 'Guide', 'feature INSERT INTO searchIndex(name, type, path) VALUES ('JSON Merge Patch', 'Guide', 'features/merge_patch/index.html'); INSERT INTO searchIndex(name, type, path) VALUES ('JSON Patch and Diff', 'Guide', 'features/json_patch/index.html'); INSERT INTO searchIndex(name, type, path) VALUES ('JSON Pointer', 'Guide', 'features/json_pointer/index.html'); +INSERT INTO searchIndex(name, type, path) VALUES ('Zero-copy JSON views', 'Guide', 'features/json_view/index.html'); INSERT INTO searchIndex(name, type, path) VALUES ('nlohmann Namespace', 'Guide', 'features/namespace/index.html'); INSERT INTO searchIndex(name, type, path) VALUES ('Types', 'Guide', 'features/types/index.html'); INSERT INTO searchIndex(name, type, path) VALUES ('Types: Number Handling', 'Guide', 'features/types/number_handling/index.html'); diff --git a/docs/mkdocs/docs/api/basic_json/empty.md b/docs/mkdocs/docs/api/basic_json/empty.md index 8d566738d..70421a149 100644 --- a/docs/mkdocs/docs/api/basic_json/empty.md +++ b/docs/mkdocs/docs/api/basic_json/empty.md @@ -60,6 +60,10 @@ itself is empty which is `#!cpp false` in the case of a string. --8<-- "examples/empty.output" ``` +## See also + +- [basic_json_view::empty](../basic_json_view/empty.md) - the same check on a zero-copy view + ## Version history - Added in version 1.0.0. diff --git a/docs/mkdocs/docs/api/basic_json/is_array.md b/docs/mkdocs/docs/api/basic_json/is_array.md index 64468c357..ca8e87494 100644 --- a/docs/mkdocs/docs/api/basic_json/is_array.md +++ b/docs/mkdocs/docs/api/basic_json/is_array.md @@ -34,6 +34,10 @@ Constant. --8<-- "examples/is_array.output" ``` +## See also + +- [basic_json_view::is_array](../basic_json_view/is_array.md) - the same check on a zero-copy view + ## Version history - Added in version 1.0.0. diff --git a/docs/mkdocs/docs/api/basic_json/is_binary.md b/docs/mkdocs/docs/api/basic_json/is_binary.md index 2a42e5edf..076c1c53d 100644 --- a/docs/mkdocs/docs/api/basic_json/is_binary.md +++ b/docs/mkdocs/docs/api/basic_json/is_binary.md @@ -34,6 +34,10 @@ Constant. --8<-- "examples/is_binary.output" ``` +## See also + +- [basic_json_view::is_binary](../basic_json_view/is_binary.md) - the same check on a zero-copy view + ## Version history - Added in version 3.8.0. diff --git a/docs/mkdocs/docs/api/basic_json/is_boolean.md b/docs/mkdocs/docs/api/basic_json/is_boolean.md index dc41d84bd..6fcefe528 100644 --- a/docs/mkdocs/docs/api/basic_json/is_boolean.md +++ b/docs/mkdocs/docs/api/basic_json/is_boolean.md @@ -34,6 +34,10 @@ Constant. --8<-- "examples/is_boolean.output" ``` +## See also + +- [basic_json_view::is_boolean](../basic_json_view/is_boolean.md) - the same check on a zero-copy view + ## Version history - Added in version 1.0.0. diff --git a/docs/mkdocs/docs/api/basic_json/is_discarded.md b/docs/mkdocs/docs/api/basic_json/is_discarded.md index 56fae2a49..51874ce6d 100644 --- a/docs/mkdocs/docs/api/basic_json/is_discarded.md +++ b/docs/mkdocs/docs/api/basic_json/is_discarded.md @@ -69,6 +69,11 @@ with `allow_exceptions` set to `#!cpp false`: a parse error then yields a discar --8<-- "examples/is_discarded.output" ``` +## See also + +- [basic_json_view::is_discarded](../basic_json_view/is_discarded.md) - the corresponding check on a zero-copy view, + which is `#!cpp true` if the view refers to no value + ## Version history - Added in version 1.0.0. diff --git a/docs/mkdocs/docs/api/basic_json/is_null.md b/docs/mkdocs/docs/api/basic_json/is_null.md index d080ad32f..f96d3a025 100644 --- a/docs/mkdocs/docs/api/basic_json/is_null.md +++ b/docs/mkdocs/docs/api/basic_json/is_null.md @@ -34,6 +34,10 @@ Constant. --8<-- "examples/is_null.output" ``` +## See also + +- [basic_json_view::is_null](../basic_json_view/is_null.md) - the same check on a zero-copy view + ## Version history - Added in version 1.0.0. diff --git a/docs/mkdocs/docs/api/basic_json/is_number.md b/docs/mkdocs/docs/api/basic_json/is_number.md index afb30bb0c..5db28d3e0 100644 --- a/docs/mkdocs/docs/api/basic_json/is_number.md +++ b/docs/mkdocs/docs/api/basic_json/is_number.md @@ -49,6 +49,7 @@ constexpr bool is_number() const noexcept - [is_number_integer()](is_number_integer.md) check if the value is an integer or unsigned integer number - [is_number_unsigned()](is_number_unsigned.md) check if the value is an unsigned integer number - [is_number_float()](is_number_float.md) check if the value is a floating-point number +- [basic_json_view::is_number](../basic_json_view/is_number.md) - the same check on a zero-copy view ## Version history diff --git a/docs/mkdocs/docs/api/basic_json/is_number_float.md b/docs/mkdocs/docs/api/basic_json/is_number_float.md index ad18858e3..c94825b41 100644 --- a/docs/mkdocs/docs/api/basic_json/is_number_float.md +++ b/docs/mkdocs/docs/api/basic_json/is_number_float.md @@ -40,6 +40,7 @@ Constant. - [is_number()](is_number.md) check if the value is a number - [is_number_integer()](is_number_integer.md) check if the value is an integer or unsigned integer number - [is_number_unsigned()](is_number_unsigned.md) check if the value is an unsigned integer number +- [basic_json_view::is_number_float](../basic_json_view/is_number_float.md) - the same check on a zero-copy view ## Version history diff --git a/docs/mkdocs/docs/api/basic_json/is_number_integer.md b/docs/mkdocs/docs/api/basic_json/is_number_integer.md index b8f971bd6..71e2aba20 100644 --- a/docs/mkdocs/docs/api/basic_json/is_number_integer.md +++ b/docs/mkdocs/docs/api/basic_json/is_number_integer.md @@ -40,6 +40,7 @@ Constant. - [is_number()](is_number.md) check if the value is a number - [is_number_unsigned()](is_number_unsigned.md) check if the value is an unsigned integer number - [is_number_float()](is_number_float.md) check if the value is a floating-point number +- [basic_json_view::is_number_integer](../basic_json_view/is_number_integer.md) - the same check on a zero-copy view ## Version history diff --git a/docs/mkdocs/docs/api/basic_json/is_number_unsigned.md b/docs/mkdocs/docs/api/basic_json/is_number_unsigned.md index 50083164e..3e0720ef1 100644 --- a/docs/mkdocs/docs/api/basic_json/is_number_unsigned.md +++ b/docs/mkdocs/docs/api/basic_json/is_number_unsigned.md @@ -40,6 +40,7 @@ Constant. - [is_number()](is_number.md) check if the value is a number - [is_number_integer()](is_number_integer.md) check if the value is an integer or unsigned integer number - [is_number_float()](is_number_float.md) check if the value is a floating-point number +- [basic_json_view::is_number_unsigned](../basic_json_view/is_number_unsigned.md) - the same check on a zero-copy view ## Version history diff --git a/docs/mkdocs/docs/api/basic_json/is_object.md b/docs/mkdocs/docs/api/basic_json/is_object.md index 04457013b..502faa780 100644 --- a/docs/mkdocs/docs/api/basic_json/is_object.md +++ b/docs/mkdocs/docs/api/basic_json/is_object.md @@ -34,6 +34,10 @@ Constant. --8<-- "examples/is_object.output" ``` +## See also + +- [basic_json_view::is_object](../basic_json_view/is_object.md) - the same check on a zero-copy view + ## Version history - Added in version 1.0.0. diff --git a/docs/mkdocs/docs/api/basic_json/is_primitive.md b/docs/mkdocs/docs/api/basic_json/is_primitive.md index 076c2bfef..70836ecdd 100644 --- a/docs/mkdocs/docs/api/basic_json/is_primitive.md +++ b/docs/mkdocs/docs/api/basic_json/is_primitive.md @@ -62,6 +62,7 @@ This library extends primitive types to binary types, because binary types are r - [is_boolean()](is_boolean.md) returns whether the JSON value is a boolean - [is_number()](is_number.md) returns whether the JSON value is a number - [is_binary()](is_binary.md) returns whether the JSON value is a binary array +- [basic_json_view::is_primitive](../basic_json_view/is_primitive.md) - the same check on a zero-copy view ## Version history diff --git a/docs/mkdocs/docs/api/basic_json/is_string.md b/docs/mkdocs/docs/api/basic_json/is_string.md index b82c92465..41ecaa919 100644 --- a/docs/mkdocs/docs/api/basic_json/is_string.md +++ b/docs/mkdocs/docs/api/basic_json/is_string.md @@ -34,6 +34,10 @@ Constant. --8<-- "examples/is_string.output" ``` +## See also + +- [basic_json_view::is_string](../basic_json_view/is_string.md) - the same check on a zero-copy view + ## Version history - Added in version 1.0.0. diff --git a/docs/mkdocs/docs/api/basic_json/is_structured.md b/docs/mkdocs/docs/api/basic_json/is_structured.md index f2d9e79ff..a67f2778b 100644 --- a/docs/mkdocs/docs/api/basic_json/is_structured.md +++ b/docs/mkdocs/docs/api/basic_json/is_structured.md @@ -57,6 +57,7 @@ Note that though strings are containers in C++, they are treated as primitive va - [is_primitive()](is_primitive.md) returns whether JSON value is primitive - [is_array()](is_array.md) returns whether the value is an array - [is_object()](is_object.md) returns whether the value is an object +- [basic_json_view::is_structured](../basic_json_view/is_structured.md) - the same check on a zero-copy view ## Version history diff --git a/docs/mkdocs/docs/api/basic_json/size.md b/docs/mkdocs/docs/api/basic_json/size.md index 4ff582db2..8169fd020 100644 --- a/docs/mkdocs/docs/api/basic_json/size.md +++ b/docs/mkdocs/docs/api/basic_json/size.md @@ -51,6 +51,10 @@ JSON value which is `1` in the case of a string. --8<-- "examples/size.output" ``` +## See also + +- [basic_json_view::size](../basic_json_view/size.md) - the same function on a zero-copy view + ## Version history - Added in version 1.0.0. diff --git a/docs/mkdocs/docs/api/basic_json/type.md b/docs/mkdocs/docs/api/basic_json/type.md index deedd6b69..dd16a1478 100644 --- a/docs/mkdocs/docs/api/basic_json/type.md +++ b/docs/mkdocs/docs/api/basic_json/type.md @@ -47,6 +47,10 @@ Constant. --8<-- "examples/type.output" ``` +## See also + +- [basic_json_view::type](../basic_json_view/type.md) - the same function on a zero-copy view + ## Version history - Added in version 1.0.0. diff --git a/docs/mkdocs/docs/api/basic_json_document/accept.md b/docs/mkdocs/docs/api/basic_json_document/accept.md new file mode 100644 index 000000000..5aa1fc93d --- /dev/null +++ b/docs/mkdocs/docs/api/basic_json_document/accept.md @@ -0,0 +1,67 @@ +# nlohmann::basic_json_document::accept + +```cpp +template +static bool accept(InputType&& input, + const bool ignore_comments = false, + const bool ignore_trailing_commas = false); +``` + +Checks whether the input is valid JSON, accepting and rejecting exactly what +[`BasicJsonType::accept()`](../basic_json/accept.md) does, with the same options. Unlike [`parse()`](parse.md), this +function never throws an exception for invalid input, and the returned `#!cpp bool` is the only result -- no document +is returned. + +## Template parameters + +`InputType` +: A compatible input; see [`parse`](parse.md#template-parameters). + +## Parameters + +`input` (in) +: Input to check. + +`ignore_comments` (in) +: whether comments should be ignored and treated like whitespace (`#!cpp true`) or yield a parse error + (`#!cpp false`); (optional, `#!cpp false` by default) + +`ignore_trailing_commas` (in) +: whether trailing commas in arrays or objects should be ignored and treated like whitespace (`#!cpp true`) or + yield a parse error (`#!cpp false`); (optional, `#!cpp false` by default) + +## Return value + +Whether the input is valid JSON. + +## Exception safety + +Strong guarantee: this function itself never throws for an invalid input; it can only throw what allocating the +input's own copy (for inputs that are always read into a buffer) throws. + +## Complexity + +Linear in the length of the input. + +## Examples + +??? example + + ```cpp + --8<-- "examples/basic_json_document__accept.cpp" + ``` + + Output: + + ```json + --8<-- "examples/basic_json_document__accept.output" + ``` + +## See also + +- [parse](parse.md) - deserialize from a compatible input +- [`BasicJsonType::accept`](../basic_json/accept.md) - the corresponding function of `basic_json` + +## Version history + +- Added in version 3.13.0. diff --git a/docs/mkdocs/docs/api/basic_json_document/basic_json_document.md b/docs/mkdocs/docs/api/basic_json_document/basic_json_document.md new file mode 100644 index 000000000..b877e8895 --- /dev/null +++ b/docs/mkdocs/docs/api/basic_json_document/basic_json_document.md @@ -0,0 +1,58 @@ +# nlohmann::basic_json_document::basic_json_document + +```cpp +// (1) +basic_json_document() = default; + +// (2) +basic_json_document(basic_json_document&& other) noexcept = default; + +// (3) +basic_json_document(const basic_json_document&) = delete; +``` + +1. Creates an empty (discarded) document: [`root()`](root.md) returns a discarded view, and + [`is_discarded()`](is_discarded.md) is `#!cpp true`. +2. Move constructor. Takes over `other`'s index and, if owned, its text; `other` is left as an empty document. Views + taken from `other` before the move remain valid, because the index is heap-allocated independently of the + `basic_json_document` object. +3. `basic_json_document` is move-only. Copying is disabled because it would either duplicate a potentially large index + and text, or leave two documents claiming to borrow the same buffer. + +## Parameters + +`other` (in) +: another document to move the index and text from + +## Exception safety + +No-throw guarantee: the default and move constructors never throw exceptions. + +## Complexity + +Constant, for the default and move constructors. + +## Examples + +??? example + + The example below shows the default constructor and demonstrates that `basic_json_document` is move-only. + + ```cpp + --8<-- "examples/basic_json_document__basic_json_document.cpp" + ``` + + Output: + + ```json + --8<-- "examples/basic_json_document__basic_json_document.output" + ``` + +## See also + +- [parse](parse.md) - deserialize from a compatible input +- [is_discarded](is_discarded.md) - return whether the last parse failed + +## Version history + +- Added in version 3.13.0. diff --git a/docs/mkdocs/docs/api/basic_json_document/index.md b/docs/mkdocs/docs/api/basic_json_document/index.md new file mode 100644 index 000000000..d3987303a --- /dev/null +++ b/docs/mkdocs/docs/api/basic_json_document/index.md @@ -0,0 +1,55 @@ +# nlohmann::basic_json_document + +Defined in header `` + +```cpp +template +class basic_json_document; +``` + +A parsed JSON text, held as a flat index of its values (16 bytes per value) instead of a tree of `BasicJsonType` +values. Strings and numbers stay in the source text; only strings that contain escapes are decoded, into one buffer +owned by the document. [`basic_json_view`](../basic_json_view/index.md) is a read-only handle to one value of a +`basic_json_document`; [`materialize()`](../basic_json_view/materialize.md) turns a subtree back into the +`BasicJsonType` value that [`BasicJsonType::parse()`](../basic_json/parse.md) would have produced for it. + +A document may **borrow** the text it was parsed from (the caller's buffer must then outlive the document) or **own** +it (a copy, or an rvalue `#!cpp std::string` that was moved in); see [`owns_source`](owns_source.md). `basic_json_document` +is move-only: copying a document would either duplicate a potentially large index and text, or leave two documents +claiming to borrow the same buffer, so it is disabled. + +## Template parameters + +`BasicJsonType` +: a specialization of [`basic_json`](../basic_json/index.md), for instance [`json`](../json.md) or + [`ordered_json`](../ordered_json.md). Only 64-bit `number_integer_t`/`number_unsigned_t` types are supported; this + is checked with a `static_assert`. + +## Specializations + +- [**json_document**](../json_document.md) - documents of the default specialization [`json`](../json.md) +- [**ordered_json_document**](../ordered_json_document.md) - documents of [`ordered_json`](../ordered_json.md) + +## Member types + +- **view_type** - the type of view returned by [`root()`](root.md) (`#!cpp basic_json_view`) +- **value_t** - the JSON type enumeration, see [`basic_json::value_t`](../basic_json/value_t.md) + +## Member functions + +- [(constructor)](basic_json_document.md) +- [**parse**](parse.md) (_static_) - deserialize from a compatible input, borrowing or owning it as appropriate +- [**parse_copy**](parse_copy.md) (_static_) - deserialize a copy of a compatible input +- [**accept**](accept.md) (_static_) - check whether the input is valid JSON +- [**read**](read.md) - (re-)parse into this document, reusing its memory +- [**root**](root.md) - the view of the root value +- [**is_discarded**](is_discarded.md) - return whether the last parse failed +- [**source**](source.md) - the parsed text +- [**owns_source**](owns_source.md) - return whether the document holds its own copy of the text +- [**node_count**](node_count.md) - the number of index entries (values plus object keys) +- [**memory_usage**](memory_usage.md) - the number of bytes held by the document +- [**shrink_to_fit**](shrink_to_fit.md) - release unused index capacity + +## Version history + +- Added in version 3.13.0. diff --git a/docs/mkdocs/docs/api/basic_json_document/is_discarded.md b/docs/mkdocs/docs/api/basic_json_document/is_discarded.md new file mode 100644 index 000000000..3c062dddd --- /dev/null +++ b/docs/mkdocs/docs/api/basic_json_document/is_discarded.md @@ -0,0 +1,49 @@ +# nlohmann::basic_json_document::is_discarded + +```cpp +bool is_discarded() const noexcept; +``` + +Returns whether the document holds no value, either because it was default-constructed or because the last call to +[`parse()`](parse.md), [`parse_copy()`](parse_copy.md), or [`read()`](read.md) failed with `allow_exceptions` set to +`#!cpp false`. + +## Return value + +`#!cpp true` if the document is discarded, `#!cpp false` otherwise. + +## Exception safety + +No-throw guarantee: this function never throws exceptions. + +## Complexity + +Constant. + +## Notes + +When the document is discarded, [`root()`](root.md) returns a discarded view (its +[`is_discarded()`](../basic_json_view/is_discarded.md) is also `#!cpp true`). + +## Examples + +??? example + + ```cpp + --8<-- "examples/basic_json_document__is_discarded.cpp" + ``` + + Output: + + ```json + --8<-- "examples/basic_json_document__is_discarded.output" + ``` + +## See also + +- [parse](parse.md) - deserialize from a compatible input +- [is_discarded (basic_json_view)](../basic_json_view/is_discarded.md) - return whether a view is invalid + +## Version history + +- Added in version 3.13.0. diff --git a/docs/mkdocs/docs/api/basic_json_document/memory_usage.md b/docs/mkdocs/docs/api/basic_json_document/memory_usage.md new file mode 100644 index 000000000..5ad25911b --- /dev/null +++ b/docs/mkdocs/docs/api/basic_json_document/memory_usage.md @@ -0,0 +1,50 @@ +# nlohmann::basic_json_document::memory_usage + +```cpp +std::size_t memory_usage() const noexcept; +``` + +Returns the number of bytes held by the document: the node index, the decoded-string buffer (for strings that +contain escapes), and, for an owned document, its copy of the source text. + +## Return value + +The number of bytes the document holds, `0` for a [discarded](is_discarded.md) document. + +## Exception safety + +No-throw guarantee: this function never throws exceptions. + +## Complexity + +Constant. + +## Notes + +The exact value depends on the platform, the allocator, and the library's own layout, and may change between +versions; do not rely on it being a specific number, and do not compare it across different builds or platforms. +Compare it for the same document over time, or between documents built with the same binary, instead -- for instance +to observe the effect of [`shrink_to_fit()`](shrink_to_fit.md). + +## Examples + +??? example + + ```cpp + --8<-- "examples/basic_json_document__memory_usage.cpp" + ``` + + Output: + + ```json + --8<-- "examples/basic_json_document__memory_usage.output" + ``` + +## See also + +- [node_count](node_count.md) - the number of index entries +- [shrink_to_fit](shrink_to_fit.md) - release unused index capacity + +## Version history + +- Added in version 3.13.0. diff --git a/docs/mkdocs/docs/api/basic_json_document/node_count.md b/docs/mkdocs/docs/api/basic_json_document/node_count.md new file mode 100644 index 000000000..5a5c5b4d0 --- /dev/null +++ b/docs/mkdocs/docs/api/basic_json_document/node_count.md @@ -0,0 +1,48 @@ +# nlohmann::basic_json_document::node_count + +```cpp +std::size_t node_count() const noexcept; +``` + +Returns the number of entries in the document's flat index. + +## Return value + +The number of index entries: one per value (of any type, at any nesting depth) plus one per object key. `0` for a +[discarded](is_discarded.md) document. + +## Exception safety + +No-throw guarantee: this function never throws exceptions. + +## Complexity + +Constant. + +## Notes + +Each index entry is 16 bytes, so `#!cpp node_count() * 16` is the size of the index itself (part, but not all, of +[`memory_usage()`](memory_usage.md), which also counts decoded strings and, for an owned document, the text). + +## Examples + +??? example + + ```cpp + --8<-- "examples/basic_json_document__node_count.cpp" + ``` + + Output: + + ```json + --8<-- "examples/basic_json_document__node_count.output" + ``` + +## See also + +- [memory_usage](memory_usage.md) - the number of bytes held by the document +- [shrink_to_fit](shrink_to_fit.md) - release unused index capacity + +## Version history + +- Added in version 3.13.0. diff --git a/docs/mkdocs/docs/api/basic_json_document/owns_source.md b/docs/mkdocs/docs/api/basic_json_document/owns_source.md new file mode 100644 index 000000000..ab1fdb45e --- /dev/null +++ b/docs/mkdocs/docs/api/basic_json_document/owns_source.md @@ -0,0 +1,49 @@ +# nlohmann::basic_json_document::owns_source + +```cpp +bool owns_source() const noexcept; +``` + +Returns whether the document holds its own copy of the parsed text, as opposed to borrowing the caller's buffer. + +## Return value + +`#!cpp true` if the document owns the text returned by [`source()`](source.md), `#!cpp false` if it borrows it (or if +the document is [discarded](is_discarded.md)). + +## Exception safety + +No-throw guarantee: this function never throws exceptions. + +## Complexity + +Constant. + +## Notes + +See the ownership table on [`parse`](parse.md#notes) for which inputs are borrowed and which are owned. A borrowed +document (`#!cpp owns_source() == false`) is only valid while the buffer it was parsed from is still alive. + +## Examples + +??? example + + ```cpp + --8<-- "examples/basic_json_document__owns_source.cpp" + ``` + + Output: + + ```json + --8<-- "examples/basic_json_document__owns_source.output" + ``` + +## See also + +- [parse](parse.md) - deserialize from a compatible input +- [parse_copy](parse_copy.md) - deserialize a copy of a compatible input, always owned +- [source](source.md) - the parsed text + +## Version history + +- Added in version 3.13.0. diff --git a/docs/mkdocs/docs/api/basic_json_document/parse.md b/docs/mkdocs/docs/api/basic_json_document/parse.md new file mode 100644 index 000000000..a3c44f4e0 --- /dev/null +++ b/docs/mkdocs/docs/api/basic_json_document/parse.md @@ -0,0 +1,139 @@ +# nlohmann::basic_json_document::parse + +```cpp +// (1) +template +static basic_json_document parse(InputType&& input, + const bool allow_exceptions = true, + const bool ignore_comments = false, + const bool ignore_trailing_commas = false); + +// (2) +template +static basic_json_document parse(IteratorType first, IteratorType last, + const bool allow_exceptions = true, + const bool ignore_comments = false, + const bool ignore_trailing_commas = false); +``` + +1. Deserialize from a compatible input, borrowing or owning it depending on its value category and type (see Notes). +2. Deserialize from a pair of input iterators. + +Both overloads accept exactly what [`BasicJsonType::parse()`](../basic_json/parse.md) accepts, with the same +`ignore_comments`/`ignore_trailing_commas` options, but build a [`basic_json_document`](index.md) (a flat index into +the input) instead of a tree of `BasicJsonType` values. + +## Template parameters + +`InputType` +: A compatible input, for instance: + + - a `#!cpp std::string`, `#!cpp std::string_view`, or a C-style array of characters + - a pointer to a null-terminated string of single byte characters + - a container for which `#!cpp obj.data()` and `#!cpp obj.size()` give contiguous single-byte access, e.g. + `#!cpp std::vector` or `#!cpp std::vector` + - an `#!cpp std::istream` object, or anything else [`BasicJsonType::parse()`](../basic_json/parse.md) accepts + +`IteratorType` +: a compatible iterator type, for instance a pair of pointers such as `ptr` and `ptr + len`, or a pair of + `#!cpp std::string::iterator` + +## Parameters + +`input` (in) +: Input to parse from. + +`allow_exceptions` (in) +: whether to throw exceptions in case of a parse error (optional, `#!cpp true` by default) + +`ignore_comments` (in) +: whether comments should be ignored and treated like whitespace (`#!cpp true`) or yield a parse error + (`#!cpp false`); (optional, `#!cpp false` by default) + +`ignore_trailing_commas` (in) +: whether trailing commas in arrays or objects should be ignored and treated like whitespace (`#!cpp true`) or + yield a parse error (`#!cpp false`); (optional, `#!cpp false` by default) + +`first` (in) +: iterator to the start of a character range + +`last` (in) +: iterator to the end of a character range + +## Return value + +The parsed document. If `allow_exceptions` is `#!cpp false` and the input is not valid JSON, the returned document is +discarded; see [`is_discarded`](is_discarded.md). + +## Exceptions + +Throws the same exception [`BasicJsonType::parse()`](../basic_json/parse.md) throws for the same input and options -- +the same exception id, message, and position -- because on a failing input the library's own parser is run on the +same bytes to produce the diagnostic. Additionally throws +[`out_of_range.416`](../../home/exceptions.md#jsonexceptionout_of_range416) if the input is 4 GiB or larger, a size +[`BasicJsonType::parse()`](../basic_json/parse.md) does not reject. + +## Complexity + +Linear in the length of the input. + +## Notes + +**Ownership.** Whether the document borrows `input` or owns a copy of it depends on its value category and type: + +| `input` | ownership | +|--------------------------------------------------------------------------------------|--------------------------------------------------------------| +| lvalue byte container (`std::string`, `std::vector`, ...), `std::string_view`, C string, character array | **borrowed** -- `input` must outlive the document | +| rvalue `#!cpp std::string` | **owned**, moved in without a copy | +| rvalue byte container other than `#!cpp std::string` | **owned**, copied | +| stream, wide string, or anything else read through the general input adapter | **owned**, read into a buffer (a stream is read to its end) | + +For overload (2), a pair of pointers to single-byte integers (e.g. `#!cpp const char*`, `#!cpp std::uint8_t*`) is +borrowed. From C++20 on, so is any other contiguous iterator over single bytes, such as +`#!cpp std::vector::iterator` or `#!cpp std::string::const_iterator`. Before C++20 these iterators cannot be +told apart from other class-type iterators, so their range is read into an owned buffer, as is any non-contiguous +range (e.g. of a `#!cpp std::list`). + +See [`owns_source`](owns_source.md) to check which happened after a call, and the +[feature page](../../features/json_view.md) for the reasoning. + +**Numbers.** As for [`BasicJsonType::parse()`](../basic_json/parse.md), an integer literal too large for the 64-bit +integer type becomes a floating-point value. + +## Examples + +??? example "Example: (1) borrowed vs. owned input, and errors identical to `BasicJsonType::parse()`" + + ```cpp + --8<-- "examples/basic_json_document__parse.cpp" + ``` + + Output: + + ```json + --8<-- "examples/basic_json_document__parse.output" + ``` + +??? example "Example: (2) parse an iterator range (no NUL terminator required)" + + ```cpp + --8<-- "examples/basic_json_document__parse_iterator_pair.cpp" + ``` + + Output: + + ```json + --8<-- "examples/basic_json_document__parse_iterator_pair.output" + ``` + +## See also + +- [parse_copy](parse_copy.md) - deserialize a copy of a compatible input +- [accept](accept.md) - check whether the input is valid JSON +- [read](read.md) - (re-)parse into this document, reusing its memory +- [owns_source](owns_source.md) - return whether the document holds its own copy of the text +- [`BasicJsonType::parse`](../basic_json/parse.md) - the corresponding function of `basic_json` + +## Version history + +- Added in version 3.13.0. diff --git a/docs/mkdocs/docs/api/basic_json_document/parse_copy.md b/docs/mkdocs/docs/api/basic_json_document/parse_copy.md new file mode 100644 index 000000000..ed4714d22 --- /dev/null +++ b/docs/mkdocs/docs/api/basic_json_document/parse_copy.md @@ -0,0 +1,77 @@ +# nlohmann::basic_json_document::parse_copy + +```cpp +template +static basic_json_document parse_copy(InputType&& input, + const bool allow_exceptions = true, + const bool ignore_comments = false, + const bool ignore_trailing_commas = false); +``` + +Deserialize from a compatible input, always taking the document's own copy of it, regardless of the value category or +type of `input`. Unlike [`parse()`](parse.md), the returned document never depends on `input` staying alive. + +## Template parameters + +`InputType` +: A compatible input; see [`parse`](parse.md#template-parameters). + +## Parameters + +`input` (in) +: Input to parse from. + +`allow_exceptions` (in) +: whether to throw exceptions in case of a parse error (optional, `#!cpp true` by default) + +`ignore_comments` (in) +: whether comments should be ignored and treated like whitespace (`#!cpp true`) or yield a parse error + (`#!cpp false`); (optional, `#!cpp false` by default) + +`ignore_trailing_commas` (in) +: whether trailing commas in arrays or objects should be ignored and treated like whitespace (`#!cpp true`) or + yield a parse error (`#!cpp false`); (optional, `#!cpp false` by default) + +## Return value + +The parsed document, with [`owns_source()`](owns_source.md) `#!cpp true`. If `allow_exceptions` is `#!cpp false` and +the input is not valid JSON, the returned document is discarded; see [`is_discarded`](is_discarded.md). + +## Exceptions + +Same as [`parse`](parse.md#exceptions). + +## Complexity + +Linear in the length of the input. + +## Notes + +`parse_copy()` accepts and rejects exactly what [`parse()`](parse.md) does, and classifies numbers the same way; it +only differs in that the input is always copied rather than sometimes borrowed. Prefer [`parse()`](parse.md) when the +input's lifetime already covers the document's, since it avoids the copy for borrowed inputs. + +## Examples + +??? example + + The example below returns a document from a function whose local buffer would otherwise not outlive it. + + ```cpp + --8<-- "examples/basic_json_document__parse_copy.cpp" + ``` + + Output: + + ```json + --8<-- "examples/basic_json_document__parse_copy.output" + ``` + +## See also + +- [parse](parse.md) - deserialize from a compatible input, borrowing it where possible +- [owns_source](owns_source.md) - return whether the document holds its own copy of the text + +## Version history + +- Added in version 3.13.0. diff --git a/docs/mkdocs/docs/api/basic_json_document/read.md b/docs/mkdocs/docs/api/basic_json_document/read.md new file mode 100644 index 000000000..2267e46bd --- /dev/null +++ b/docs/mkdocs/docs/api/basic_json_document/read.md @@ -0,0 +1,76 @@ +# nlohmann::basic_json_document::read + +```cpp +template +void read(InputType&& input, + const bool allow_exceptions = true, + const bool ignore_comments = false, + const bool ignore_trailing_commas = false); +``` + +(Re-)parses `input` into `#!cpp *this`, discarding the document's previous value and reusing its memory (the node +index, the decoded-string buffer, and, if applicable, the owned copy of the text) rather than allocating a fresh +document. [`parse()`](parse.md) is implemented in terms of this function, applied to a default-constructed document. + +## Template parameters + +`InputType` +: A compatible input; see [`parse`](parse.md#template-parameters). + +## Parameters + +`input` (in) +: Input to parse from. + +`allow_exceptions` (in) +: whether to throw exceptions in case of a parse error (optional, `#!cpp true` by default) + +`ignore_comments` (in) +: whether comments should be ignored and treated like whitespace (`#!cpp true`) or yield a parse error + (`#!cpp false`); (optional, `#!cpp false` by default) + +`ignore_trailing_commas` (in) +: whether trailing commas in arrays or objects should be ignored and treated like whitespace (`#!cpp true`) or + yield a parse error (`#!cpp false`); (optional, `#!cpp false` by default) + +## Exceptions + +Same as [`parse`](parse.md#exceptions). + +## Complexity + +Linear in the length of the input. + +## Notes + +Every view taken from `#!cpp *this` before the call -- including the previous [`root()`](root.md) -- is invalidated, +whether or not the new parse succeeds; take fresh views from [`root()`](root.md) afterward. + +`input` is borrowed or owned by the same rules as [`parse()`](parse.md#notes); a document can borrow on one call and +own on the next, since ownership is decided freshly each time. + +## Examples + +??? example + + The example below parses a sequence of messages into the same document, reusing its memory instead of allocating + a new document for each one. + + ```cpp + --8<-- "examples/basic_json_document__read.cpp" + ``` + + Output: + + ```json + --8<-- "examples/basic_json_document__read.output" + ``` + +## See also + +- [parse](parse.md) - deserialize from a compatible input +- [root](root.md) - the view of the root value + +## Version history + +- Added in version 3.13.0. diff --git a/docs/mkdocs/docs/api/basic_json_document/root.md b/docs/mkdocs/docs/api/basic_json_document/root.md new file mode 100644 index 000000000..85682dbcd --- /dev/null +++ b/docs/mkdocs/docs/api/basic_json_document/root.md @@ -0,0 +1,50 @@ +# nlohmann::basic_json_document::root + +```cpp +view_type root() const noexcept; +``` + +Returns a view of the root value of the document. + +## Return value + +A [`view_type`](index.md#member-types) (i.e. `#!cpp basic_json_view`) for the root value, or a +discarded view if the document is [discarded](is_discarded.md). + +## Exception safety + +No-throw guarantee: this function never throws exceptions. + +## Complexity + +Constant. + +## Notes + +`root()` is a cheap handle into the document's index, not a copy of anything; call it as often as needed. The +returned view is valid under the same conditions as any other view of the document -- see +[Object inspection](../basic_json_view/index.md) -- in particular, it is invalidated by the next +[`read()`](read.md) or [`shrink_to_fit()`](shrink_to_fit.md) on this document. + +## Examples + +??? example + + ```cpp + --8<-- "examples/basic_json_document__root.cpp" + ``` + + Output: + + ```json + --8<-- "examples/basic_json_document__root.output" + ``` + +## See also + +- [is_discarded](is_discarded.md) - return whether the last parse failed +- [materialize](../basic_json_view/materialize.md) - build the `BasicJsonType` value of a subtree + +## Version history + +- Added in version 3.13.0. diff --git a/docs/mkdocs/docs/api/basic_json_document/shrink_to_fit.md b/docs/mkdocs/docs/api/basic_json_document/shrink_to_fit.md new file mode 100644 index 000000000..f8f8a4312 --- /dev/null +++ b/docs/mkdocs/docs/api/basic_json_document/shrink_to_fit.md @@ -0,0 +1,58 @@ +# nlohmann::basic_json_document::shrink_to_fit + +```cpp +void shrink_to_fit(); +``` + +Releases capacity that is no longer needed, both of the node index and of the buffer for decoded strings (strings that +contained escape sequences), e.g. after [`read()`](read.md) replaced a large document with a much smaller one. Like +`#!cpp std::vector::shrink_to_fit()`, this is a non-binding request: the library may keep more capacity than strictly +necessary. + +## Exception safety + +Strong guarantee: if an exception is thrown, there are no changes to the document. + +## Exceptions + +May throw `#!cpp std::bad_alloc` if the reallocation fails; on exception, the document is unchanged. + +## Complexity + +Linear in [`node_count()`](node_count.md) plus the length of the decoded strings. + +## Notes + +!!! warning "Invalidates views" + + Unlike moving the document, `shrink_to_fit()` **invalidates every view taken from this document before the + call**, including a previously obtained [`root()`](root.md): the node index is moved into a new, smaller + allocation, and the old one is freed. Take a fresh view from [`root()`](root.md) after calling this function. + +This is unlike `#!cpp std::vector::shrink_to_fit()`, which promises nothing about validity but in practice often +leaves iterators alone when it did not need to reallocate; here, an implementation that avoids a reallocation when +possible would be an internal optimization only, not a guarantee to rely on. + +## Examples + +??? example + + ```cpp + --8<-- "examples/basic_json_document__shrink_to_fit.cpp" + ``` + + Output: + + ```json + --8<-- "examples/basic_json_document__shrink_to_fit.output" + ``` + +## See also + +- [node_count](node_count.md) - the number of index entries +- [memory_usage](memory_usage.md) - the number of bytes held by the document +- [root](root.md) - the view of the root value + +## Version history + +- Added in version 3.13.0. diff --git a/docs/mkdocs/docs/api/basic_json_document/source.md b/docs/mkdocs/docs/api/basic_json_document/source.md new file mode 100644 index 000000000..dcefb88a9 --- /dev/null +++ b/docs/mkdocs/docs/api/basic_json_document/source.md @@ -0,0 +1,48 @@ +# nlohmann::basic_json_document::source + +```cpp +view_type::string_view_t source() const noexcept; +``` + +Returns the parsed text, whether it is borrowed from the caller or owned by the document. + +## Return value + +A `#!cpp string_view_t` (`#!cpp std::string_view` on C++17 and newer) over the parsed text, or an empty one if the +document is [discarded](is_discarded.md). + +## Exception safety + +No-throw guarantee: this function never throws exceptions. + +## Complexity + +Constant. + +## Notes + +For a borrowed document, `source()` points directly into the caller's buffer, so it is only valid while that buffer +is; see [`owns_source`](owns_source.md). + +## Examples + +??? example + + ```cpp + --8<-- "examples/basic_json_document__source.cpp" + ``` + + Output: + + ```json + --8<-- "examples/basic_json_document__source.output" + ``` + +## See also + +- [owns_source](owns_source.md) - return whether the document holds its own copy of the text +- [source_offset](../basic_json_view/source_offset.md) - byte offset of a value in the source text + +## Version history + +- Added in version 3.13.0. diff --git a/docs/mkdocs/docs/api/basic_json_view/basic_json_view.md b/docs/mkdocs/docs/api/basic_json_view/basic_json_view.md new file mode 100644 index 000000000..143ea2bea --- /dev/null +++ b/docs/mkdocs/docs/api/basic_json_view/basic_json_view.md @@ -0,0 +1,51 @@ +# nlohmann::basic_json_view::basic_json_view + +```cpp +basic_json_view() noexcept = default; +``` + +Creates an invalid (discarded) view: [`type()`](type.md) is `#!cpp value_t::discarded`, +[`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 +[`basic_json_document`](../basic_json_document/index.md), via [`root()`](../basic_json_document/root.md) or (once +element access is added) from navigating into a container. + +## Exception safety + +No-throw guarantee: this constructor never throws exceptions. + +## Complexity + +Constant. + +## Notes + +`basic_json_view` is trivially copyable (it holds two pointers), so a default-constructed view can be used as a +placeholder for "no value yet" and later be assigned a real view. + +## Examples + +??? example + + The example below shows the default constructor and that a `basic_json_view` is a small, copyable handle. + + ```cpp + --8<-- "examples/basic_json_view__basic_json_view.cpp" + ``` + + Output: + + ```json + --8<-- "examples/basic_json_view__basic_json_view.output" + ``` + +## See also + +- [is_discarded](is_discarded.md) - return whether the view is invalid +- [operator bool](operator_bool.md) - return whether the view refers to a value +- [root](../basic_json_document/root.md) - the view of a document's root value + +## Version history + +- Added in version 3.13.0. diff --git a/docs/mkdocs/docs/api/basic_json_view/empty.md b/docs/mkdocs/docs/api/basic_json_view/empty.md new file mode 100644 index 000000000..0d57fe9e7 --- /dev/null +++ b/docs/mkdocs/docs/api/basic_json_view/empty.md @@ -0,0 +1,61 @@ +# nlohmann::basic_json_view::empty + +```cpp +bool empty() const noexcept; +``` + +Checks whether [`size()`](size.md) is `0`, as [`BasicJsonType::empty()`](../basic_json/empty.md) would for the same +value. + +## Return value + +The return value depends on the type and is defined as follows: + +| Value type | return value | +|----------------------|-----------------| +| null | `#!cpp true` | +| discarded | `#!cpp true` | +| boolean | `#!cpp false` | +| string | `#!cpp false` | +| number | `#!cpp false` | +| object | `#!cpp object_t::empty()` | +| array | `#!cpp array_t::empty()` | + +## Exception safety + +No-throw guarantee: this function never throws exceptions. + +## Complexity + +Constant. + +## Notes + +As for [`BasicJsonType::empty()`](../basic_json/empty.md), this does not return whether a string value is empty -- it +is `#!cpp false` for any string, regardless of its length. + +## Examples + +??? example + + The example below uses [`size()`](size.md) and `empty()` to decide whether a parsed message is worth acting on, + without materializing it into a `BasicJsonType` value. + + ```cpp + --8<-- "examples/basic_json_view__size_empty.cpp" + ``` + + Output: + + ```json + --8<-- "examples/basic_json_view__size_empty.output" + ``` + +## See also + +- [size](size.md) - return the number of elements +- [`BasicJsonType::empty`](../basic_json/empty.md) - the corresponding function of `basic_json` + +## Version history + +- Added in version 3.13.0. diff --git a/docs/mkdocs/docs/api/basic_json_view/index.md b/docs/mkdocs/docs/api/basic_json_view/index.md new file mode 100644 index 000000000..564406667 --- /dev/null +++ b/docs/mkdocs/docs/api/basic_json_view/index.md @@ -0,0 +1,82 @@ +# nlohmann::basic_json_view + +Defined in header `` + +```cpp +template +class basic_json_view; +``` + +A read-only handle to one value of a [`basic_json_document`](../basic_json_document/index.md): two pointers (a pointer +to the document and a pointer into its index), trivially copyable. A view is valid as long as + +- the document is alive, +- the document has not been re-parsed with [`read()`](../basic_json_document/read.md) (or + [`parse()`](../basic_json_document/parse.md) into it) or shrunk with + [`shrink_to_fit()`](../basic_json_document/shrink_to_fit.md) since the view was taken, and +- if the document borrows its source text, that text is still alive. + +Moving the document itself does not invalidate its views: the index is heap-allocated independently of the +`basic_json_document` object. + +`basic_json_view` provides the read-only part of the `BasicJsonType` interface: the type-inspection functions, and +[`materialize()`](materialize.md) to build the `BasicJsonType` value of a subtree on demand. It does not (yet) provide +element access, iteration, `get()`, JSON Pointer support, `dump()`, or comparison. + +## Template parameters + +`BasicJsonType` +: a specialization of [`basic_json`](../basic_json/index.md), matching the + [`basic_json_document`](../basic_json_document/index.md) the view was taken from. + +## Specializations + +- [**json_view**](../json_view.md) - views of a [`json_document`](../json_document.md) +- [**ordered_json_view**](../ordered_json_view.md) - views of an [`ordered_json_document`](../ordered_json_document.md) + +## Member types + +- **value_t** - the JSON type enumeration, see [`basic_json::value_t`](../basic_json/value_t.md) +- **string_t**, **number_integer_t**, **number_unsigned_t**, **number_float_t**, **json_pointer** - the corresponding + member types of `BasicJsonType` +- **size_type** - `#!cpp std::size_t` +- **string_view_t** - `#!cpp std::string_view` on C++17 and newer, a minimal internal substitute otherwise + +## Member functions + +- [(constructor)](basic_json_view.md) + +### Object inspection + +- [**type**](type.md) - return the type of the value +- [**is_null**](is_null.md) - return whether the value is null +- [**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_integer**](is_number_integer.md) - return whether the value is an integer number +- [**is_number_unsigned**](is_number_unsigned.md) - return whether the value is an unsigned integer number +- [**is_number_float**](is_number_float.md) - return whether the value is a floating-point number +- [**is_string**](is_string.md) - return whether the value is a string +- [**is_array**](is_array.md) - return whether the value is an array +- [**is_object**](is_object.md) - return whether the value is an object +- [**is_binary**](is_binary.md) - return whether the value is a binary array (always `#!cpp false`) +- [**is_primitive**](is_primitive.md) - return whether the type is primitive +- [**is_structured**](is_structured.md) - return whether the type is structured +- [**is_discarded**](is_discarded.md) - return whether the view is invalid +- [**operator bool**](operator_bool.md) - return whether the view refers to a value + +### Capacity + +- [**size**](size.md) - return the number of elements +- [**empty**](empty.md) - return whether the value has no elements + +### Conversion + +- [**materialize**](materialize.md) - build the `BasicJsonType` value of this subtree + +### Source access + +- [**source_offset**](source_offset.md) - byte offset of this value in the document's source text + +## Version history + +- Added in version 3.13.0. diff --git a/docs/mkdocs/docs/api/basic_json_view/is_array.md b/docs/mkdocs/docs/api/basic_json_view/is_array.md new file mode 100644 index 000000000..a33176d2b --- /dev/null +++ b/docs/mkdocs/docs/api/basic_json_view/is_array.md @@ -0,0 +1,46 @@ +# nlohmann::basic_json_view::is_array + +```cpp +bool is_array() const noexcept; +``` + +This function returns `#!cpp true` if and only if the value is an array. + +## Return value + +`#!cpp true` if the type is an array, `#!cpp false` otherwise. + +## Exception safety + +No-throw guarantee: this function never throws exceptions. + +## Complexity + +Constant. + +## Examples + +??? example + + The example below classifies several parsed documents by the type of their root value, without materializing any + of them into a `BasicJsonType` value. + + ```cpp + --8<-- "examples/basic_json_view__type_predicates.cpp" + ``` + + Output: + + ```json + --8<-- "examples/basic_json_view__type_predicates.output" + ``` + +## See also + +- [is_structured](is_structured.md) - return whether the type is structured +- [size](size.md), [empty](empty.md) - the number of elements, and whether there are none +- [`BasicJsonType::is_array`](../basic_json/is_array.md) - the corresponding function of `basic_json` + +## Version history + +- Added in version 3.13.0. diff --git a/docs/mkdocs/docs/api/basic_json_view/is_binary.md b/docs/mkdocs/docs/api/basic_json_view/is_binary.md new file mode 100644 index 000000000..829a1fbb3 --- /dev/null +++ b/docs/mkdocs/docs/api/basic_json_view/is_binary.md @@ -0,0 +1,46 @@ +# nlohmann::basic_json_view::is_binary + +```cpp +bool is_binary() const noexcept; +``` + +This function always returns `#!cpp false`: a JSON text has no binary values, so a view can never refer to one. The +function exists for interface parity with [`BasicJsonType::is_binary`](../basic_json/is_binary.md). + +## Return value + +`#!cpp false`, always. + +## Exception safety + +No-throw guarantee: this function never throws exceptions. + +## Complexity + +Constant. + +## Examples + +??? example + + The example below classifies several parsed documents by the type of their root value, without materializing any + of them into a `BasicJsonType` value. + + ```cpp + --8<-- "examples/basic_json_view__type_predicates.cpp" + ``` + + Output: + + ```json + --8<-- "examples/basic_json_view__type_predicates.output" + ``` + +## See also + +- [type](type.md) - return the type of the value +- [`BasicJsonType::is_binary`](../basic_json/is_binary.md) - the corresponding function of `basic_json` + +## Version history + +- Added in version 3.13.0. diff --git a/docs/mkdocs/docs/api/basic_json_view/is_boolean.md b/docs/mkdocs/docs/api/basic_json_view/is_boolean.md new file mode 100644 index 000000000..148fe2a61 --- /dev/null +++ b/docs/mkdocs/docs/api/basic_json_view/is_boolean.md @@ -0,0 +1,45 @@ +# nlohmann::basic_json_view::is_boolean + +```cpp +bool is_boolean() const noexcept; +``` + +This function returns `#!cpp true` if and only if the value is a boolean. + +## Return value + +`#!cpp true` if the type is a boolean, `#!cpp false` otherwise. + +## Exception safety + +No-throw guarantee: this function never throws exceptions. + +## Complexity + +Constant. + +## Examples + +??? example + + The example below classifies several parsed documents by the type of their root value, without materializing any + of them into a `BasicJsonType` value. + + ```cpp + --8<-- "examples/basic_json_view__type_predicates.cpp" + ``` + + Output: + + ```json + --8<-- "examples/basic_json_view__type_predicates.output" + ``` + +## See also + +- [type](type.md) - return the type of the value +- [`BasicJsonType::is_boolean`](../basic_json/is_boolean.md) - the corresponding function of `basic_json` + +## Version history + +- Added in version 3.13.0. diff --git a/docs/mkdocs/docs/api/basic_json_view/is_discarded.md b/docs/mkdocs/docs/api/basic_json_view/is_discarded.md new file mode 100644 index 000000000..4cc11077d --- /dev/null +++ b/docs/mkdocs/docs/api/basic_json_view/is_discarded.md @@ -0,0 +1,55 @@ +# nlohmann::basic_json_view::is_discarded + +```cpp +bool is_discarded() const noexcept; +``` + +Returns whether this view is invalid, i.e. does not refer to a value. This is the case for a default-constructed +view (see [(constructor)](basic_json_view.md)), and for [`root()`](../basic_json_document/root.md) of a document +that is itself [discarded](../basic_json_document/is_discarded.md) -- in particular, the root of a failed +[`parse()`](../basic_json_document/parse.md) with `allow_exceptions` set to `#!cpp false`. + +## Return value + +`#!cpp true` if the view is discarded, `#!cpp false` otherwise. + +## Exception safety + +No-throw guarantee: this function never throws exceptions. + +## Complexity + +Constant. + +## Notes + +`#!cpp v.is_discarded()` and `#!cpp !static_cast(v)` are equivalent; use whichever reads better at the call +site. + +## Examples + +??? example + + The example below classifies several parsed documents by the type of their root value, without materializing any + of them into a `BasicJsonType` value. + + ```cpp + --8<-- "examples/basic_json_view__type_predicates.cpp" + ``` + + Output: + + ```json + --8<-- "examples/basic_json_view__type_predicates.output" + ``` + +## See also + +- [operator bool](operator_bool.md) - return whether the view refers to a value +- [(constructor)](basic_json_view.md) - the default constructor creates a discarded view +- [is_discarded (basic_json_document)](../basic_json_document/is_discarded.md) - return whether the last parse failed +- [`BasicJsonType::is_discarded`](../basic_json/is_discarded.md) - the corresponding function of `basic_json` + +## Version history + +- Added in version 3.13.0. diff --git a/docs/mkdocs/docs/api/basic_json_view/is_null.md b/docs/mkdocs/docs/api/basic_json_view/is_null.md new file mode 100644 index 000000000..fffaa836b --- /dev/null +++ b/docs/mkdocs/docs/api/basic_json_view/is_null.md @@ -0,0 +1,45 @@ +# nlohmann::basic_json_view::is_null + +```cpp +bool is_null() const noexcept; +``` + +This function returns `#!cpp true` if and only if the value is `#!json null`. + +## Return value + +`#!cpp true` if the type is `#!json null`, `#!cpp false` otherwise. + +## Exception safety + +No-throw guarantee: this function never throws exceptions. + +## Complexity + +Constant. + +## Examples + +??? example + + The example below classifies several parsed documents by the type of their root value, without materializing any + of them into a `BasicJsonType` value. + + ```cpp + --8<-- "examples/basic_json_view__type_predicates.cpp" + ``` + + Output: + + ```json + --8<-- "examples/basic_json_view__type_predicates.output" + ``` + +## See also + +- [type](type.md) - return the type of the value +- [`BasicJsonType::is_null`](../basic_json/is_null.md) - the corresponding function of `basic_json` + +## Version history + +- Added in version 3.13.0. diff --git a/docs/mkdocs/docs/api/basic_json_view/is_number.md b/docs/mkdocs/docs/api/basic_json_view/is_number.md new file mode 100644 index 000000000..158734364 --- /dev/null +++ b/docs/mkdocs/docs/api/basic_json_view/is_number.md @@ -0,0 +1,47 @@ +# nlohmann::basic_json_view::is_number + +```cpp +bool is_number() const noexcept; +``` + +This function returns `#!cpp true` if and only if the value is a number, i.e. an integer, unsigned integer, or floating-point value. It is defined as `#!cpp is_number_integer() || is_number_float()`. + +## Return value + +`#!cpp true` if the type is a number, `#!cpp false` otherwise. + +## Exception safety + +No-throw guarantee: this function never throws exceptions. + +## Complexity + +Constant. + +## Examples + +??? example + + The example below classifies several parsed documents by the type of their root value, without materializing any + of them into a `BasicJsonType` value. + + ```cpp + --8<-- "examples/basic_json_view__type_predicates.cpp" + ``` + + Output: + + ```json + --8<-- "examples/basic_json_view__type_predicates.output" + ``` + +## See also + +- [is_number_integer](is_number_integer.md) - return whether the value is an integer or unsigned integer number +- [is_number_unsigned](is_number_unsigned.md) - return whether the value is an unsigned integer number +- [is_number_float](is_number_float.md) - return whether the value is a floating-point number +- [`BasicJsonType::is_number`](../basic_json/is_number.md) - the corresponding function of `basic_json` + +## Version history + +- Added in version 3.13.0. diff --git a/docs/mkdocs/docs/api/basic_json_view/is_number_float.md b/docs/mkdocs/docs/api/basic_json_view/is_number_float.md new file mode 100644 index 000000000..52bb43f20 --- /dev/null +++ b/docs/mkdocs/docs/api/basic_json_view/is_number_float.md @@ -0,0 +1,51 @@ +# nlohmann::basic_json_view::is_number_float + +```cpp +bool is_number_float() const noexcept; +``` + +This function returns `#!cpp true` if and only if the value is a floating-point number. + +## Return value + +`#!cpp true` if the type is `#!cpp value_t::number_float`, `#!cpp false` otherwise. + +## Exception safety + +No-throw guarantee: this function never throws exceptions. + +## Complexity + +Constant. + +## Notes + +As for [`BasicJsonType::parse`](../basic_json/parse.md), an integer literal that does not fit into the 64-bit +integer type is classified as a floating-point number, so `is_number_float()` can be `#!cpp true` even for an +integer-looking token in the source text. + +## Examples + +??? example + + The example below classifies several parsed documents by the type of their root value, without materializing any + of them into a `BasicJsonType` value. + + ```cpp + --8<-- "examples/basic_json_view__type_predicates.cpp" + ``` + + Output: + + ```json + --8<-- "examples/basic_json_view__type_predicates.output" + ``` + +## See also + +- [is_number](is_number.md) - return whether the value is a number +- [`BasicJsonType::is_number_float`](../basic_json/is_number_float.md) - the corresponding function of `basic_json` + +## Version history + +- Added in version 3.13.0. diff --git a/docs/mkdocs/docs/api/basic_json_view/is_number_integer.md b/docs/mkdocs/docs/api/basic_json_view/is_number_integer.md new file mode 100644 index 000000000..fda0c29c9 --- /dev/null +++ b/docs/mkdocs/docs/api/basic_json_view/is_number_integer.md @@ -0,0 +1,51 @@ +# nlohmann::basic_json_view::is_number_integer + +```cpp +bool is_number_integer() const noexcept; +``` + +This function returns `#!cpp true` if and only if the value is an integer or unsigned integer number. + +## Return value + +`#!cpp true` if the type is `#!cpp value_t::number_integer` or `#!cpp value_t::number_unsigned`, `#!cpp false` otherwise. + +## Exception safety + +No-throw guarantee: this function never throws exceptions. + +## Complexity + +Constant. + +## Notes + +As for [`BasicJsonType::is_number_integer`](../basic_json/is_number_integer.md), this includes unsigned integer +values; use [`is_number_unsigned`](is_number_unsigned.md) to test for those specifically. + +## Examples + +??? example + + The example below classifies several parsed documents by the type of their root value, without materializing any + of them into a `BasicJsonType` value. + + ```cpp + --8<-- "examples/basic_json_view__type_predicates.cpp" + ``` + + Output: + + ```json + --8<-- "examples/basic_json_view__type_predicates.output" + ``` + +## See also + +- [is_number](is_number.md) - return whether the value is a number +- [is_number_unsigned](is_number_unsigned.md) - return whether the value is an unsigned integer number +- [`BasicJsonType::is_number_integer`](../basic_json/is_number_integer.md) - the corresponding function of `basic_json` + +## Version history + +- Added in version 3.13.0. diff --git a/docs/mkdocs/docs/api/basic_json_view/is_number_unsigned.md b/docs/mkdocs/docs/api/basic_json_view/is_number_unsigned.md new file mode 100644 index 000000000..d2cf10ebe --- /dev/null +++ b/docs/mkdocs/docs/api/basic_json_view/is_number_unsigned.md @@ -0,0 +1,45 @@ +# nlohmann::basic_json_view::is_number_unsigned + +```cpp +bool is_number_unsigned() const noexcept; +``` + +This function returns `#!cpp true` if and only if the value is an unsigned integer number. + +## Return value + +`#!cpp true` if the type is `#!cpp value_t::number_unsigned`, `#!cpp false` otherwise. + +## Exception safety + +No-throw guarantee: this function never throws exceptions. + +## Complexity + +Constant. + +## Examples + +??? example + + The example below classifies several parsed documents by the type of their root value, without materializing any + of them into a `BasicJsonType` value. + + ```cpp + --8<-- "examples/basic_json_view__type_predicates.cpp" + ``` + + Output: + + ```json + --8<-- "examples/basic_json_view__type_predicates.output" + ``` + +## See also + +- [is_number_integer](is_number_integer.md) - return whether the value is an integer or unsigned integer number +- [`BasicJsonType::is_number_unsigned`](../basic_json/is_number_unsigned.md) - the corresponding function of `basic_json` + +## Version history + +- Added in version 3.13.0. diff --git a/docs/mkdocs/docs/api/basic_json_view/is_object.md b/docs/mkdocs/docs/api/basic_json_view/is_object.md new file mode 100644 index 000000000..5421aeeb1 --- /dev/null +++ b/docs/mkdocs/docs/api/basic_json_view/is_object.md @@ -0,0 +1,46 @@ +# nlohmann::basic_json_view::is_object + +```cpp +bool is_object() const noexcept; +``` + +This function returns `#!cpp true` if and only if the value is an object. + +## Return value + +`#!cpp true` if the type is an object, `#!cpp false` otherwise. + +## Exception safety + +No-throw guarantee: this function never throws exceptions. + +## Complexity + +Constant. + +## Examples + +??? example + + The example below classifies several parsed documents by the type of their root value, without materializing any + of them into a `BasicJsonType` value. + + ```cpp + --8<-- "examples/basic_json_view__type_predicates.cpp" + ``` + + Output: + + ```json + --8<-- "examples/basic_json_view__type_predicates.output" + ``` + +## See also + +- [is_structured](is_structured.md) - return whether the type is structured +- [size](size.md), [empty](empty.md) - the number of elements, and whether there are none +- [`BasicJsonType::is_object`](../basic_json/is_object.md) - the corresponding function of `basic_json` + +## Version history + +- Added in version 3.13.0. diff --git a/docs/mkdocs/docs/api/basic_json_view/is_primitive.md b/docs/mkdocs/docs/api/basic_json_view/is_primitive.md new file mode 100644 index 000000000..a28b478f0 --- /dev/null +++ b/docs/mkdocs/docs/api/basic_json_view/is_primitive.md @@ -0,0 +1,46 @@ +# nlohmann::basic_json_view::is_primitive + +```cpp +bool is_primitive() const noexcept; +``` + +This function returns `#!cpp true` if and only if the value is primitive, i.e. `#!json null`, a boolean, a number, or a string. It is defined as `#!cpp is_null() || is_string() || is_boolean() || is_number()`. + +## Return value + +`#!cpp true` if the type is primitive, `#!cpp false` otherwise. + +## Exception safety + +No-throw guarantee: this function never throws exceptions. + +## Complexity + +Constant. + +## Examples + +??? example + + The example below classifies several parsed documents by the type of their root value, without materializing any + of them into a `BasicJsonType` value. + + ```cpp + --8<-- "examples/basic_json_view__type_predicates.cpp" + ``` + + Output: + + ```json + --8<-- "examples/basic_json_view__type_predicates.output" + ``` + +## See also + +- [is_structured](is_structured.md) - return whether the type is structured (the complement of this function, for a + non-discarded view) +- [`BasicJsonType::is_primitive`](../basic_json/is_primitive.md) - the corresponding function of `basic_json` + +## Version history + +- Added in version 3.13.0. diff --git a/docs/mkdocs/docs/api/basic_json_view/is_string.md b/docs/mkdocs/docs/api/basic_json_view/is_string.md new file mode 100644 index 000000000..c40c8ab4b --- /dev/null +++ b/docs/mkdocs/docs/api/basic_json_view/is_string.md @@ -0,0 +1,45 @@ +# nlohmann::basic_json_view::is_string + +```cpp +bool is_string() const noexcept; +``` + +This function returns `#!cpp true` if and only if the value is a string. + +## Return value + +`#!cpp true` if the type is a string, `#!cpp false` otherwise. + +## Exception safety + +No-throw guarantee: this function never throws exceptions. + +## Complexity + +Constant. + +## Examples + +??? example + + The example below classifies several parsed documents by the type of their root value, without materializing any + of them into a `BasicJsonType` value. + + ```cpp + --8<-- "examples/basic_json_view__type_predicates.cpp" + ``` + + Output: + + ```json + --8<-- "examples/basic_json_view__type_predicates.output" + ``` + +## See also + +- [source_offset](source_offset.md) - byte offset of this value in the document's source text +- [`BasicJsonType::is_string`](../basic_json/is_string.md) - the corresponding function of `basic_json` + +## Version history + +- Added in version 3.13.0. diff --git a/docs/mkdocs/docs/api/basic_json_view/is_structured.md b/docs/mkdocs/docs/api/basic_json_view/is_structured.md new file mode 100644 index 000000000..de5dd5f7e --- /dev/null +++ b/docs/mkdocs/docs/api/basic_json_view/is_structured.md @@ -0,0 +1,46 @@ +# nlohmann::basic_json_view::is_structured + +```cpp +bool is_structured() const noexcept; +``` + +This function returns `#!cpp true` if and only if the value is structured, i.e. an array or an object. It is defined as `#!cpp is_array() || is_object()`. + +## Return value + +`#!cpp true` if the type is structured, `#!cpp false` otherwise. + +## Exception safety + +No-throw guarantee: this function never throws exceptions. + +## Complexity + +Constant. + +## Examples + +??? example + + The example below classifies several parsed documents by the type of their root value, without materializing any + of them into a `BasicJsonType` value. + + ```cpp + --8<-- "examples/basic_json_view__type_predicates.cpp" + ``` + + Output: + + ```json + --8<-- "examples/basic_json_view__type_predicates.output" + ``` + +## See also + +- [is_primitive](is_primitive.md) - return whether the type is primitive +- [size](size.md), [empty](empty.md) - the number of elements, and whether there are none +- [`BasicJsonType::is_structured`](../basic_json/is_structured.md) - the corresponding function of `basic_json` + +## Version history + +- Added in version 3.13.0. diff --git a/docs/mkdocs/docs/api/basic_json_view/materialize.md b/docs/mkdocs/docs/api/basic_json_view/materialize.md new file mode 100644 index 000000000..225af3c9a --- /dev/null +++ b/docs/mkdocs/docs/api/basic_json_view/materialize.md @@ -0,0 +1,69 @@ +# nlohmann::basic_json_view::materialize + +```cpp +BasicJsonType materialize() const; +``` + +Builds the `BasicJsonType` value of this subtree: the value [`BasicJsonType::parse()`](../basic_json/parse.md) would +have produced for the same source text, allocated for the first time by this call. + +## Return value + +The `BasicJsonType` value of this subtree, or a discarded `BasicJsonType` value (`#!cpp BasicJsonType(value_t::discarded)`) +if the view is [discarded](is_discarded.md). + +## Exception safety + +Strong guarantee: if an exception is thrown, there are no changes to the view or the document it refers to (nothing +about either is mutated by this function). + +## Exceptions + +May throw `#!cpp std::bad_alloc` (via `BasicJsonType`'s allocator) if constructing the result fails. + +## Complexity + +Linear in the size of the subtree. + +## Notes + +`materialize()` replays the subtree through the same SAX builder [`BasicJsonType::parse()`](../basic_json/parse.md) +uses internally, so the result matches it exactly -- including, for an object, that a repeated key keeps only its +last value. The replay is iterative, so it is not limited by the call stack the way a naive recursive conversion +would be; the JSON nesting depth is limited only by available memory, as for `BasicJsonType::parse()` itself. + +Unlike parsing with [`JSON_DIAGNOSTIC_POSITIONS`](../macros/json_diagnostic_positions.md) enabled, the values +produced by `materialize()` do not carry source positions: there is no lexer run during the replay to record them. + +Calling `materialize()` on the same view repeatedly builds a new, independent `BasicJsonType` value each time; it +never caches the result. + +## Examples + +??? example + + The example below skips messages that are not useful -- a discarded value, or an empty array -- using only + [`is_array()`](is_array.md) and [`empty()`](empty.md), and calls `materialize()` only for the messages that are + actually used, so no `BasicJsonType` value (and none of its per-element allocations) is ever built for the + skipped ones. + + ```cpp + --8<-- "examples/basic_json_view__materialize.cpp" + ``` + + Output: + + ```json + --8<-- "examples/basic_json_view__materialize.output" + ``` + +## See also + +- [root](../basic_json_document/root.md) - the view of a document's root value +- [`BasicJsonType::parse`](../basic_json/parse.md) - build a `BasicJsonType` value directly from a JSON text +- [`JSON_DIAGNOSTIC_POSITIONS`](../macros/json_diagnostic_positions.md) - source positions on parsed values (not + produced by `materialize()`) + +## Version history + +- Added in version 3.13.0. diff --git a/docs/mkdocs/docs/api/basic_json_view/operator_bool.md b/docs/mkdocs/docs/api/basic_json_view/operator_bool.md new file mode 100644 index 000000000..bc13c100c --- /dev/null +++ b/docs/mkdocs/docs/api/basic_json_view/operator_bool.md @@ -0,0 +1,46 @@ +# nlohmann::basic_json_view::operator bool + +```cpp +explicit operator bool() const noexcept; +``` + +Returns whether this view refers to a value, i.e. the negation of [`is_discarded()`](is_discarded.md). Being +`#!cpp explicit`, this conversion is only considered in a boolean context (`#!cpp if (v)`, `#!cpp !v`, `#!cpp v && +...`), not for implicit conversions to other types. + +## Return value + +`#!cpp true` if the view refers to a value, `#!cpp false` if it is [discarded](is_discarded.md). + +## Exception safety + +No-throw guarantee: this function never throws exceptions. + +## Complexity + +Constant. + +## Examples + +??? example + + The example below classifies several parsed documents by the type of their root value, without materializing any + of them into a `BasicJsonType` value. + + ```cpp + --8<-- "examples/basic_json_view__type_predicates.cpp" + ``` + + Output: + + ```json + --8<-- "examples/basic_json_view__type_predicates.output" + ``` + +## See also + +- [is_discarded](is_discarded.md) - return whether the view is invalid + +## Version history + +- Added in version 3.13.0. diff --git a/docs/mkdocs/docs/api/basic_json_view/size.md b/docs/mkdocs/docs/api/basic_json_view/size.md new file mode 100644 index 000000000..cd354d2f3 --- /dev/null +++ b/docs/mkdocs/docs/api/basic_json_view/size.md @@ -0,0 +1,60 @@ +# nlohmann::basic_json_view::size + +```cpp +size_type size() const noexcept; +``` + +Returns the number of elements, as [`BasicJsonType::size()`](../basic_json/size.md) would for the same value. + +## Return value + +The return value depends on the type and is defined as follows: + +| Value type | return value | +|----------------------|-----------------------------| +| null | `0` | +| discarded | `0` | +| boolean | `1` | +| string | `1` | +| number | `1` | +| object | number of key/value pairs | +| array | number of elements | + +## Exception safety + +No-throw guarantee: this function never throws exceptions. + +## Complexity + +Constant: for an object or array, the element count is stored in the index, not counted on demand. + +## Notes + +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. + +## Examples + +??? example + + The example below uses `size()` and [`empty()`](empty.md) to decide whether a parsed message is worth acting on, + without materializing it into a `BasicJsonType` value. + + ```cpp + --8<-- "examples/basic_json_view__size_empty.cpp" + ``` + + Output: + + ```json + --8<-- "examples/basic_json_view__size_empty.output" + ``` + +## See also + +- [empty](empty.md) - return whether the value has no elements +- [`BasicJsonType::size`](../basic_json/size.md) - the corresponding function of `basic_json` + +## Version history + +- Added in version 3.13.0. diff --git a/docs/mkdocs/docs/api/basic_json_view/source_offset.md b/docs/mkdocs/docs/api/basic_json_view/source_offset.md new file mode 100644 index 000000000..5f7e06221 --- /dev/null +++ b/docs/mkdocs/docs/api/basic_json_view/source_offset.md @@ -0,0 +1,55 @@ +# nlohmann::basic_json_view::source_offset + +```cpp +std::size_t source_offset() const noexcept; +``` + +Returns the byte offset of this value in the document's [`source()`](../basic_json_document/source.md) text, without +materializing anything. + +## Return value + +- For a string with no escapes, a number, `#!json true`/`#!json false`/`#!json null`, an array, or an object: the + byte offset of the first byte of the value's token (for a string: the first byte after the opening quote) in + [`source()`](../basic_json_document/source.md). +- `#!cpp static_cast(-1)` for a [discarded](is_discarded.md) view, and for a string that contains + escapes -- such a string was decoded once into the document's own buffer, so there is no single byte range in + `source()` left to point at. + +## Exception safety + +No-throw guarantee: this function never throws exceptions. + +## Complexity + +Constant. + +## Notes + +This is a raw offset, not a length: the API does not (yet) expose how many bytes the token occupies in the source +text, so `source_offset()` alone is enough to report *where* a value came from (for an error message, for syntax +highlighting, ...) but not to slice its exact text back out of [`source()`](../basic_json_document/source.md) for a +string, whose token length is not the same as its decoded [`size()`](size.md). + +## Examples + +??? example + + ```cpp + --8<-- "examples/basic_json_view__source_offset.cpp" + ``` + + Output: + + ```json + --8<-- "examples/basic_json_view__source_offset.output" + ``` + +## See also + +- [source](../basic_json_document/source.md) - the parsed text +- [is_string](is_string.md) - return whether the value is a string + +## Version history + +- Added in version 3.13.0. diff --git a/docs/mkdocs/docs/api/basic_json_view/type.md b/docs/mkdocs/docs/api/basic_json_view/type.md new file mode 100644 index 000000000..17dbc3c34 --- /dev/null +++ b/docs/mkdocs/docs/api/basic_json_view/type.md @@ -0,0 +1,53 @@ +# nlohmann::basic_json_view::type + +```cpp +value_t type() const noexcept; +``` + +Returns the type of the value this view refers to, as a value from the [`value_t`](../basic_json/value_t.md) +enumeration -- the same enumeration [`BasicJsonType::type()`](../basic_json/type.md) uses. + +## Return value + +The type of the value; `#!cpp value_t::discarded` for a [discarded](is_discarded.md) view. + +## Exception safety + +No-throw guarantee: this function never throws exceptions. + +## Complexity + +Constant. + +## Notes + +Unlike [`BasicJsonType::type()`](../basic_json/type.md), this function can never return `#!cpp value_t::binary`: a +JSON text has no binary values, so `type()` only distinguishes the eight ordinary JSON value types (plus +`#!cpp discarded`). + +## Examples + +??? example + + The example below classifies several parsed documents by the type of their root value, without materializing any + of them into a `BasicJsonType` value. + + ```cpp + --8<-- "examples/basic_json_view__type_predicates.cpp" + ``` + + Output: + + ```json + --8<-- "examples/basic_json_view__type_predicates.output" + ``` + +## See also + +- [is_null](is_null.md), [is_boolean](is_boolean.md), [is_number](is_number.md), [is_string](is_string.md), + [is_array](is_array.md), [is_object](is_object.md) - type-specific predicates built on `type()` +- [`BasicJsonType::type`](../basic_json/type.md) - the corresponding function of `basic_json` + +## Version history + +- Added in version 3.13.0. diff --git a/docs/mkdocs/docs/api/json_document.md b/docs/mkdocs/docs/api/json_document.md new file mode 100644 index 000000000..ea365badc --- /dev/null +++ b/docs/mkdocs/docs/api/json_document.md @@ -0,0 +1,35 @@ +# nlohmann::json_document + +Defined in header `` + +```cpp +using json_document = basic_json_document; +``` + +This type is a [`basic_json_document`](basic_json_document/index.md) of the default [`json`](json.md) +specialization. + +## Examples + +??? example + + The example below demonstrates how to use the type `nlohmann::json_document`. + + ```cpp + --8<-- "examples/json_document.cpp" + ``` + + Output: + + ```json + --8<-- "examples/json_document.output" + ``` + +## See also + +- [json_view](json_view.md) - a view of a value of a `json_document` +- [ordered_json_document](ordered_json_document.md) - the corresponding document for `ordered_json` + +## Version history + +Since version 3.13.0. diff --git a/docs/mkdocs/docs/api/json_view.md b/docs/mkdocs/docs/api/json_view.md new file mode 100644 index 000000000..819dfe501 --- /dev/null +++ b/docs/mkdocs/docs/api/json_view.md @@ -0,0 +1,34 @@ +# nlohmann::json_view + +Defined in header `` + +```cpp +using json_view = basic_json_view; +``` + +This type is a [`basic_json_view`](basic_json_view/index.md) of a value of a [`json_document`](json_document.md). + +## Examples + +??? example + + The example below demonstrates how to use the type `nlohmann::json_view`. + + ```cpp + --8<-- "examples/json_view.cpp" + ``` + + Output: + + ```json + --8<-- "examples/json_view.output" + ``` + +## See also + +- [json_document](json_document.md) - the document type this view refers into +- [ordered_json_view](ordered_json_view.md) - the corresponding view for `ordered_json_document` + +## Version history + +Since version 3.13.0. diff --git a/docs/mkdocs/docs/api/ordered_json_document.md b/docs/mkdocs/docs/api/ordered_json_document.md new file mode 100644 index 000000000..dd6760ead --- /dev/null +++ b/docs/mkdocs/docs/api/ordered_json_document.md @@ -0,0 +1,38 @@ +# nlohmann::ordered_json_document + +Defined in header `` + +```cpp +using ordered_json_document = basic_json_document; +``` + +This type is a [`basic_json_document`](basic_json_document/index.md) of the [`ordered_json`](ordered_json.md) +specialization: [`materialize()`](basic_json_view/materialize.md) on one of its views preserves the insertion order +of object keys, instead of sorting them like [`json_document`](json_document.md) does. + +## Examples + +??? example + + The example below demonstrates how `ordered_json_document` preserves the insertion order of object keys when + materializing. + + ```cpp + --8<-- "examples/ordered_json_document.cpp" + ``` + + Output: + + ```json + --8<-- "examples/ordered_json_document.output" + ``` + +## See also + +- [ordered_json_view](ordered_json_view.md) - a view of a value of an `ordered_json_document` +- [json_document](json_document.md) - the corresponding document for the default `json` specialization +- [Object Order](../features/object_order.md) + +## Version history + +Since version 3.13.0. diff --git a/docs/mkdocs/docs/api/ordered_json_view.md b/docs/mkdocs/docs/api/ordered_json_view.md new file mode 100644 index 000000000..9800b0752 --- /dev/null +++ b/docs/mkdocs/docs/api/ordered_json_view.md @@ -0,0 +1,35 @@ +# nlohmann::ordered_json_view + +Defined in header `` + +```cpp +using ordered_json_view = basic_json_view; +``` + +This type is a [`basic_json_view`](basic_json_view/index.md) of a value of an +[`ordered_json_document`](ordered_json_document.md). + +## Examples + +??? example + + The example below demonstrates how to use the type `nlohmann::ordered_json_view`. + + ```cpp + --8<-- "examples/ordered_json_view.cpp" + ``` + + Output: + + ```json + --8<-- "examples/ordered_json_view.output" + ``` + +## See also + +- [ordered_json_document](ordered_json_document.md) - the document type this view refers into +- [json_view](json_view.md) - the corresponding view for `json_document` + +## Version history + +Since version 3.13.0. diff --git a/docs/mkdocs/docs/examples/basic_json_document__accept.cpp b/docs/mkdocs/docs/examples/basic_json_document__accept.cpp new file mode 100644 index 000000000..675fa823f --- /dev/null +++ b/docs/mkdocs/docs/examples/basic_json_document__accept.cpp @@ -0,0 +1,19 @@ +#include +#include +#include + +using json_document = nlohmann::json_document; + +int main() +{ + std::cout << std::boolalpha; + + // accept() behaves exactly like basic_json::accept(): the same inputs are + // accepted or rejected, with the same ignore_comments/ignore_trailing_commas + // options + std::cout << json_document::accept(R"({"a": 1})") << '\n'; + std::cout << json_document::accept(R"({"a": 1,})") << '\n'; // trailing comma: rejected by default + std::cout << json_document::accept(R"({"a": 1,})", false, true) << '\n'; // ignore_trailing_commas + + std::cout << (json_document::accept(R"({"a": 1})") == nlohmann::json::accept(R"({"a": 1})")) << '\n'; +} diff --git a/docs/mkdocs/docs/examples/basic_json_document__accept.output b/docs/mkdocs/docs/examples/basic_json_document__accept.output new file mode 100644 index 000000000..271474188 --- /dev/null +++ b/docs/mkdocs/docs/examples/basic_json_document__accept.output @@ -0,0 +1,4 @@ +true +false +true +true diff --git a/docs/mkdocs/docs/examples/basic_json_document__basic_json_document.cpp b/docs/mkdocs/docs/examples/basic_json_document__basic_json_document.cpp new file mode 100644 index 000000000..0c185f7b8 --- /dev/null +++ b/docs/mkdocs/docs/examples/basic_json_document__basic_json_document.cpp @@ -0,0 +1,23 @@ +#include +#include +#include + +using json_document = nlohmann::json_document; + +int main() +{ + std::cout << std::boolalpha; + + // the default constructor creates an empty (discarded) document + json_document empty; + std::cout << empty.is_discarded() << '\n'; + + // json_document is move-only: parse() itself returns by value (moved out), + // and a document can be moved again, e.g. into a container + json_document doc = json_document::parse(R"({"a": 1})"); + json_document moved = std::move(doc); + std::cout << moved.root().is_object() << '\n'; + + // copying is disabled at compile time: + // json_document another = moved; // does not compile +} diff --git a/docs/mkdocs/docs/examples/basic_json_document__basic_json_document.output b/docs/mkdocs/docs/examples/basic_json_document__basic_json_document.output new file mode 100644 index 000000000..bb101b641 --- /dev/null +++ b/docs/mkdocs/docs/examples/basic_json_document__basic_json_document.output @@ -0,0 +1,2 @@ +true +true diff --git a/docs/mkdocs/docs/examples/basic_json_document__is_discarded.cpp b/docs/mkdocs/docs/examples/basic_json_document__is_discarded.cpp new file mode 100644 index 000000000..d64d37d23 --- /dev/null +++ b/docs/mkdocs/docs/examples/basic_json_document__is_discarded.cpp @@ -0,0 +1,19 @@ +#include +#include + +using json_document = nlohmann::json_document; + +int main() +{ + std::cout << std::boolalpha; + + // with allow_exceptions == false, a parse error produces a discarded + // document instead of throwing -- exactly like basic_json::parse() + json_document doc = json_document::parse(R"({"a": )", /* allow_exceptions */ false); + std::cout << doc.is_discarded() << '\n'; + std::cout << doc.root().is_discarded() << '\n'; + + // a successful parse is never discarded + json_document ok = json_document::parse(R"({"a": 1})", false); + std::cout << ok.is_discarded() << '\n'; +} diff --git a/docs/mkdocs/docs/examples/basic_json_document__is_discarded.output b/docs/mkdocs/docs/examples/basic_json_document__is_discarded.output new file mode 100644 index 000000000..9e8a46acf --- /dev/null +++ b/docs/mkdocs/docs/examples/basic_json_document__is_discarded.output @@ -0,0 +1,3 @@ +true +true +false diff --git a/docs/mkdocs/docs/examples/basic_json_document__memory_usage.cpp b/docs/mkdocs/docs/examples/basic_json_document__memory_usage.cpp new file mode 100644 index 000000000..efa235310 --- /dev/null +++ b/docs/mkdocs/docs/examples/basic_json_document__memory_usage.cpp @@ -0,0 +1,28 @@ +#include +#include +#include + +using json_document = nlohmann::json_document; + +int main() +{ + std::cout << std::boolalpha; + + // long enough that copying it needs a real (heap) allocation, so the + // comparison below does not depend on the standard library's small + // string optimization threshold + const std::string text = std::string(200, ' ') + "[1, 2, 3, 4, 5]"; + + // memory_usage() is not portable across platforms/allocators/compilers, so + // compare it relatively instead of printing the raw byte count + json_document borrowed = json_document::parse(text); + json_document owned = json_document::parse_copy(text); + + // the owned document additionally stores its own copy of the source text + std::cout << (owned.memory_usage() > borrowed.memory_usage()) << '\n'; + + // a document with more values needs a larger index + json_document small = json_document::parse(std::string("[1]")); + json_document large = json_document::parse(std::string("[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]")); + std::cout << (large.memory_usage() > small.memory_usage()) << '\n'; +} diff --git a/docs/mkdocs/docs/examples/basic_json_document__memory_usage.output b/docs/mkdocs/docs/examples/basic_json_document__memory_usage.output new file mode 100644 index 000000000..bb101b641 --- /dev/null +++ b/docs/mkdocs/docs/examples/basic_json_document__memory_usage.output @@ -0,0 +1,2 @@ +true +true diff --git a/docs/mkdocs/docs/examples/basic_json_document__node_count.cpp b/docs/mkdocs/docs/examples/basic_json_document__node_count.cpp new file mode 100644 index 000000000..d6ae5f89b --- /dev/null +++ b/docs/mkdocs/docs/examples/basic_json_document__node_count.cpp @@ -0,0 +1,15 @@ +#include +#include + +using json_document = nlohmann::json_document; + +int main() +{ + // node_count() is the size of the flat index: one 16-byte node per value, + // plus one per object key (values and keys are all the index stores) + json_document scalar = json_document::parse("42"); + std::cout << scalar.node_count() << '\n'; + + json_document doc = json_document::parse(R"({"a": 1, "b": [1, 2]})"); + std::cout << doc.node_count() << '\n'; +} diff --git a/docs/mkdocs/docs/examples/basic_json_document__node_count.output b/docs/mkdocs/docs/examples/basic_json_document__node_count.output new file mode 100644 index 000000000..fea32e7d8 --- /dev/null +++ b/docs/mkdocs/docs/examples/basic_json_document__node_count.output @@ -0,0 +1,2 @@ +1 +7 diff --git a/docs/mkdocs/docs/examples/basic_json_document__owns_source.cpp b/docs/mkdocs/docs/examples/basic_json_document__owns_source.cpp new file mode 100644 index 000000000..8f442ea13 --- /dev/null +++ b/docs/mkdocs/docs/examples/basic_json_document__owns_source.cpp @@ -0,0 +1,24 @@ +#include +#include +#include + +using json_document = nlohmann::json_document; + +int main() +{ + std::cout << std::boolalpha; + + std::string text = R"({"a": 1})"; + + // borrowed: the document only points into `text`; `text` must outlive it + json_document borrowed = json_document::parse(text); + std::cout << borrowed.owns_source() << '\n'; + + // owned: parse_copy() always takes its own copy + json_document copied = json_document::parse_copy(text); + std::cout << copied.owns_source() << '\n'; + + // owned: an rvalue std::string is moved in, not copied, but still owned + json_document moved_in = json_document::parse(std::string(text)); + std::cout << moved_in.owns_source() << '\n'; +} diff --git a/docs/mkdocs/docs/examples/basic_json_document__owns_source.output b/docs/mkdocs/docs/examples/basic_json_document__owns_source.output new file mode 100644 index 000000000..dac32ecf1 --- /dev/null +++ b/docs/mkdocs/docs/examples/basic_json_document__owns_source.output @@ -0,0 +1,3 @@ +false +true +true diff --git a/docs/mkdocs/docs/examples/basic_json_document__parse.cpp b/docs/mkdocs/docs/examples/basic_json_document__parse.cpp new file mode 100644 index 000000000..4eba7350d --- /dev/null +++ b/docs/mkdocs/docs/examples/basic_json_document__parse.cpp @@ -0,0 +1,33 @@ +#include +#include +#include +#include + +using json_document = nlohmann::json_document; + +int main() +{ + std::cout << std::boolalpha; + + // an lvalue std::string is BORROWED: the document only stores a pointer + // into `text`, so `text` must outlive `borrowed` + std::string text = R"({"count": 3})"; + json_document borrowed = json_document::parse(text); + std::cout << borrowed.owns_source() << '\n'; // false + + // an rvalue std::string is MOVED into the document -- no copy of the text + json_document owned = json_document::parse(std::string(R"({"count": 3})")); + std::cout << owned.owns_source() << '\n'; // true + + // errors are identical to basic_json::parse: same exception id, message, + // and position, because the library parser runs on the same bytes on a + // failing input + try + { + static_cast(json_document::parse(R"({"count": )")); + } + catch (const nlohmann::json::parse_error& e) + { + std::cout << e.id << '\n'; + } +} diff --git a/docs/mkdocs/docs/examples/basic_json_document__parse.output b/docs/mkdocs/docs/examples/basic_json_document__parse.output new file mode 100644 index 000000000..99fd51a73 --- /dev/null +++ b/docs/mkdocs/docs/examples/basic_json_document__parse.output @@ -0,0 +1,3 @@ +false +true +101 diff --git a/docs/mkdocs/docs/examples/basic_json_document__parse_copy.cpp b/docs/mkdocs/docs/examples/basic_json_document__parse_copy.cpp new file mode 100644 index 000000000..16d3ce939 --- /dev/null +++ b/docs/mkdocs/docs/examples/basic_json_document__parse_copy.cpp @@ -0,0 +1,22 @@ +#include +#include + +using json_document = nlohmann::json_document; + +json_document parse_from_temporary_buffer() +{ + char buffer[] = R"({"a": 1})"; + // parse() would borrow `buffer`, which is about to go out of scope; + // parse_copy() takes its own copy instead, so the returned document does + // not depend on `buffer` afterward + return json_document::parse_copy(buffer); +} + +int main() +{ + std::cout << std::boolalpha; + + json_document doc = parse_from_temporary_buffer(); + std::cout << doc.owns_source() << '\n'; + std::cout << doc.root().is_object() << '\n'; +} diff --git a/docs/mkdocs/docs/examples/basic_json_document__parse_copy.output b/docs/mkdocs/docs/examples/basic_json_document__parse_copy.output new file mode 100644 index 000000000..bb101b641 --- /dev/null +++ b/docs/mkdocs/docs/examples/basic_json_document__parse_copy.output @@ -0,0 +1,2 @@ +true +true diff --git a/docs/mkdocs/docs/examples/basic_json_document__parse_iterator_pair.cpp b/docs/mkdocs/docs/examples/basic_json_document__parse_iterator_pair.cpp new file mode 100644 index 000000000..6d446bd67 --- /dev/null +++ b/docs/mkdocs/docs/examples/basic_json_document__parse_iterator_pair.cpp @@ -0,0 +1,22 @@ +#include +#include +#include + +using json_document = nlohmann::json_document; + +int main() +{ + std::cout << std::boolalpha; + + // a JSON value embedded in a larger, non-null-terminated buffer (e.g. a + // slice received over the network) + std::vector buffer = {'[', '1', ',', '2', ']', 'j', 'u', 'n', 'k'}; + + // a pointer pair is BORROWED, exactly like a byte container lvalue: the + // document points into the buffer. (From C++20 on, std::vector + // iterators are borrowed as well; before, they are copied.) + const char* first = buffer.data(); + json_document doc = json_document::parse(first, first + 5); + std::cout << doc.root().is_array() << ' ' << doc.root().size() << '\n'; + std::cout << doc.owns_source() << '\n'; // false: borrowed +} diff --git a/docs/mkdocs/docs/examples/basic_json_document__parse_iterator_pair.output b/docs/mkdocs/docs/examples/basic_json_document__parse_iterator_pair.output new file mode 100644 index 000000000..1ea7a5a0e --- /dev/null +++ b/docs/mkdocs/docs/examples/basic_json_document__parse_iterator_pair.output @@ -0,0 +1,2 @@ +true 2 +false diff --git a/docs/mkdocs/docs/examples/basic_json_document__read.cpp b/docs/mkdocs/docs/examples/basic_json_document__read.cpp new file mode 100644 index 000000000..4858a7db7 --- /dev/null +++ b/docs/mkdocs/docs/examples/basic_json_document__read.cpp @@ -0,0 +1,31 @@ +#include +#include +#include +#include + +using json_document = nlohmann::json_document; + +int main() +{ + std::cout << std::boolalpha; + + std::vector messages = + { + R"({"id": 1})", R"({"id": 2, "tag": "x"})", R"({"id": 3})" + }; + + // parse into the same document over and over: its node index and decode + // buffer are reused instead of being freed and reallocated for each message + json_document doc; + std::size_t total = 0; + for (const auto& msg : messages) + { + doc.read(msg); + total += doc.root().size(); + } + std::cout << total << '\n'; + + // read() can also change what kind of input is owned/borrowed between calls + doc.read(std::string(R"({"owned": true})")); + std::cout << doc.owns_source() << '\n'; +} diff --git a/docs/mkdocs/docs/examples/basic_json_document__read.output b/docs/mkdocs/docs/examples/basic_json_document__read.output new file mode 100644 index 000000000..fea15e47f --- /dev/null +++ b/docs/mkdocs/docs/examples/basic_json_document__read.output @@ -0,0 +1,2 @@ +4 +true diff --git a/docs/mkdocs/docs/examples/basic_json_document__root.cpp b/docs/mkdocs/docs/examples/basic_json_document__root.cpp new file mode 100644 index 000000000..9789f2566 --- /dev/null +++ b/docs/mkdocs/docs/examples/basic_json_document__root.cpp @@ -0,0 +1,19 @@ +#include +#include + +using json_document = nlohmann::json_document; + +int main() +{ + std::cout << std::boolalpha; + + json_document doc = json_document::parse(R"({"greeting": "hi"})"); + std::cout << doc.root().is_object() << '\n'; + + // root() is a cheap handle, not a copy: repeated calls observe the same value + std::cout << (doc.root().type() == doc.root().type()) << '\n'; + + // the root of a failed parse (allow_exceptions == false) is discarded + json_document failed = json_document::parse("{", false); + std::cout << failed.root().is_discarded() << '\n'; +} diff --git a/docs/mkdocs/docs/examples/basic_json_document__root.output b/docs/mkdocs/docs/examples/basic_json_document__root.output new file mode 100644 index 000000000..b979d62f4 --- /dev/null +++ b/docs/mkdocs/docs/examples/basic_json_document__root.output @@ -0,0 +1,3 @@ +true +true +true diff --git a/docs/mkdocs/docs/examples/basic_json_document__shrink_to_fit.cpp b/docs/mkdocs/docs/examples/basic_json_document__shrink_to_fit.cpp new file mode 100644 index 000000000..f2560078a --- /dev/null +++ b/docs/mkdocs/docs/examples/basic_json_document__shrink_to_fit.cpp @@ -0,0 +1,44 @@ +#include +#include +#include +#include + +using json_document = nlohmann::json_document; + +int main() +{ + std::cout << std::boolalpha; + + // build a large array (many nodes), then read a small one into the same + // document: the index grown for the large input is still allocated + std::ostringstream big; + big << '['; + for (int i = 0; i < 500; ++i) + { + if (i != 0) + { + big << ','; + } + big << i; + } + big << ']'; + + json_document doc; + doc.read(big.str()); + const std::size_t big_nodes = doc.node_count(); + + doc.read(std::string("[1]")); + std::cout << (doc.node_count() < big_nodes) << '\n'; // far fewer live nodes now + const std::size_t before = doc.memory_usage(); + + // shrink_to_fit() moves the index into a block sized for what is actually + // used. This INVALIDATES every view taken from this document before the + // call (they point into the old, now-freed block) -- take fresh ones from + // root() afterward. + doc.shrink_to_fit(); + const std::size_t after = doc.memory_usage(); + std::cout << (after <= before) << '\n'; + + // a freshly taken view is valid and correct + std::cout << doc.root().is_array() << ' ' << doc.root().size() << '\n'; +} diff --git a/docs/mkdocs/docs/examples/basic_json_document__shrink_to_fit.output b/docs/mkdocs/docs/examples/basic_json_document__shrink_to_fit.output new file mode 100644 index 000000000..9e7440e42 --- /dev/null +++ b/docs/mkdocs/docs/examples/basic_json_document__shrink_to_fit.output @@ -0,0 +1,3 @@ +true +true +true 1 diff --git a/docs/mkdocs/docs/examples/basic_json_document__source.cpp b/docs/mkdocs/docs/examples/basic_json_document__source.cpp new file mode 100644 index 000000000..722cdffaf --- /dev/null +++ b/docs/mkdocs/docs/examples/basic_json_document__source.cpp @@ -0,0 +1,20 @@ +#include +#include +#include + +using json_document = nlohmann::json_document; + +int main() +{ + std::cout << std::boolalpha; + + std::string text = R"({"a": 1})"; + json_document doc = json_document::parse(text); + + // source() is the parsed text, whether borrowed or owned + std::cout << (doc.source().size() == text.size()) << '\n'; + std::cout << std::string(doc.source().data(), doc.source().size()) << '\n'; + + // for a borrowed document, source() points right into the caller's buffer + std::cout << (doc.source().data() == text.data()) << '\n'; +} diff --git a/docs/mkdocs/docs/examples/basic_json_document__source.output b/docs/mkdocs/docs/examples/basic_json_document__source.output new file mode 100644 index 000000000..1570aec3a --- /dev/null +++ b/docs/mkdocs/docs/examples/basic_json_document__source.output @@ -0,0 +1,3 @@ +true +{"a": 1} +true diff --git a/docs/mkdocs/docs/examples/basic_json_view__basic_json_view.cpp b/docs/mkdocs/docs/examples/basic_json_view__basic_json_view.cpp new file mode 100644 index 000000000..af08f22e0 --- /dev/null +++ b/docs/mkdocs/docs/examples/basic_json_view__basic_json_view.cpp @@ -0,0 +1,17 @@ +#include +#include + +int main() +{ + std::cout << std::boolalpha; + + // the default constructor is the only public one: it creates an invalid + // (discarded) view, useful as a "no value yet" placeholder + nlohmann::json_view v; + std::cout << static_cast(v) << ' ' << v.is_discarded() << '\n'; + + // views are trivially copyable handles (two pointers); the document owns + // the actual data + nlohmann::json_view copy = v; + std::cout << static_cast(copy) << '\n'; +} diff --git a/docs/mkdocs/docs/examples/basic_json_view__basic_json_view.output b/docs/mkdocs/docs/examples/basic_json_view__basic_json_view.output new file mode 100644 index 000000000..8192d6145 --- /dev/null +++ b/docs/mkdocs/docs/examples/basic_json_view__basic_json_view.output @@ -0,0 +1,2 @@ +false true +false diff --git a/docs/mkdocs/docs/examples/basic_json_view__materialize.cpp b/docs/mkdocs/docs/examples/basic_json_view__materialize.cpp new file mode 100644 index 000000000..38160b461 --- /dev/null +++ b/docs/mkdocs/docs/examples/basic_json_view__materialize.cpp @@ -0,0 +1,33 @@ +#include +#include +#include + +using json_document = nlohmann::json_document; + +int main() +{ + // three incoming messages; skip the ones that are not useful without ever + // building a nlohmann::json value for them + json_document heartbeat = json_document::parse("null"); + json_document empty_batch = json_document::parse("[]"); + json_document batch = json_document::parse(R"([{"id": 1}, {"id": 2}, {"id": 3}])"); + std::array messages = {{&heartbeat, &empty_batch, &batch}}; + + for (const json_document* d : messages) + { + // is_array()/empty() only look at the flat index: a discarded + // heartbeat or an empty batch is never turned into a nlohmann::json + // value, so no per-element allocation happens for them + if (!d->root().is_array() || d->root().empty()) + { + std::cout << "skipped\n"; + continue; + } + + // materialize() replays the subtree through the same SAX builder + // basic_json::parse() uses, so the result is exactly what + // basic_json::parse() would have produced for the same text + nlohmann::json value = d->root().materialize(); + std::cout << value.dump() << '\n'; + } +} diff --git a/docs/mkdocs/docs/examples/basic_json_view__materialize.output b/docs/mkdocs/docs/examples/basic_json_view__materialize.output new file mode 100644 index 000000000..207c875ff --- /dev/null +++ b/docs/mkdocs/docs/examples/basic_json_view__materialize.output @@ -0,0 +1,3 @@ +skipped +skipped +[{"id":1},{"id":2},{"id":3}] diff --git a/docs/mkdocs/docs/examples/basic_json_view__size_empty.cpp b/docs/mkdocs/docs/examples/basic_json_view__size_empty.cpp new file mode 100644 index 000000000..36700ef9d --- /dev/null +++ b/docs/mkdocs/docs/examples/basic_json_view__size_empty.cpp @@ -0,0 +1,22 @@ +#include +#include + +using json_document = nlohmann::json_document; + +int main() +{ + std::cout << std::boolalpha; + + // decide whether a batch is worth processing before building any + // nlohmann::json value for it + json_document batch = json_document::parse(R"([1, 2, 3, 4, 5])"); + json_document empty_batch = json_document::parse("[]"); + + std::cout << batch.root().empty() << ' ' << batch.root().size() << '\n'; + std::cout << empty_batch.root().empty() << ' ' << empty_batch.root().size() << '\n'; + + // as for basic_json: null has size 0, every other scalar has size 1 + json_document n = json_document::parse("null"); + json_document s = json_document::parse(R"("hi")"); + std::cout << n.root().size() << ' ' << s.root().size() << '\n'; +} diff --git a/docs/mkdocs/docs/examples/basic_json_view__size_empty.output b/docs/mkdocs/docs/examples/basic_json_view__size_empty.output new file mode 100644 index 000000000..8e7ccf182 --- /dev/null +++ b/docs/mkdocs/docs/examples/basic_json_view__size_empty.output @@ -0,0 +1,3 @@ +false 5 +true 0 +0 1 diff --git a/docs/mkdocs/docs/examples/basic_json_view__source_offset.cpp b/docs/mkdocs/docs/examples/basic_json_view__source_offset.cpp new file mode 100644 index 000000000..651964f0f --- /dev/null +++ b/docs/mkdocs/docs/examples/basic_json_view__source_offset.cpp @@ -0,0 +1,33 @@ +#include +#include +#include + +using json_document = nlohmann::json_document; + +int main() +{ + std::cout << std::boolalpha; + + // source_offset() points into source(): useful to report *where* in the + // original text a value came from (error messages, syntax highlighting, + // forwarding a sub-range verbatim, ...) without materializing it + json_document doc = json_document::parse(R"( 123)"); + auto v = doc.root(); + std::cout << v.source_offset() << ' ' + << std::string(doc.source().data() + v.source_offset(), 3) << '\n'; + + // a string without escapes also stays in the source text + json_document plain = json_document::parse(R"("ab")"); + std::cout << plain.source()[plain.root().source_offset()] << '\n'; + + // a string with escapes is decoded once into the document's own buffer, so + // there is no single byte range in source() to point at: source_offset() + // returns the "not applicable" sentinel + json_document escaped = json_document::parse(R"("a\nb")"); + std::cout << (escaped.root().source_offset() == static_cast(-1)) << '\n'; + + // a discarded view -- default-constructed, or the root of a failed parse + // with allow_exceptions == false -- has no offset either + json_document failed = json_document::parse("not json", false); + std::cout << (failed.root().source_offset() == static_cast(-1)) << '\n'; +} diff --git a/docs/mkdocs/docs/examples/basic_json_view__source_offset.output b/docs/mkdocs/docs/examples/basic_json_view__source_offset.output new file mode 100644 index 000000000..eae7db157 --- /dev/null +++ b/docs/mkdocs/docs/examples/basic_json_view__source_offset.output @@ -0,0 +1,4 @@ +2 123 +a +true +true diff --git a/docs/mkdocs/docs/examples/basic_json_view__type_predicates.cpp b/docs/mkdocs/docs/examples/basic_json_view__type_predicates.cpp new file mode 100644 index 000000000..1e3ed62e2 --- /dev/null +++ b/docs/mkdocs/docs/examples/basic_json_view__type_predicates.cpp @@ -0,0 +1,43 @@ +#include +#include + +using json_document = nlohmann::json_document; + +int main() +{ + std::cout << std::boolalpha; + + // several incoming messages, one json_document per message. type() and + // is_*() only look at the flat index built by parse(); no nlohmann::json + // tree exists yet, and none is built unless materialize() is called + json_document d_null = json_document::parse("null"); + json_document d_bool = json_document::parse("true"); + json_document d_int = json_document::parse("-42"); + json_document d_unsigned = json_document::parse("42"); + json_document d_float = json_document::parse("4.2"); + json_document d_string = json_document::parse(R"("hi")"); + json_document d_array = json_document::parse("[1, 2, 3]"); + json_document d_object = json_document::parse(R"({"a": 1})"); + + std::cout << d_null.root().is_null() << '\n'; + std::cout << d_bool.root().is_boolean() << '\n'; + std::cout << d_int.root().is_number() << ' ' << d_int.root().is_number_integer() << '\n'; + std::cout << d_unsigned.root().is_number_unsigned() << '\n'; + std::cout << d_float.root().is_number_float() << '\n'; + std::cout << d_string.root().is_string() << '\n'; + std::cout << d_array.root().is_array() << ' ' << d_array.root().is_structured() << '\n'; + std::cout << d_object.root().is_object() << ' ' << d_object.root().is_primitive() << '\n'; + + // JSON text can never produce a binary value: is_binary() is always false + std::cout << d_array.root().is_binary() << '\n'; + + // a default-constructed view, and the root of a document that failed to + // parse without exceptions, are both discarded + nlohmann::json_view invalid; + json_document failed = json_document::parse("not json", /* allow_exceptions */ false); + std::cout << static_cast(invalid) << ' ' << invalid.is_discarded() << '\n'; + std::cout << static_cast(failed.root()) << ' ' << failed.root().is_discarded() << '\n'; + + // type() returns the same value_t enumeration as basic_json::type() + std::cout << (d_object.root().type() == nlohmann::json::value_t::object) << '\n'; +} diff --git a/docs/mkdocs/docs/examples/basic_json_view__type_predicates.output b/docs/mkdocs/docs/examples/basic_json_view__type_predicates.output new file mode 100644 index 000000000..285d31ca0 --- /dev/null +++ b/docs/mkdocs/docs/examples/basic_json_view__type_predicates.output @@ -0,0 +1,12 @@ +true +true +true true +true +true +true +true true +true false +false +false true +false true +true diff --git a/docs/mkdocs/docs/examples/json_document.cpp b/docs/mkdocs/docs/examples/json_document.cpp new file mode 100644 index 000000000..01f2847e2 --- /dev/null +++ b/docs/mkdocs/docs/examples/json_document.cpp @@ -0,0 +1,16 @@ +#include +#include + +using json_document = nlohmann::json_document; + +int main() +{ + std::cout << std::boolalpha; + + // json_document is basic_json_document: same value types + // and containers as the ordinary json specialization + json_document doc = json_document::parse(R"({"pi": 3.14, "numbers": [1, 2, 3]})"); + + std::cout << doc.root().is_object() << '\n'; + std::cout << doc.root().materialize().dump() << '\n'; +} diff --git a/docs/mkdocs/docs/examples/json_document.output b/docs/mkdocs/docs/examples/json_document.output new file mode 100644 index 000000000..48225d164 --- /dev/null +++ b/docs/mkdocs/docs/examples/json_document.output @@ -0,0 +1,2 @@ +true +{"numbers":[1,2,3],"pi":3.14} diff --git a/docs/mkdocs/docs/examples/json_view.cpp b/docs/mkdocs/docs/examples/json_view.cpp new file mode 100644 index 000000000..64f8ec575 --- /dev/null +++ b/docs/mkdocs/docs/examples/json_view.cpp @@ -0,0 +1,14 @@ +#include +#include + +int main() +{ + std::cout << std::boolalpha; + + // json_view is basic_json_view: a read-only handle + // returned by json_document::root() + nlohmann::json_document doc = nlohmann::json_document::parse("[1, 2, 3]"); + nlohmann::json_view v = doc.root(); + + std::cout << v.is_array() << ' ' << v.size() << '\n'; +} diff --git a/docs/mkdocs/docs/examples/json_view.output b/docs/mkdocs/docs/examples/json_view.output new file mode 100644 index 000000000..0a43dc098 --- /dev/null +++ b/docs/mkdocs/docs/examples/json_view.output @@ -0,0 +1 @@ +true 3 diff --git a/docs/mkdocs/docs/examples/json_view_ownership.cpp b/docs/mkdocs/docs/examples/json_view_ownership.cpp new file mode 100644 index 000000000..fa0e8262a --- /dev/null +++ b/docs/mkdocs/docs/examples/json_view_ownership.cpp @@ -0,0 +1,33 @@ +#include +#include +#include +#include + +using json_document = nlohmann::json_document; + +int main() +{ + std::cout << std::boolalpha; + + // BORROWED: doc only points into `text`; `text` must outlive `doc` + std::string text = R"({"a": 1})"; + json_document doc = json_document::parse(text); + std::cout << doc.owns_source() << '\n'; // false + + // a view is valid as long as the document is alive, has not been + // re-parsed (read()) or shrunk (shrink_to_fit()), and -- if borrowed -- + // the source text is alive + nlohmann::json_view v = doc.root(); + std::cout << v.is_object() << '\n'; + + // re-parsing the SAME document invalidates views taken before the call; + // `v` above must not be used after this line + doc.read(R"([1, 2, 3])"); + v = doc.root(); // take a fresh view instead + std::cout << v.is_array() << '\n'; + + // moving the document does not invalidate views: the node index is + // heap-allocated and does not move with the document object + json_document moved = std::move(doc); + std::cout << v.is_array() << '\n'; +} diff --git a/docs/mkdocs/docs/examples/json_view_ownership.output b/docs/mkdocs/docs/examples/json_view_ownership.output new file mode 100644 index 000000000..fc2b492b1 --- /dev/null +++ b/docs/mkdocs/docs/examples/json_view_ownership.output @@ -0,0 +1,4 @@ +false +true +true +true diff --git a/docs/mkdocs/docs/examples/ordered_json_document.cpp b/docs/mkdocs/docs/examples/ordered_json_document.cpp new file mode 100644 index 000000000..2cae413bf --- /dev/null +++ b/docs/mkdocs/docs/examples/ordered_json_document.cpp @@ -0,0 +1,13 @@ +#include +#include + +using ordered_json_document = nlohmann::ordered_json_document; + +int main() +{ + // ordered_json_document is basic_json_document: + // materialize() preserves the insertion (source) order of object keys, + // instead of sorting them like json_document does + ordered_json_document doc = ordered_json_document::parse(R"({"z": 1, "a": 2, "m": 3})"); + std::cout << doc.root().materialize().dump() << '\n'; +} diff --git a/docs/mkdocs/docs/examples/ordered_json_document.output b/docs/mkdocs/docs/examples/ordered_json_document.output new file mode 100644 index 000000000..4d441f752 --- /dev/null +++ b/docs/mkdocs/docs/examples/ordered_json_document.output @@ -0,0 +1 @@ +{"z":1,"a":2,"m":3} diff --git a/docs/mkdocs/docs/examples/ordered_json_view.cpp b/docs/mkdocs/docs/examples/ordered_json_view.cpp new file mode 100644 index 000000000..5fdf09a82 --- /dev/null +++ b/docs/mkdocs/docs/examples/ordered_json_view.cpp @@ -0,0 +1,10 @@ +#include +#include + +int main() +{ + nlohmann::ordered_json_document doc = nlohmann::ordered_json_document::parse(R"({"z": 1, "a": 2})"); + nlohmann::ordered_json_view v = doc.root(); + + std::cout << std::boolalpha << v.is_object() << ' ' << v.size() << '\n'; +} diff --git a/docs/mkdocs/docs/examples/ordered_json_view.output b/docs/mkdocs/docs/examples/ordered_json_view.output new file mode 100644 index 000000000..fc59b1f20 --- /dev/null +++ b/docs/mkdocs/docs/examples/ordered_json_view.output @@ -0,0 +1 @@ +true 2 diff --git a/docs/mkdocs/docs/features/index.md b/docs/mkdocs/docs/features/index.md index 33403a58c..246e47aee 100644 --- a/docs/mkdocs/docs/features/index.md +++ b/docs/mkdocs/docs/features/index.md @@ -11,6 +11,8 @@ C++ types, and finally serialize it again. - [Parsing](parsing/index.md) — read a JSON value from a string, file, or stream, including [JSON Lines](parsing/json_lines.md), [callbacks](parsing/parser_callbacks.md), the [SAX interface](parsing/sax_interface.md), and [error handling](parsing/parse_exceptions.md). +- [Zero-copy JSON views](json_view.md) — read a JSON text through a flat index instead of building a `json` tree; + strings and numbers stay in the input and are only decoded when needed. - [Comments](comments.md) and [trailing commas](trailing_commas.md) — opt-in relaxations of the JSON grammar. ## Accessing and modifying values diff --git a/docs/mkdocs/docs/features/json_view.md b/docs/mkdocs/docs/features/json_view.md new file mode 100644 index 000000000..baf96b263 --- /dev/null +++ b/docs/mkdocs/docs/features/json_view.md @@ -0,0 +1,134 @@ +# Zero-copy JSON views + +`#!cpp ` adds a read-only, non-owning way to look at a parsed JSON text, as an alternative to +building a [`basic_json`](../api/basic_json/index.md) tree with [`parse()`](../api/basic_json/parse.md). + +## The problem + +[`basic_json::parse()`](../api/basic_json/parse.md) builds a tree of `basic_json` values: one allocation for every +array and object, and every string copied into its own `std::string`. That is the right trade-off when the program +goes on to read and write the value freely, but it does more work than necessary when only a small part of a large +JSON text is actually needed, or when the same text is parsed over and over (many small messages, for instance) and +most of the resulting tree is thrown away almost immediately. + +## The idea + +[`basic_json_document::parse()`](../api/basic_json_document/parse.md) parses the same JSON grammar, with the same +options, but instead of a tree it builds a flat index of the values it found: one 16-byte entry per value (and one +per object key), in document order. Strings and numbers are not copied out of the input; they stay in the source +text, and are only decoded when actually needed (for a string, only if it contains escape sequences, into one shared +buffer owned by the document). + +[`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 -- +[`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 +`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 + +Include `` in addition to (or instead of) ``. Parse into a +[`json_document`](../api/json_document.md), inspect its [`root()`](../api/basic_json_document/root.md), and +`materialize()` when you need a real value: + +??? example "Example: parse a document, inspect its root, and materialize it" + + ```cpp + --8<-- "examples/json_document.cpp" + ``` + + Output: + + ```json + --8<-- "examples/json_document.output" + ``` + +[`ordered_json_document`](../api/ordered_json_document.md) is the equivalent for +[`ordered_json`](../api/ordered_json.md), just as [`ordered_json`](../api/ordered_json.md) is to +[`json`](../api/json.md). + +## Ownership and lifetime + +A document either **borrows** the text it was parsed from, or **owns** its own copy of it; call +[`owns_source()`](../api/basic_json_document/owns_source.md) to find out which happened. +[`parse()`](../api/basic_json_document/parse.md) decides this from the value category and type of its argument (an +lvalue `#!cpp std::string` is borrowed; an rvalue `#!cpp std::string` is moved in, owned without a copy; a stream is +read into an owned buffer; and so on -- see [`parse`'s Notes](../api/basic_json_document/parse.md#notes) for the full +table). [`parse_copy()`](../api/basic_json_document/parse_copy.md) always owns a copy, regardless of the input. + +!!! warning "A borrowed document depends on your buffer" + + If a document borrows its text, that text **must outlive the document** (and every view taken from it). Reading + or writing through a view after the underlying buffer is gone is undefined behavior, exactly as it would be for + a dangling `#!cpp std::string_view`. + +A view is valid only while all of the following hold: + +- the document is alive, +- the document has not been re-parsed since the view was taken (with [`read()`](../api/basic_json_document/read.md) + or [`parse()`](../api/basic_json_document/parse.md) into it), and has not had + [`shrink_to_fit()`](../api/basic_json_document/shrink_to_fit.md) called on it since, and +- if the document borrows its source text, that text is still alive. + +Moving the document itself is fine and does **not** invalidate its views: the index is a separate heap allocation +that keeps its address across the move. Take a fresh view from [`root()`](../api/basic_json_document/root.md) +whenever any of the other conditions above was not met. + +??? example "Example: borrowed and owned documents, and when views become invalid" + + ```cpp + --8<-- "examples/json_view_ownership.cpp" + ``` + + Output: + + ```json + --8<-- "examples/json_view_ownership.output" + ``` + +## What is the same as `parse()` + +- **Accept/reject.** [`accept()`](../api/basic_json_document/accept.md) and + [`parse()`](../api/basic_json_document/parse.md) accept and reject exactly the same inputs as + [`basic_json::accept()`](../api/basic_json/accept.md)/[`basic_json::parse()`](../api/basic_json/parse.md), with the + same `ignore_comments` and `ignore_trailing_commas` options. +- **Errors.** A failing parse throws the same exception -- the same id, message, and position -- because on failure + the library's own parser is run on the same bytes to produce the diagnostic. + `#!cpp allow_exceptions == false` gives a [discarded](../api/basic_json_document/is_discarded.md) document instead + of throwing, just as it gives a discarded value for `#!cpp basic_json::parse()`. +- **Number classification.** An integer literal that does not fit into the 64-bit integer type becomes a + floating-point value, exactly as it does for `#!cpp basic_json::parse()`. +- **Macros.** [`JSON_STRICT_NUL_HANDLING`](../api/macros/json_strict_nul_handling.md) and + [`JSON_NOEXCEPTION`](../api/macros/json_noexception.md)/[`JSON_THROW_USER`](../api/macros/json_throw_user.md) + behave the same way they do for ``. + +## What is different + +- **Only 64-bit integers.** `basic_json_document` requires `BasicJsonType::number_integer_t` and + `number_unsigned_t` to both be 64 bits wide; this is a compile-time `#!cpp static_assert`. +- **A 4 GiB input limit.** An input of 4 GiB or more throws + [`out_of_range.416`](../home/exceptions.md#jsonexceptionout_of_range416), a limit + `#!cpp basic_json::parse()` does not have. +- **A stream is always read to its end.** There is no partial/streaming read of an `#!cpp std::istream`. +- **No source positions on `materialize()`.** Even with + [`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 + replay to record them. +- **Element access, iteration, `get()`, 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` + +| | [`json`](../api/json.md) / [`ordered_json`](../api/ordered_json.md) | [SAX interface](parsing/sax_interface.md) | [`json_document`](../api/json_document.md) / [`json_view`](../api/json_view.md) | +|---|---|---|---| +| **Ownership** | owns every value | owns nothing; you decide what to keep, in your handler | borrows or owns the *text*; the index is always owned by the document | +| **Mutability** | freely mutable | not applicable (a one-shot event stream) | read-only | +| **What you get** | a full tree you can read, write, and keep as long as you like | a sequence of callbacks; whatever your handler builds from them | a flat index plus, on demand, [`materialize()`](../api/basic_json_view/materialize.md)d `json`/`ordered_json` values for the parts you actually use | +| **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 | + +## Version history + +- Added in version 3.13.0. diff --git a/docs/mkdocs/docs/home/architecture.md b/docs/mkdocs/docs/home/architecture.md index 6c0892f11..fc2d7a344 100644 --- a/docs/mkdocs/docs/home/architecture.md +++ b/docs/mkdocs/docs/home/architecture.md @@ -51,6 +51,11 @@ The public headers are in [`include/nlohmann`](https://github.com/nlohmann/json/ [`adl_serializer`](../api/adl_serializer/index.md), [`byte_container_with_subtype`](../api/byte_container_with_subtype/index.md), and [`ordered_map`](../api/ordered_map.md). +- [`json_view.hpp`](https://github.com/nlohmann/json/blob/develop/include/nlohmann/json_view.hpp) is a separate, + optional header that defines [`basic_json_document`](../api/basic_json_document/index.md) and + [`basic_json_view`](../api/basic_json_view/index.md), a flat-index, read-only, non-owning way to look at a parsed + JSON text; see [Zero-copy JSON views](../features/json_view.md). It builds on `json.hpp` internals (it requires the + same library version) and has its own `detail/view/` subdirectory. Everything else lives in [`detail/`](https://github.com/nlohmann/json/tree/develop/include/nlohmann/detail) and namespace `nlohmann::detail`, which is not part of the public API. Paths below are relative to `include/nlohmann`. @@ -74,7 +79,9 @@ below are relative to `include/nlohmann`. | Macros | [`detail/macro_scope.hpp`](https://github.com/nlohmann/json/blob/develop/include/nlohmann/detail/macro_scope.hpp), [`detail/macro_unscope.hpp`](https://github.com/nlohmann/json/blob/develop/include/nlohmann/detail/macro_unscope.hpp), [`detail/abi_macros.hpp`](https://github.com/nlohmann/json/blob/develop/include/nlohmann/detail/abi_macros.hpp) | The single-header version [`single_include/nlohmann/json.hpp`](https://github.com/nlohmann/json/blob/develop/single_include/nlohmann/json.hpp) -is generated from these files with `make amalgamate` and must not be edited by hand. +is generated from these files with `make amalgamate` and must not be edited by hand. The same command also generates +[`single_include/nlohmann/json_view.hpp`](https://github.com/nlohmann/json/blob/develop/single_include/nlohmann/json_view.hpp) +from `json_view.hpp` and `detail/view/`. ## Template parameters diff --git a/docs/mkdocs/docs/home/exceptions.md b/docs/mkdocs/docs/home/exceptions.md index 407f3c3f1..d3c01a681 100644 --- a/docs/mkdocs/docs/home/exceptions.md +++ b/docs/mkdocs/docs/home/exceptions.md @@ -1002,6 +1002,23 @@ MessagePack's ext type and BSON's binary subtype are each stored in a single byt This exception was added in version 3.13.0. Before that, subtypes above 255 were silently truncated modulo 256 instead of raising an error. +### json.exception.out_of_range.416 + +[`basic_json_document::parse()`](../api/basic_json_document/parse.md) and the other parsing functions of +[`basic_json_document`](../api/basic_json_document/index.md) index a value's position in the source text in 32 bits, +so they do not support an input of 4 GiB or more. + +!!! failure "Example message" + + ``` + [json.exception.out_of_range.416] input of 4 GiB or more is not supported by json_document + ``` + +!!! note + + This exception was added in version 3.13.0, together with [``](../features/json_view.md). + [`basic_json::parse()`](../api/basic_json/parse.md) has no such limit. + ## Further exceptions This exception is thrown in case of errors that cannot be classified with the diff --git a/docs/mkdocs/docs/home/license.md b/docs/mkdocs/docs/home/license.md index 863b7c1d6..9e602777c 100644 --- a/docs/mkdocs/docs/home/license.md +++ b/docs/mkdocs/docs/home/license.md @@ -21,3 +21,5 @@ The class contains a slightly modified version of the Grisu2 algorithm from Flor The class contains a copy of [Hedley](https://nemequ.github.io/hedley/) from Evan Nemerson which is licensed as [CC0-1.0](https://creativecommons.org/publicdomain/zero/1.0/). The class contains an adapted version of the Eisel-Lemire algorithm and its table of powers of five from [fast_float](https://github.com/fastfloat/fast_float) by Daniel Lemire and contributors, which is available under the [MIT License](https://opensource.org/licenses/MIT) (used here), the Apache 2.0 License, and the Boost Software License. Copyright © 2021 The fast_float authors + +The view's parser (``) contains techniques and code adapted from [yyjson](https://github.com/ibireme/yyjson) by YaoYuan, which is licensed under the [MIT License](https://opensource.org/licenses/MIT) (see above): table-driven decoding of `\u` escapes and fixed-offset unrolled checks. diff --git a/docs/mkdocs/docs/integration/index.md b/docs/mkdocs/docs/integration/index.md index 2bbaa8604..e6968ea42 100644 --- a/docs/mkdocs/docs/integration/index.md +++ b/docs/mkdocs/docs/integration/index.md @@ -16,3 +16,8 @@ Clang). You can further use file [`single_include/nlohmann/json_fwd.hpp`](https://github.com/nlohmann/json/blob/develop/single_include/nlohmann/json_fwd.hpp) for forward declarations. + +For the read-only, non-owning [`basic_json_document`](../api/basic_json_document/index.md)/[`basic_json_view`](../api/basic_json_view/index.md) +types, additionally include +[`single_include/nlohmann/json_view.hpp`](https://github.com/nlohmann/json/blob/develop/single_include/nlohmann/json_view.hpp); +see [Zero-copy JSON views](../features/json_view.md). diff --git a/docs/mkdocs/mkdocs.yml b/docs/mkdocs/mkdocs.yml index 70537bd27..0058b0e58 100644 --- a/docs/mkdocs/mkdocs.yml +++ b/docs/mkdocs/mkdocs.yml @@ -100,6 +100,7 @@ nav: - features/types/index.md - features/types/number_handling.md - features/types/template_parameters.md + - features/json_view.md - Integration: - integration/index.md - integration/migration_guide.md @@ -228,6 +229,42 @@ nav: - 'update': api/basic_json/update.md - 'value': api/basic_json/value.md - 'value_t': api/basic_json/value_t.md + - basic_json_document: + - 'Overview': api/basic_json_document/index.md + - '(Constructor)': api/basic_json_document/basic_json_document.md + - 'accept': api/basic_json_document/accept.md + - 'is_discarded': api/basic_json_document/is_discarded.md + - 'memory_usage': api/basic_json_document/memory_usage.md + - 'node_count': api/basic_json_document/node_count.md + - 'owns_source': api/basic_json_document/owns_source.md + - 'parse': api/basic_json_document/parse.md + - 'parse_copy': api/basic_json_document/parse_copy.md + - 'read': api/basic_json_document/read.md + - 'root': api/basic_json_document/root.md + - 'shrink_to_fit': api/basic_json_document/shrink_to_fit.md + - 'source': api/basic_json_document/source.md + - basic_json_view: + - 'Overview': api/basic_json_view/index.md + - '(Constructor)': api/basic_json_view/basic_json_view.md + - 'empty': api/basic_json_view/empty.md + - 'is_array': api/basic_json_view/is_array.md + - 'is_binary': api/basic_json_view/is_binary.md + - 'is_boolean': api/basic_json_view/is_boolean.md + - 'is_discarded': api/basic_json_view/is_discarded.md + - 'is_null': api/basic_json_view/is_null.md + - 'is_number': api/basic_json_view/is_number.md + - 'is_number_float': api/basic_json_view/is_number_float.md + - 'is_number_integer': api/basic_json_view/is_number_integer.md + - 'is_number_unsigned': api/basic_json_view/is_number_unsigned.md + - 'is_object': api/basic_json_view/is_object.md + - 'is_primitive': api/basic_json_view/is_primitive.md + - 'is_string': api/basic_json_view/is_string.md + - 'is_structured': api/basic_json_view/is_structured.md + - 'materialize': api/basic_json_view/materialize.md + - 'operator bool': api/basic_json_view/operator_bool.md + - 'size': api/basic_json_view/size.md + - 'source_offset': api/basic_json_view/source_offset.md + - 'type': api/basic_json_view/type.md - byte_container_with_subtype: - 'Overview': api/byte_container_with_subtype/index.md - '(constructor)': api/byte_container_with_subtype/byte_container_with_subtype.md @@ -240,6 +277,7 @@ nav: - 'from_json': api/adl_serializer/from_json.md - 'to_json': api/adl_serializer/to_json.md - 'json': api/json.md + - 'json_document': api/json_document.md - json_pointer: - 'Overview': api/json_pointer/index.md - '(Constructor)': api/json_pointer/json_pointer.md @@ -273,11 +311,14 @@ nav: - 'start_array': api/json_sax/start_array.md - 'start_object': api/json_sax/start_object.md - 'string': api/json_sax/string.md + - 'json_view': api/json_view.md - 'operator<<(basic_json), operator<<(json_pointer)': api/operator_ltlt.md - 'operator>>(basic_json)': api/operator_gtgt.md - 'operator""_json': api/operator_literal_json.md - 'operator""_json_pointer': api/operator_literal_json_pointer.md - 'ordered_json': api/ordered_json.md + - 'ordered_json_document': api/ordered_json_document.md + - 'ordered_json_view': api/ordered_json_view.md - 'ordered_map': api/ordered_map.md - macros: - 'Overview': api/macros/index.md @@ -431,6 +472,8 @@ plugins: API Documentation: - api/*.md - api/basic_json/*.md + - api/basic_json_document/*.md + - api/basic_json_view/*.md - api/adl_serializer/*.md - api/byte_container_with_subtype/*.md - api/json_pointer/*.md