Function sample_anchors_and_aliases
Synopsis
#include <samples/quickstart.cpp>
void sample_anchors_and_aliases()
Description
deal with YAML anchors and aliases
demonstrates usage with anchors and alias references.
Note that dereferencing is opt-in; after parsing, you have to call Tree::resolve()
explicitly if you want resolved references in the tree. This method will resolve all references and substitute the anchored values in place of the reference.
The Tree::resolve()
method first does a full traversal of the tree to gather all anchors and references in a separate collection, then it goes through that collection to locate the names, which it does by obeying the YAML standard diktat that
an alias node refers to the most recent node in
the serialization having the specified anchor
So, depending on the number of anchor/alias nodes, this is a potentially expensive operation, with a best-case linear complexity (from the initial traversal) and a worst-case quadratic complexity (if every node has an alias/anchor). This potential cost is the reason for requiring an explicit call to Tree::resolve()
.
Mentioned in
- Getting Started / Quick start
Source
Lines 3160-3208 in samples/quickstart.cpp. Line 70 in samples/quickstart.cpp.
void sample_anchors_and_aliases()
{
std::string unresolved = R"(base: &base
name: Everyone has same name
foo: &foo
<<: *base
age: 10
bar: &bar
<<: *base
age: 20
bill_to: &id001
street: |-
123 Tornado Alley
Suite 16
city: East Centerville
state: KS
ship_to: *id001
&keyref key: &valref val
*valref: *keyref
)";
ryml::Tree tree = ryml::parse(ryml::to_csubstr(unresolved));
// by default, references are not resolved when parsing:
CHECK( ! tree["base"].has_key_anchor());
CHECK( tree["base"].has_val_anchor());
CHECK( tree["base"].val_anchor() == "base");
CHECK( tree["key"].key_anchor() == "keyref");
CHECK( tree["key"].val_anchor() == "valref");
CHECK( tree["*valref"].is_key_ref());
CHECK( tree["*valref"].is_val_ref());
CHECK( tree["*valref"].key_ref() == "valref");
CHECK( tree["*valref"].val_ref() == "keyref");
// to resolve references, simply call tree.resolve(),
// which will perform the reference instantiations:
tree.resolve();
// all the anchors and references are substistuted and then removed:
CHECK( ! tree["base"].has_key_anchor());
CHECK( ! tree["base"].has_val_anchor());
CHECK( ! tree["base"].has_val_anchor());
CHECK( ! tree["key"].has_key_anchor());
CHECK( ! tree["key"].has_val_anchor());
CHECK( ! tree["val"].is_key_ref()); // notice *valref is now turned to val
CHECK( ! tree["val"].is_val_ref()); // notice *valref is now turned to val
CHECK(tree["ship_to"]["city"] == "East Centerville");
CHECK(tree["ship_to"]["state"] == "KS");
}