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

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");
}





Add Discussion as Guest

Log in