Function resolve

Synopsis

#include <src/c4/yml/tree.hpp>

void resolve()

Description

Resolve references (aliases <- anchors) in the tree.

Dereferencing is opt-in; after parsing, Tree::resolve() has to be called explicitly for obtaining resolved references in the tree. This method will resolve all references and substitute the anchored values in place of the reference.

This 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). This potential cost is the reason for requiring an explicit call.

Mentioned in

Source

Lines 1234-1293 in src/c4/yml/tree.cpp. Line 698 in src/c4/yml/tree.hpp.

void Tree::resolve()
{
    if(m_size == 0) return;

    detail::ReferenceResolver rr(this);

    // insert the resolved references
    size_t prev_parent_ref = NONE;
    size_t prev_parent_ref_after = NONE;
    for(auto const& C4_RESTRICT rd : rr.refs)
    {
        if( ! rd.is_ref) continue;
        if(rd.parent_ref != NONE)
        {
            RYML_ASSERT(is_seq(rd.parent_ref));
            size_t after, p = parent(rd.parent_ref);
            if(prev_parent_ref != rd.parent_ref)
            {
                after = rd.parent_ref;//prev_sibling(rd.parent_ref_sibling);
                prev_parent_ref_after = after;
            }
            else
            {
                after = prev_parent_ref_after;
            }
            prev_parent_ref = rd.parent_ref;
            prev_parent_ref_after = duplicate_children_no_rep(rd.target, p, after);
            remove(rd.node);
        }
        else
        {
            if(has_key(rd.node) && key(rd.node) == "<<")
            {
                RYML_ASSERT(is_keyval(rd.node));
                size_t p = parent(rd.node);
                size_t after = prev_sibling(rd.node);
                duplicate_children_no_rep(rd.target, p, after);
                remove(rd.node);
            }
            else
            {
                duplicate_contents(rd.target, rd.node);
            }
        }
    }

    // clear anchors and refs
    for(auto const& C4_RESTRICT ar : rr.refs)
    {
        rem_anchor_ref(ar.node);
        if(ar.parent_ref != NONE)
        {
            if(type(ar.parent_ref) != NOTYPE)
            {
                remove(ar.parent_ref);
            }
        }
    }

}





Add Discussion as Guest

Log in