- fig-jsonview.js/.css: point the header comments at the new pages - reading.md: views' strings are valid as long as the document (and a borrowed source text), as lifetime.md says - reading.md, generic_code.md: link to differences.md instead of restating the member-order and repeated-key rules - differences.md: drop the third mention of ordering comparisons, name rbegin()/rend() in the iterator row - exceptions.md: link editable documents to editing.md Signed-off-by: Niels Lohmann <mail@nlohmann.me>
4.9 KiB
Reading values
Getting values out without copying
get<T>() converts most T directly from the flat index, without ever building a
basic_json value for the conversion: #!cpp bool, arithmetic types, #!cpp std::nullptr_t,
#!cpp std::string/other #!cpp std::basic_strings (copied once), basic_json_view itself, the standard containers
and other types the library converts (#!cpp std::vector, #!cpp std::map, #!cpp std::list, #!cpp std::array,
#!cpp std::pair, #!cpp std::tuple, #!cpp std::optional, ...), and the types of the NLOHMANN_DEFINE_TYPE_* and
NLOHMANN_JSON_SERIALIZE_ENUM macros. Types whose from_json() is written for basic_json only go through
materialize().get<T>() instead: the subtree is built into a real
basic_json value first, exactly as parse() would, and converted from there. See
A from_json() that reads views for how to write a from_json() that
reads views, and Duplicate keys for the one case in which the two ways give different
results.
Two conversions never copy at all:
get_string()(equivalently,#!cpp get<string_view_t>()) returns a string as astring_view_tpointing into the document'ssource()text — or, for a string that contains escape sequences, into the document's own buffer of decoded strings — instead of allocating a new#!cpp std::string.number_token()returns a number exactly as it was written in the source, e.g.#!cpp "1.50",#!cpp "1E2", or an integer with more digits than any number type holds, instead of rounding it into a#!cpp double/#!cpp int64_tthe way#!cpp get<T>()(andbasic_json::parse()) would.
Both results are only valid as long as the document and, if it borrows its source text, that text.
string_view members
A struct whose member is a #!cpp std::string_view (C++17) can be decoded from a view with the
NLOHMANN_DEFINE_TYPE_* macros, and the member is not copied either: for a string without escape sequences it points
into the document's source text, and for a string with escape sequences into the document's buffer of decoded
strings. The member is valid as long as the document is alive and, for a document that
borrows its source text (as parse() does for an lvalue
#!cpp std::string, a #!cpp std::string_view, or a C string), as long as that text is.
struct record
{
std::string_view name;
int count;
NLOHMANN_DEFINE_TYPE_INTRUSIVE(record, name, count)
};
const std::string text = R"({"name": "widget", "count": 3})";
const json_document doc = json_document::parse(text); // borrows text
const record r = doc.root().get<record>(); // r.name points into text, valid while text and doc are
!!! warning "Decoding into a string_view from a json value dangles at once"
The same struct also compiles with `#!cpp json::parse(text).get<record>()`, but there `name` points into the
temporary `json` value, which is destroyed at the end of the statement. Use a named
[`json_document`](../../api/json_document.md), as above, to decode such a struct.
Writing a view back
dump() serializes a view directly from the flat index, without ever building a
basic_json value. It writes object members in document order and every occurrence of a repeated key, so it can
differ from #!cpp materialize().dump(); see Serialization.
By default, numbers are written the way basic_json::dump() would.
number_format::source instead copies every number exactly as it was
written in the source text — a price like #!cpp 19.90, a long order or account ID with more digits than any number
type holds, or a high-precision coordinate — something basic_json cannot do at all, since parsing already reduces
a number to its parsed #!cpp double/#!cpp int64_t value. Together with an editable document, this
lets you patch a file without reformatting the rest of it.
operator<< writes a view to a stream the way basic_json's does, using
the stream's width/fill for indentation.
See also
- Zero-copy JSON views - overview
get- convert a viewdump- serialize a view- Writing generic code - functions and
from_json()overloads that accept views
Version history
- Added in version 3.13.0.