mirror of
https://github.com/nlohmann/json.git
synced 2026-10-28 19:45:22 +00:00
deploy: 4155e2938f
This commit is contained in:
@@ -0,0 +1,100 @@
|
||||
# <small>nlohmann::basic_json_document::</small>accept
|
||||
|
||||
```cpp
|
||||
template<typename InputType>
|
||||
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.
|
||||
|
||||
The result is the same as that of `BasicJsonType::accept()` by design; the difference is how the check is made. This
|
||||
function runs the document's index builder (and discards the index), while `BasicJsonType::accept()` runs the SAX
|
||||
parser with a handler that ignores every event. Use this one if you go on to parse the same input with
|
||||
[`parse()`](parse.md) anyway, so that both use the same code; either is fine for a plain yes/no answer.
|
||||
|
||||
## 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.
|
||||
|
||||
## Notes
|
||||
|
||||
An integer argument that is not a `#!cpp bool` where the flags are expected, such as `#!cpp accept(ptr, len)`, does not
|
||||
compile; see [`parse`](parse.md#notes).
|
||||
|
||||
## Examples
|
||||
|
||||
??? example
|
||||
|
||||
```cpp
|
||||
#include <iostream>
|
||||
#include <nlohmann/json.hpp>
|
||||
#include <nlohmann/json_view.hpp>
|
||||
|
||||
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';
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
Output:
|
||||
|
||||
```json
|
||||
true
|
||||
false
|
||||
true
|
||||
true
|
||||
|
||||
```
|
||||
|
||||
## 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.
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,84 @@
|
||||
# nlohmann::basic_json_document::accept
|
||||
|
||||
```
|
||||
template<typename InputType>
|
||||
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()`](https://json.nlohmann.me/api/basic_json/accept/index.md) does, with the same options. Unlike [`parse()`](https://json.nlohmann.me/api/basic_json_document/parse/index.md), this function never throws an exception for invalid input, and the returned `bool` is the only result -- no document is returned.
|
||||
|
||||
The result is the same as that of `BasicJsonType::accept()` by design; the difference is how the check is made. This function runs the document's index builder (and discards the index), while `BasicJsonType::accept()` runs the SAX parser with a handler that ignores every event. Use this one if you go on to parse the same input with [`parse()`](https://json.nlohmann.me/api/basic_json_document/parse/index.md) anyway, so that both use the same code; either is fine for a plain yes/no answer.
|
||||
|
||||
## Template parameters
|
||||
|
||||
`InputType` : A compatible input; see [`parse`](https://json.nlohmann.me/api/basic_json_document/parse/#template-parameters).
|
||||
|
||||
## Parameters
|
||||
|
||||
`input` (in) : Input to check.
|
||||
|
||||
`ignore_comments` (in) : whether comments should be ignored and treated like whitespace (`true`) or yield a parse error (`false`); (optional, `false` by default)
|
||||
|
||||
`ignore_trailing_commas` (in) : whether trailing commas in arrays or objects should be ignored and treated like whitespace (`true`) or yield a parse error (`false`); (optional, `false` by default)
|
||||
|
||||
## 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.
|
||||
|
||||
## Notes
|
||||
|
||||
An integer argument that is not a `bool` where the flags are expected, such as `accept(ptr, len)`, does not compile; see [`parse`](https://json.nlohmann.me/api/basic_json_document/parse/#notes).
|
||||
|
||||
## Examples
|
||||
|
||||
Example
|
||||
|
||||
```
|
||||
#include <iostream>
|
||||
#include <nlohmann/json.hpp>
|
||||
#include <nlohmann/json_view.hpp>
|
||||
|
||||
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';
|
||||
}
|
||||
```
|
||||
|
||||
Output:
|
||||
|
||||
```
|
||||
true
|
||||
false
|
||||
true
|
||||
true
|
||||
```
|
||||
|
||||
## See also
|
||||
|
||||
- [parse](https://json.nlohmann.me/api/basic_json_document/parse/index.md) - deserialize from a compatible input
|
||||
- [`BasicJsonType::accept`](https://json.nlohmann.me/api/basic_json/accept/index.md) - the corresponding function of `basic_json`
|
||||
|
||||
## Version history
|
||||
|
||||
- Added in version 3.13.0 unreleased.
|
||||
@@ -0,0 +1,83 @@
|
||||
# <small>nlohmann::basic_json_document::</small>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 of its cost: a copy would duplicate the whole
|
||||
index, the decoded-string buffer, and the owned text, while a move is enough in every use we know of.
|
||||
|
||||
## 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.
|
||||
|
||||
## Examples
|
||||
|
||||
??? example
|
||||
|
||||
The example below shows the default constructor and demonstrates that `basic_json_document` is move-only.
|
||||
|
||||
```cpp
|
||||
#include <iostream>
|
||||
#include <utility>
|
||||
#include <nlohmann/json_view.hpp>
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
Output:
|
||||
|
||||
```json
|
||||
true
|
||||
true
|
||||
|
||||
```
|
||||
|
||||
## 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.
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,76 @@
|
||||
# nlohmann::basic_json_document::basic_json_document
|
||||
|
||||
```
|
||||
// (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()`](https://json.nlohmann.me/api/basic_json_document/root/index.md) returns a discarded view, and [`is_discarded()`](https://json.nlohmann.me/api/basic_json_document/is_discarded/index.md) is `true`.
|
||||
1. 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.
|
||||
1. `basic_json_document` is move-only. Copying is disabled because of its cost: a copy would duplicate the whole index, the decoded-string buffer, and the owned text, while a move is enough in every use we know of.
|
||||
|
||||
## 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.
|
||||
|
||||
## Examples
|
||||
|
||||
Example
|
||||
|
||||
The example below shows the default constructor and demonstrates that `basic_json_document` is move-only.
|
||||
|
||||
```
|
||||
#include <iostream>
|
||||
#include <utility>
|
||||
#include <nlohmann/json_view.hpp>
|
||||
|
||||
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
|
||||
}
|
||||
```
|
||||
|
||||
Output:
|
||||
|
||||
```
|
||||
true
|
||||
true
|
||||
```
|
||||
|
||||
## See also
|
||||
|
||||
- [parse](https://json.nlohmann.me/api/basic_json_document/parse/index.md) - deserialize from a compatible input
|
||||
- [is_discarded](https://json.nlohmann.me/api/basic_json_document/is_discarded/index.md) - return whether the last parse failed
|
||||
|
||||
## Version history
|
||||
|
||||
- Added in version 3.13.0 unreleased.
|
||||
@@ -0,0 +1,185 @@
|
||||
# <small>nlohmann::basic_json_document::</small>erase
|
||||
|
||||
```cpp
|
||||
// (1)
|
||||
std::size_t erase(view_type object, string_view_t key);
|
||||
|
||||
// (2)
|
||||
template<typename I>
|
||||
void erase(view_type array, I idx);
|
||||
|
||||
// (3)
|
||||
std::size_t erase(const json_pointer& ptr);
|
||||
```
|
||||
|
||||
Only an **editable** document (`#!cpp Editable == true`, e.g. [`json_editable_document`](../json_editable_document.md))
|
||||
has `erase`; calling it on a read-only `basic_json_document` fails to compile (`#!cpp static_assert`).
|
||||
|
||||
1. Removes every member of `object` whose key is `key` (see [Notes](#notes) on duplicate keys) and returns how many
|
||||
were removed; `#!cpp 0` if `object` has no member with this key.
|
||||
2. Removes the element at index `idx` of `array`, which must already exist (`#!cpp idx < array.size()`).
|
||||
3. Removes the value the JSON pointer `ptr` refers to, relative to [`root()`](root.md). `ptr` must not be empty
|
||||
([`root()`](root.md) itself cannot be erased), and the *parent* of the target must already exist. The target is
|
||||
removed as in 1. if the parent is an object (returns the number of removed members, `#!cpp 0` or more) and as in 2.
|
||||
if it is an array (always returns `#!cpp 1`).
|
||||
|
||||
## Template parameters
|
||||
|
||||
`I`
|
||||
: an integral type other than `#!cpp bool`, deduced (overloads taking a `#!cpp bool` or a non-integral type for
|
||||
`idx` do not participate in overload resolution).
|
||||
|
||||
## Parameters
|
||||
|
||||
`object` (in)
|
||||
: the object to remove a member of
|
||||
|
||||
`array` (in)
|
||||
: the array to remove an element of
|
||||
|
||||
`key` (in)
|
||||
: the key of the member(s) to remove
|
||||
|
||||
`idx` (in)
|
||||
: the index of the element to remove; a negative value throws (see [Exceptions](#exceptions))
|
||||
|
||||
`ptr` (in)
|
||||
: a JSON pointer to the value to remove, relative to `root()`
|
||||
|
||||
## Return value
|
||||
|
||||
1. the number of removed members (`#!cpp 0` if `object` had none with this `key`)
|
||||
2. (nothing)
|
||||
3. the number of removed values (`#!cpp 0` or more for an object member, always `#!cpp 1` for an array element)
|
||||
|
||||
## Exceptions
|
||||
|
||||
1. Throws [`type_error.307`](../../home/exceptions.md#jsonexceptiontype_error307) if `object` is not an object -- the
|
||||
same message [`BasicJsonType::erase`](../basic_json/erase.md) throws for the same type.
|
||||
2. Throws `type_error.307` if `array` is not an array. Throws
|
||||
[`out_of_range.401`](../../home/exceptions.md#jsonexceptionout_of_range401) if `idx` is negative, or if
|
||||
`#!cpp idx >= array.size()`.
|
||||
3. Throws [`out_of_range.405`](../../home/exceptions.md#jsonexceptionout_of_range405) ("JSON pointer has no parent")
|
||||
if `ptr` is empty. Throws what [`at`](../basic_json_view/at.md) throws (overload 3) for resolving `ptr`'s parent.
|
||||
For the last reference token itself: if the parent is an array, throws what 2. throws for an index that is out of
|
||||
range, or, for a token that is not a valid array index,
|
||||
[`parse_error.106`](../../home/exceptions.md#jsonexceptionparse_error106) (a leading `#!cpp '0'`),
|
||||
[`parse_error.109`](../../home/exceptions.md#jsonexceptionparse_error109) (not a number),
|
||||
[`out_of_range.410`](../../home/exceptions.md#jsonexceptionout_of_range410) (too large for `size_type`), or
|
||||
[`out_of_range.404`](../../home/exceptions.md#jsonexceptionout_of_range404) (an empty token); otherwise (an
|
||||
object, or a primitive value the pointer's parent resolves to) throws what 1. throws.
|
||||
|
||||
Overloads 1. and 2. also throw [`invalid_iterator.202`](../../home/exceptions.md#jsonexceptioninvalid_iterator202)
|
||||
("view does not belong to this document") if `object`/`array` is a [discarded](../basic_json_view/is_discarded.md)
|
||||
view or a view of a *different* document. Overload 3. never throws `invalid_iterator.202`: it takes no view, and it
|
||||
always starts from this document's own [`root()`](root.md).
|
||||
|
||||
## Complexity
|
||||
|
||||
1. Linear in the number of members of `object`.
|
||||
2. Linear in the number of elements of `array` at or after `idx` (they move one slot over).
|
||||
3. Linear in the number of reference tokens of `ptr` and, for each token, in the number of members of the object at
|
||||
that level or the index into the array (as [`at`](../basic_json_view/at.md)), plus the complexity of 1. or 2. for
|
||||
the last token.
|
||||
|
||||
## Notes
|
||||
|
||||
!!! info "Duplicate keys"
|
||||
|
||||
Overload 1. removes *every* member with `key`, not just the first -- unlike [`set`](set.md), which assigns the
|
||||
first occurrence and drops the rest. This is why it returns a count rather than a single view: there may be
|
||||
more than one member removed, or none.
|
||||
|
||||
Like [`set`](set.md) and [`push_back`](push_back.md), `erase` never moves an element's *value*: a view still
|
||||
referring to a removed member or element keeps showing what it last held (see [Edits](index.md#edits)) -- it just no
|
||||
longer appears when `array`/`object` is read, dumped, or iterated. What does change is the container's sequence of
|
||||
*links* to its elements: removing an element of `array` (2.) shifts the links to the elements after it by one, as
|
||||
[`insert`](insert.md) does in the other direction. *Every* iterator already taken over `array`/`object` is invalidated
|
||||
by an erase, not only those at or after the removed element, since the container may now use a different sequence.
|
||||
|
||||
## Examples
|
||||
|
||||
??? example
|
||||
|
||||
The example below drops a deprecated field and a decommissioned entry from a configuration document -- using all
|
||||
three overloads -- and shows what stays intact that would not with a plain `json`/`ordered_json` value: the order
|
||||
of the fields around the ones removed, and the exact spelling of a number that was never touched.
|
||||
|
||||
```cpp
|
||||
#include <iostream>
|
||||
#include <nlohmann/json_view.hpp>
|
||||
|
||||
using json = nlohmann::json;
|
||||
using json_editable_document = nlohmann::json_editable_document;
|
||||
using json_editable_view = nlohmann::json_editable_view;
|
||||
|
||||
int main()
|
||||
{
|
||||
// a deprecated field is dropped from a configuration file, and a
|
||||
// decommissioned replica is removed from the list -- "price" keeps its
|
||||
// trailing zero, and the fields around the removed ones keep their order
|
||||
const std::string text = R"({
|
||||
"name": "cache",
|
||||
"legacy_host": "db0",
|
||||
"host": "db1",
|
||||
"price": 19.90,
|
||||
"replicas": ["db2", "db3", "db4"]
|
||||
})";
|
||||
|
||||
json_editable_document doc = json_editable_document::parse(text);
|
||||
|
||||
doc.erase(doc.root(), "legacy_host"); // (1) an object member
|
||||
doc.erase(doc.root()["replicas"], 1); // (2) an array element ("db3")
|
||||
const std::size_t removed = doc.erase(json::json_pointer("/replicas/0")); // (3) via a JSON pointer
|
||||
|
||||
std::cout << removed << '\n';
|
||||
std::cout << doc.root().dump(2, ' ', false, json_editable_view::number_format::source) << "\n\n";
|
||||
|
||||
// the same edits on a plain json value: object_t is a std::map, so
|
||||
// parsing already sorted the keys, and dump() rewrites every number to
|
||||
// its shortest form, even "price", which was never touched
|
||||
json plain = json::parse(text);
|
||||
plain.erase("legacy_host");
|
||||
plain["replicas"].erase(1);
|
||||
plain["replicas"].erase(0);
|
||||
std::cout << plain.dump(2) << '\n';
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
Output:
|
||||
|
||||
```json
|
||||
1
|
||||
{
|
||||
"name": "cache",
|
||||
"host": "db1",
|
||||
"price": 19.90,
|
||||
"replicas": [
|
||||
"db4"
|
||||
]
|
||||
}
|
||||
|
||||
{
|
||||
"host": "db1",
|
||||
"name": "cache",
|
||||
"price": 19.9,
|
||||
"replicas": [
|
||||
"db4"
|
||||
]
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
## See also
|
||||
|
||||
- [insert](insert.md) - insert an element into an array
|
||||
- [set](set.md) - replace a value, or set an object member, an array element, or the value a JSON pointer refers to
|
||||
- [push_back](push_back.md) - append to an array
|
||||
- [root](root.md) - the view of the root value, the starting point of overload 3
|
||||
- [`BasicJsonType::erase`](../basic_json/erase.md) - the corresponding function of `basic_json`
|
||||
- [Edits](index.md#edits) - what an edit guarantees, for every overload
|
||||
|
||||
## Version history
|
||||
|
||||
- Added in version 3.13.0.
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,146 @@
|
||||
# nlohmann::basic_json_document::erase
|
||||
|
||||
```
|
||||
// (1)
|
||||
std::size_t erase(view_type object, string_view_t key);
|
||||
|
||||
// (2)
|
||||
template<typename I>
|
||||
void erase(view_type array, I idx);
|
||||
|
||||
// (3)
|
||||
std::size_t erase(const json_pointer& ptr);
|
||||
```
|
||||
|
||||
Only an **editable** document (`Editable == true`, e.g. [`json_editable_document`](https://json.nlohmann.me/api/json_editable_document/index.md)) has `erase`; calling it on a read-only `basic_json_document` fails to compile (`static_assert`).
|
||||
|
||||
1. Removes every member of `object` whose key is `key` (see [Notes](#notes) on duplicate keys) and returns how many were removed; `0` if `object` has no member with this key.
|
||||
1. Removes the element at index `idx` of `array`, which must already exist (`idx < array.size()`).
|
||||
1. Removes the value the JSON pointer `ptr` refers to, relative to [`root()`](https://json.nlohmann.me/api/basic_json_document/root/index.md). `ptr` must not be empty ([`root()`](https://json.nlohmann.me/api/basic_json_document/root/index.md) itself cannot be erased), and the *parent* of the target must already exist. The target is removed as in 1. if the parent is an object (returns the number of removed members, `0` or more) and as in 2. if it is an array (always returns `1`).
|
||||
|
||||
## Template parameters
|
||||
|
||||
`I` : an integral type other than `bool`, deduced (overloads taking a `bool` or a non-integral type for `idx` do not participate in overload resolution).
|
||||
|
||||
## Parameters
|
||||
|
||||
`object` (in) : the object to remove a member of
|
||||
|
||||
`array` (in) : the array to remove an element of
|
||||
|
||||
`key` (in) : the key of the member(s) to remove
|
||||
|
||||
`idx` (in) : the index of the element to remove; a negative value throws (see [Exceptions](#exceptions))
|
||||
|
||||
`ptr` (in) : a JSON pointer to the value to remove, relative to `root()`
|
||||
|
||||
## Return value
|
||||
|
||||
1. the number of removed members (`0` if `object` had none with this `key`)
|
||||
1. (nothing)
|
||||
1. the number of removed values (`0` or more for an object member, always `1` for an array element)
|
||||
|
||||
## Exceptions
|
||||
|
||||
1. Throws [`type_error.307`](https://json.nlohmann.me/home/exceptions/#jsonexceptiontype_error307) if `object` is not an object -- the same message [`BasicJsonType::erase`](https://json.nlohmann.me/api/basic_json/erase/index.md) throws for the same type.
|
||||
1. Throws `type_error.307` if `array` is not an array. Throws [`out_of_range.401`](https://json.nlohmann.me/home/exceptions/#jsonexceptionout_of_range401) if `idx` is negative, or if `idx >= array.size()`.
|
||||
1. Throws [`out_of_range.405`](https://json.nlohmann.me/home/exceptions/#jsonexceptionout_of_range405) ("JSON pointer has no parent") if `ptr` is empty. Throws what [`at`](https://json.nlohmann.me/api/basic_json_view/at/index.md) throws (overload 3) for resolving `ptr`'s parent. For the last reference token itself: if the parent is an array, throws what 2. throws for an index that is out of range, or, for a token that is not a valid array index, [`parse_error.106`](https://json.nlohmann.me/home/exceptions/#jsonexceptionparse_error106) (a leading `'0'`), [`parse_error.109`](https://json.nlohmann.me/home/exceptions/#jsonexceptionparse_error109) (not a number), [`out_of_range.410`](https://json.nlohmann.me/home/exceptions/#jsonexceptionout_of_range410) (too large for `size_type`), or [`out_of_range.404`](https://json.nlohmann.me/home/exceptions/#jsonexceptionout_of_range404) (an empty token); otherwise (an object, or a primitive value the pointer's parent resolves to) throws what 1. throws.
|
||||
|
||||
Overloads 1. and 2. also throw [`invalid_iterator.202`](https://json.nlohmann.me/home/exceptions/#jsonexceptioninvalid_iterator202) ("view does not belong to this document") if `object`/`array` is a [discarded](https://json.nlohmann.me/api/basic_json_view/is_discarded/index.md) view or a view of a *different* document. Overload 3. never throws `invalid_iterator.202`: it takes no view, and it always starts from this document's own [`root()`](https://json.nlohmann.me/api/basic_json_document/root/index.md).
|
||||
|
||||
## Complexity
|
||||
|
||||
1. Linear in the number of members of `object`.
|
||||
1. Linear in the number of elements of `array` at or after `idx` (they move one slot over).
|
||||
1. Linear in the number of reference tokens of `ptr` and, for each token, in the number of members of the object at that level or the index into the array (as [`at`](https://json.nlohmann.me/api/basic_json_view/at/index.md)), plus the complexity of 1. or 2. for the last token.
|
||||
|
||||
## Notes
|
||||
|
||||
Duplicate keys
|
||||
|
||||
Overload 1. removes *every* member with `key`, not just the first -- unlike [`set`](https://json.nlohmann.me/api/basic_json_document/set/index.md), which assigns the first occurrence and drops the rest. This is why it returns a count rather than a single view: there may be more than one member removed, or none.
|
||||
|
||||
Like [`set`](https://json.nlohmann.me/api/basic_json_document/set/index.md) and [`push_back`](https://json.nlohmann.me/api/basic_json_document/push_back/index.md), `erase` never moves an element's *value*: a view still referring to a removed member or element keeps showing what it last held (see [Edits](https://json.nlohmann.me/api/basic_json_document/#edits)) -- it just no longer appears when `array`/`object` is read, dumped, or iterated. What does change is the container's sequence of *links* to its elements: removing an element of `array` (2.) shifts the links to the elements after it by one, as [`insert`](https://json.nlohmann.me/api/basic_json_document/insert/index.md) does in the other direction. *Every* iterator already taken over `array`/`object` is invalidated by an erase, not only those at or after the removed element, since the container may now use a different sequence.
|
||||
|
||||
## Examples
|
||||
|
||||
Example
|
||||
|
||||
The example below drops a deprecated field and a decommissioned entry from a configuration document -- using all three overloads -- and shows what stays intact that would not with a plain `json`/`ordered_json` value: the order of the fields around the ones removed, and the exact spelling of a number that was never touched.
|
||||
|
||||
```
|
||||
#include <iostream>
|
||||
#include <nlohmann/json_view.hpp>
|
||||
|
||||
using json = nlohmann::json;
|
||||
using json_editable_document = nlohmann::json_editable_document;
|
||||
using json_editable_view = nlohmann::json_editable_view;
|
||||
|
||||
int main()
|
||||
{
|
||||
// a deprecated field is dropped from a configuration file, and a
|
||||
// decommissioned replica is removed from the list -- "price" keeps its
|
||||
// trailing zero, and the fields around the removed ones keep their order
|
||||
const std::string text = R"({
|
||||
"name": "cache",
|
||||
"legacy_host": "db0",
|
||||
"host": "db1",
|
||||
"price": 19.90,
|
||||
"replicas": ["db2", "db3", "db4"]
|
||||
})";
|
||||
|
||||
json_editable_document doc = json_editable_document::parse(text);
|
||||
|
||||
doc.erase(doc.root(), "legacy_host"); // (1) an object member
|
||||
doc.erase(doc.root()["replicas"], 1); // (2) an array element ("db3")
|
||||
const std::size_t removed = doc.erase(json::json_pointer("/replicas/0")); // (3) via a JSON pointer
|
||||
|
||||
std::cout << removed << '\n';
|
||||
std::cout << doc.root().dump(2, ' ', false, json_editable_view::number_format::source) << "\n\n";
|
||||
|
||||
// the same edits on a plain json value: object_t is a std::map, so
|
||||
// parsing already sorted the keys, and dump() rewrites every number to
|
||||
// its shortest form, even "price", which was never touched
|
||||
json plain = json::parse(text);
|
||||
plain.erase("legacy_host");
|
||||
plain["replicas"].erase(1);
|
||||
plain["replicas"].erase(0);
|
||||
std::cout << plain.dump(2) << '\n';
|
||||
}
|
||||
```
|
||||
|
||||
Output:
|
||||
|
||||
```
|
||||
1
|
||||
{
|
||||
"name": "cache",
|
||||
"host": "db1",
|
||||
"price": 19.90,
|
||||
"replicas": [
|
||||
"db4"
|
||||
]
|
||||
}
|
||||
|
||||
{
|
||||
"host": "db1",
|
||||
"name": "cache",
|
||||
"price": 19.9,
|
||||
"replicas": [
|
||||
"db4"
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## See also
|
||||
|
||||
- [insert](https://json.nlohmann.me/api/basic_json_document/insert/index.md) - insert an element into an array
|
||||
- [set](https://json.nlohmann.me/api/basic_json_document/set/index.md) - replace a value, or set an object member, an array element, or the value a JSON pointer refers to
|
||||
- [push_back](https://json.nlohmann.me/api/basic_json_document/push_back/index.md) - append to an array
|
||||
- [root](https://json.nlohmann.me/api/basic_json_document/root/index.md) - the view of the root value, the starting point of overload 3
|
||||
- [`BasicJsonType::erase`](https://json.nlohmann.me/api/basic_json/erase/index.md) - the corresponding function of `basic_json`
|
||||
- [Edits](https://json.nlohmann.me/api/basic_json_document/#edits) - what an edit guarantees, for every overload
|
||||
|
||||
## Version history
|
||||
|
||||
- Added in version 3.13.0 unreleased.
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,80 @@
|
||||
# nlohmann::basic_json_document
|
||||
|
||||
Defined in header `<nlohmann/json_view.hpp>`
|
||||
|
||||
```
|
||||
template<typename BasicJsonType, bool Editable = false>
|
||||
class basic_json_document;
|
||||
```
|
||||
|
||||
A parsed JSON text, held as a flat index of its values ([16 bytes per value](https://json.nlohmann.me/home/architecture/#node-index-of-json-views)) 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`](https://json.nlohmann.me/api/basic_json_view/index.md) is a read-only handle to one value of a `basic_json_document`; [`materialize()`](https://json.nlohmann.me/api/basic_json_view/materialize/index.md) turns a subtree into the `BasicJsonType` value that [`BasicJsonType::parse()`](https://json.nlohmann.me/api/basic_json/parse/index.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 `std::string` that was moved in); see [`owns_source`](https://json.nlohmann.me/api/basic_json_document/owns_source/index.md). `basic_json_document` is move-only: a copy would duplicate the whole index, the decoded-string buffer, and the owned text, and a move is enough in every use we know of. The index, the decoded strings, and the owned text live in one heap block that the document holds through a `std::unique_ptr`; this is also why views survive a move of the document.
|
||||
|
||||
With `Editable == true`, the document also offers [`set`](https://json.nlohmann.me/api/basic_json_document/set/index.md), [`push_back`](https://json.nlohmann.me/api/basic_json_document/push_back/index.md), [`insert`](https://json.nlohmann.me/api/basic_json_document/insert/index.md), and [`erase`](https://json.nlohmann.me/api/basic_json_document/erase/index.md) to change values in place, see [Edits](#edits) below. The source text itself is never written; a read-only document (`Editable == false`, the default) does not carry any of the bookkeeping edits need, and calling any of them on one fails to compile (`static_assert`).
|
||||
|
||||
## Template parameters
|
||||
|
||||
`BasicJsonType` : a specialization of [`basic_json`](https://json.nlohmann.me/api/basic_json/index.md), for instance [`json`](https://json.nlohmann.me/api/json/index.md) or [`ordered_json`](https://json.nlohmann.me/api/ordered_json/index.md). Only 64-bit `number_integer_t`/`number_unsigned_t` types are supported; this is checked with a `static_assert`.
|
||||
|
||||
`Editable` : whether the document supports [`set`](https://json.nlohmann.me/api/basic_json_document/set/index.md), [`push_back`](https://json.nlohmann.me/api/basic_json_document/push_back/index.md), [`insert`](https://json.nlohmann.me/api/basic_json_document/insert/index.md), and [`erase`](https://json.nlohmann.me/api/basic_json_document/erase/index.md) (optional, `false` by default). See [Edits](#edits) below.
|
||||
|
||||
## Specializations
|
||||
|
||||
- [**json_document**](https://json.nlohmann.me/api/json_document/index.md) - read-only documents of the default specialization [`json`](https://json.nlohmann.me/api/json/index.md)
|
||||
- [**ordered_json_document**](https://json.nlohmann.me/api/ordered_json_document/index.md) - read-only documents of [`ordered_json`](https://json.nlohmann.me/api/ordered_json/index.md)
|
||||
- [**json_editable_document**](https://json.nlohmann.me/api/json_editable_document/index.md) - editable documents of [`json`](https://json.nlohmann.me/api/json/index.md)
|
||||
- [**ordered_json_editable_document**](https://json.nlohmann.me/api/ordered_json_editable_document/index.md) - editable documents of [`ordered_json`](https://json.nlohmann.me/api/ordered_json/index.md)
|
||||
|
||||
## Member types
|
||||
|
||||
- **view_type** - the type of view returned by [`root()`](https://json.nlohmann.me/api/basic_json_document/root/index.md) (`basic_json_view<BasicJsonType, Editable>`)
|
||||
- **value_t** - the JSON type enumeration, see [`basic_json::value_t`](https://json.nlohmann.me/api/basic_json/value_t/index.md)
|
||||
- **image_check** - how [`load()`](https://json.nlohmann.me/api/basic_json_document/load/index.md) validates an image (`full`, `bounds`, `none`), see [`image_check`](https://json.nlohmann.me/api/basic_json_document/load/#image_check)
|
||||
|
||||
## Member functions
|
||||
|
||||
- [(constructor)](https://json.nlohmann.me/api/basic_json_document/basic_json_document/index.md)
|
||||
|
||||
### Parsing
|
||||
|
||||
- [**parse**](https://json.nlohmann.me/api/basic_json_document/parse/index.md) (*static*) - deserialize from a compatible input, borrowing or owning it as appropriate
|
||||
- [**parse_copy**](https://json.nlohmann.me/api/basic_json_document/parse_copy/index.md) (*static*) - deserialize a copy of a compatible input
|
||||
- [**accept**](https://json.nlohmann.me/api/basic_json_document/accept/index.md) (*static*) - check whether the input is valid JSON
|
||||
- [**read**](https://json.nlohmann.me/api/basic_json_document/read/index.md) - (re-)parse into this document, reusing its memory
|
||||
|
||||
### Access
|
||||
|
||||
- [**root**](https://json.nlohmann.me/api/basic_json_document/root/index.md) - the view of the root value
|
||||
- [**is_discarded**](https://json.nlohmann.me/api/basic_json_document/is_discarded/index.md) - return whether the last parse failed
|
||||
- [**source**](https://json.nlohmann.me/api/basic_json_document/source/index.md) - the parsed text
|
||||
- [**owns_source**](https://json.nlohmann.me/api/basic_json_document/owns_source/index.md) - return whether the document holds its own copy of the text
|
||||
- [**node_count**](https://json.nlohmann.me/api/basic_json_document/node_count/index.md) - the number of index entries (values plus object keys)
|
||||
- [**memory_usage**](https://json.nlohmann.me/api/basic_json_document/memory_usage/index.md) - the number of bytes held by the document
|
||||
- [**shrink_to_fit**](https://json.nlohmann.me/api/basic_json_document/shrink_to_fit/index.md) - release unused index capacity
|
||||
|
||||
### Images
|
||||
|
||||
- [**save**](https://json.nlohmann.me/api/basic_json_document/save/index.md) - the document as an image that `load()` reads without parsing
|
||||
- [**load**](https://json.nlohmann.me/api/basic_json_document/load/index.md) (*static*) - read an image written by `save()`
|
||||
|
||||
### Edits
|
||||
|
||||
- [**set**](https://json.nlohmann.me/api/basic_json_document/set/index.md) - replace a value, or set an object member, an array element, or the value a JSON pointer refers to (`Editable` documents only)
|
||||
- [**push_back**](https://json.nlohmann.me/api/basic_json_document/push_back/index.md) - append to an array (`Editable` documents only)
|
||||
- [**insert**](https://json.nlohmann.me/api/basic_json_document/insert/index.md) - insert an element into an array before a given position (`Editable` documents only)
|
||||
- [**erase**](https://json.nlohmann.me/api/basic_json_document/erase/index.md) - remove an object member, an array element, or the value a JSON pointer refers to (`Editable` documents only)
|
||||
|
||||
## Edits
|
||||
|
||||
An editable document (`Editable == true`) can be changed after parsing, with [`set`](https://json.nlohmann.me/api/basic_json_document/set/index.md), [`push_back`](https://json.nlohmann.me/api/basic_json_document/push_back/index.md), [`insert`](https://json.nlohmann.me/api/basic_json_document/insert/index.md), and [`erase`](https://json.nlohmann.me/api/basic_json_document/erase/index.md); [`json_editable_document`](https://json.nlohmann.me/api/json_editable_document/index.md) and [`ordered_json_editable_document`](https://json.nlohmann.me/api/ordered_json_editable_document/index.md) are the corresponding specializations. A few points apply to every edit:
|
||||
|
||||
- **The source text is never written**, and the parsed index never moves: every value keeps the node it was parsed into, so [views](https://json.nlohmann.me/api/basic_json_view/index.md) taken before an edit stay valid, including [`root()`](https://json.nlohmann.me/api/basic_json_document/root/index.md). New values (and the element sequences of an edited array/object) go to storage owned by the document, allocated on demand.
|
||||
- **A view keeps referring to the same value.** After [`set`](https://json.nlohmann.me/api/basic_json_document/set/index.md) replaces the value a view refers to, that view sees the new value; a view of a value that a later edit replaces or drops keeps showing what it last held. An edit of an array or object, however, **invalidates the iterators taken over it** (its members may now live in a different sequence), and a string obtained with [`get_string()`](https://json.nlohmann.me/api/basic_json_view/get_string/index.md) stays valid even as further edits happen (earlier buffers of edited text are kept alive, not overwritten).
|
||||
- **Values are accepted three ways:** a [`basic_json_view`](https://json.nlohmann.me/api/basic_json_view/index.md) of *any* document (read-only or editable; it is copied, nothing is shared with the source document), a `BasicJsonType` value, or anything `BasicJsonType` can be constructed from (numbers, strings, `bool`, `nullptr`, containers, ...).
|
||||
- [`dump()`](https://json.nlohmann.me/api/basic_json_view/dump/index.md) writes an edited document with members in document order, new members at the end, and, with [`number_format::source`](https://json.nlohmann.me/api/basic_json_view/number_format/index.md), keeps the spelling of every number that was not itself edited -- see [Editing a document](https://json.nlohmann.me/features/json_view/#editing-a-document) for why this matters.
|
||||
- [`read()`](https://json.nlohmann.me/api/basic_json_document/read/index.md) discards all edits, [`shrink_to_fit()`](https://json.nlohmann.me/api/basic_json_document/shrink_to_fit/index.md) does not move the node index once there are edits, and [`memory_usage()`](https://json.nlohmann.me/api/basic_json_document/memory_usage/index.md) includes the memory edits use. [`source_offset()`](https://json.nlohmann.me/api/basic_json_view/source_offset/index.md) of a value introduced by an edit is `static_cast<std::size_t>(-1)`, the same value it reports for a decoded string.
|
||||
|
||||
## Version history
|
||||
|
||||
- Added in version 3.13.0 unreleased.
|
||||
@@ -0,0 +1,175 @@
|
||||
# <small>nlohmann::basic_json_document::</small>insert
|
||||
|
||||
```cpp
|
||||
template<typename I, typename V>
|
||||
view_type insert(view_type array, I idx, V&& value);
|
||||
```
|
||||
|
||||
Only an **editable** document (`#!cpp Editable == true`, e.g. [`json_editable_document`](../json_editable_document.md))
|
||||
has `insert`; calling it on a read-only `basic_json_document` fails to compile (`#!cpp static_assert`).
|
||||
|
||||
Inserts `value` into `array` as a new element before position `idx`, which must not be past the end
|
||||
(`#!cpp idx <= array.size()`; `#!cpp idx == array.size()` appends, like [`push_back`](push_back.md)). Unlike
|
||||
[`push_back`](push_back.md), a [null](../basic_json_view/is_null.md) `array` does *not* first become an empty array:
|
||||
`array` must already be an array.
|
||||
|
||||
`value` is accepted three ways: a [`basic_json_view`](../basic_json_view/index.md) of *any* document -- read-only or
|
||||
editable, and it does not have to be `array`'s own document -- which is copied so that nothing is shared with the
|
||||
source document afterward; a `BasicJsonType` value; or anything `BasicJsonType` can be constructed from (numbers,
|
||||
strings, `#!cpp bool`, `#!cpp nullptr`, containers, ...).
|
||||
|
||||
## Template parameters
|
||||
|
||||
`I`
|
||||
: an integral type other than `#!cpp bool`, deduced (overloads taking a `#!cpp bool` or a non-integral type for
|
||||
`idx` do not participate in overload resolution).
|
||||
|
||||
`V`
|
||||
: the type of `value`, deduced; see above for what is accepted.
|
||||
|
||||
## Parameters
|
||||
|
||||
`array` (in)
|
||||
: the array to insert into
|
||||
|
||||
`idx` (in)
|
||||
: the position to insert `value` before; a negative value throws (see [Exceptions](#exceptions))
|
||||
|
||||
`value` (in)
|
||||
: the value to insert
|
||||
|
||||
## Return value
|
||||
|
||||
a view of the new element, now holding `value`
|
||||
|
||||
## Exception safety
|
||||
|
||||
Basic exception safety: `value` is fully encoded -- including the checks below -- into storage owned by the document
|
||||
before anything already reachable from [`root()`](root.md) is touched, so a failure while encoding `value` (an
|
||||
invalid argument, or `#!cpp std::bad_alloc`) leaves the document completely unchanged, other than memory allocated
|
||||
for the encoding that is not reclaimed. A failure of a later allocation -- while `array` switches from its parsed
|
||||
layout to a growable block, or while that block grows, see [Notes](#notes) -- can still leave `array` already
|
||||
switched to that layout even though `value` itself was not inserted.
|
||||
|
||||
## Exceptions
|
||||
|
||||
Throws [`type_error.309`](../../home/exceptions.md#jsonexceptiontype_error309) if `array` is not an array -- the same
|
||||
message [`BasicJsonType::insert`](../basic_json/insert.md) throws for the same type; a null `array` throws this too
|
||||
(see above). Throws [`out_of_range.401`](../../home/exceptions.md#jsonexceptionout_of_range401) if `idx` is negative,
|
||||
or if `#!cpp idx > array.size()`. Throws
|
||||
[`invalid_iterator.202`](../../home/exceptions.md#jsonexceptioninvalid_iterator202) ("view does not belong to this
|
||||
document") if `array` is a [discarded](../basic_json_view/is_discarded.md) view or a view of a *different* document.
|
||||
Throws [`type_error.302`](../../home/exceptions.md#jsonexceptiontype_error302) if `value` is a
|
||||
[discarded](../basic_json_view/is_discarded.md) view or a [discarded](../basic_json/is_discarded.md) `BasicJsonType`
|
||||
value, and [`type_error.319`](../../home/exceptions.md#jsonexceptiontype_error319) if `value` is (or contains) a
|
||||
binary value -- `BasicJsonType` can hold one, but a `json_document` cannot. Throws
|
||||
[`type_error.316`](../../home/exceptions.md#jsonexceptiontype_error316) if `value` is (or contains) a string that is
|
||||
not valid UTF-8, with the same message [`BasicJsonType::dump()`](../basic_json/dump.md) gives for that string.
|
||||
|
||||
## Complexity
|
||||
|
||||
Linear in the number of elements of `array` at or after `idx` (they move one slot over), plus time linear in the
|
||||
size of `value` to encode it into the document's storage (constant for a scalar, linear in the number of nested
|
||||
values for an array or object): like [`push_back`](push_back.md), the elements of `array` move to a growable block
|
||||
of links the first time it is inserted into (or [`set`](set.md)/[`push_back`](push_back.md) on), and that block
|
||||
grows in amortized constant time; inserting before the end within that block still shifts every later element.
|
||||
|
||||
## Notes
|
||||
|
||||
Like [`set`](set.md) on a member or an element, `insert` never moves an existing *element's value* -- only where
|
||||
`array`'s *links* to its elements live -- so a view of an existing element of `array` stays valid across an
|
||||
`insert`, and keeps referring to the same element even though its index shifts. Any iterator already taken over
|
||||
`array` is invalidated, since it was walking the old layout. See [Edits](index.md#edits) for what stays valid across
|
||||
an edit in general.
|
||||
|
||||
## Examples
|
||||
|
||||
??? example
|
||||
|
||||
The example below inserts a step into the middle of a deployment plan, without touching the steps that come
|
||||
after it, and shows that a view taken before the insert keeps referring to the same element even though its
|
||||
index shifts -- something a plain `json`/`ordered_json` array, or its `std::vector`-based storage, has no
|
||||
equivalent for.
|
||||
|
||||
```cpp
|
||||
#include <iostream>
|
||||
#include <nlohmann/json_view.hpp>
|
||||
|
||||
using json = nlohmann::json;
|
||||
using json_editable_document = nlohmann::json_editable_document;
|
||||
using json_editable_view = nlohmann::json_editable_view;
|
||||
|
||||
int main()
|
||||
{
|
||||
// a deployment plan -- "budget" is written with a trailing zero that has
|
||||
// no effect on its value
|
||||
const std::string text = R"({
|
||||
"release": "2026.09",
|
||||
"steps": ["build", "test", "deploy"],
|
||||
"budget": 19.90
|
||||
})";
|
||||
|
||||
json_editable_document doc = json_editable_document::parse(text);
|
||||
|
||||
const std::size_t deploy_index = 2;
|
||||
const auto deploy = doc.root()["steps"][deploy_index]; // held across the insert
|
||||
|
||||
doc.insert(doc.root()["steps"], deploy_index, "smoke-test"); // insert before "deploy"
|
||||
|
||||
// the held view still refers to "deploy", even though its index moved
|
||||
// from 2 to 3, and nothing else in the document was touched
|
||||
std::cout << deploy.dump() << '\n';
|
||||
std::cout << doc.root().dump(2, ' ', false, json_editable_view::number_format::source) << "\n\n";
|
||||
|
||||
// the same edit on a plain json value: an index held from before the
|
||||
// insert now refers to whatever moved into that slot, and dump()
|
||||
// rewrites "budget" to its shortest form even though it was never
|
||||
// touched
|
||||
json plain = json::parse(text);
|
||||
plain["steps"].insert(plain["steps"].begin() + static_cast<std::ptrdiff_t>(deploy_index), "smoke-test");
|
||||
std::cout << plain["steps"][deploy_index].dump() << '\n';
|
||||
std::cout << plain.dump(2) << '\n';
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
Output:
|
||||
|
||||
```json
|
||||
"deploy"
|
||||
{
|
||||
"release": "2026.09",
|
||||
"steps": [
|
||||
"build",
|
||||
"test",
|
||||
"smoke-test",
|
||||
"deploy"
|
||||
],
|
||||
"budget": 19.90
|
||||
}
|
||||
|
||||
"smoke-test"
|
||||
{
|
||||
"budget": 19.9,
|
||||
"release": "2026.09",
|
||||
"steps": [
|
||||
"build",
|
||||
"test",
|
||||
"smoke-test",
|
||||
"deploy"
|
||||
]
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
## See also
|
||||
|
||||
- [push_back](push_back.md) - append to an array
|
||||
- [erase](erase.md) - remove an object member, an array element, or the value a JSON pointer refers to
|
||||
- [set](set.md) - replace a value, or set an object member, an array element, or the value a JSON pointer refers to
|
||||
- [`BasicJsonType::insert`](../basic_json/insert.md) - the corresponding function of `basic_json`
|
||||
- [Edits](index.md#edits) - what an edit guarantees, for every overload
|
||||
|
||||
## Version history
|
||||
|
||||
- Added in version 3.13.0.
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,133 @@
|
||||
# nlohmann::basic_json_document::insert
|
||||
|
||||
```
|
||||
template<typename I, typename V>
|
||||
view_type insert(view_type array, I idx, V&& value);
|
||||
```
|
||||
|
||||
Only an **editable** document (`Editable == true`, e.g. [`json_editable_document`](https://json.nlohmann.me/api/json_editable_document/index.md)) has `insert`; calling it on a read-only `basic_json_document` fails to compile (`static_assert`).
|
||||
|
||||
Inserts `value` into `array` as a new element before position `idx`, which must not be past the end (`idx <= array.size()`; `idx == array.size()` appends, like [`push_back`](https://json.nlohmann.me/api/basic_json_document/push_back/index.md)). Unlike [`push_back`](https://json.nlohmann.me/api/basic_json_document/push_back/index.md), a [null](https://json.nlohmann.me/api/basic_json_view/is_null/index.md) `array` does *not* first become an empty array: `array` must already be an array.
|
||||
|
||||
`value` is accepted three ways: a [`basic_json_view`](https://json.nlohmann.me/api/basic_json_view/index.md) of *any* document -- read-only or editable, and it does not have to be `array`'s own document -- which is copied so that nothing is shared with the source document afterward; a `BasicJsonType` value; or anything `BasicJsonType` can be constructed from (numbers, strings, `bool`, `nullptr`, containers, ...).
|
||||
|
||||
## Template parameters
|
||||
|
||||
`I` : an integral type other than `bool`, deduced (overloads taking a `bool` or a non-integral type for `idx` do not participate in overload resolution).
|
||||
|
||||
`V` : the type of `value`, deduced; see above for what is accepted.
|
||||
|
||||
## Parameters
|
||||
|
||||
`array` (in) : the array to insert into
|
||||
|
||||
`idx` (in) : the position to insert `value` before; a negative value throws (see [Exceptions](#exceptions))
|
||||
|
||||
`value` (in) : the value to insert
|
||||
|
||||
## Return value
|
||||
|
||||
a view of the new element, now holding `value`
|
||||
|
||||
## Exception safety
|
||||
|
||||
Basic exception safety: `value` is fully encoded -- including the checks below -- into storage owned by the document before anything already reachable from [`root()`](https://json.nlohmann.me/api/basic_json_document/root/index.md) is touched, so a failure while encoding `value` (an invalid argument, or `std::bad_alloc`) leaves the document completely unchanged, other than memory allocated for the encoding that is not reclaimed. A failure of a later allocation -- while `array` switches from its parsed layout to a growable block, or while that block grows, see [Notes](#notes) -- can still leave `array` already switched to that layout even though `value` itself was not inserted.
|
||||
|
||||
## Exceptions
|
||||
|
||||
Throws [`type_error.309`](https://json.nlohmann.me/home/exceptions/#jsonexceptiontype_error309) if `array` is not an array -- the same message [`BasicJsonType::insert`](https://json.nlohmann.me/api/basic_json/insert/index.md) throws for the same type; a null `array` throws this too (see above). Throws [`out_of_range.401`](https://json.nlohmann.me/home/exceptions/#jsonexceptionout_of_range401) if `idx` is negative, or if `idx > array.size()`. Throws [`invalid_iterator.202`](https://json.nlohmann.me/home/exceptions/#jsonexceptioninvalid_iterator202) ("view does not belong to this document") if `array` is a [discarded](https://json.nlohmann.me/api/basic_json_view/is_discarded/index.md) view or a view of a *different* document. Throws [`type_error.302`](https://json.nlohmann.me/home/exceptions/#jsonexceptiontype_error302) if `value` is a [discarded](https://json.nlohmann.me/api/basic_json_view/is_discarded/index.md) view or a [discarded](https://json.nlohmann.me/api/basic_json/is_discarded/index.md) `BasicJsonType` value, and [`type_error.319`](https://json.nlohmann.me/home/exceptions/#jsonexceptiontype_error319) if `value` is (or contains) a binary value -- `BasicJsonType` can hold one, but a `json_document` cannot. Throws [`type_error.316`](https://json.nlohmann.me/home/exceptions/#jsonexceptiontype_error316) if `value` is (or contains) a string that is not valid UTF-8, with the same message [`BasicJsonType::dump()`](https://json.nlohmann.me/api/basic_json/dump/index.md) gives for that string.
|
||||
|
||||
## Complexity
|
||||
|
||||
Linear in the number of elements of `array` at or after `idx` (they move one slot over), plus time linear in the size of `value` to encode it into the document's storage (constant for a scalar, linear in the number of nested values for an array or object): like [`push_back`](https://json.nlohmann.me/api/basic_json_document/push_back/index.md), the elements of `array` move to a growable block of links the first time it is inserted into (or [`set`](https://json.nlohmann.me/api/basic_json_document/set/index.md)/[`push_back`](https://json.nlohmann.me/api/basic_json_document/push_back/index.md) on), and that block grows in amortized constant time; inserting before the end within that block still shifts every later element.
|
||||
|
||||
## Notes
|
||||
|
||||
Like [`set`](https://json.nlohmann.me/api/basic_json_document/set/index.md) on a member or an element, `insert` never moves an existing *element's value* -- only where `array`'s *links* to its elements live -- so a view of an existing element of `array` stays valid across an `insert`, and keeps referring to the same element even though its index shifts. Any iterator already taken over `array` is invalidated, since it was walking the old layout. See [Edits](https://json.nlohmann.me/api/basic_json_document/#edits) for what stays valid across an edit in general.
|
||||
|
||||
## Examples
|
||||
|
||||
Example
|
||||
|
||||
The example below inserts a step into the middle of a deployment plan, without touching the steps that come after it, and shows that a view taken before the insert keeps referring to the same element even though its index shifts -- something a plain `json`/`ordered_json` array, or its `std::vector`-based storage, has no equivalent for.
|
||||
|
||||
```
|
||||
#include <iostream>
|
||||
#include <nlohmann/json_view.hpp>
|
||||
|
||||
using json = nlohmann::json;
|
||||
using json_editable_document = nlohmann::json_editable_document;
|
||||
using json_editable_view = nlohmann::json_editable_view;
|
||||
|
||||
int main()
|
||||
{
|
||||
// a deployment plan -- "budget" is written with a trailing zero that has
|
||||
// no effect on its value
|
||||
const std::string text = R"({
|
||||
"release": "2026.09",
|
||||
"steps": ["build", "test", "deploy"],
|
||||
"budget": 19.90
|
||||
})";
|
||||
|
||||
json_editable_document doc = json_editable_document::parse(text);
|
||||
|
||||
const std::size_t deploy_index = 2;
|
||||
const auto deploy = doc.root()["steps"][deploy_index]; // held across the insert
|
||||
|
||||
doc.insert(doc.root()["steps"], deploy_index, "smoke-test"); // insert before "deploy"
|
||||
|
||||
// the held view still refers to "deploy", even though its index moved
|
||||
// from 2 to 3, and nothing else in the document was touched
|
||||
std::cout << deploy.dump() << '\n';
|
||||
std::cout << doc.root().dump(2, ' ', false, json_editable_view::number_format::source) << "\n\n";
|
||||
|
||||
// the same edit on a plain json value: an index held from before the
|
||||
// insert now refers to whatever moved into that slot, and dump()
|
||||
// rewrites "budget" to its shortest form even though it was never
|
||||
// touched
|
||||
json plain = json::parse(text);
|
||||
plain["steps"].insert(plain["steps"].begin() + static_cast<std::ptrdiff_t>(deploy_index), "smoke-test");
|
||||
std::cout << plain["steps"][deploy_index].dump() << '\n';
|
||||
std::cout << plain.dump(2) << '\n';
|
||||
}
|
||||
```
|
||||
|
||||
Output:
|
||||
|
||||
```
|
||||
"deploy"
|
||||
{
|
||||
"release": "2026.09",
|
||||
"steps": [
|
||||
"build",
|
||||
"test",
|
||||
"smoke-test",
|
||||
"deploy"
|
||||
],
|
||||
"budget": 19.90
|
||||
}
|
||||
|
||||
"smoke-test"
|
||||
{
|
||||
"budget": 19.9,
|
||||
"release": "2026.09",
|
||||
"steps": [
|
||||
"build",
|
||||
"test",
|
||||
"smoke-test",
|
||||
"deploy"
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## See also
|
||||
|
||||
- [push_back](https://json.nlohmann.me/api/basic_json_document/push_back/index.md) - append to an array
|
||||
- [erase](https://json.nlohmann.me/api/basic_json_document/erase/index.md) - remove an object member, an array element, or the value a JSON pointer refers to
|
||||
- [set](https://json.nlohmann.me/api/basic_json_document/set/index.md) - replace a value, or set an object member, an array element, or the value a JSON pointer refers to
|
||||
- [`BasicJsonType::insert`](https://json.nlohmann.me/api/basic_json/insert/index.md) - the corresponding function of `basic_json`
|
||||
- [Edits](https://json.nlohmann.me/api/basic_json_document/#edits) - what an edit guarantees, for every overload
|
||||
|
||||
## Version history
|
||||
|
||||
- Added in version 3.13.0 unreleased.
|
||||
@@ -0,0 +1,71 @@
|
||||
# <small>nlohmann::basic_json_document::</small>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
|
||||
#include <iostream>
|
||||
#include <nlohmann/json_view.hpp>
|
||||
|
||||
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';
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
Output:
|
||||
|
||||
```json
|
||||
true
|
||||
true
|
||||
false
|
||||
|
||||
```
|
||||
|
||||
## 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.
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,66 @@
|
||||
# nlohmann::basic_json_document::is_discarded
|
||||
|
||||
```
|
||||
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()`](https://json.nlohmann.me/api/basic_json_document/parse/index.md), [`parse_copy()`](https://json.nlohmann.me/api/basic_json_document/parse_copy/index.md), or [`read()`](https://json.nlohmann.me/api/basic_json_document/read/index.md) failed with `allow_exceptions` set to `false`.
|
||||
|
||||
## Return value
|
||||
|
||||
`true` if the document is discarded, `false` otherwise.
|
||||
|
||||
## Exception safety
|
||||
|
||||
No-throw guarantee: this function never throws exceptions.
|
||||
|
||||
## Complexity
|
||||
|
||||
Constant.
|
||||
|
||||
## Notes
|
||||
|
||||
When the document is discarded, [`root()`](https://json.nlohmann.me/api/basic_json_document/root/index.md) returns a discarded view (its [`is_discarded()`](https://json.nlohmann.me/api/basic_json_view/is_discarded/index.md) is also `true`).
|
||||
|
||||
## Examples
|
||||
|
||||
Example
|
||||
|
||||
```
|
||||
#include <iostream>
|
||||
#include <nlohmann/json_view.hpp>
|
||||
|
||||
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';
|
||||
}
|
||||
```
|
||||
|
||||
Output:
|
||||
|
||||
```
|
||||
true
|
||||
true
|
||||
false
|
||||
```
|
||||
|
||||
## See also
|
||||
|
||||
- [parse](https://json.nlohmann.me/api/basic_json_document/parse/index.md) - deserialize from a compatible input
|
||||
- [is_discarded (basic_json_view)](https://json.nlohmann.me/api/basic_json_view/is_discarded/index.md) - return whether a view is invalid
|
||||
|
||||
## Version history
|
||||
|
||||
- Added in version 3.13.0 unreleased.
|
||||
@@ -0,0 +1,236 @@
|
||||
# <small>nlohmann::basic_json_document::</small>load
|
||||
|
||||
```cpp
|
||||
// (1)
|
||||
static basic_json_document load(const std::uint8_t* image, std::size_t size,
|
||||
const image_check check = image_check::full);
|
||||
|
||||
// (2)
|
||||
static basic_json_document load(const std::vector<std::uint8_t>& image,
|
||||
const image_check check = image_check::full);
|
||||
|
||||
// (3)
|
||||
static basic_json_document load(std::vector<std::uint8_t>&& image,
|
||||
const image_check check = image_check::full);
|
||||
```
|
||||
|
||||
1. Reads an image [`save()`](save.md) wrote, from a pointer and a byte count. The image is **borrowed**: `image`
|
||||
must stay alive and unchanged for as long as the returned document, and any view taken from it, is used.
|
||||
2. Reads an image from a `#!cpp std::vector`. Also **borrowed** -- equivalent to overload 1 called with
|
||||
`#!cpp image.data()` and `#!cpp image.size()`.
|
||||
3. Reads an image, keeping the vector instead of copying it: `image` is moved into the document (no copy), which
|
||||
then owns it for as long as it needs the text and the decoded strings. [`owns_source()`](owns_source.md) is
|
||||
`#!cpp true` afterward.
|
||||
|
||||
In every overload, the node index is copied into storage the document itself owns -- so that it is properly aligned,
|
||||
and, for an [editable](index.md#edits) document, can be edited -- while the text and the decoded strings stay in
|
||||
`image`. The hash indexes [large objects](../../features/json_view.md) use for lookup are rebuilt, exactly as after
|
||||
parsing.
|
||||
|
||||
## Parameters
|
||||
|
||||
`image` (in)
|
||||
: the image [`save()`](save.md) wrote (overloads 1 and 2), or one to take ownership of (overload 3)
|
||||
|
||||
`size` (in)
|
||||
: the number of bytes at `image` (overload 1)
|
||||
|
||||
`check` (in)
|
||||
: how thoroughly to validate `image` before trusting it; see [`image_check`](#image_check) below (optional,
|
||||
`#!cpp image_check::full` by default)
|
||||
|
||||
## Return value
|
||||
|
||||
The document read from the image.
|
||||
|
||||
## Exception safety
|
||||
|
||||
Overloads 1 and 2 give the strong guarantee: `image` is only read, never written, so a thrown exception leaves the
|
||||
caller's buffer untouched.
|
||||
|
||||
Overload 3 moves `image` into the document *before* validating it, so that a good image is kept without a copy. If
|
||||
loading then fails, the partially built document -- and the vector now inside it -- is discarded along with the
|
||||
exception, and `image` itself is left **empty**, not restored to what was passed in. Move a copy in instead, or
|
||||
validate with overload 2 first, if the original vector must survive a failed load.
|
||||
|
||||
## Exceptions
|
||||
|
||||
On a big-endian target, throws [`type_error.320`](../../home/exceptions.md#jsonexceptiontype_error320) -- the same
|
||||
exception [`save()`](save.md#exceptions) throws there, since the image format is little-endian only.
|
||||
|
||||
Otherwise throws [`parse_error.116`](../../home/exceptions.md#jsonexceptionparse_error116) if `image` is not one
|
||||
`save()` could have written, or fails the requested `check`:
|
||||
|
||||
| message | when |
|
||||
|------------------------|------------------------------------------------------------------------------------------------------|
|
||||
| `too short` | `image` is `#!cpp nullptr`, or `size` is smaller than the 64-byte header |
|
||||
| `unknown format` | the header's magic bytes or version do not match, or a reserved header field is not zero |
|
||||
| `sizes out of range` | the node count, text size, or decoded-string size the header describes does not fit `size`, or the `#!cpp '\0'` after the text or after the decoded strings is missing |
|
||||
| `the check failed` | `check` is not `#!cpp image_check::none`, and the image fails it -- see [`image_check`](#image_check) |
|
||||
|
||||
!!! failure "Example messages"
|
||||
|
||||
```
|
||||
[json.exception.parse_error.116] parse error: invalid json_document image: too short
|
||||
```
|
||||
```
|
||||
[json.exception.parse_error.116] parse error: invalid json_document image: unknown format
|
||||
```
|
||||
```
|
||||
[json.exception.parse_error.116] parse error: invalid json_document image: sizes out of range
|
||||
```
|
||||
```
|
||||
[json.exception.parse_error.116] parse error: invalid json_document image: the check failed
|
||||
```
|
||||
|
||||
## Complexity
|
||||
|
||||
Linear in the number of nodes, which are always copied into the document. `#!cpp image_check::none` does not read
|
||||
the text or the decoded strings. `#!cpp image_check::bounds` reads one byte of the text for each float token (its sign,
|
||||
to check the recorded digits against the token's length), and nothing else of the text or the decoded strings.
|
||||
|
||||
With `#!cpp image_check::full`, linear in the size of the image (the nodes, the text, and the decoded strings), plus
|
||||
sorting the ranges of the strings and of the float tokens (at most one per node): the contents of each distinct range
|
||||
are checked once, however many nodes refer to it.
|
||||
|
||||
## Notes
|
||||
|
||||
### `image_check` { #image_check }
|
||||
|
||||
```cpp
|
||||
using image_check = detail::view::image_check;
|
||||
|
||||
enum class image_check
|
||||
{
|
||||
full,
|
||||
bounds,
|
||||
none
|
||||
};
|
||||
```
|
||||
|
||||
How thoroughly `load()` validates `image` before trusting it.
|
||||
|
||||
`full` (the default)
|
||||
: Checks everything the parser itself guarantees: structure and bounds; that every string is valid UTF-8 (and, for a
|
||||
string still in the source text, that it contains no quote, backslash, or control character); and that every number
|
||||
token is well-formed and matches the value stored for it. Strings and float tokens may share a range only if the
|
||||
ranges are identical (as nodes that share a value do), and never overlap otherwise. Reading and serializing a
|
||||
checked image is safe and always produces valid JSON, exactly as for a parsed document. This is the right choice for
|
||||
an image from anything you do not fully control -- a file, a cache shared with other processes, a peer on the
|
||||
network.
|
||||
|
||||
`bounds`
|
||||
: Checks structure and bounds only: that every offset and count in the node index stays inside the image. So
|
||||
`load()`, [`root()`](root.md), element access, and [`materialize()`](../basic_json_view/materialize.md) can never
|
||||
read outside the image, even on a damaged one. It does *not* guarantee that the image describes valid JSON: a
|
||||
string that a `full` check would have rejected can make [`dump()`](../basic_json_view/dump.md) write invalid UTF-8
|
||||
or invalid JSON, or throw [`type_error.316`](../../home/exceptions.md#jsonexceptiontype_error316), and a number can
|
||||
read back with a value that does not match how it is spelled. An [editable document](../json_editable_document.md)
|
||||
does not take such a string over: [`set`](set.md), [`push_back`](push_back.md) and [`insert`](insert.md) throw
|
||||
`type_error.316` when they copy it from a view of the loaded document, and leave the editable document unchanged.
|
||||
`bounds` skips scanning the text and the decoded strings, so it fits a cache your own process just wrote and reads
|
||||
straight back, where damage would mean a bug or a hardware fault rather than adversarial input.
|
||||
|
||||
`none`
|
||||
: Checks nothing. Reading a damaged image is undefined behavior, so use it only for an image you trust as much as
|
||||
your own memory.
|
||||
|
||||
**Lifetime.** Overloads 1 and 2 borrow `image`: it must stay alive and byte-for-byte unchanged for as long as the
|
||||
returned document, and any [view](../basic_json_view/index.md) taken from it, is used -- exactly like a document
|
||||
[`parse()`](parse.md) borrowed its input for. Overload 3 avoids this by keeping the vector itself; see
|
||||
[`owns_source`](owns_source.md).
|
||||
|
||||
!!! warning "Experimental"
|
||||
|
||||
The image format is versioned but not yet stable, and may change in an incompatible way before it is declared
|
||||
stable; `load()` already rejects an image written by a different format version with `parse_error.116`
|
||||
("unknown format"). Use images to cache a document within one build of the library, or to hand one to another
|
||||
process running the *same* build on the *same* (little-endian) machine -- not as a long-term storage format.
|
||||
|
||||
## Examples
|
||||
|
||||
??? example "Caching a document, ownership, and a rejected image"
|
||||
|
||||
The example below saves a parsed document as an image, checks that `load()` reproduces the original
|
||||
[`dump()`](../basic_json_view/dump.md) without parsing, and shows the difference between
|
||||
`load(std::move(image))` (owned) and `load(image)` (borrowed). It then damages one byte of the image and shows
|
||||
`image_check::full` rejecting it with `parse_error.116`, while `image_check::bounds` -- meant for a cache the
|
||||
process already trusts -- still reads it without going out of bounds.
|
||||
|
||||
```cpp
|
||||
#include <cstdint>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <nlohmann/json_view.hpp>
|
||||
|
||||
using json = nlohmann::json;
|
||||
using json_document = nlohmann::json_document;
|
||||
using image_check = json_document::image_check;
|
||||
|
||||
int main()
|
||||
{
|
||||
std::cout << std::boolalpha;
|
||||
|
||||
// the image of a parsed document -- as if read back from a cache file or
|
||||
// received from another process running the same build of the library
|
||||
const std::string text = R"({"name": "cache", "note": "caf\u00e9", "replicas": ["db2", "db3"]})";
|
||||
const json_document parsed = json_document::parse(text);
|
||||
const std::vector<std::uint8_t> image = parsed.save();
|
||||
|
||||
// (1)/(2) load() needs no parsing, yet dumps exactly what parsing did
|
||||
const json_document borrowed = json_document::load(image);
|
||||
std::cout << (borrowed.root().dump() == parsed.root().dump()) << '\n';
|
||||
std::cout << borrowed.owns_source() << '\n'; // borrowed: still points into `image`
|
||||
|
||||
// (3) load(std::move(image)) keeps the vector instead of copying it
|
||||
std::vector<std::uint8_t> to_move = image;
|
||||
const json_document owned = json_document::load(std::move(to_move));
|
||||
std::cout << owned.owns_source() << '\n';
|
||||
|
||||
// a damaged image -- the last byte of the decoded string "note" holds
|
||||
// (an escape sequence, so it was unescaped into the document's own
|
||||
// buffer), flipped, as storage or transport corruption might do
|
||||
std::vector<std::uint8_t> damaged = image;
|
||||
damaged[damaged.size() - 2] = 0xFF;
|
||||
|
||||
// image_check::full inspects strings and numbers, so it catches the damage
|
||||
try
|
||||
{
|
||||
static_cast<void>(json_document::load(damaged, image_check::full));
|
||||
}
|
||||
catch (const json::parse_error& e)
|
||||
{
|
||||
std::cout << e.id << '\n';
|
||||
}
|
||||
|
||||
// image_check::bounds only checks structure and bounds, so a cache the
|
||||
// process already trusts loads without the extra scan -- reading a value
|
||||
// the damage did not touch is still safe
|
||||
const json_document trusted = json_document::load(damaged, image_check::bounds);
|
||||
std::cout << trusted.root()["name"].get<std::string>() << '\n';
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
Output:
|
||||
|
||||
```json
|
||||
true
|
||||
false
|
||||
true
|
||||
116
|
||||
cache
|
||||
|
||||
```
|
||||
|
||||
## See also
|
||||
|
||||
- [save](save.md) - write the document as an image
|
||||
- [owns_source](owns_source.md) - return whether the document holds its own copy of the text
|
||||
- [parse](parse.md) - deserialize from JSON text instead of an image
|
||||
- [Images](../../features/json_view.md#images) - why and when to use images
|
||||
|
||||
## Version history
|
||||
|
||||
- Added in version 3.13.0.
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,187 @@
|
||||
# nlohmann::basic_json_document::load
|
||||
|
||||
```
|
||||
// (1)
|
||||
static basic_json_document load(const std::uint8_t* image, std::size_t size,
|
||||
const image_check check = image_check::full);
|
||||
|
||||
// (2)
|
||||
static basic_json_document load(const std::vector<std::uint8_t>& image,
|
||||
const image_check check = image_check::full);
|
||||
|
||||
// (3)
|
||||
static basic_json_document load(std::vector<std::uint8_t>&& image,
|
||||
const image_check check = image_check::full);
|
||||
```
|
||||
|
||||
1. Reads an image [`save()`](https://json.nlohmann.me/api/basic_json_document/save/index.md) wrote, from a pointer and a byte count. The image is **borrowed**: `image` must stay alive and unchanged for as long as the returned document, and any view taken from it, is used.
|
||||
1. Reads an image from a `std::vector`. Also **borrowed** -- equivalent to overload 1 called with `image.data()` and `image.size()`.
|
||||
1. Reads an image, keeping the vector instead of copying it: `image` is moved into the document (no copy), which then owns it for as long as it needs the text and the decoded strings. [`owns_source()`](https://json.nlohmann.me/api/basic_json_document/owns_source/index.md) is `true` afterward.
|
||||
|
||||
In every overload, the node index is copied into storage the document itself owns -- so that it is properly aligned, and, for an [editable](https://json.nlohmann.me/api/basic_json_document/#edits) document, can be edited -- while the text and the decoded strings stay in `image`. The hash indexes [large objects](https://json.nlohmann.me/features/json_view/index.md) use for lookup are rebuilt, exactly as after parsing.
|
||||
|
||||
## Parameters
|
||||
|
||||
`image` (in) : the image [`save()`](https://json.nlohmann.me/api/basic_json_document/save/index.md) wrote (overloads 1 and 2), or one to take ownership of (overload 3)
|
||||
|
||||
`size` (in) : the number of bytes at `image` (overload 1)
|
||||
|
||||
`check` (in) : how thoroughly to validate `image` before trusting it; see [`image_check`](#image_check) below (optional, `image_check::full` by default)
|
||||
|
||||
## Return value
|
||||
|
||||
The document read from the image.
|
||||
|
||||
## Exception safety
|
||||
|
||||
Overloads 1 and 2 give the strong guarantee: `image` is only read, never written, so a thrown exception leaves the caller's buffer untouched.
|
||||
|
||||
Overload 3 moves `image` into the document *before* validating it, so that a good image is kept without a copy. If loading then fails, the partially built document -- and the vector now inside it -- is discarded along with the exception, and `image` itself is left **empty**, not restored to what was passed in. Move a copy in instead, or validate with overload 2 first, if the original vector must survive a failed load.
|
||||
|
||||
## Exceptions
|
||||
|
||||
On a big-endian target, throws [`type_error.320`](https://json.nlohmann.me/home/exceptions/#jsonexceptiontype_error320) -- the same exception [`save()`](https://json.nlohmann.me/api/basic_json_document/save/#exceptions) throws there, since the image format is little-endian only.
|
||||
|
||||
Otherwise throws [`parse_error.116`](https://json.nlohmann.me/home/exceptions/#jsonexceptionparse_error116) if `image` is not one `save()` could have written, or fails the requested `check`:
|
||||
|
||||
| message | when |
|
||||
| -------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `too short` | `image` is `nullptr`, or `size` is smaller than the 64-byte header |
|
||||
| `unknown format` | the header's magic bytes or version do not match, or a reserved header field is not zero |
|
||||
| `sizes out of range` | the node count, text size, or decoded-string size the header describes does not fit `size`, or the `'\0'` after the text or after the decoded strings is missing |
|
||||
| `the check failed` | `check` is not `image_check::none`, and the image fails it -- see [`image_check`](#image_check) |
|
||||
|
||||
Example messages
|
||||
|
||||
```
|
||||
[json.exception.parse_error.116] parse error: invalid json_document image: too short
|
||||
```
|
||||
|
||||
```
|
||||
[json.exception.parse_error.116] parse error: invalid json_document image: unknown format
|
||||
```
|
||||
|
||||
```
|
||||
[json.exception.parse_error.116] parse error: invalid json_document image: sizes out of range
|
||||
```
|
||||
|
||||
```
|
||||
[json.exception.parse_error.116] parse error: invalid json_document image: the check failed
|
||||
```
|
||||
|
||||
## Complexity
|
||||
|
||||
Linear in the number of nodes, which are always copied into the document. `image_check::none` does not read the text or the decoded strings. `image_check::bounds` reads one byte of the text for each float token (its sign, to check the recorded digits against the token's length), and nothing else of the text or the decoded strings.
|
||||
|
||||
With `image_check::full`, linear in the size of the image (the nodes, the text, and the decoded strings), plus sorting the ranges of the strings and of the float tokens (at most one per node): the contents of each distinct range are checked once, however many nodes refer to it.
|
||||
|
||||
## Notes
|
||||
|
||||
### `image_check`
|
||||
|
||||
```
|
||||
using image_check = detail::view::image_check;
|
||||
|
||||
enum class image_check
|
||||
{
|
||||
full,
|
||||
bounds,
|
||||
none
|
||||
};
|
||||
```
|
||||
|
||||
How thoroughly `load()` validates `image` before trusting it.
|
||||
|
||||
`full` (the default) : Checks everything the parser itself guarantees: structure and bounds; that every string is valid UTF-8 (and, for a string still in the source text, that it contains no quote, backslash, or control character); and that every number token is well-formed and matches the value stored for it. Strings and float tokens may share a range only if the ranges are identical (as nodes that share a value do), and never overlap otherwise. Reading and serializing a checked image is safe and always produces valid JSON, exactly as for a parsed document. This is the right choice for an image from anything you do not fully control -- a file, a cache shared with other processes, a peer on the network.
|
||||
|
||||
`bounds` : Checks structure and bounds only: that every offset and count in the node index stays inside the image. So `load()`, [`root()`](https://json.nlohmann.me/api/basic_json_document/root/index.md), element access, and [`materialize()`](https://json.nlohmann.me/api/basic_json_view/materialize/index.md) can never read outside the image, even on a damaged one. It does *not* guarantee that the image describes valid JSON: a string that a `full` check would have rejected can make [`dump()`](https://json.nlohmann.me/api/basic_json_view/dump/index.md) write invalid UTF-8 or invalid JSON, or throw [`type_error.316`](https://json.nlohmann.me/home/exceptions/#jsonexceptiontype_error316), and a number can read back with a value that does not match how it is spelled. An [editable document](https://json.nlohmann.me/api/json_editable_document/index.md) does not take such a string over: [`set`](https://json.nlohmann.me/api/basic_json_document/set/index.md), [`push_back`](https://json.nlohmann.me/api/basic_json_document/push_back/index.md) and [`insert`](https://json.nlohmann.me/api/basic_json_document/insert/index.md) throw `type_error.316` when they copy it from a view of the loaded document, and leave the editable document unchanged. `bounds` skips scanning the text and the decoded strings, so it fits a cache your own process just wrote and reads straight back, where damage would mean a bug or a hardware fault rather than adversarial input.
|
||||
|
||||
`none` : Checks nothing. Reading a damaged image is undefined behavior, so use it only for an image you trust as much as your own memory.
|
||||
|
||||
**Lifetime.** Overloads 1 and 2 borrow `image`: it must stay alive and byte-for-byte unchanged for as long as the returned document, and any [view](https://json.nlohmann.me/api/basic_json_view/index.md) taken from it, is used -- exactly like a document [`parse()`](https://json.nlohmann.me/api/basic_json_document/parse/index.md) borrowed its input for. Overload 3 avoids this by keeping the vector itself; see [`owns_source`](https://json.nlohmann.me/api/basic_json_document/owns_source/index.md).
|
||||
|
||||
Experimental
|
||||
|
||||
The image format is versioned but not yet stable, and may change in an incompatible way before it is declared stable; `load()` already rejects an image written by a different format version with `parse_error.116` ("unknown format"). Use images to cache a document within one build of the library, or to hand one to another process running the *same* build on the *same* (little-endian) machine -- not as a long-term storage format.
|
||||
|
||||
## Examples
|
||||
|
||||
Caching a document, ownership, and a rejected image
|
||||
|
||||
The example below saves a parsed document as an image, checks that `load()` reproduces the original [`dump()`](https://json.nlohmann.me/api/basic_json_view/dump/index.md) without parsing, and shows the difference between `load(std::move(image))` (owned) and `load(image)` (borrowed). It then damages one byte of the image and shows `image_check::full` rejecting it with `parse_error.116`, while `image_check::bounds` -- meant for a cache the process already trusts -- still reads it without going out of bounds.
|
||||
|
||||
```
|
||||
#include <cstdint>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <nlohmann/json_view.hpp>
|
||||
|
||||
using json = nlohmann::json;
|
||||
using json_document = nlohmann::json_document;
|
||||
using image_check = json_document::image_check;
|
||||
|
||||
int main()
|
||||
{
|
||||
std::cout << std::boolalpha;
|
||||
|
||||
// the image of a parsed document -- as if read back from a cache file or
|
||||
// received from another process running the same build of the library
|
||||
const std::string text = R"({"name": "cache", "note": "caf\u00e9", "replicas": ["db2", "db3"]})";
|
||||
const json_document parsed = json_document::parse(text);
|
||||
const std::vector<std::uint8_t> image = parsed.save();
|
||||
|
||||
// (1)/(2) load() needs no parsing, yet dumps exactly what parsing did
|
||||
const json_document borrowed = json_document::load(image);
|
||||
std::cout << (borrowed.root().dump() == parsed.root().dump()) << '\n';
|
||||
std::cout << borrowed.owns_source() << '\n'; // borrowed: still points into `image`
|
||||
|
||||
// (3) load(std::move(image)) keeps the vector instead of copying it
|
||||
std::vector<std::uint8_t> to_move = image;
|
||||
const json_document owned = json_document::load(std::move(to_move));
|
||||
std::cout << owned.owns_source() << '\n';
|
||||
|
||||
// a damaged image -- the last byte of the decoded string "note" holds
|
||||
// (an escape sequence, so it was unescaped into the document's own
|
||||
// buffer), flipped, as storage or transport corruption might do
|
||||
std::vector<std::uint8_t> damaged = image;
|
||||
damaged[damaged.size() - 2] = 0xFF;
|
||||
|
||||
// image_check::full inspects strings and numbers, so it catches the damage
|
||||
try
|
||||
{
|
||||
static_cast<void>(json_document::load(damaged, image_check::full));
|
||||
}
|
||||
catch (const json::parse_error& e)
|
||||
{
|
||||
std::cout << e.id << '\n';
|
||||
}
|
||||
|
||||
// image_check::bounds only checks structure and bounds, so a cache the
|
||||
// process already trusts loads without the extra scan -- reading a value
|
||||
// the damage did not touch is still safe
|
||||
const json_document trusted = json_document::load(damaged, image_check::bounds);
|
||||
std::cout << trusted.root()["name"].get<std::string>() << '\n';
|
||||
}
|
||||
```
|
||||
|
||||
Output:
|
||||
|
||||
```
|
||||
true
|
||||
false
|
||||
true
|
||||
116
|
||||
cache
|
||||
```
|
||||
|
||||
## See also
|
||||
|
||||
- [save](https://json.nlohmann.me/api/basic_json_document/save/index.md) - write the document as an image
|
||||
- [owns_source](https://json.nlohmann.me/api/basic_json_document/owns_source/index.md) - return whether the document holds its own copy of the text
|
||||
- [parse](https://json.nlohmann.me/api/basic_json_document/parse/index.md) - deserialize from JSON text instead of an image
|
||||
- [Images](https://json.nlohmann.me/features/json_view/#images) - why and when to use images
|
||||
|
||||
## Version history
|
||||
|
||||
- Added in version 3.13.0 unreleased.
|
||||
@@ -0,0 +1,80 @@
|
||||
# <small>nlohmann::basic_json_document::</small>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
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <nlohmann/json_view.hpp>
|
||||
|
||||
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';
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
Output:
|
||||
|
||||
```json
|
||||
true
|
||||
true
|
||||
|
||||
```
|
||||
|
||||
## 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.
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,74 @@
|
||||
# nlohmann::basic_json_document::memory_usage
|
||||
|
||||
```
|
||||
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](https://json.nlohmann.me/api/basic_json_document/is_discarded/index.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()`](https://json.nlohmann.me/api/basic_json_document/shrink_to_fit/index.md).
|
||||
|
||||
## Examples
|
||||
|
||||
Example
|
||||
|
||||
```
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <nlohmann/json_view.hpp>
|
||||
|
||||
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';
|
||||
}
|
||||
```
|
||||
|
||||
Output:
|
||||
|
||||
```
|
||||
true
|
||||
true
|
||||
```
|
||||
|
||||
## See also
|
||||
|
||||
- [node_count](https://json.nlohmann.me/api/basic_json_document/node_count/index.md) - the number of index entries
|
||||
- [shrink_to_fit](https://json.nlohmann.me/api/basic_json_document/shrink_to_fit/index.md) - release unused index capacity
|
||||
|
||||
## Version history
|
||||
|
||||
- Added in version 3.13.0 unreleased.
|
||||
@@ -0,0 +1,66 @@
|
||||
# <small>nlohmann::basic_json_document::</small>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](../../home/architecture.md#node-index-of-json-views), 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
|
||||
#include <iostream>
|
||||
#include <nlohmann/json_view.hpp>
|
||||
|
||||
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';
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
Output:
|
||||
|
||||
```json
|
||||
1
|
||||
7
|
||||
|
||||
```
|
||||
|
||||
## 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.
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,61 @@
|
||||
# nlohmann::basic_json_document::node_count
|
||||
|
||||
```
|
||||
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](https://json.nlohmann.me/api/basic_json_document/is_discarded/index.md) document.
|
||||
|
||||
## Exception safety
|
||||
|
||||
No-throw guarantee: this function never throws exceptions.
|
||||
|
||||
## Complexity
|
||||
|
||||
Constant.
|
||||
|
||||
## Notes
|
||||
|
||||
Each index entry is [16 bytes](https://json.nlohmann.me/home/architecture/#node-index-of-json-views), so `node_count() * 16` is the size of the index itself (part, but not all, of [`memory_usage()`](https://json.nlohmann.me/api/basic_json_document/memory_usage/index.md), which also counts decoded strings and, for an owned document, the text).
|
||||
|
||||
## Examples
|
||||
|
||||
Example
|
||||
|
||||
```
|
||||
#include <iostream>
|
||||
#include <nlohmann/json_view.hpp>
|
||||
|
||||
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';
|
||||
}
|
||||
```
|
||||
|
||||
Output:
|
||||
|
||||
```
|
||||
1
|
||||
7
|
||||
```
|
||||
|
||||
## See also
|
||||
|
||||
- [memory_usage](https://json.nlohmann.me/api/basic_json_document/memory_usage/index.md) - the number of bytes held by the document
|
||||
- [shrink_to_fit](https://json.nlohmann.me/api/basic_json_document/shrink_to_fit/index.md) - release unused index capacity
|
||||
|
||||
## Version history
|
||||
|
||||
- Added in version 3.13.0 unreleased.
|
||||
@@ -0,0 +1,76 @@
|
||||
# <small>nlohmann::basic_json_document::</small>owns_source
|
||||
|
||||
```cpp
|
||||
bool owns_source() const noexcept;
|
||||
```
|
||||
|
||||
Returns whether the document holds its own copy of the parsed text or is 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
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <nlohmann/json_view.hpp>
|
||||
|
||||
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';
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
Output:
|
||||
|
||||
```json
|
||||
false
|
||||
true
|
||||
true
|
||||
|
||||
```
|
||||
|
||||
## 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.
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,72 @@
|
||||
# nlohmann::basic_json_document::owns_source
|
||||
|
||||
```
|
||||
bool owns_source() const noexcept;
|
||||
```
|
||||
|
||||
Returns whether the document holds its own copy of the parsed text or is borrowing the caller's buffer.
|
||||
|
||||
## Return value
|
||||
|
||||
`true` if the document owns the text returned by [`source()`](https://json.nlohmann.me/api/basic_json_document/source/index.md), `false` if it borrows it (or if the document is [discarded](https://json.nlohmann.me/api/basic_json_document/is_discarded/index.md)).
|
||||
|
||||
## Exception safety
|
||||
|
||||
No-throw guarantee: this function never throws exceptions.
|
||||
|
||||
## Complexity
|
||||
|
||||
Constant.
|
||||
|
||||
## Notes
|
||||
|
||||
See the ownership table on [`parse`](https://json.nlohmann.me/api/basic_json_document/parse/#notes) for which inputs are borrowed and which are owned. A borrowed document (`owns_source() == false`) is only valid while the buffer it was parsed from is still alive.
|
||||
|
||||
## Examples
|
||||
|
||||
Example
|
||||
|
||||
```
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <nlohmann/json_view.hpp>
|
||||
|
||||
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';
|
||||
}
|
||||
```
|
||||
|
||||
Output:
|
||||
|
||||
```
|
||||
false
|
||||
true
|
||||
true
|
||||
```
|
||||
|
||||
## See also
|
||||
|
||||
- [parse](https://json.nlohmann.me/api/basic_json_document/parse/index.md) - deserialize from a compatible input
|
||||
- [parse_copy](https://json.nlohmann.me/api/basic_json_document/parse_copy/index.md) - deserialize a copy of a compatible input, always owned
|
||||
- [source](https://json.nlohmann.me/api/basic_json_document/source/index.md) - the parsed text
|
||||
|
||||
## Version history
|
||||
|
||||
- Added in version 3.13.0 unreleased.
|
||||
@@ -0,0 +1,217 @@
|
||||
# <small>nlohmann::basic_json_document::</small>parse
|
||||
|
||||
```cpp
|
||||
// (1)
|
||||
template<typename InputType>
|
||||
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<typename IteratorType>
|
||||
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 the same JSON text as [`BasicJsonType::parse()`](../basic_json/parse.md), 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. They take the same inputs as `BasicJsonType::parse()`. Byte
|
||||
inputs that stay alive can be borrowed; all others (streams, `#!cpp FILE*`, wide characters, non-contiguous
|
||||
iterators) are read into a copy that the document owns -- see the Notes. Use [`parse_copy()`](parse_copy.md) to get an
|
||||
owned copy of a borrowable input as well.
|
||||
|
||||
## Template parameters
|
||||
|
||||
`InputType`
|
||||
: A compatible input, for instance:
|
||||
|
||||
- a `#!cpp std::string`, `#!cpp std::string_view`, or a C-style array of single-byte characters
|
||||
- a pointer to a null-terminated string of single-byte characters (`#!cpp char`, `#!cpp signed char`,
|
||||
`#!cpp unsigned char`, `#!cpp std::uint8_t`)
|
||||
- a container for which `#!cpp obj.data()` and `#!cpp obj.size()` give contiguous single-byte access, e.g.
|
||||
`#!cpp std::vector<char>` or `#!cpp std::vector<std::uint8_t>`
|
||||
- an `#!cpp std::istream` object
|
||||
- a `#!cpp FILE*` pointer
|
||||
- wide characters (`#!cpp wchar_t`, `#!cpp char16_t`, `#!cpp char32_t`), which are converted to UTF-8: a wide
|
||||
string object (`#!cpp std::wstring`, `#!cpp std::u16string`, `#!cpp std::u32string`), an array (e.g. a wide
|
||||
string literal), or a pointer to a null-terminated wide string
|
||||
|
||||
`IteratorType`
|
||||
: an input iterator type, for instance a pair of pointers such as `ptr` and `ptr + len`, or a pair of
|
||||
`#!cpp std::string::iterator`; the iterators of single-byte characters are borrowed or read like the byte inputs
|
||||
above, those of wide characters are converted to UTF-8
|
||||
|
||||
## 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. This replay runs only for a failing input, and costs about a lexing pass up to
|
||||
the error (its SAX handler builds no values); with `allow_exceptions` set to `#!cpp false`, it is skipped and a
|
||||
discarded document is returned instead. Additionally throws
|
||||
[`out_of_range.416`](../../home/exceptions.md#jsonexceptionout_of_range416) if the input is 4294967280 bytes (4 GiB
|
||||
minus 16 bytes) 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<char>`, ...), `std::string_view`, C string, character array | **borrowed** -- `input` must outlive the document |
|
||||
| non-const rvalue `#!cpp std::string` | **owned**, moved in without a copy |
|
||||
| other rvalue byte container (including a `#!cpp const` rvalue `#!cpp std::string`) | **owned**, copied |
|
||||
| stream, `#!cpp FILE*`, wide characters, 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<char>::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<char>`).
|
||||
|
||||
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.
|
||||
|
||||
**No lengths.** An integer argument that is not a `#!cpp bool` where the flags are expected -- for example
|
||||
`#!cpp parse(ptr, len)` -- does not compile (the overload is deleted). Such a call would convert `len` to
|
||||
`allow_exceptions` and read `ptr` as a null-terminated string, past the end of a buffer that has none. To parse a
|
||||
buffer of a given length, pass a pair of pointers: `#!cpp parse(ptr, ptr + len)`. The same holds for
|
||||
[`parse_copy`](parse_copy.md), [`accept`](accept.md), and [`read`](read.md).
|
||||
|
||||
## Examples
|
||||
|
||||
??? example "Example: (1) borrowed vs. owned input, and errors identical to `BasicJsonType::parse()`"
|
||||
|
||||
```cpp
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <nlohmann/json.hpp>
|
||||
#include <nlohmann/json_view.hpp>
|
||||
|
||||
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<void>(json_document::parse(R"({"count": )"));
|
||||
}
|
||||
catch (const nlohmann::json::parse_error& e)
|
||||
{
|
||||
std::cout << e.id << '\n';
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
Output:
|
||||
|
||||
```json
|
||||
false
|
||||
true
|
||||
101
|
||||
|
||||
```
|
||||
|
||||
??? example "Example: (2) parse an iterator range (no NUL terminator required)"
|
||||
|
||||
```cpp
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <nlohmann/json_view.hpp>
|
||||
|
||||
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<char> 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<char>
|
||||
// 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
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
Output:
|
||||
|
||||
```json
|
||||
true 2
|
||||
false
|
||||
|
||||
```
|
||||
|
||||
## 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
|
||||
- [load](load.md) - read a document from an image instead of parsing JSON text
|
||||
- [`BasicJsonType::parse`](../basic_json/parse.md) - the corresponding function of `basic_json`
|
||||
|
||||
## Version history
|
||||
|
||||
- Added in version 3.13.0.
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,181 @@
|
||||
# nlohmann::basic_json_document::parse
|
||||
|
||||
```
|
||||
// (1)
|
||||
template<typename InputType>
|
||||
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<typename IteratorType>
|
||||
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).
|
||||
1. Deserialize from a pair of input iterators.
|
||||
|
||||
Both overloads accept the same JSON text as [`BasicJsonType::parse()`](https://json.nlohmann.me/api/basic_json/parse/index.md), with the same `ignore_comments`/`ignore_trailing_commas` options, but build a [`basic_json_document`](https://json.nlohmann.me/api/basic_json_document/index.md) (a flat index into the input) instead of a tree of `BasicJsonType` values. They take the same inputs as `BasicJsonType::parse()`. Byte inputs that stay alive can be borrowed; all others (streams, `FILE*`, wide characters, non-contiguous iterators) are read into a copy that the document owns -- see the Notes. Use [`parse_copy()`](https://json.nlohmann.me/api/basic_json_document/parse_copy/index.md) to get an owned copy of a borrowable input as well.
|
||||
|
||||
## Template parameters
|
||||
|
||||
`InputType` : A compatible input, for instance:
|
||||
|
||||
```
|
||||
- a `std::string`, `std::string_view`, or a C-style array of single-byte characters
|
||||
- a pointer to a null-terminated string of single-byte characters (`char`, `signed char`,
|
||||
`unsigned char`, `std::uint8_t`)
|
||||
- a container for which `obj.data()` and `obj.size()` give contiguous single-byte access, e.g.
|
||||
`std::vector<char>` or `std::vector<std::uint8_t>`
|
||||
- an `std::istream` object
|
||||
- a `FILE*` pointer
|
||||
- wide characters (`wchar_t`, `char16_t`, `char32_t`), which are converted to UTF-8: a wide
|
||||
string object (`std::wstring`, `std::u16string`, `std::u32string`), an array (e.g. a wide
|
||||
string literal), or a pointer to a null-terminated wide string
|
||||
```
|
||||
|
||||
`IteratorType` : an input iterator type, for instance a pair of pointers such as `ptr` and `ptr + len`, or a pair of `std::string::iterator`; the iterators of single-byte characters are borrowed or read like the byte inputs above, those of wide characters are converted to UTF-8
|
||||
|
||||
## Parameters
|
||||
|
||||
`input` (in) : Input to parse from.
|
||||
|
||||
`allow_exceptions` (in) : whether to throw exceptions in case of a parse error (optional, `true` by default)
|
||||
|
||||
`ignore_comments` (in) : whether comments should be ignored and treated like whitespace (`true`) or yield a parse error (`false`); (optional, `false` by default)
|
||||
|
||||
`ignore_trailing_commas` (in) : whether trailing commas in arrays or objects should be ignored and treated like whitespace (`true`) or yield a parse error (`false`); (optional, `false` by default)
|
||||
|
||||
`first` (in) : iterator to the start of a character range
|
||||
|
||||
`last` (in) : iterator to the end of a character range
|
||||
|
||||
## Return value
|
||||
|
||||
The parsed document. If `allow_exceptions` is `false` and the input is not valid JSON, the returned document is discarded; see [`is_discarded`](https://json.nlohmann.me/api/basic_json_document/is_discarded/index.md).
|
||||
|
||||
## Exceptions
|
||||
|
||||
Throws the same exception [`BasicJsonType::parse()`](https://json.nlohmann.me/api/basic_json/parse/index.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. This replay runs only for a failing input, and costs about a lexing pass up to the error (its SAX handler builds no values); with `allow_exceptions` set to `false`, it is skipped and a discarded document is returned instead. Additionally throws [`out_of_range.416`](https://json.nlohmann.me/home/exceptions/#jsonexceptionout_of_range416) if the input is 4294967280 bytes (4 GiB minus 16 bytes) or larger, a size [`BasicJsonType::parse()`](https://json.nlohmann.me/api/basic_json/parse/index.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<char>`, ...), `std::string_view`, C string, character array | **borrowed** -- `input` must outlive the document |
|
||||
| non-const rvalue `std::string` | **owned**, moved in without a copy |
|
||||
| other rvalue byte container (including a `const` rvalue `std::string`) | **owned**, copied |
|
||||
| stream, `FILE*`, wide characters, 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. `const char*`, `std::uint8_t*`) is borrowed. From C++20 on, so is any other contiguous iterator over single bytes, such as `std::vector<char>::iterator` or `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 `std::list<char>`).
|
||||
|
||||
See [`owns_source`](https://json.nlohmann.me/api/basic_json_document/owns_source/index.md) to check which happened after a call, and the [feature page](https://json.nlohmann.me/features/json_view/index.md) for the reasoning.
|
||||
|
||||
**Numbers.** As for [`BasicJsonType::parse()`](https://json.nlohmann.me/api/basic_json/parse/index.md), an integer literal too large for the 64-bit integer type becomes a floating-point value.
|
||||
|
||||
**No lengths.** An integer argument that is not a `bool` where the flags are expected -- for example `parse(ptr, len)` -- does not compile (the overload is deleted). Such a call would convert `len` to `allow_exceptions` and read `ptr` as a null-terminated string, past the end of a buffer that has none. To parse a buffer of a given length, pass a pair of pointers: `parse(ptr, ptr + len)`. The same holds for [`parse_copy`](https://json.nlohmann.me/api/basic_json_document/parse_copy/index.md), [`accept`](https://json.nlohmann.me/api/basic_json_document/accept/index.md), and [`read`](https://json.nlohmann.me/api/basic_json_document/read/index.md).
|
||||
|
||||
## Examples
|
||||
|
||||
Example: (1) borrowed vs. owned input, and errors identical to `BasicJsonType::parse()`
|
||||
|
||||
```
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <nlohmann/json.hpp>
|
||||
#include <nlohmann/json_view.hpp>
|
||||
|
||||
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<void>(json_document::parse(R"({"count": )"));
|
||||
}
|
||||
catch (const nlohmann::json::parse_error& e)
|
||||
{
|
||||
std::cout << e.id << '\n';
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Output:
|
||||
|
||||
```
|
||||
false
|
||||
true
|
||||
101
|
||||
```
|
||||
|
||||
Example: (2) parse an iterator range (no NUL terminator required)
|
||||
|
||||
```
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <nlohmann/json_view.hpp>
|
||||
|
||||
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<char> 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<char>
|
||||
// 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
|
||||
}
|
||||
```
|
||||
|
||||
Output:
|
||||
|
||||
```
|
||||
true 2
|
||||
false
|
||||
```
|
||||
|
||||
## See also
|
||||
|
||||
- [parse_copy](https://json.nlohmann.me/api/basic_json_document/parse_copy/index.md) - deserialize a copy of a compatible input
|
||||
- [accept](https://json.nlohmann.me/api/basic_json_document/accept/index.md) - check whether the input is valid JSON
|
||||
- [read](https://json.nlohmann.me/api/basic_json_document/read/index.md) - (re-)parse into this document, reusing its memory
|
||||
- [owns_source](https://json.nlohmann.me/api/basic_json_document/owns_source/index.md) - return whether the document holds its own copy of the text
|
||||
- [load](https://json.nlohmann.me/api/basic_json_document/load/index.md) - read a document from an image instead of parsing JSON text
|
||||
- [`BasicJsonType::parse`](https://json.nlohmann.me/api/basic_json/parse/index.md) - the corresponding function of `basic_json`
|
||||
|
||||
## Version history
|
||||
|
||||
- Added in version 3.13.0 unreleased.
|
||||
@@ -0,0 +1,104 @@
|
||||
# <small>nlohmann::basic_json_document::</small>parse_copy
|
||||
|
||||
```cpp
|
||||
template<typename InputType>
|
||||
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.
|
||||
|
||||
An integer argument that is not a `#!cpp bool` where the flags are expected, such as `#!cpp parse_copy(ptr, len)`, does not
|
||||
compile; see [`parse`](parse.md#notes).
|
||||
|
||||
## Examples
|
||||
|
||||
??? example
|
||||
|
||||
The example below returns a document from a function whose local buffer would otherwise not outlive it.
|
||||
|
||||
```cpp
|
||||
#include <iostream>
|
||||
#include <nlohmann/json_view.hpp>
|
||||
|
||||
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';
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
Output:
|
||||
|
||||
```json
|
||||
true
|
||||
true
|
||||
|
||||
```
|
||||
|
||||
## 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.
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,90 @@
|
||||
# nlohmann::basic_json_document::parse_copy
|
||||
|
||||
```
|
||||
template<typename InputType>
|
||||
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()`](https://json.nlohmann.me/api/basic_json_document/parse/index.md), the returned document never depends on `input` staying alive.
|
||||
|
||||
## Template parameters
|
||||
|
||||
`InputType` : A compatible input; see [`parse`](https://json.nlohmann.me/api/basic_json_document/parse/#template-parameters).
|
||||
|
||||
## Parameters
|
||||
|
||||
`input` (in) : Input to parse from.
|
||||
|
||||
`allow_exceptions` (in) : whether to throw exceptions in case of a parse error (optional, `true` by default)
|
||||
|
||||
`ignore_comments` (in) : whether comments should be ignored and treated like whitespace (`true`) or yield a parse error (`false`); (optional, `false` by default)
|
||||
|
||||
`ignore_trailing_commas` (in) : whether trailing commas in arrays or objects should be ignored and treated like whitespace (`true`) or yield a parse error (`false`); (optional, `false` by default)
|
||||
|
||||
## Return value
|
||||
|
||||
The parsed document, with [`owns_source()`](https://json.nlohmann.me/api/basic_json_document/owns_source/index.md) `true`. If `allow_exceptions` is `false` and the input is not valid JSON, the returned document is discarded; see [`is_discarded`](https://json.nlohmann.me/api/basic_json_document/is_discarded/index.md).
|
||||
|
||||
## Exceptions
|
||||
|
||||
Same as [`parse`](https://json.nlohmann.me/api/basic_json_document/parse/#exceptions).
|
||||
|
||||
## Complexity
|
||||
|
||||
Linear in the length of the input.
|
||||
|
||||
## Notes
|
||||
|
||||
`parse_copy()` accepts and rejects exactly what [`parse()`](https://json.nlohmann.me/api/basic_json_document/parse/index.md) does, and classifies numbers the same way; it only differs in that the input is always copied rather than sometimes borrowed. Prefer [`parse()`](https://json.nlohmann.me/api/basic_json_document/parse/index.md) when the input's lifetime already covers the document's, since it avoids the copy for borrowed inputs.
|
||||
|
||||
An integer argument that is not a `bool` where the flags are expected, such as `parse_copy(ptr, len)`, does not compile; see [`parse`](https://json.nlohmann.me/api/basic_json_document/parse/#notes).
|
||||
|
||||
## Examples
|
||||
|
||||
Example
|
||||
|
||||
The example below returns a document from a function whose local buffer would otherwise not outlive it.
|
||||
|
||||
```
|
||||
#include <iostream>
|
||||
#include <nlohmann/json_view.hpp>
|
||||
|
||||
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';
|
||||
}
|
||||
```
|
||||
|
||||
Output:
|
||||
|
||||
```
|
||||
true
|
||||
true
|
||||
```
|
||||
|
||||
## See also
|
||||
|
||||
- [parse](https://json.nlohmann.me/api/basic_json_document/parse/index.md) - deserialize from a compatible input, borrowing it where possible
|
||||
- [owns_source](https://json.nlohmann.me/api/basic_json_document/owns_source/index.md) - return whether the document holds its own copy of the text
|
||||
|
||||
## Version history
|
||||
|
||||
- Added in version 3.13.0 unreleased.
|
||||
@@ -0,0 +1,149 @@
|
||||
# <small>nlohmann::basic_json_document::</small>push_back
|
||||
|
||||
```cpp
|
||||
template<typename V>
|
||||
view_type push_back(view_type array, V&& value);
|
||||
```
|
||||
|
||||
Appends `value` as a new last element of `array`. A [null](../basic_json_view/is_null.md) `array` first becomes an
|
||||
empty array, the same way [`set`](set.md) turns a null `object` into an empty object.
|
||||
|
||||
`value` is accepted three ways: a [`basic_json_view`](../basic_json_view/index.md) of *any* document -- read-only or
|
||||
editable, and it does not have to be `array`'s own document -- which is copied so that nothing is shared with the
|
||||
source document afterward; a `BasicJsonType` value; or anything `BasicJsonType` can be constructed from (numbers,
|
||||
strings, `#!cpp bool`, `#!cpp nullptr`, containers, ...).
|
||||
|
||||
Only an **editable** document (`#!cpp Editable == true`, e.g. [`json_editable_document`](../json_editable_document.md))
|
||||
has `push_back`; calling it on a read-only `basic_json_document` fails to compile (`#!cpp static_assert`).
|
||||
|
||||
## Template parameters
|
||||
|
||||
`V`
|
||||
: the type of `value`, deduced; see above for what is accepted.
|
||||
|
||||
## Parameters
|
||||
|
||||
`array` (in)
|
||||
: the array (or null value) to append to
|
||||
|
||||
`value` (in)
|
||||
: the value to append
|
||||
|
||||
## Return value
|
||||
|
||||
a view of the new last element of `array`, now holding `value`
|
||||
|
||||
## Exception safety
|
||||
|
||||
Basic exception safety: `value` is fully encoded -- including the checks below -- into storage owned by the document
|
||||
before anything already reachable from [`root()`](root.md) is touched, so a failure while encoding `value` (an
|
||||
invalid argument, or `#!cpp std::bad_alloc`) leaves the document completely unchanged, other than memory allocated
|
||||
for the encoding that is not reclaimed. A failure of a later allocation -- while `array` switches from its parsed
|
||||
layout to a growable block, or while that block grows, see [Notes](#notes) -- can still leave a partial effect, such
|
||||
as a null `array` argument already turned into an empty array even though `value` itself was not appended.
|
||||
|
||||
## Exceptions
|
||||
|
||||
Throws [`type_error.308`](../../home/exceptions.md#jsonexceptiontype_error308) if `array` is neither an array nor
|
||||
null -- the same message [`BasicJsonType::push_back`](../basic_json/push_back.md) throws for the same type. Throws
|
||||
[`invalid_iterator.202`](../../home/exceptions.md#jsonexceptioninvalid_iterator202) ("view does not belong to this
|
||||
document") if `array` is a [discarded](../basic_json_view/is_discarded.md) view or a view of a *different* document.
|
||||
Throws [`type_error.302`](../../home/exceptions.md#jsonexceptiontype_error302) if `value` is a
|
||||
[discarded](../basic_json_view/is_discarded.md) view or a [discarded](../basic_json/is_discarded.md) `BasicJsonType`
|
||||
value, and [`type_error.319`](../../home/exceptions.md#jsonexceptiontype_error319) if `value` is (or contains) a
|
||||
binary value -- `BasicJsonType` can hold one, but a `json_document` cannot. Throws
|
||||
[`type_error.316`](../../home/exceptions.md#jsonexceptiontype_error316) if `value` is (or contains) a string that is
|
||||
not valid UTF-8, with the same message [`BasicJsonType::dump()`](../basic_json/dump.md) gives for that string.
|
||||
|
||||
## Complexity
|
||||
|
||||
Amortized constant, plus time linear in the size of `value` to encode it into the document's storage (constant for
|
||||
a scalar, linear in the number of nested values for an array or object): the elements of `array` move to a growable
|
||||
block of links the first time it is appended to (or [`set`](set.md) on), and that block itself grows -- doubling its
|
||||
capacity, so the cost of growing it amortizes to constant per element -- only once it runs out of room. See
|
||||
[Notes](#notes).
|
||||
|
||||
## Notes
|
||||
|
||||
Like [`set`](set.md) on a member or an element, `push_back` never moves an existing element itself -- only where
|
||||
`array`'s *links* to its elements live -- so a view of an existing element of `array` stays valid across a
|
||||
`push_back`, but any iterator already taken over `array` is invalidated, since it was walking the old layout. See
|
||||
[Edits](index.md#edits) for what stays valid across an edit in general.
|
||||
|
||||
## Examples
|
||||
|
||||
??? example
|
||||
|
||||
The example below appends records to an array one at a time, as they might arrive from a stream of events,
|
||||
without ever building a `BasicJsonType` value for the array or for the records already in it, and shows that a
|
||||
view taken from an earlier `push_back` still refers to the same element once later ones have run.
|
||||
|
||||
```cpp
|
||||
#include <iostream>
|
||||
#include <nlohmann/json_view.hpp>
|
||||
|
||||
using json = nlohmann::json;
|
||||
using json_editable_document = nlohmann::json_editable_document;
|
||||
|
||||
int main()
|
||||
{
|
||||
// "events" starts out null -- the first push_back() turns it into an
|
||||
// array, exactly like set() turns a null object member into an object
|
||||
json_editable_document doc = json_editable_document::parse(R"({"source": "sensor-1", "events": null})");
|
||||
|
||||
const auto first = doc.push_back(doc.root()["events"], json{{"type", "start"}, {"t", 0}});
|
||||
for (int t = 1; t <= 3; ++t)
|
||||
{
|
||||
doc.push_back(doc.root()["events"], json{{"type", "tick"}, {"t", t}});
|
||||
}
|
||||
|
||||
// push_back() never moves an existing element: a view taken from an
|
||||
// earlier call still refers to the same element after later ones
|
||||
std::cout << first.dump() << '\n';
|
||||
std::cout << doc.root()["events"].size() << '\n';
|
||||
std::cout << doc.root().dump(2) << '\n';
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
Output:
|
||||
|
||||
```json
|
||||
{"t":0,"type":"start"}
|
||||
4
|
||||
{
|
||||
"source": "sensor-1",
|
||||
"events": [
|
||||
{
|
||||
"t": 0,
|
||||
"type": "start"
|
||||
},
|
||||
{
|
||||
"t": 1,
|
||||
"type": "tick"
|
||||
},
|
||||
{
|
||||
"t": 2,
|
||||
"type": "tick"
|
||||
},
|
||||
{
|
||||
"t": 3,
|
||||
"type": "tick"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
## See also
|
||||
|
||||
- [set](set.md) - replace a value, or set an object member, an array element, or the value a JSON pointer refers to
|
||||
- [insert](insert.md) - insert an element into an array before a given position
|
||||
- [erase](erase.md) - remove an object member, an array element, or the value a JSON pointer refers to
|
||||
- [root](root.md) - the view of the root value
|
||||
- [`BasicJsonType::push_back`](../basic_json/push_back.md) - the corresponding function of `basic_json`
|
||||
- [Edits](index.md#edits) - what an edit guarantees, for every overload
|
||||
|
||||
## Version history
|
||||
|
||||
- Added in version 3.13.0.
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,116 @@
|
||||
# nlohmann::basic_json_document::push_back
|
||||
|
||||
```
|
||||
template<typename V>
|
||||
view_type push_back(view_type array, V&& value);
|
||||
```
|
||||
|
||||
Appends `value` as a new last element of `array`. A [null](https://json.nlohmann.me/api/basic_json_view/is_null/index.md) `array` first becomes an empty array, the same way [`set`](https://json.nlohmann.me/api/basic_json_document/set/index.md) turns a null `object` into an empty object.
|
||||
|
||||
`value` is accepted three ways: a [`basic_json_view`](https://json.nlohmann.me/api/basic_json_view/index.md) of *any* document -- read-only or editable, and it does not have to be `array`'s own document -- which is copied so that nothing is shared with the source document afterward; a `BasicJsonType` value; or anything `BasicJsonType` can be constructed from (numbers, strings, `bool`, `nullptr`, containers, ...).
|
||||
|
||||
Only an **editable** document (`Editable == true`, e.g. [`json_editable_document`](https://json.nlohmann.me/api/json_editable_document/index.md)) has `push_back`; calling it on a read-only `basic_json_document` fails to compile (`static_assert`).
|
||||
|
||||
## Template parameters
|
||||
|
||||
`V` : the type of `value`, deduced; see above for what is accepted.
|
||||
|
||||
## Parameters
|
||||
|
||||
`array` (in) : the array (or null value) to append to
|
||||
|
||||
`value` (in) : the value to append
|
||||
|
||||
## Return value
|
||||
|
||||
a view of the new last element of `array`, now holding `value`
|
||||
|
||||
## Exception safety
|
||||
|
||||
Basic exception safety: `value` is fully encoded -- including the checks below -- into storage owned by the document before anything already reachable from [`root()`](https://json.nlohmann.me/api/basic_json_document/root/index.md) is touched, so a failure while encoding `value` (an invalid argument, or `std::bad_alloc`) leaves the document completely unchanged, other than memory allocated for the encoding that is not reclaimed. A failure of a later allocation -- while `array` switches from its parsed layout to a growable block, or while that block grows, see [Notes](#notes) -- can still leave a partial effect, such as a null `array` argument already turned into an empty array even though `value` itself was not appended.
|
||||
|
||||
## Exceptions
|
||||
|
||||
Throws [`type_error.308`](https://json.nlohmann.me/home/exceptions/#jsonexceptiontype_error308) if `array` is neither an array nor null -- the same message [`BasicJsonType::push_back`](https://json.nlohmann.me/api/basic_json/push_back/index.md) throws for the same type. Throws [`invalid_iterator.202`](https://json.nlohmann.me/home/exceptions/#jsonexceptioninvalid_iterator202) ("view does not belong to this document") if `array` is a [discarded](https://json.nlohmann.me/api/basic_json_view/is_discarded/index.md) view or a view of a *different* document. Throws [`type_error.302`](https://json.nlohmann.me/home/exceptions/#jsonexceptiontype_error302) if `value` is a [discarded](https://json.nlohmann.me/api/basic_json_view/is_discarded/index.md) view or a [discarded](https://json.nlohmann.me/api/basic_json/is_discarded/index.md) `BasicJsonType` value, and [`type_error.319`](https://json.nlohmann.me/home/exceptions/#jsonexceptiontype_error319) if `value` is (or contains) a binary value -- `BasicJsonType` can hold one, but a `json_document` cannot. Throws [`type_error.316`](https://json.nlohmann.me/home/exceptions/#jsonexceptiontype_error316) if `value` is (or contains) a string that is not valid UTF-8, with the same message [`BasicJsonType::dump()`](https://json.nlohmann.me/api/basic_json/dump/index.md) gives for that string.
|
||||
|
||||
## Complexity
|
||||
|
||||
Amortized constant, plus time linear in the size of `value` to encode it into the document's storage (constant for a scalar, linear in the number of nested values for an array or object): the elements of `array` move to a growable block of links the first time it is appended to (or [`set`](https://json.nlohmann.me/api/basic_json_document/set/index.md) on), and that block itself grows -- doubling its capacity, so the cost of growing it amortizes to constant per element -- only once it runs out of room. See [Notes](#notes).
|
||||
|
||||
## Notes
|
||||
|
||||
Like [`set`](https://json.nlohmann.me/api/basic_json_document/set/index.md) on a member or an element, `push_back` never moves an existing element itself -- only where `array`'s *links* to its elements live -- so a view of an existing element of `array` stays valid across a `push_back`, but any iterator already taken over `array` is invalidated, since it was walking the old layout. See [Edits](https://json.nlohmann.me/api/basic_json_document/#edits) for what stays valid across an edit in general.
|
||||
|
||||
## Examples
|
||||
|
||||
Example
|
||||
|
||||
The example below appends records to an array one at a time, as they might arrive from a stream of events, without ever building a `BasicJsonType` value for the array or for the records already in it, and shows that a view taken from an earlier `push_back` still refers to the same element once later ones have run.
|
||||
|
||||
```
|
||||
#include <iostream>
|
||||
#include <nlohmann/json_view.hpp>
|
||||
|
||||
using json = nlohmann::json;
|
||||
using json_editable_document = nlohmann::json_editable_document;
|
||||
|
||||
int main()
|
||||
{
|
||||
// "events" starts out null -- the first push_back() turns it into an
|
||||
// array, exactly like set() turns a null object member into an object
|
||||
json_editable_document doc = json_editable_document::parse(R"({"source": "sensor-1", "events": null})");
|
||||
|
||||
const auto first = doc.push_back(doc.root()["events"], json{{"type", "start"}, {"t", 0}});
|
||||
for (int t = 1; t <= 3; ++t)
|
||||
{
|
||||
doc.push_back(doc.root()["events"], json{{"type", "tick"}, {"t", t}});
|
||||
}
|
||||
|
||||
// push_back() never moves an existing element: a view taken from an
|
||||
// earlier call still refers to the same element after later ones
|
||||
std::cout << first.dump() << '\n';
|
||||
std::cout << doc.root()["events"].size() << '\n';
|
||||
std::cout << doc.root().dump(2) << '\n';
|
||||
}
|
||||
```
|
||||
|
||||
Output:
|
||||
|
||||
```
|
||||
{"t":0,"type":"start"}
|
||||
4
|
||||
{
|
||||
"source": "sensor-1",
|
||||
"events": [
|
||||
{
|
||||
"t": 0,
|
||||
"type": "start"
|
||||
},
|
||||
{
|
||||
"t": 1,
|
||||
"type": "tick"
|
||||
},
|
||||
{
|
||||
"t": 2,
|
||||
"type": "tick"
|
||||
},
|
||||
{
|
||||
"t": 3,
|
||||
"type": "tick"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## See also
|
||||
|
||||
- [set](https://json.nlohmann.me/api/basic_json_document/set/index.md) - replace a value, or set an object member, an array element, or the value a JSON pointer refers to
|
||||
- [insert](https://json.nlohmann.me/api/basic_json_document/insert/index.md) - insert an element into an array before a given position
|
||||
- [erase](https://json.nlohmann.me/api/basic_json_document/erase/index.md) - remove an object member, an array element, or the value a JSON pointer refers to
|
||||
- [root](https://json.nlohmann.me/api/basic_json_document/root/index.md) - the view of the root value
|
||||
- [`BasicJsonType::push_back`](https://json.nlohmann.me/api/basic_json/push_back/index.md) - the corresponding function of `basic_json`
|
||||
- [Edits](https://json.nlohmann.me/api/basic_json_document/#edits) - what an edit guarantees, for every overload
|
||||
|
||||
## Version history
|
||||
|
||||
- Added in version 3.13.0 unreleased.
|
||||
@@ -0,0 +1,120 @@
|
||||
# <small>nlohmann::basic_json_document::</small>read
|
||||
|
||||
```cpp
|
||||
template<typename InputType>
|
||||
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. An input that is copied (see the table in
|
||||
[`parse()`](parse.md#notes)) is written into the document's previous owned copy, reusing its memory; a moved-in
|
||||
`#!cpp std::string` replaces it.
|
||||
|
||||
Reusing a document matters most for large inputs: the operating system provides the memory of a fresh node index one
|
||||
page at a time, and every page costs a page fault the first time it is written. On x86-64 Linux (4 KiB pages), parsing
|
||||
a 55 MB document into a reused document took about 40 % less time than parsing it into a fresh one. Programs that parse
|
||||
many documents of similar size should therefore keep one document and call `read()`.
|
||||
|
||||
An integer argument that is not a `#!cpp bool` where the flags are expected, such as `#!cpp read(ptr, len)`, does not
|
||||
compile; see [`parse`](parse.md#notes).
|
||||
|
||||
## 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
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <nlohmann/json_view.hpp>
|
||||
|
||||
using json_document = nlohmann::json_document;
|
||||
|
||||
int main()
|
||||
{
|
||||
std::cout << std::boolalpha;
|
||||
|
||||
std::vector<std::string> 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';
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
Output:
|
||||
|
||||
```json
|
||||
4
|
||||
true
|
||||
|
||||
```
|
||||
|
||||
## See also
|
||||
|
||||
- [parse](parse.md) - deserialize from a compatible input
|
||||
- [root](root.md) - the view of the root value
|
||||
- [load](load.md) - read a document from an image instead of parsing JSON text
|
||||
|
||||
## Version history
|
||||
|
||||
- Added in version 3.13.0.
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,100 @@
|
||||
# nlohmann::basic_json_document::read
|
||||
|
||||
```
|
||||
template<typename InputType>
|
||||
void read(InputType&& input,
|
||||
const bool allow_exceptions = true,
|
||||
const bool ignore_comments = false,
|
||||
const bool ignore_trailing_commas = false);
|
||||
```
|
||||
|
||||
(Re-)parses `input` into `*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()`](https://json.nlohmann.me/api/basic_json_document/parse/index.md) is implemented in terms of this function, applied to a default-constructed document.
|
||||
|
||||
## Template parameters
|
||||
|
||||
`InputType` : A compatible input; see [`parse`](https://json.nlohmann.me/api/basic_json_document/parse/#template-parameters).
|
||||
|
||||
## Parameters
|
||||
|
||||
`input` (in) : Input to parse from.
|
||||
|
||||
`allow_exceptions` (in) : whether to throw exceptions in case of a parse error (optional, `true` by default)
|
||||
|
||||
`ignore_comments` (in) : whether comments should be ignored and treated like whitespace (`true`) or yield a parse error (`false`); (optional, `false` by default)
|
||||
|
||||
`ignore_trailing_commas` (in) : whether trailing commas in arrays or objects should be ignored and treated like whitespace (`true`) or yield a parse error (`false`); (optional, `false` by default)
|
||||
|
||||
## Exceptions
|
||||
|
||||
Same as [`parse`](https://json.nlohmann.me/api/basic_json_document/parse/#exceptions).
|
||||
|
||||
## Complexity
|
||||
|
||||
Linear in the length of the input.
|
||||
|
||||
## Notes
|
||||
|
||||
Every view taken from `*this` before the call -- including the previous [`root()`](https://json.nlohmann.me/api/basic_json_document/root/index.md) -- is invalidated, whether or not the new parse succeeds; take fresh views from [`root()`](https://json.nlohmann.me/api/basic_json_document/root/index.md) afterward.
|
||||
|
||||
`input` is borrowed or owned by the same rules as [`parse()`](https://json.nlohmann.me/api/basic_json_document/parse/#notes); a document can borrow on one call and own on the next, since ownership is decided freshly each time. An input that is copied (see the table in [`parse()`](https://json.nlohmann.me/api/basic_json_document/parse/#notes)) is written into the document's previous owned copy, reusing its memory; a moved-in `std::string` replaces it.
|
||||
|
||||
Reusing a document matters most for large inputs: the operating system provides the memory of a fresh node index one page at a time, and every page costs a page fault the first time it is written. On x86-64 Linux (4 KiB pages), parsing a 55 MB document into a reused document took about 40 % less time than parsing it into a fresh one. Programs that parse many documents of similar size should therefore keep one document and call `read()`.
|
||||
|
||||
An integer argument that is not a `bool` where the flags are expected, such as `read(ptr, len)`, does not compile; see [`parse`](https://json.nlohmann.me/api/basic_json_document/parse/#notes).
|
||||
|
||||
## 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.
|
||||
|
||||
```
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <nlohmann/json_view.hpp>
|
||||
|
||||
using json_document = nlohmann::json_document;
|
||||
|
||||
int main()
|
||||
{
|
||||
std::cout << std::boolalpha;
|
||||
|
||||
std::vector<std::string> 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';
|
||||
}
|
||||
```
|
||||
|
||||
Output:
|
||||
|
||||
```
|
||||
4
|
||||
true
|
||||
```
|
||||
|
||||
## See also
|
||||
|
||||
- [parse](https://json.nlohmann.me/api/basic_json_document/parse/index.md) - deserialize from a compatible input
|
||||
- [root](https://json.nlohmann.me/api/basic_json_document/root/index.md) - the view of the root value
|
||||
- [load](https://json.nlohmann.me/api/basic_json_document/load/index.md) - read a document from an image instead of parsing JSON text
|
||||
|
||||
## Version history
|
||||
|
||||
- Added in version 3.13.0 unreleased.
|
||||
@@ -0,0 +1,88 @@
|
||||
# <small>nlohmann::basic_json_document::</small>root
|
||||
|
||||
```cpp
|
||||
// (1)
|
||||
view_type root() const& noexcept;
|
||||
|
||||
// (2)
|
||||
view_type root() const&& = delete;
|
||||
```
|
||||
|
||||
1. Returns a view of the root value of the document.
|
||||
2. Deleted: the view of a temporary document would dangle.
|
||||
|
||||
## Return value
|
||||
|
||||
A [`view_type`](index.md#member-types) (i.e. `#!cpp basic_json_view<BasicJsonType>`) 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
|
||||
|
||||
**Lifetime.** A view refers into the document, so the document must outlive it. `root()` can therefore only be called
|
||||
on a document that has a name (an lvalue); calling it on a temporary does not compile:
|
||||
|
||||
```cpp
|
||||
auto v = json_document::parse(text).root(); // error: the document is destroyed at the end of the statement
|
||||
|
||||
auto doc = json_document::parse(text); // OK: keep the document alive
|
||||
auto v = doc.root();
|
||||
```
|
||||
|
||||
`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. A view can dangle, like a
|
||||
`#!cpp std::string_view`; see [Ownership and lifetime](../../features/json_view.md#ownership-and-lifetime).
|
||||
|
||||
## Examples
|
||||
|
||||
??? example
|
||||
|
||||
```cpp
|
||||
#include <iostream>
|
||||
#include <nlohmann/json_view.hpp>
|
||||
|
||||
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';
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
Output:
|
||||
|
||||
```json
|
||||
true
|
||||
true
|
||||
true
|
||||
|
||||
```
|
||||
|
||||
## 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.
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,80 @@
|
||||
# nlohmann::basic_json_document::root
|
||||
|
||||
```
|
||||
// (1)
|
||||
view_type root() const& noexcept;
|
||||
|
||||
// (2)
|
||||
view_type root() const&& = delete;
|
||||
```
|
||||
|
||||
1. Returns a view of the root value of the document.
|
||||
1. Deleted: the view of a temporary document would dangle.
|
||||
|
||||
## Return value
|
||||
|
||||
A [`view_type`](https://json.nlohmann.me/api/basic_json_document/#member-types) (i.e. `basic_json_view<BasicJsonType>`) for the root value, or a discarded view if the document is [discarded](https://json.nlohmann.me/api/basic_json_document/is_discarded/index.md).
|
||||
|
||||
## Exception safety
|
||||
|
||||
No-throw guarantee: this function never throws exceptions.
|
||||
|
||||
## Complexity
|
||||
|
||||
Constant.
|
||||
|
||||
## Notes
|
||||
|
||||
**Lifetime.** A view refers into the document, so the document must outlive it. `root()` can therefore only be called on a document that has a name (an lvalue); calling it on a temporary does not compile:
|
||||
|
||||
```
|
||||
auto v = json_document::parse(text).root(); // error: the document is destroyed at the end of the statement
|
||||
|
||||
auto doc = json_document::parse(text); // OK: keep the document alive
|
||||
auto v = doc.root();
|
||||
```
|
||||
|
||||
`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](https://json.nlohmann.me/api/basic_json_view/index.md) -- in particular, it is invalidated by the next [`read()`](https://json.nlohmann.me/api/basic_json_document/read/index.md) or [`shrink_to_fit()`](https://json.nlohmann.me/api/basic_json_document/shrink_to_fit/index.md) on this document. A view can dangle, like a `std::string_view`; see [Ownership and lifetime](https://json.nlohmann.me/features/json_view/#ownership-and-lifetime).
|
||||
|
||||
## Examples
|
||||
|
||||
Example
|
||||
|
||||
```
|
||||
#include <iostream>
|
||||
#include <nlohmann/json_view.hpp>
|
||||
|
||||
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';
|
||||
}
|
||||
```
|
||||
|
||||
Output:
|
||||
|
||||
```
|
||||
true
|
||||
true
|
||||
true
|
||||
```
|
||||
|
||||
## See also
|
||||
|
||||
- [is_discarded](https://json.nlohmann.me/api/basic_json_document/is_discarded/index.md) - return whether the last parse failed
|
||||
- [materialize](https://json.nlohmann.me/api/basic_json_view/materialize/index.md) - build the `BasicJsonType` value of a subtree
|
||||
|
||||
## Version history
|
||||
|
||||
- Added in version 3.13.0 unreleased.
|
||||
@@ -0,0 +1,137 @@
|
||||
# <small>nlohmann::basic_json_document::</small>save
|
||||
|
||||
```cpp
|
||||
std::vector<std::uint8_t> save() const;
|
||||
```
|
||||
|
||||
Writes the document as an *image*: a byte buffer that [`load`](load.md) reads back without parsing. The image holds
|
||||
the node index, the source text (plus, for an edited document, the number tokens edits wrote), and the decoded
|
||||
strings (plus the strings edits wrote) -- everything [`root()`](root.md) needs, with nothing left to parse.
|
||||
|
||||
An edited document is written in its *current* state, with its values in document order, the way the library's own
|
||||
parser would have produced them for that JSON text: a member [`set`](set.md) added goes at the end, an
|
||||
[`erase`](erase.md)d member leaves no trace, and a float that is not finite (NaN or positive/negative infinity)
|
||||
becomes null, the same substitution [`dump()`](../basic_json_view/dump.md) makes. The same document always saves to
|
||||
the same bytes -- also across `BasicJsonType` and `#!cpp Editable`, since the image reflects document order and
|
||||
values only, not which specialization produced them.
|
||||
|
||||
## Return value
|
||||
|
||||
The image, as a `#!cpp std::vector<std::uint8_t>`. Pass it, or a pointer to its data together with its size, to
|
||||
[`load`](load.md) to read the document back.
|
||||
|
||||
## Exception safety
|
||||
|
||||
Strong guarantee: `save()` does not modify `#!cpp *this` (it is `#!cpp const`), so if it throws, the document is left
|
||||
exactly as it was, and the partially built image is discarded with the exception.
|
||||
|
||||
## Exceptions
|
||||
|
||||
Throws [`type_error.320`](../../home/exceptions.md#jsonexceptiontype_error320) if the document is
|
||||
[discarded](is_discarded.md) -- a default-constructed document, or one a failed [`parse()`](parse.md)/
|
||||
[`read()`](read.md) with `allow_exceptions == false` left discarded.
|
||||
|
||||
On a big-endian target, throws `type_error.320` with a different message instead: the image format is little-endian
|
||||
only (see [Notes](#notes)).
|
||||
|
||||
Throws [`out_of_range.416`](../../home/exceptions.md#jsonexceptionout_of_range416) if the node count, the text, or
|
||||
the decoded strings of the image would individually reach 4 GiB -- the same 32-bit offsets
|
||||
[`parse()`](parse.md#exceptions) and, for edits, [`set`](set.md)/[`push_back`](push_back.md) are already limited to.
|
||||
|
||||
!!! failure "Example messages"
|
||||
|
||||
```
|
||||
[json.exception.type_error.320] cannot save a discarded json_document
|
||||
```
|
||||
```
|
||||
[json.exception.type_error.320] json_document images need a little-endian target
|
||||
```
|
||||
```
|
||||
[json.exception.out_of_range.416] images of 4 GiB or more are not supported by json_document
|
||||
```
|
||||
|
||||
## Complexity
|
||||
|
||||
Linear in the size of the document: the number of nodes, plus the length of the text and the decoded strings that end
|
||||
up in the image.
|
||||
|
||||
## Notes
|
||||
|
||||
**Format.** The image begins with a 64-byte header (the magic bytes `#!cpp "NJVI"`, a version number, the node count,
|
||||
and the sizes of the text and the decoded strings, all little-endian), followed by the nodes
|
||||
([16 bytes each](../../home/architecture.md#node-index-of-json-views)), the text and a `#!cpp '\0'`, and the decoded
|
||||
strings and a `#!cpp '\0'`. [`load`](load.md) checks the header, and the sizes it describes, before reading anything
|
||||
else -- see [`load`'s Exceptions](load.md#exceptions).
|
||||
|
||||
!!! warning "Experimental"
|
||||
|
||||
The image format is versioned but not yet stable: it may change in an incompatible way before it is declared
|
||||
stable. Use images to cache a document within one build of the library, or to hand one to another process running
|
||||
the *same* build on the *same* (little-endian) machine -- not as a long-term storage format. Keep the original
|
||||
JSON text if you need to read a saved document back with a future library version.
|
||||
|
||||
**Little-endian only.** The image is written as raw little-endian bytes, with no byte-swapping. `save()` (and
|
||||
[`load`](load.md)) throw `type_error.320` on a big-endian target rather than silently produce bytes a big-endian
|
||||
reader could not interpret correctly.
|
||||
|
||||
## Examples
|
||||
|
||||
??? example "Caching a parsed document as an image"
|
||||
|
||||
The example below saves a parsed configuration as an image -- the way a service might cache one to answer later
|
||||
requests without parsing the text again -- and confirms that loading it back gives exactly the same result as
|
||||
parsing did, and that saving is deterministic.
|
||||
|
||||
```cpp
|
||||
#include <cstdint>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <nlohmann/json_view.hpp>
|
||||
|
||||
using json_document = nlohmann::json_document;
|
||||
|
||||
int main()
|
||||
{
|
||||
std::cout << std::boolalpha;
|
||||
|
||||
// a configuration a service parses once and then caches as an image, so
|
||||
// that later requests can load() it instead of parsing the text again
|
||||
const std::string text = R"({"name": "cache", "host": "db1", "port": 6379, "replicas": ["db2", "db3"]})";
|
||||
const json_document config = json_document::parse(text);
|
||||
|
||||
// save() turns the parsed document into a byte buffer: a 64-byte header,
|
||||
// the node index, the source text, and the decoded strings
|
||||
const std::vector<std::uint8_t> image = config.save();
|
||||
std::cout << image.size() << '\n';
|
||||
|
||||
// the same document always saves to the same bytes
|
||||
std::cout << (image == json_document::parse(text).save()) << '\n';
|
||||
|
||||
// loading the image back needs no parsing, yet dumps exactly what
|
||||
// parsing the text produced
|
||||
const json_document reloaded = json_document::load(image);
|
||||
std::cout << (reloaded.root().dump() == config.root().dump()) << '\n';
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
Output:
|
||||
|
||||
```json
|
||||
316
|
||||
true
|
||||
true
|
||||
|
||||
```
|
||||
|
||||
## See also
|
||||
|
||||
- [load](load.md) - read an image written by `save()`
|
||||
- [owns_source](owns_source.md) - return whether the document holds its own copy of the text
|
||||
- [`basic_json_view::dump`](../basic_json_view/dump.md) - serialize the document to JSON text instead of an image
|
||||
- [Images](../../features/json_view.md#images) - why and when to use images
|
||||
|
||||
## Version history
|
||||
|
||||
- Added in version 3.13.0.
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,111 @@
|
||||
# nlohmann::basic_json_document::save
|
||||
|
||||
```
|
||||
std::vector<std::uint8_t> save() const;
|
||||
```
|
||||
|
||||
Writes the document as an *image*: a byte buffer that [`load`](https://json.nlohmann.me/api/basic_json_document/load/index.md) reads back without parsing. The image holds the node index, the source text (plus, for an edited document, the number tokens edits wrote), and the decoded strings (plus the strings edits wrote) -- everything [`root()`](https://json.nlohmann.me/api/basic_json_document/root/index.md) needs, with nothing left to parse.
|
||||
|
||||
An edited document is written in its *current* state, with its values in document order, the way the library's own parser would have produced them for that JSON text: a member [`set`](https://json.nlohmann.me/api/basic_json_document/set/index.md) added goes at the end, an [`erase`](https://json.nlohmann.me/api/basic_json_document/erase/index.md)d member leaves no trace, and a float that is not finite (NaN or positive/negative infinity) becomes null, the same substitution [`dump()`](https://json.nlohmann.me/api/basic_json_view/dump/index.md) makes. The same document always saves to the same bytes -- also across `BasicJsonType` and `Editable`, since the image reflects document order and values only, not which specialization produced them.
|
||||
|
||||
## Return value
|
||||
|
||||
The image, as a `std::vector<std::uint8_t>`. Pass it, or a pointer to its data together with its size, to [`load`](https://json.nlohmann.me/api/basic_json_document/load/index.md) to read the document back.
|
||||
|
||||
## Exception safety
|
||||
|
||||
Strong guarantee: `save()` does not modify `*this` (it is `const`), so if it throws, the document is left exactly as it was, and the partially built image is discarded with the exception.
|
||||
|
||||
## Exceptions
|
||||
|
||||
Throws [`type_error.320`](https://json.nlohmann.me/home/exceptions/#jsonexceptiontype_error320) if the document is [discarded](https://json.nlohmann.me/api/basic_json_document/is_discarded/index.md) -- a default-constructed document, or one a failed [`parse()`](https://json.nlohmann.me/api/basic_json_document/parse/index.md)/ [`read()`](https://json.nlohmann.me/api/basic_json_document/read/index.md) with `allow_exceptions == false` left discarded.
|
||||
|
||||
On a big-endian target, throws `type_error.320` with a different message instead: the image format is little-endian only (see [Notes](#notes)).
|
||||
|
||||
Throws [`out_of_range.416`](https://json.nlohmann.me/home/exceptions/#jsonexceptionout_of_range416) if the node count, the text, or the decoded strings of the image would individually reach 4 GiB -- the same 32-bit offsets [`parse()`](https://json.nlohmann.me/api/basic_json_document/parse/#exceptions) and, for edits, [`set`](https://json.nlohmann.me/api/basic_json_document/set/index.md)/[`push_back`](https://json.nlohmann.me/api/basic_json_document/push_back/index.md) are already limited to.
|
||||
|
||||
Example messages
|
||||
|
||||
```
|
||||
[json.exception.type_error.320] cannot save a discarded json_document
|
||||
```
|
||||
|
||||
```
|
||||
[json.exception.type_error.320] json_document images need a little-endian target
|
||||
```
|
||||
|
||||
```
|
||||
[json.exception.out_of_range.416] images of 4 GiB or more are not supported by json_document
|
||||
```
|
||||
|
||||
## Complexity
|
||||
|
||||
Linear in the size of the document: the number of nodes, plus the length of the text and the decoded strings that end up in the image.
|
||||
|
||||
## Notes
|
||||
|
||||
**Format.** The image begins with a 64-byte header (the magic bytes `"NJVI"`, a version number, the node count, and the sizes of the text and the decoded strings, all little-endian), followed by the nodes ([16 bytes each](https://json.nlohmann.me/home/architecture/#node-index-of-json-views)), the text and a `'\0'`, and the decoded strings and a `'\0'`. [`load`](https://json.nlohmann.me/api/basic_json_document/load/index.md) checks the header, and the sizes it describes, before reading anything else -- see [`load`'s Exceptions](https://json.nlohmann.me/api/basic_json_document/load/#exceptions).
|
||||
|
||||
Experimental
|
||||
|
||||
The image format is versioned but not yet stable: it may change in an incompatible way before it is declared stable. Use images to cache a document within one build of the library, or to hand one to another process running the *same* build on the *same* (little-endian) machine -- not as a long-term storage format. Keep the original JSON text if you need to read a saved document back with a future library version.
|
||||
|
||||
**Little-endian only.** The image is written as raw little-endian bytes, with no byte-swapping. `save()` (and [`load`](https://json.nlohmann.me/api/basic_json_document/load/index.md)) throw `type_error.320` on a big-endian target rather than silently produce bytes a big-endian reader could not interpret correctly.
|
||||
|
||||
## Examples
|
||||
|
||||
Caching a parsed document as an image
|
||||
|
||||
The example below saves a parsed configuration as an image -- the way a service might cache one to answer later requests without parsing the text again -- and confirms that loading it back gives exactly the same result as parsing did, and that saving is deterministic.
|
||||
|
||||
```
|
||||
#include <cstdint>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <nlohmann/json_view.hpp>
|
||||
|
||||
using json_document = nlohmann::json_document;
|
||||
|
||||
int main()
|
||||
{
|
||||
std::cout << std::boolalpha;
|
||||
|
||||
// a configuration a service parses once and then caches as an image, so
|
||||
// that later requests can load() it instead of parsing the text again
|
||||
const std::string text = R"({"name": "cache", "host": "db1", "port": 6379, "replicas": ["db2", "db3"]})";
|
||||
const json_document config = json_document::parse(text);
|
||||
|
||||
// save() turns the parsed document into a byte buffer: a 64-byte header,
|
||||
// the node index, the source text, and the decoded strings
|
||||
const std::vector<std::uint8_t> image = config.save();
|
||||
std::cout << image.size() << '\n';
|
||||
|
||||
// the same document always saves to the same bytes
|
||||
std::cout << (image == json_document::parse(text).save()) << '\n';
|
||||
|
||||
// loading the image back needs no parsing, yet dumps exactly what
|
||||
// parsing the text produced
|
||||
const json_document reloaded = json_document::load(image);
|
||||
std::cout << (reloaded.root().dump() == config.root().dump()) << '\n';
|
||||
}
|
||||
```
|
||||
|
||||
Output:
|
||||
|
||||
```
|
||||
316
|
||||
true
|
||||
true
|
||||
```
|
||||
|
||||
## See also
|
||||
|
||||
- [load](https://json.nlohmann.me/api/basic_json_document/load/index.md) - read an image written by `save()`
|
||||
- [owns_source](https://json.nlohmann.me/api/basic_json_document/owns_source/index.md) - return whether the document holds its own copy of the text
|
||||
- [`basic_json_view::dump`](https://json.nlohmann.me/api/basic_json_view/dump/index.md) - serialize the document to JSON text instead of an image
|
||||
- [Images](https://json.nlohmann.me/features/json_view/#images) - why and when to use images
|
||||
|
||||
## Version history
|
||||
|
||||
- Added in version 3.13.0 unreleased.
|
||||
@@ -0,0 +1,269 @@
|
||||
# <small>nlohmann::basic_json_document::</small>set
|
||||
|
||||
```cpp
|
||||
// (1)
|
||||
template<typename V>
|
||||
view_type set(view_type target, V&& value);
|
||||
|
||||
// (2)
|
||||
template<typename V>
|
||||
view_type set(view_type object, string_view_t key, V&& value);
|
||||
|
||||
// (3)
|
||||
template<typename I, typename V>
|
||||
view_type set(view_type array, I idx, V&& value);
|
||||
|
||||
// (4)
|
||||
template<typename V>
|
||||
view_type set(const json_pointer& ptr, V&& value);
|
||||
```
|
||||
|
||||
Only an **editable** document (`#!cpp Editable == true`, e.g. [`json_editable_document`](../json_editable_document.md))
|
||||
has `set`; calling it on a read-only `basic_json_document` fails to compile (`#!cpp static_assert`).
|
||||
|
||||
1. Replaces the value `target` refers to with `value`.
|
||||
2. Sets the member `key` of the object `object` to `value`: assigns it if `object` already has a member with this
|
||||
key -- the first one, should the key occur more than once, and the later duplicates are then dropped (see the
|
||||
[Notes](#notes) below) -- or appends a new member at the end otherwise. A [null](../basic_json_view/is_null.md)
|
||||
`object` first becomes an empty object.
|
||||
3. Assigns `value` to the element at index `idx` of the array `array`, which must already exist (`#!cpp idx <
|
||||
array.size()`).
|
||||
4. Sets the value the JSON pointer `ptr` refers to, relative to [`root()`](root.md), to `value`. The *parent* of the
|
||||
target must already exist: an object member is set as in 2. (added if it does not exist yet), an array element is
|
||||
assigned as in 3., and a last reference token of `#!cpp "-"`, or equal to the size of the array, appends `value`
|
||||
instead, exactly as [`push_back`](push_back.md) would. A [null](../basic_json_view/is_null.md) parent becomes what
|
||||
[`basic_json::operator[]`](../basic_json/operator%5B%5D.md) with a JSON pointer makes of it: an array if the last
|
||||
reference token is `#!cpp "-"` or consists of digits only (for an index beyond 0, the array is first filled with
|
||||
null values up to that index), an object otherwise. An empty `ptr` sets [`root()`](root.md) itself, as in 1.
|
||||
|
||||
In every overload, `value` is accepted three ways: a [`basic_json_view`](../basic_json_view/index.md) of *any*
|
||||
document -- read-only or editable, and it does not have to be `target`'s/`object`'s/`array`'s own document -- which
|
||||
is copied so that nothing is shared with the source document afterward; a `BasicJsonType` value; or anything
|
||||
`BasicJsonType` can be constructed from (numbers, strings, `#!cpp bool`, `#!cpp nullptr`, containers, ...).
|
||||
|
||||
## Template parameters
|
||||
|
||||
`V`
|
||||
: the type of `value`, deduced; see above for what is accepted.
|
||||
|
||||
`I`
|
||||
: an integral type other than `#!cpp bool`, deduced (overloads taking a `#!cpp bool` or a non-integral type for
|
||||
`idx` do not participate in overload resolution).
|
||||
|
||||
## Parameters
|
||||
|
||||
`target` (in)
|
||||
: the value to replace
|
||||
|
||||
`object` (in)
|
||||
: the object (or null value) whose member to set
|
||||
|
||||
`array` (in)
|
||||
: the array whose element to assign
|
||||
|
||||
`key` (in)
|
||||
: the key of the member to set
|
||||
|
||||
`idx` (in)
|
||||
: the index of the element to assign; a negative value throws (see [Exceptions](#exceptions))
|
||||
|
||||
`ptr` (in)
|
||||
: a JSON pointer to the value to set, relative to `root()`
|
||||
|
||||
`value` (in)
|
||||
: the new value
|
||||
|
||||
## Return value
|
||||
|
||||
1. a view of `target`, now holding `value`
|
||||
2. a view of the member `key` of `object`, now holding `value`
|
||||
3. a view of the element `idx` of `array`, now holding `value`
|
||||
4. a view of the value `ptr` refers to, now holding `value`
|
||||
|
||||
## Exception safety
|
||||
|
||||
Basic exception safety: `value` is fully encoded -- including the checks below -- into storage owned by the document
|
||||
before anything already reachable from [`root()`](root.md) is touched, so a failure while encoding `value` (an
|
||||
invalid argument, or `#!cpp std::bad_alloc`) leaves the document completely unchanged, other than memory allocated
|
||||
for the encoding that is not reclaimed. A failure of a later allocation -- while an edited array or object switches
|
||||
from its parsed layout to a growable block, see [Notes](#notes) -- can still leave a partial effect, such as a
|
||||
[null](../basic_json_view/is_null.md) `object`/`array` argument already turned into an empty object/array even
|
||||
though `value` itself was not linked in. Likewise, a failure of `value` in 4. leaves a null parent that is set with an
|
||||
index beyond 0 already filled with the null values before the index.
|
||||
|
||||
## Exceptions
|
||||
|
||||
1. Throws [`type_error.302`](../../home/exceptions.md#jsonexceptiontype_error302) if `value` is a
|
||||
[discarded](../basic_json_view/is_discarded.md) view, or a [discarded](../basic_json/is_discarded.md)
|
||||
`BasicJsonType` value (e.g. `#!cpp BasicJsonType(value_t::discarded)`) -- an object or array `value`, of either
|
||||
kind, is fine and is encoded as a whole subtree.
|
||||
2. Throws [`type_error.305`](../../home/exceptions.md#jsonexceptiontype_error305) if `object` is neither an object
|
||||
nor null -- the same message [`operator[]`](../basic_json_view/operator%5B%5D.md) throws for a string argument on
|
||||
such a value. Throws [`type_error.316`](../../home/exceptions.md#jsonexceptiontype_error316) if `key` is not
|
||||
valid UTF-8, with the same message [`BasicJsonType::dump()`](../basic_json/dump.md) gives for that string.
|
||||
Also throws what 1. throws for `value`.
|
||||
3. Throws `type_error.305` if `array` is not an array -- the same message `operator[]` throws for a numeric argument
|
||||
on such a value. Throws [`out_of_range.401`](../../home/exceptions.md#jsonexceptionout_of_range401) if `idx` is
|
||||
negative, or if `#!cpp idx >= array.size()`. Also throws what 1. throws for `value`.
|
||||
4. Throws what [`at`](../basic_json_view/at.md) throws (overload 3) for resolving `ptr`'s parent, except that a
|
||||
missing object member or an array index equal to the array's size at the very last reference token is not an
|
||||
error there (it becomes a new member or an appended element) instead of
|
||||
[`out_of_range.403`](../../home/exceptions.md#jsonexceptionout_of_range403)/[`out_of_range.402`](../../home/exceptions.md#jsonexceptionout_of_range402).
|
||||
For the last reference token itself: if the parent is an object (or a primitive value, where it throws
|
||||
`type_error.305`), throws what 2. throws; if the parent is an array, throws what 3. throws for an index that is
|
||||
out of range, or, for a token that is not a valid array index,
|
||||
[`parse_error.106`](../../home/exceptions.md#jsonexceptionparse_error106) (a leading `#!cpp '0'`),
|
||||
[`parse_error.109`](../../home/exceptions.md#jsonexceptionparse_error109) (not a number),
|
||||
[`out_of_range.410`](../../home/exceptions.md#jsonexceptionout_of_range410) (too large for `size_type`), or
|
||||
[`out_of_range.404`](../../home/exceptions.md#jsonexceptionout_of_range404) (an empty token); the same errors are
|
||||
thrown for a null parent and a token of digits (the parent is not changed then), and
|
||||
[`out_of_range.401`](../../home/exceptions.md#jsonexceptionout_of_range401) if the index is 4294967295 or more.
|
||||
Also throws what 1. throws for `value`.
|
||||
|
||||
Every overload also throws [`type_error.319`](../../home/exceptions.md#jsonexceptiontype_error319) if `value` is (or
|
||||
contains) a binary value -- `BasicJsonType` can hold one, but a `json_document` cannot -- and
|
||||
[`invalid_iterator.202`](../../home/exceptions.md#jsonexceptioninvalid_iterator202) ("view does not belong to this
|
||||
document") if `target`/`object`/`array` is a [discarded](../basic_json_view/is_discarded.md) view or a view of a
|
||||
*different* document (overloads 1-3 only; overload 4 always starts from this document's own [`root()`](root.md)).
|
||||
|
||||
## Complexity
|
||||
|
||||
1. Linear in the size of `value` (encoding it into the document's storage): constant for a scalar, linear in the
|
||||
number of nested values for an array or object. If `target` is itself an array or object that spans more than one
|
||||
node in its parent's original, unedited layout, and `value` is a scalar, replacing it additionally costs time
|
||||
linear in the size of the document, the *first* time (the parent of `target` is looked up from
|
||||
[`root()`](root.md), and then switches to links) -- see [Notes](#notes). Once the parent has links, `target` is
|
||||
replaced in constant time: setting every element of a large array one after the other is linear overall. To avoid
|
||||
the lookup altogether, use 3. (or 2. for an object), which know the parent.
|
||||
2. Linear in the number of members of `object`, to find an existing member with `key`, plus the complexity of 1. for
|
||||
`value`.
|
||||
3. Constant, plus the complexity of 1. for `value`.
|
||||
4. Linear in the number of reference tokens of `ptr` and, for each token, in the number of members of the object at
|
||||
that level or the index into the array (as [`at`](../basic_json_view/at.md)), plus the complexity of 2. or 3. for
|
||||
the last token; for a null parent and an index, linear in the index.
|
||||
|
||||
## Notes
|
||||
|
||||
!!! info "Duplicate keys"
|
||||
|
||||
If `object` already has more than one member with `key` (2.), the *first* one is assigned `value` and every
|
||||
later member with the same key is removed -- so that a lookup, an iteration, and
|
||||
[`materialize()`](../basic_json_view/materialize.md) of `object` afterward all agree on a single value for
|
||||
`key`, the same way [`operator[]`](../basic_json_view/operator%5B%5D.md) already picks the first occurrence of a
|
||||
duplicate key for reading. See the [Notes on duplicate keys](../basic_json_view/operator%5B%5D.md#notes) of
|
||||
`operator[]`.
|
||||
|
||||
Setting a member (2.) or an element (3., through 4.) of an array or object whose elements have not been edited
|
||||
before switches it from its parsed layout to a growable block holding links to its elements; a later
|
||||
[`push_back`](push_back.md) or `set` on the same container reuses that block, growing it (amortized constant time)
|
||||
only once it runs out of room. This never moves an element itself -- only where the container's *links* to its
|
||||
elements live -- so a view of an element stays valid, but any iterator already taken over the container is
|
||||
invalidated, since it was walking the old layout. See [Edits](index.md#edits) for what stays valid across an edit in
|
||||
general.
|
||||
|
||||
The same switch happens, for the same reason, when overload 1. replaces a multi-node array/object value with a
|
||||
scalar: the *parent's* element sequence is what has to switch to links, not `target` itself, because the parent
|
||||
originally stepped over `target`'s whole subtree by its node count, which no longer applies once `target` is a
|
||||
one-node scalar.
|
||||
|
||||
## Examples
|
||||
|
||||
??? example "Example: (1)/(2)/(3)/(4) replace a value, set a member, assign an element, set via a JSON pointer"
|
||||
|
||||
The example below edits a small configuration document -- replacing a value, adding an object member, assigning
|
||||
an array element, and reaching a field through a JSON pointer -- and shows what
|
||||
[`dump()`](../basic_json_view/dump.md) preserves that is lost once the same edits are made on a `BasicJsonType`
|
||||
value instead: the order object members were written in, and the exact spelling of a number that was never
|
||||
touched.
|
||||
|
||||
```cpp
|
||||
#include <iostream>
|
||||
#include <nlohmann/json_view.hpp>
|
||||
|
||||
using json = nlohmann::json;
|
||||
using json_editable_document = nlohmann::json_editable_document;
|
||||
using json_editable_view = nlohmann::json_editable_view;
|
||||
|
||||
int main()
|
||||
{
|
||||
// a configuration file, as it might be read from disk -- "price" is
|
||||
// written with a trailing zero that has no effect on its value
|
||||
const std::string text = R"({
|
||||
"name": "cache",
|
||||
"host": "db1",
|
||||
"port": 6379,
|
||||
"price": 19.90,
|
||||
"replicas": ["db2", "db3"],
|
||||
"timeout": 30
|
||||
})";
|
||||
|
||||
json_editable_document doc = json_editable_document::parse(text);
|
||||
|
||||
doc.set(doc.root()["port"], 6380); // (1) replace a value
|
||||
doc.set(doc.root(), "region", "us-east"); // (2) add a member
|
||||
doc.set(doc.root()["replicas"], 0, "db4"); // (3) assign an element
|
||||
doc.set(json::json_pointer("/timeout"), 45); // (4) via a JSON pointer
|
||||
|
||||
// members stay in document order (the new one at the end), and a number
|
||||
// that was not itself edited keeps its exact spelling
|
||||
std::cout << doc.root().dump(2, ' ', false, json_editable_view::number_format::source) << "\n\n";
|
||||
|
||||
// the same edits on a plain json value: object_t is a std::map, so
|
||||
// parsing already sorted the keys, and dump() rewrites every number to
|
||||
// its shortest form, even "price", which was never touched
|
||||
json plain = json::parse(text);
|
||||
plain["port"] = 6380;
|
||||
plain["region"] = "us-east";
|
||||
plain["replicas"][0] = "db4";
|
||||
plain[json::json_pointer("/timeout")] = 45;
|
||||
std::cout << plain.dump(2) << '\n';
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
Output:
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "cache",
|
||||
"host": "db1",
|
||||
"port": 6380,
|
||||
"price": 19.90,
|
||||
"replicas": [
|
||||
"db4",
|
||||
"db3"
|
||||
],
|
||||
"timeout": 45,
|
||||
"region": "us-east"
|
||||
}
|
||||
|
||||
{
|
||||
"host": "db1",
|
||||
"name": "cache",
|
||||
"port": 6380,
|
||||
"price": 19.9,
|
||||
"region": "us-east",
|
||||
"replicas": [
|
||||
"db4",
|
||||
"db3"
|
||||
],
|
||||
"timeout": 45
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
## See also
|
||||
|
||||
- [push_back](push_back.md) - append to an array
|
||||
- [insert](insert.md) - insert an element into an array
|
||||
- [erase](erase.md) - remove an object member, an array element, or the value a JSON pointer refers to
|
||||
- [root](root.md) - the view of the root value, the starting point of overload 4
|
||||
- [`basic_json_view::dump`](../basic_json_view/dump.md) - serialize the document, keeping an untouched number's
|
||||
spelling with `#!cpp number_format::source`
|
||||
- [Edits](index.md#edits) - what an edit guarantees, for every overload
|
||||
- [Editing a document](../../features/json_view.md#editing-a-document) - why editable documents keep the source
|
||||
text's order and number spelling
|
||||
|
||||
## Version history
|
||||
|
||||
- Added in version 3.13.0.
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,181 @@
|
||||
# nlohmann::basic_json_document::set
|
||||
|
||||
```
|
||||
// (1)
|
||||
template<typename V>
|
||||
view_type set(view_type target, V&& value);
|
||||
|
||||
// (2)
|
||||
template<typename V>
|
||||
view_type set(view_type object, string_view_t key, V&& value);
|
||||
|
||||
// (3)
|
||||
template<typename I, typename V>
|
||||
view_type set(view_type array, I idx, V&& value);
|
||||
|
||||
// (4)
|
||||
template<typename V>
|
||||
view_type set(const json_pointer& ptr, V&& value);
|
||||
```
|
||||
|
||||
Only an **editable** document (`Editable == true`, e.g. [`json_editable_document`](https://json.nlohmann.me/api/json_editable_document/index.md)) has `set`; calling it on a read-only `basic_json_document` fails to compile (`static_assert`).
|
||||
|
||||
1. Replaces the value `target` refers to with `value`.
|
||||
1. Sets the member `key` of the object `object` to `value`: assigns it if `object` already has a member with this key -- the first one, should the key occur more than once, and the later duplicates are then dropped (see the [Notes](#notes) below) -- or appends a new member at the end otherwise. A [null](https://json.nlohmann.me/api/basic_json_view/is_null/index.md) `object` first becomes an empty object.
|
||||
1. Assigns `value` to the element at index `idx` of the array `array`, which must already exist (`idx < array.size()`).
|
||||
1. Sets the value the JSON pointer `ptr` refers to, relative to [`root()`](https://json.nlohmann.me/api/basic_json_document/root/index.md), to `value`. The *parent* of the target must already exist: an object member is set as in 2. (added if it does not exist yet), an array element is assigned as in 3., and a last reference token of `"-"`, or equal to the size of the array, appends `value` instead, exactly as [`push_back`](https://json.nlohmann.me/api/basic_json_document/push_back/index.md) would. A [null](https://json.nlohmann.me/api/basic_json_view/is_null/index.md) parent becomes what [`basic_json::operator[]`](https://json.nlohmann.me/api/basic_json/operator%5B%5D/index.md) with a JSON pointer makes of it: an array if the last reference token is `"-"` or consists of digits only (for an index beyond 0, the array is first filled with null values up to that index), an object otherwise. An empty `ptr` sets [`root()`](https://json.nlohmann.me/api/basic_json_document/root/index.md) itself, as in 1.
|
||||
|
||||
In every overload, `value` is accepted three ways: a [`basic_json_view`](https://json.nlohmann.me/api/basic_json_view/index.md) of *any* document -- read-only or editable, and it does not have to be `target`'s/`object`'s/`array`'s own document -- which is copied so that nothing is shared with the source document afterward; a `BasicJsonType` value; or anything `BasicJsonType` can be constructed from (numbers, strings, `bool`, `nullptr`, containers, ...).
|
||||
|
||||
## Template parameters
|
||||
|
||||
`V` : the type of `value`, deduced; see above for what is accepted.
|
||||
|
||||
`I` : an integral type other than `bool`, deduced (overloads taking a `bool` or a non-integral type for `idx` do not participate in overload resolution).
|
||||
|
||||
## Parameters
|
||||
|
||||
`target` (in) : the value to replace
|
||||
|
||||
`object` (in) : the object (or null value) whose member to set
|
||||
|
||||
`array` (in) : the array whose element to assign
|
||||
|
||||
`key` (in) : the key of the member to set
|
||||
|
||||
`idx` (in) : the index of the element to assign; a negative value throws (see [Exceptions](#exceptions))
|
||||
|
||||
`ptr` (in) : a JSON pointer to the value to set, relative to `root()`
|
||||
|
||||
`value` (in) : the new value
|
||||
|
||||
## Return value
|
||||
|
||||
1. a view of `target`, now holding `value`
|
||||
1. a view of the member `key` of `object`, now holding `value`
|
||||
1. a view of the element `idx` of `array`, now holding `value`
|
||||
1. a view of the value `ptr` refers to, now holding `value`
|
||||
|
||||
## Exception safety
|
||||
|
||||
Basic exception safety: `value` is fully encoded -- including the checks below -- into storage owned by the document before anything already reachable from [`root()`](https://json.nlohmann.me/api/basic_json_document/root/index.md) is touched, so a failure while encoding `value` (an invalid argument, or `std::bad_alloc`) leaves the document completely unchanged, other than memory allocated for the encoding that is not reclaimed. A failure of a later allocation -- while an edited array or object switches from its parsed layout to a growable block, see [Notes](#notes) -- can still leave a partial effect, such as a [null](https://json.nlohmann.me/api/basic_json_view/is_null/index.md) `object`/`array` argument already turned into an empty object/array even though `value` itself was not linked in. Likewise, a failure of `value` in 4. leaves a null parent that is set with an index beyond 0 already filled with the null values before the index.
|
||||
|
||||
## Exceptions
|
||||
|
||||
1. Throws [`type_error.302`](https://json.nlohmann.me/home/exceptions/#jsonexceptiontype_error302) if `value` is a [discarded](https://json.nlohmann.me/api/basic_json_view/is_discarded/index.md) view, or a [discarded](https://json.nlohmann.me/api/basic_json/is_discarded/index.md) `BasicJsonType` value (e.g. `BasicJsonType(value_t::discarded)`) -- an object or array `value`, of either kind, is fine and is encoded as a whole subtree.
|
||||
1. Throws [`type_error.305`](https://json.nlohmann.me/home/exceptions/#jsonexceptiontype_error305) if `object` is neither an object nor null -- the same message [`operator[]`](https://json.nlohmann.me/api/basic_json_view/operator%5B%5D/index.md) throws for a string argument on such a value. Throws [`type_error.316`](https://json.nlohmann.me/home/exceptions/#jsonexceptiontype_error316) if `key` is not valid UTF-8, with the same message [`BasicJsonType::dump()`](https://json.nlohmann.me/api/basic_json/dump/index.md) gives for that string. Also throws what 1. throws for `value`.
|
||||
1. Throws `type_error.305` if `array` is not an array -- the same message `operator[]` throws for a numeric argument on such a value. Throws [`out_of_range.401`](https://json.nlohmann.me/home/exceptions/#jsonexceptionout_of_range401) if `idx` is negative, or if `idx >= array.size()`. Also throws what 1. throws for `value`.
|
||||
1. Throws what [`at`](https://json.nlohmann.me/api/basic_json_view/at/index.md) throws (overload 3) for resolving `ptr`'s parent, except that a missing object member or an array index equal to the array's size at the very last reference token is not an error there (it becomes a new member or an appended element) instead of [`out_of_range.403`](https://json.nlohmann.me/home/exceptions/#jsonexceptionout_of_range403)/[`out_of_range.402`](https://json.nlohmann.me/home/exceptions/#jsonexceptionout_of_range402). For the last reference token itself: if the parent is an object (or a primitive value, where it throws `type_error.305`), throws what 2. throws; if the parent is an array, throws what 3. throws for an index that is out of range, or, for a token that is not a valid array index, [`parse_error.106`](https://json.nlohmann.me/home/exceptions/#jsonexceptionparse_error106) (a leading `'0'`), [`parse_error.109`](https://json.nlohmann.me/home/exceptions/#jsonexceptionparse_error109) (not a number), [`out_of_range.410`](https://json.nlohmann.me/home/exceptions/#jsonexceptionout_of_range410) (too large for `size_type`), or [`out_of_range.404`](https://json.nlohmann.me/home/exceptions/#jsonexceptionout_of_range404) (an empty token); the same errors are thrown for a null parent and a token of digits (the parent is not changed then), and [`out_of_range.401`](https://json.nlohmann.me/home/exceptions/#jsonexceptionout_of_range401) if the index is 4294967295 or more. Also throws what 1. throws for `value`.
|
||||
|
||||
Every overload also throws [`type_error.319`](https://json.nlohmann.me/home/exceptions/#jsonexceptiontype_error319) if `value` is (or contains) a binary value -- `BasicJsonType` can hold one, but a `json_document` cannot -- and [`invalid_iterator.202`](https://json.nlohmann.me/home/exceptions/#jsonexceptioninvalid_iterator202) ("view does not belong to this document") if `target`/`object`/`array` is a [discarded](https://json.nlohmann.me/api/basic_json_view/is_discarded/index.md) view or a view of a *different* document (overloads 1-3 only; overload 4 always starts from this document's own [`root()`](https://json.nlohmann.me/api/basic_json_document/root/index.md)).
|
||||
|
||||
## Complexity
|
||||
|
||||
1. Linear in the size of `value` (encoding it into the document's storage): constant for a scalar, linear in the number of nested values for an array or object. If `target` is itself an array or object that spans more than one node in its parent's original, unedited layout, and `value` is a scalar, replacing it additionally costs time linear in the size of the document, the *first* time (the parent of `target` is looked up from [`root()`](https://json.nlohmann.me/api/basic_json_document/root/index.md), and then switches to links) -- see [Notes](#notes). Once the parent has links, `target` is replaced in constant time: setting every element of a large array one after the other is linear overall. To avoid the lookup altogether, use 3. (or 2. for an object), which know the parent.
|
||||
1. Linear in the number of members of `object`, to find an existing member with `key`, plus the complexity of 1. for `value`.
|
||||
1. Constant, plus the complexity of 1. for `value`.
|
||||
1. Linear in the number of reference tokens of `ptr` and, for each token, in the number of members of the object at that level or the index into the array (as [`at`](https://json.nlohmann.me/api/basic_json_view/at/index.md)), plus the complexity of 2. or 3. for the last token; for a null parent and an index, linear in the index.
|
||||
|
||||
## Notes
|
||||
|
||||
Duplicate keys
|
||||
|
||||
If `object` already has more than one member with `key` (2.), the *first* one is assigned `value` and every later member with the same key is removed -- so that a lookup, an iteration, and [`materialize()`](https://json.nlohmann.me/api/basic_json_view/materialize/index.md) of `object` afterward all agree on a single value for `key`, the same way [`operator[]`](https://json.nlohmann.me/api/basic_json_view/operator%5B%5D/index.md) already picks the first occurrence of a duplicate key for reading. See the [Notes on duplicate keys](https://json.nlohmann.me/api/basic_json_view/operator%5B%5D/#notes) of `operator[]`.
|
||||
|
||||
Setting a member (2.) or an element (3., through 4.) of an array or object whose elements have not been edited before switches it from its parsed layout to a growable block holding links to its elements; a later [`push_back`](https://json.nlohmann.me/api/basic_json_document/push_back/index.md) or `set` on the same container reuses that block, growing it (amortized constant time) only once it runs out of room. This never moves an element itself -- only where the container's *links* to its elements live -- so a view of an element stays valid, but any iterator already taken over the container is invalidated, since it was walking the old layout. See [Edits](https://json.nlohmann.me/api/basic_json_document/#edits) for what stays valid across an edit in general.
|
||||
|
||||
The same switch happens, for the same reason, when overload 1. replaces a multi-node array/object value with a scalar: the *parent's* element sequence is what has to switch to links, not `target` itself, because the parent originally stepped over `target`'s whole subtree by its node count, which no longer applies once `target` is a one-node scalar.
|
||||
|
||||
## Examples
|
||||
|
||||
Example: (1)/(2)/(3)/(4) replace a value, set a member, assign an element, set via a JSON pointer
|
||||
|
||||
The example below edits a small configuration document -- replacing a value, adding an object member, assigning an array element, and reaching a field through a JSON pointer -- and shows what [`dump()`](https://json.nlohmann.me/api/basic_json_view/dump/index.md) preserves that is lost once the same edits are made on a `BasicJsonType` value instead: the order object members were written in, and the exact spelling of a number that was never touched.
|
||||
|
||||
```
|
||||
#include <iostream>
|
||||
#include <nlohmann/json_view.hpp>
|
||||
|
||||
using json = nlohmann::json;
|
||||
using json_editable_document = nlohmann::json_editable_document;
|
||||
using json_editable_view = nlohmann::json_editable_view;
|
||||
|
||||
int main()
|
||||
{
|
||||
// a configuration file, as it might be read from disk -- "price" is
|
||||
// written with a trailing zero that has no effect on its value
|
||||
const std::string text = R"({
|
||||
"name": "cache",
|
||||
"host": "db1",
|
||||
"port": 6379,
|
||||
"price": 19.90,
|
||||
"replicas": ["db2", "db3"],
|
||||
"timeout": 30
|
||||
})";
|
||||
|
||||
json_editable_document doc = json_editable_document::parse(text);
|
||||
|
||||
doc.set(doc.root()["port"], 6380); // (1) replace a value
|
||||
doc.set(doc.root(), "region", "us-east"); // (2) add a member
|
||||
doc.set(doc.root()["replicas"], 0, "db4"); // (3) assign an element
|
||||
doc.set(json::json_pointer("/timeout"), 45); // (4) via a JSON pointer
|
||||
|
||||
// members stay in document order (the new one at the end), and a number
|
||||
// that was not itself edited keeps its exact spelling
|
||||
std::cout << doc.root().dump(2, ' ', false, json_editable_view::number_format::source) << "\n\n";
|
||||
|
||||
// the same edits on a plain json value: object_t is a std::map, so
|
||||
// parsing already sorted the keys, and dump() rewrites every number to
|
||||
// its shortest form, even "price", which was never touched
|
||||
json plain = json::parse(text);
|
||||
plain["port"] = 6380;
|
||||
plain["region"] = "us-east";
|
||||
plain["replicas"][0] = "db4";
|
||||
plain[json::json_pointer("/timeout")] = 45;
|
||||
std::cout << plain.dump(2) << '\n';
|
||||
}
|
||||
```
|
||||
|
||||
Output:
|
||||
|
||||
```
|
||||
{
|
||||
"name": "cache",
|
||||
"host": "db1",
|
||||
"port": 6380,
|
||||
"price": 19.90,
|
||||
"replicas": [
|
||||
"db4",
|
||||
"db3"
|
||||
],
|
||||
"timeout": 45,
|
||||
"region": "us-east"
|
||||
}
|
||||
|
||||
{
|
||||
"host": "db1",
|
||||
"name": "cache",
|
||||
"port": 6380,
|
||||
"price": 19.9,
|
||||
"region": "us-east",
|
||||
"replicas": [
|
||||
"db4",
|
||||
"db3"
|
||||
],
|
||||
"timeout": 45
|
||||
}
|
||||
```
|
||||
|
||||
## See also
|
||||
|
||||
- [push_back](https://json.nlohmann.me/api/basic_json_document/push_back/index.md) - append to an array
|
||||
- [insert](https://json.nlohmann.me/api/basic_json_document/insert/index.md) - insert an element into an array
|
||||
- [erase](https://json.nlohmann.me/api/basic_json_document/erase/index.md) - remove an object member, an array element, or the value a JSON pointer refers to
|
||||
- [root](https://json.nlohmann.me/api/basic_json_document/root/index.md) - the view of the root value, the starting point of overload 4
|
||||
- [`basic_json_view::dump`](https://json.nlohmann.me/api/basic_json_view/dump/index.md) - serialize the document, keeping an untouched number's spelling with `number_format::source`
|
||||
- [Edits](https://json.nlohmann.me/api/basic_json_document/#edits) - what an edit guarantees, for every overload
|
||||
- [Editing a document](https://json.nlohmann.me/features/json_view/#editing-a-document) - why editable documents keep the source text's order and number spelling
|
||||
|
||||
## Version history
|
||||
|
||||
- Added in version 3.13.0 unreleased.
|
||||
@@ -0,0 +1,105 @@
|
||||
# <small>nlohmann::basic_json_document::</small>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
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <nlohmann/json_view.hpp>
|
||||
|
||||
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';
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
Output:
|
||||
|
||||
```json
|
||||
true
|
||||
true
|
||||
true 1
|
||||
|
||||
```
|
||||
|
||||
## 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.
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,96 @@
|
||||
# nlohmann::basic_json_document::shrink_to_fit
|
||||
|
||||
```
|
||||
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()`](https://json.nlohmann.me/api/basic_json_document/read/index.md) replaced a large document with a much smaller one. Like `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 `std::bad_alloc` if the reallocation fails; on exception, the document is unchanged.
|
||||
|
||||
## Complexity
|
||||
|
||||
Linear in [`node_count()`](https://json.nlohmann.me/api/basic_json_document/node_count/index.md) plus the length of the decoded strings.
|
||||
|
||||
## Notes
|
||||
|
||||
Invalidates views
|
||||
|
||||
Unlike moving the document, `shrink_to_fit()` **invalidates every view taken from this document before the call**, including a previously obtained [`root()`](https://json.nlohmann.me/api/basic_json_document/root/index.md): the node index is moved into a new, smaller allocation, and the old one is freed. Take a fresh view from [`root()`](https://json.nlohmann.me/api/basic_json_document/root/index.md) after calling this function.
|
||||
|
||||
This is unlike `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
|
||||
|
||||
```
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <nlohmann/json_view.hpp>
|
||||
|
||||
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';
|
||||
}
|
||||
```
|
||||
|
||||
Output:
|
||||
|
||||
```
|
||||
true
|
||||
true
|
||||
true 1
|
||||
```
|
||||
|
||||
## See also
|
||||
|
||||
- [node_count](https://json.nlohmann.me/api/basic_json_document/node_count/index.md) - the number of index entries
|
||||
- [memory_usage](https://json.nlohmann.me/api/basic_json_document/memory_usage/index.md) - the number of bytes held by the document
|
||||
- [root](https://json.nlohmann.me/api/basic_json_document/root/index.md) - the view of the root value
|
||||
|
||||
## Version history
|
||||
|
||||
- Added in version 3.13.0 unreleased.
|
||||
@@ -0,0 +1,71 @@
|
||||
# <small>nlohmann::basic_json_document::</small>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
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <nlohmann/json_view.hpp>
|
||||
|
||||
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';
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
Output:
|
||||
|
||||
```json
|
||||
true
|
||||
{"a": 1}
|
||||
true
|
||||
|
||||
```
|
||||
|
||||
## 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.
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,67 @@
|
||||
# nlohmann::basic_json_document::source
|
||||
|
||||
```
|
||||
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 `string_view_t` (`std::string_view` on C++17 and newer) over the parsed text, or an empty one if the document is [discarded](https://json.nlohmann.me/api/basic_json_document/is_discarded/index.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`](https://json.nlohmann.me/api/basic_json_document/owns_source/index.md).
|
||||
|
||||
## Examples
|
||||
|
||||
Example
|
||||
|
||||
```
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <nlohmann/json_view.hpp>
|
||||
|
||||
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';
|
||||
}
|
||||
```
|
||||
|
||||
Output:
|
||||
|
||||
```
|
||||
true
|
||||
{"a": 1}
|
||||
true
|
||||
```
|
||||
|
||||
## See also
|
||||
|
||||
- [owns_source](https://json.nlohmann.me/api/basic_json_document/owns_source/index.md) - return whether the document holds its own copy of the text
|
||||
- [source_offset](https://json.nlohmann.me/api/basic_json_view/source_offset/index.md) - byte offset of a value in the source text
|
||||
|
||||
## Version history
|
||||
|
||||
- Added in version 3.13.0 unreleased.
|
||||
Reference in New Issue
Block a user