Parsing sequences

#include <x/yaml/sequencenode.H>

switch (n->nodetype) {

// ...
case YAML_SEQUENCE_NODE:
    handle_sequence(x::yaml::sequencenode(n));
    break;

// ...
};

// ...

void handle_sequence(const x::yaml::sequencenode &seq)
{
    size_t n=seq->size();

    std::cout << n << " elements" << std::endl;
    for (size_t i=0; i<n; ++i)
        dump(x::yaml::scalarnode(seq->get(i)));
}

x::yaml::sequencenode refers to a subclass of x::yaml::nodeObj that represents a sequence in a YAML document. Its size() method gives the number of values in the sequence. get() returns a x::yaml::node, which can be converted to another x::yaml::scalarnode, x::yaml::sequencenode, or an x::yaml::mappingnode, according to its nodetype.

void handle_sequence(const x::yaml::sequencenode &seq)
{
    for (x::yaml::scalarnode scalar: *seq)
    {
        dump(scalar);
    }
}

The referenced sequence object implements a begin() and an end() that return x::yaml::sequencenode::base::iterators over x::yaml::node values in the sequence. This example iterates over a sequence that's expected to consist entirely of x::yaml::scalarnode values, so the range iteration value gets coerced accordingly. An exception gets thrown in the event of a type conversion failure if the sequence contains a different node type.

void handle_sequence(const x::yaml::sequencenode &seq)
{
    seq->for_each([],
        (x::yaml::scalarnode &&n)
        {
            dump(n);
        });
}

The for_each() method produces slightly more efficient code that iterates over the sequence, and invokes the functor or the lambda argument passing each node in the sequence by rvalue.

Note

Sequences do not have to be mono-typed. The same sequence may contain a mixture of x::yaml::scalarnodes and x::yaml::sequencenodes, for example. In this case, the range iteration or the for_each() should take a x::yaml::node rvalue, then proceed based on its nodetype.