| # 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 (`view_mode::editable`, 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 nlohmann::json; | |
| using nlohmann::json_editable_document; | |
| using 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. |