deploy: 4155e2938f
This commit is contained in:
1 parent
be4d0a6f4b
commit
90f0c9d411
714 files changed
+22067
-622
No files matched your search
@@ -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.
|
||||
Reference in new issue
Block a user