nlohmann::basic_json_view::materialize¶
BasicJsonType materialize() const;
Builds the BasicJsonType value of this subtree: the value BasicJsonType::parse() would have produced for the same source text, allocated for the first time by this call.
Return value¶
The BasicJsonType value of this subtree, or a discarded BasicJsonType value (BasicJsonType(value_t::discarded)) if the view is discarded.
Exception safety¶
Strong guarantee: there are no changes to the view or the document it refers to (nothing about either is mutated by this function).
Exceptions¶
May throw std::bad_alloc (via BasicJsonType's allocator) if constructing the result fails.
Complexity¶
Linear in the size of the subtree.
Notes¶
materialize() replays the subtree through the same SAX builder BasicJsonType::parse() uses, so the result matches it exactly -- including, for an object, that a repeated key keeps only its last value. The replay is iterative, so it is not limited by the call stack the way a naive recursive conversion would be; the JSON nesting depth is limited only by available memory, as for BasicJsonType::parse() itself.
Unlike parsing with JSON_DIAGNOSTIC_POSITIONS enabled, the values produced by materialize() do not carry source positions. The index has the start offset of every value, but not the end of arrays, objects, and escaped strings, which the positions also need.
Calling materialize() on the same view repeatedly builds a new, independent BasicJsonType value each time; it never caches the result.
Examples¶
Example
The example below skips messages that are not useful -- a discarded value, or an empty array -- using only is_array() and empty(), and calls materialize() only for the messages that are actually used, so no BasicJsonType value (and none of its per-element allocations) is ever built for the skipped ones.
#include <array>
#include <iostream>
#include <nlohmann/json_view.hpp>
using json_document = nlohmann::json_document;
int main()
{
// three incoming messages; skip the ones that are not useful without ever
// building a nlohmann::json value for them
json_document heartbeat = json_document::parse("null");
json_document empty_batch = json_document::parse("[]");
json_document batch = json_document::parse(R"([{"id": 1}, {"id": 2}, {"id": 3}])");
std::array<const json_document*, 3> messages = {{&heartbeat, &empty_batch, &batch}};
for (const json_document* d : messages)
{
// is_array()/empty() only look at the flat index: a discarded
// heartbeat or an empty batch is never turned into a nlohmann::json
// value, so no per-element allocation happens for them
if (!d->root().is_array() || d->root().empty())
{
std::cout << "skipped\n";
continue;
}
// materialize() replays the subtree through the same SAX builder
// basic_json::parse() uses, so the result is exactly what
// basic_json::parse() would have produced for the same text
nlohmann::json value = d->root().materialize();
std::cout << value.dump() << '\n';
}
}
Output:
skipped
skipped
[{"id":1},{"id":2},{"id":3}]
See also¶
- root - the view of a document's root value
BasicJsonType::parse- build aBasicJsonTypevalue directly from a JSON textJSON_DIAGNOSTIC_POSITIONS- source positions on parsed values (not produced bymaterialize())
Version history¶
- Added in version 3.13.0 unreleased.