=====================
YAML I/O
=====================

.. contents::
   :local:

Introduction to YAML
====================

YAML is a human-readable data serialization language.  The full YAML language
spec can be read at `yaml.org
<http://www.yaml.org/spec/1.2/spec.html#Introduction>`_.  The simplest form of
YAML is just "scalars", "mappings", and "sequences".  A scalar is any number
or string.  The pound/hash symbol (#) begins a comment line.   A mapping is
a set of key-value pairs where the key ends with a colon.  For example:

.. code-block:: yaml

     # a mapping
     name:      Tom
     hat-size:  7

A sequence is a list of items where each item starts with a leading dash ('-').
For example:

.. code-block:: yaml

     # a sequence
     - x86
     - x86_64
     - PowerPC

You can combine mappings and sequences by indenting.  For example a sequence
of mappings in which one of the mapping values is itself a sequence:

.. code-block:: yaml

     # a sequence of mappings with one key's value being a sequence
     - name:      Tom
       cpus:
        - x86
        - x86_64
     - name:      Bob
       cpus:
        - x86
     - name:      Dan
       cpus:
        - PowerPC
        - x86

Sometimes sequences are known to be short and the one entry per line is too
verbose, so YAML offers an alternative syntax for sequences called a "Flow
Sequence" in which you put comma separated sequence elements into square
brackets.  The above example could then be simplified to:


.. code-block:: yaml

     # a sequence of mappings with one key's value being a flow sequence
     - name:      Tom
       cpus:      [ x86, x86_64 ]
     - name:      Bob
       cpus:      [ x86 ]
     - name:      Dan
       cpus:      [ PowerPC, x86 ]


Introduction to YAML I/O
========================

The use of indenting makes the YAML easy for a human to read and understand,
but having a program read and write YAML involves a lot of tedious details.
The YAML I/O library structures and simplifies reading and writing YAML
documents.

YAML I/O assumes you have some "native" data structures which you want to be
able to dump as YAML and recreate from YAML.  The first step is to try
writing example YAML for your data structures. You may find after looking at
possible YAML representations that a direct mapping of your data structures
to YAML is not very readable.  Often, the fields are not in an order that
a human would find readable.  Or the same information is replicated in multiple
locations, making it hard for a human to write such YAML correctly.

In relational database theory there is a design step called normalization in
which you reorganize fields and tables.  The same considerations need to
go into the design of your YAML encoding.  But, you may not want to change
your existing native data structures.  Therefore, when writing out YAML,
there may be a normalization step, and when reading YAML there would be a
corresponding denormalization step.

YAML I/O uses a non-invasive, traits-based design.  YAML I/O defines some
abstract base templates.  You specialize those templates on your data types.
For instance, if you have an enumerated type ``FooBar`` you could specialize
``ScalarEnumerationTraits`` on that type and define the ``enumeration()`` method:

.. code-block:: c++

    using llvm::yaml::ScalarEnumerationTraits;
    using llvm::yaml::IO;

    template <>
    struct ScalarEnumerationTraits<FooBar> {
      static void enumeration(IO &io, FooBar &value) {
      ...
      }
    };


As with all YAML I/O template specializations, the ``ScalarEnumerationTraits`` is used for
both reading and writing YAML. That is, the mapping between in-memory enum
values and the YAML string representation is only in one place.
This assures that the code for writing and parsing of YAML stays in sync.

To specify YAML mappings, you define a specialization on
``llvm::yaml::MappingTraits``.
If your native data structure happens to be a struct that is already normalized,
then the specialization is simple.  For example:

.. code-block:: c++

    using llvm::yaml::MappingTraits;
    using llvm::yaml::IO;

    template <>
    struct MappingTraits<Person> {
      static void mapping(IO &io, Person &info) {
        io.mapRequired("name",         info.name);
        io.mapOptional("hat-size",     info.hatSize);
      }
    };


A YAML sequence is automatically inferred if your data type has ``begin()``/``end()``
iterators and a ``push_back()`` method.  Therefore any of the STL containers
(such as ``std::vector<>``) will automatically translate to YAML sequences.

Once you have defined specializations for your data types, you can
programmatically use YAML I/O to write a YAML document:

.. code-block:: c++

    using llvm::yaml::Output;

    Person tom;
    tom.name = "Tom";
    tom.hatSize = 8;
    Person dan;
    dan.name = "Dan";
    dan.hatSize = 7;
    std::vector<Person> persons;
    persons.push_back(tom);
    persons.push_back(dan);

    Output yout(llvm::outs());
    yout << persons;

This would write the following:

.. code-block:: yaml

     - name:      Tom
       hat-size:  8
     - name:      Dan
       hat-size:  7

And you can also read such YAML documents with the following code:

.. code-block:: c++

    using llvm::yaml::Input;

    typedef std::vector<Person> PersonList;
    std::vector<PersonList> docs;

    Input yin(document.getBuffer());
    yin >> docs;

    if ( yin.error() )
      return;

    // Process read document
    for ( PersonList &pl : docs ) {
      for ( Person &person : pl ) {
        cout << "name=" << person.name;
      }
    }

One other feature of YAML is the ability to define multiple documents in a
single file.  That is why reading YAML produces a vector of your document type.



Error Handling
==============

When parsing a YAML document, if the input does not match your schema (as
expressed in your ``XxxTraits<>`` specializations).  YAML I/O
will print out an error message and your Input object's ``error()`` method will
return true. For instance, the following document:

.. code-block:: yaml

     - name:      Tom
       shoe-size: 12
     - name:      Dan
       hat-size:  7

Has a key (shoe-size) that is not defined in the schema.  YAML I/O will
automatically generate this error:

.. code-block:: yaml

    YAML:2:2: error: unknown key 'shoe-size'
      shoe-size:       12
      ^~~~~~~~~

Similar errors are produced for other input not conforming to the schema.


Scalars
=======

YAML scalars are just strings (i.e. not a sequence or mapping).  The YAML I/O
library provides support for translating between YAML scalars and specific
C++ types.


Built-in types
--------------
The following types have built-in support in YAML I/O:

* bool
* float
* double
* StringRef
* std::string
* int64_t
* int32_t
* int16_t
* int8_t
* uint64_t
* uint32_t
* uint16_t
* uint8_t

That is, you can use those types in fields of ``MappingTraits`` or as the element type
in a sequence.  When reading, YAML I/O will validate that the string found
is convertible to that type and error out if not.


Unique types
------------
Given that YAML I/O is trait based, the selection of how to convert your data
to YAML is based on the type of your data.  But in C++ type matching, typedefs
do not generate unique type names.  That means if you have two typedefs of
unsigned int, to YAML I/O both types look exactly like unsigned int.  To
facilitate making unique type names, YAML I/O provides a macro which is used
like a typedef on built-in types, but expands to create a class with conversion
operators to and from the base type.  For example:

.. code-block:: c++

    LLVM_YAML_STRONG_TYPEDEF(uint32_t, MyFooFlags)
    LLVM_YAML_STRONG_TYPEDEF(uint32_t, MyBarFlags)

This generates two classes MyFooFlags and MyBarFlags which you can use in your
native data structures instead of ``uint32_t``. They are implicitly
converted to and from ``uint32_t``.  The point of creating these unique types
is that you can now specify traits on them to get different YAML conversions.

Hex types
---------
An example use of a unique type is that YAML I/O provides fixed-sized unsigned
integers that are written with YAML I/O as hexadecimal instead of the decimal
format used by the built-in integer types:

* Hex64
* Hex32
* Hex16
* Hex8

You can use ``llvm::yaml::Hex32`` instead of ``uint32_t`` and the only difference will
be that when YAML I/O writes out that type it will be formatted in hexadecimal.


ScalarEnumerationTraits
-----------------------
YAML I/O supports translating between in-memory enumerations and a set of string
values in YAML documents. This is done by specializing ``ScalarEnumerationTraits<>``
on your enumeration type and defining an ``enumeration()`` method.
For instance, suppose you had an enumeration of CPUs and a struct with it as
a field:

.. code-block:: c++

    enum CPUs {
      cpu_x86_64  = 5,
      cpu_x86     = 7,
      cpu_PowerPC = 8
    };

    struct Info {
      CPUs      cpu;
      uint32_t  flags;
    };

To support reading and writing of this enumeration, you can define a
``ScalarEnumerationTraits`` specialization on CPUs, which can then be used
as a field type:

.. code-block:: c++

    using llvm::yaml::ScalarEnumerationTraits;
    using llvm::yaml::MappingTraits;
    using llvm::yaml::IO;

    template <>
    struct ScalarEnumerationTraits<CPUs> {
      static void enumeration(IO &io, CPUs &value) {
        io.enumCase(value, "x86_64",  cpu_x86_64);
        io.enumCase(value, "x86",     cpu_x86);
        io.enumCase(value, "PowerPC", cpu_PowerPC);
      }
    };

    template <>
    struct MappingTraits<Info> {
      static void mapping(IO &io, Info &info) {
        io.mapRequired("cpu",       info.cpu);
        io.mapOptional("flags",     info.flags, 0);
      }
    };

When reading YAML, if the string found does not match any of the strings
specified by ``enumCase()`` methods, an error is automatically generated.
When writing YAML, if the value being written does not match any of the values
specified by the ``enumCase()`` methods, a runtime assertion is triggered.


BitValue
--------
Another common data structure in C++ is a field where each bit has a unique
meaning.  This is often used in a "flags" field.  YAML I/O has support for
converting such fields to a flow sequence.   For instance suppose you
had the following bit flags defined:

.. code-block:: c++

    enum {
      flagsPointy = 1
      flagsHollow = 2
      flagsFlat   = 4
      flagsRound  = 8
    };

    LLVM_YAML_STRONG_TYPEDEF(uint32_t, MyFlags)

To support reading and writing of MyFlags, you specialize ``ScalarBitSetTraits<>``
on MyFlags and provide the bit values and their names.

.. code-block:: c++

    using llvm::yaml::ScalarBitSetTraits;
    using llvm::yaml::MappingTraits;
    using llvm::yaml::IO;

    template <>
    struct ScalarBitSetTraits<MyFlags> {
      static void bitset(IO &io, MyFlags &value) {
        io.bitSetCase(value, "hollow",  flagHollow);
        io.bitSetCase(value, "flat",    flagFlat);
        io.bitSetCase(value, "round",   flagRound);
        io.bitSetCase(value, "pointy",  flagPointy);
      }
    };

    struct Info {
      StringRef   name;
      MyFlags     flags;
    };

    template <>
    struct MappingTraits<Info> {
      static void mapping(IO &io, Info& info) {
        io.mapRequired("name",  info.name);
        io.mapRequired("flags", info.flags);
       }
    };

With the above, YAML I/O (when writing) will test mask each value in the
bitset trait against the flags field, and each that matches will
cause the corresponding string to be added to the flow sequence.  The opposite
is done when reading and any unknown string values will result in an error. With
the above schema, a same valid YAML document is:

.. code-block:: yaml

    name:    Tom
    flags:   [ pointy, flat ]

Sometimes a "flags" field might contain an enumeration part
defined by a bit-mask.

.. code-block:: c++

    enum {
      flagsFeatureA = 1,
      flagsFeatureB = 2,
      flagsFeatureC = 4,

      flagsCPUMask = 24,

      flagsCPU1 = 8,
      flagsCPU2 = 16
    };

To support reading and writing such fields, you need to use the ``maskedBitSet()``
method and provide the bit values, their names and the enumeration mask.

.. code-block:: c++

    template <>
    struct ScalarBitSetTraits<MyFlags> {
      static void bitset(IO &io, MyFlags &value) {
        io.bitSetCase(value, "featureA",  flagsFeatureA);
        io.bitSetCase(value, "featureB",  flagsFeatureB);
        io.bitSetCase(value, "featureC",  flagsFeatureC);
        io.maskedBitSetCase(value, "CPU1",  flagsCPU1, flagsCPUMask);
        io.maskedBitSetCase(value, "CPU2",  flagsCPU2, flagsCPUMask);
      }
    };

YAML I/O (when writing) will apply the enumeration mask to the flags field,
and compare the result and values from the bitset. As in case of a regular
bitset, each that matches will cause the corresponding string to be added
to the flow sequence.

Custom Scalar
-------------
Sometimes, for readability, a scalar needs to be formatted in a custom way. For
instance, your internal data structure may use an integer for time (seconds since
some epoch), but in YAML it would be much nicer to express that integer in
some time format (e.g. 4-May-2012 10:30pm).  YAML I/O has a way to support
custom formatting and parsing of scalar types by specializing ``ScalarTraits<>`` on
your data type.  When writing, YAML I/O will provide the native type and
your specialization must create a temporary ``llvm::StringRef``.  When reading,
YAML I/O will provide an ``llvm::StringRef`` of scalar and your specialization
must convert that to your native data type.  An outline of a custom scalar type
looks like:

.. code-block:: c++

    using llvm::yaml::ScalarTraits;
    using llvm::yaml::IO;

    template <>
    struct ScalarTraits<MyCustomType> {
      static void output(const MyCustomType &value, void*,
                         llvm::raw_ostream &out) {
        out << value;  // do custom formatting here
      }
      static StringRef input(StringRef scalar, void*, MyCustomType &value) {
        // do custom parsing here.  Return the empty string on success,
        // or an error message on failure.
        return StringRef();
      }
      // Determine if this scalar needs quotes.
      static QuotingType mustQuote(StringRef) { return QuotingType::Single; }
    };

Block Scalars
-------------

YAML block scalars are string literals that are represented in YAML using the
literal block notation, just like the example shown below:

.. code-block:: yaml

    text: |
      First line
      Second line

The YAML I/O library provides support for translating between YAML block scalars
and specific C++ types by allowing you to specialize ``BlockScalarTraits<>`` on
your data type. The library doesn't provide any built-in support for block
scalar I/O for types like ``std::string`` and ``llvm::StringRef`` as they are already
supported by YAML I/O and use the ordinary scalar notation by default.

``BlockScalarTraits`` specializations are very similar to the
``ScalarTraits`` specialization - YAML I/O will provide the native type and your
specialization must create a temporary ``llvm::StringRef`` when writing, and
it will also provide an ``llvm::StringRef`` that has the value of that block scalar
and your specialization must convert that to your native data type when reading.
An example of a custom type with an appropriate specialization of
``BlockScalarTraits`` is shown below:

.. code-block:: c++

    using llvm::yaml::BlockScalarTraits;
    using llvm::yaml::IO;

    struct MyStringType {
      std::string Str;
    };

    template <>
    struct BlockScalarTraits<MyStringType> {
      static void output(const MyStringType &Value, void *Ctxt,
                         llvm::raw_ostream &OS) {
        OS << Value.Str;
      }

      static StringRef input(StringRef Scalar, void *Ctxt,
                             MyStringType &Value) {
        Value.Str = Scalar.str();
        return StringRef();
      }
    };



Mappings
========

To be translated to or from a YAML mapping for your type T you must specialize
``llvm::yaml::MappingTraits`` on T and implement the "void mapping(IO &io, T&)"
method. If your native data structures use pointers to a class everywhere,
you can specialize on the class pointer.  Examples:

.. code-block:: c++

    using llvm::yaml::MappingTraits;
    using llvm::yaml::IO;

    // Example of struct Foo which is used by value
    template <>
    struct MappingTraits<Foo> {
      static void mapping(IO &io, Foo &foo) {
        io.mapOptional("size",      foo.size);
      ...
      }
    };

    // Example of struct Bar which is natively always a pointer
    template <>
    struct MappingTraits<Bar*> {
      static void mapping(IO &io, Bar *&bar) {
        io.mapOptional("size",    bar->size);
      ...
      }
    };

There are circumstances where we want to allow the entire mapping to be
read as an enumeration.  For example, say some configuration option
started as an enumeration.  Then it got more complex so it is now a
mapping.  But it is necessary to support the old configuration files.
In that case, add a function ``enumInput`` like for
``ScalarEnumerationTraits::enumeration``.  Examples:

.. code-block:: c++

    struct FooBarEnum {
      int Foo;
      int Bar;
      bool operator==(const FooBarEnum &R) const {
        return Foo == R.Foo && Bar == R.Bar;
      }
    };

    template <> struct MappingTraits<FooBarEnum> {
      static void enumInput(IO &io, FooBarEnum &Val) {
        io.enumCase(Val, "OnlyFoo", FooBarEnum({1, 0}));
        io.enumCase(Val, "OnlyBar", FooBarEnum({0, 1}));
      }
      static void mapping(IO &io, FooBarEnum &Val) {
        io.mapOptional("Foo", Val.Foo);
        io.mapOptional("Bar", Val.Bar);
      }
    };


No Normalization
----------------

The ``mapping()`` method is responsible, if needed, for normalizing and
denormalizing. In a simple case where the native data structure requires no
normalization, the mapping method just uses ``mapOptional()`` or ``mapRequired()`` to
bind the struct's fields to YAML key names.  For example:

.. code-block:: c++

    using llvm::yaml::MappingTraits;
    using llvm::yaml::IO;

    template <>
    struct MappingTraits<Person> {
      static void mapping(IO &io, Person &info) {
        io.mapRequired("name",         info.name);
        io.mapOptional("hat-size",     info.hatSize);
      }
    };


Normalization
----------------

When [de]normalization is required, the ``mapping()`` method needs a way to access
normalized values as fields. To help with this, there is
a template ``MappingNormalization<>`` which you can then use to automatically
do the normalization and denormalization.  The template is used to create
a local variable in your ``mapping()`` method which contains the normalized keys.

Suppose you have native data type
Polar which specifies a position in polar coordinates (distance, angle):

.. code-block:: c++

    struct Polar {
      float distance;
      float angle;
    };

but you've decided the normalized YAML form should be in x,y coordinates. That
is, you want the yaml to look like:

.. code-block:: yaml

    x:   10.3
    y:   -4.7

You can support this by defining a ``MappingTraits`` that normalizes the polar
coordinates to x,y coordinates when writing YAML and denormalizes x,y
coordinates into polar when reading YAML.

.. code-block:: c++

    using llvm::yaml::MappingTraits;
    using llvm::yaml::IO;

    template <>
    struct MappingTraits<Polar> {

      class NormalizedPolar {
      public:
        NormalizedPolar(IO &io)
          : x(0.0), y(0.0) {
        }
        NormalizedPolar(IO &, Polar &polar)
          : x(polar.distance * cos(polar.angle)),
            y(polar.distance * sin(polar.angle)) {
        }
        Polar denormalize(IO &) {
          return Polar(sqrt(x*x+y*y), arctan(x,y));
        }

        float        x;
        float        y;
      };

      static void mapping(IO &io, Polar &polar) {
        MappingNormalization<NormalizedPolar, Polar> keys(io, polar);

        io.mapRequired("x",    keys->x);
        io.mapRequired("y",    keys->y);
      }
    };

When writing YAML, the local variable "keys" will be a stack allocated
instance of ``NormalizedPolar``, constructed from the supplied polar object which
initializes it x and y fields.  The ``mapRequired()`` methods then write out the x
and y values as key/value pairs.

When reading YAML, the local variable "keys" will be a stack allocated instance
of ``NormalizedPolar``, constructed by the empty constructor.  The ``mapRequired()``
methods will find the matching key in the YAML document and fill in the x and y
fields of the ``NormalizedPolar`` object keys. At the end of the ``mapping()`` method
when the local keys variable goes out of scope, the ``denormalize()`` method will
automatically be called to convert the read values back to polar coordinates,
and then assigned back to the second parameter to ``mapping()``.

In some cases, the normalized class may be a subclass of the native type and
could be returned by the ``denormalize()`` method, except that the temporary
normalized instance is stack allocated.  In these cases, the utility template
``MappingNormalizationHeap<>`` can be used instead.  It just like
``MappingNormalization<>`` except that it heap allocates the normalized object
when reading YAML.  It never destroys the normalized object.  The ``denormalize()``
method can this return "this".


Default values
--------------
Within a ``mapping()`` method, calls to ``io.mapRequired()`` mean that that key is
required to exist when parsing YAML documents, otherwise YAML I/O will issue an
error.

On the other hand, keys registered with ``io.mapOptional()`` are allowed to not
exist in the YAML document being read.  So what value is put in the field
for those optional keys?
There are two steps to how those optional fields are filled in. First, the
second parameter to the ``mapping()`` method is a reference to a native class.  That
native class must have a default constructor.  Whatever value the default
constructor initially sets for an optional field will be that field's value.
Second, the ``mapOptional()`` method has an optional third parameter.  If provided
it is the value that ``mapOptional()`` should set that field to if the YAML document
does not have that key.

There is one important difference between those two ways (default constructor
and third parameter to ``mapOptional()``). When YAML I/O generates a YAML document,
if the ``mapOptional()`` third parameter is used, if the actual value being written
is the same as (using ==) the default value, then that key/value is not written.


Order of Keys
--------------

When writing out a YAML document, the keys are written in the order that the
calls to ``mapRequired()``/``mapOptional()`` are made in the ``mapping()`` method. This
gives you a chance to write the fields in an order that a human reader of
the YAML document would find natural.  This may be different that the order
of the fields in the native class.

When reading in a YAML document, the keys in the document can be in any order,
but they are processed in the order that the calls to ``mapRequired()``/``mapOptional()``
are made in the ``mapping()`` method.  That enables some interesting
functionality.  For instance, if the first field bound is the cpu and the second
field bound is flags, and the flags are cpu specific, you can programmatically
switch how the flags are converted to and from YAML based on the cpu.
This works for both reading and writing. For example:

.. code-block:: c++

    using llvm::yaml::MappingTraits;
    using llvm::yaml::IO;

    struct Info {
      CPUs        cpu;
      uint32_t    flags;
    };

    template <>
    struct MappingTraits<Info> {
      static void mapping(IO &io, Info &info) {
        io.mapRequired("cpu",       info.cpu);
        // flags must come after cpu for this to work when reading yaml
        if ( info.cpu == cpu_x86_64 )
          io.mapRequired("flags",  *(My86_64Flags*)info.flags);
        else
          io.mapRequired("flags",  *(My86Flags*)info.flags);
     }
    };


Tags
----

The YAML syntax supports tags as a way to specify the type of a node before
it is parsed. This allows dynamic types of nodes.  But the YAML I/O model uses
static typing, so there are limits to how you can use tags with the YAML I/O
model. Recently, we added support to YAML I/O for checking/setting the optional
tag on a map. Using this functionality it is even possible to support different
mappings, as long as they are convertible.

To check a tag, inside your ``mapping()`` method you can use ``io.mapTag()`` to specify
what the tag should be.  This will also add that tag when writing YAML.

Validation
----------

Sometimes in a YAML map, each key/value pair is valid, but the combination is
not.  This is similar to something having no syntax errors, but still having
semantic errors.  To support semantic-level checking, YAML I/O allows
an optional ``validate()`` method in a MappingTraits template specialization.

When parsing YAML, the ``validate()`` method is call *after* all key/values in
the map have been processed. Any error message returned by the ``validate()``
method during input will be printed just like a syntax error would be printed.
When writing YAML, the ``validate()`` method is called *before* the YAML
key/values  are written.  Any error during output will trigger an ``assert()``
because it is a programming error to have invalid struct values.


.. code-block:: c++

    using llvm::yaml::MappingTraits;
    using llvm::yaml::IO;

    struct Stuff {
      ...
    };

    template <>
    struct MappingTraits<Stuff> {
      static void mapping(IO &io, Stuff &stuff) {
      ...
      }
      static std::string validate(IO &io, Stuff &stuff) {
        // Look at all fields in 'stuff' and if there
        // are any bad values return a string describing
        // the error.  Otherwise return an empty string.
        return std::string{};
      }
    };

Flow Mapping
------------
A YAML "flow mapping" is a mapping that uses the inline notation
(e.g { x: 1, y: 0 } ) when written to YAML. To specify that a type should be
written in YAML using flow mapping, your MappingTraits specialization should
add "static const bool flow = true;". For instance:

.. code-block:: c++

    using llvm::yaml::MappingTraits;
    using llvm::yaml::IO;

    struct Stuff {
      ...
    };

    template <>
    struct MappingTraits<Stuff> {
      static void mapping(IO &io, Stuff &stuff) {
        ...
      }

      static const bool flow = true;
    }

Flow mappings are subject to line wrapping according to the ``Output`` object
configuration.

Sequence
========

To be translated to or from a YAML sequence for your type T you must specialize
``llvm::yaml::SequenceTraits`` on T and implement two methods:
``size_t size(IO &io, T&)`` and
``T::value_type& element(IO &io, T&, size_t indx)``.  For example:

.. code-block:: c++

  template <>
  struct SequenceTraits<MySeq> {
    static size_t size(IO &io, MySeq &list) { ... }
    static MySeqEl &element(IO &io, MySeq &list, size_t index) { ... }
  };

The ``size()`` method returns how many elements are currently in your sequence.
The ``element()`` method returns a reference to the i'th element in the sequence.
When parsing YAML, the ``element()`` method may be called with an index one bigger
than the current size.  Your ``element()`` method should allocate space for one
more element (using default constructor if element is a C++ object) and return
a reference to that new allocated space.


Flow Sequence
-------------
A YAML "flow sequence" is a sequence that when written to YAML it uses the
inline notation (e.g [ foo, bar ] ).  To specify that a sequence type should
be written in YAML as a flow sequence, your SequenceTraits specialization should
add "static const bool flow = true;".  For instance:

.. code-block:: c++

  template <>
  struct SequenceTraits<MyList> {
    static size_t size(IO &io, MyList &list) { ... }
    static MyListEl &element(IO &io, MyList &list, size_t index) { ... }

    // The existence of this member causes YAML I/O to use a flow sequence
    static const bool flow = true;
  };

With the above, if you used MyList as the data type in your native data
structures, then when converted to YAML, a flow sequence of integers
will be used (e.g. [ 10, -3, 4 ]).

Flow sequences are subject to line wrapping according to the Output object
configuration.

Utility Macros
--------------
Since a common source of sequences is ``std::vector<>``, YAML I/O provides macros:
``LLVM_YAML_IS_SEQUENCE_VECTOR()`` and ``LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR()`` which
can be used to easily specify ``SequenceTraits<>`` on a ``std::vector`` type.  YAML
I/O does not partial specialize ``SequenceTraits`` on ``std::vector<>`` because that
would force all vectors to be sequences.  An example use of the macros:

.. code-block:: c++

  std::vector<MyType1>;
  std::vector<MyType2>;
  LLVM_YAML_IS_SEQUENCE_VECTOR(MyType1)
  LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(MyType2)



Document List
=============

YAML allows you to define multiple "documents" in a single YAML file.  Each
new document starts with a left aligned "---" token.  The end of all documents
is denoted with a left aligned "..." token.  Many users of YAML will never
have need for multiple documents.  The top level node in their YAML schema
will be a mapping or sequence. For those cases, the following is not needed.
But for cases where you do want multiple documents, you can specify a
trait for you document list type.  The trait has the same methods as
``SequenceTraits`` but is named ``DocumentListTraits``.  For example:

.. code-block:: c++

  template <>
  struct DocumentListTraits<MyDocList> {
    static size_t size(IO &io, MyDocList &list) { ... }
    static MyDocType element(IO &io, MyDocList &list, size_t index) { ... }
  };


User Context Data
=================
When an ``llvm::yaml::Input`` or ``llvm::yaml::Output`` object is created, its
constructor takes an optional "context" parameter.  This is a pointer to
whatever state information you might need.

For instance, in a previous example we showed how the conversion type for a
flags field could be determined at runtime based on the value of another field
in the mapping. But what if an inner mapping needs to know some field value
of an outer mapping?  That is where the "context" parameter comes in. You
can set values in the context in the outer map's ``mapping()`` method and
retrieve those values in the inner map's ``mapping()`` method.

The context value is just a ``void*``.  All your traits which use the context
and operate on your native data types, need to agree what the context value
actually is.  It could be a pointer to an object or struct which your various
traits use to share context sensitive information.


Output
======

The ``llvm::yaml::Output`` class is used to generate a YAML document from your
in-memory data structures, using traits defined on your data types.
To instantiate an ``Output`` object you need an ``llvm::raw_ostream``, an optional
context pointer and an optional wrapping column:

.. code-block:: c++

      class Output : public IO {
      public:
        Output(llvm::raw_ostream &, void *context = NULL, int WrapColumn = 70);

Once you have an ``Output`` object, you can use the C++ stream operator on it
to write your native data as YAML. One thing to recall is that a YAML file
can contain multiple "documents".  If the top level data structure you are
streaming as YAML is a mapping, scalar, or sequence, then ``Output`` assumes you
are generating one document and wraps the mapping output
with  "``---``" and trailing "``...``".

The ``WrapColumn`` parameter will cause the flow mappings and sequences to
line-wrap when they go over the supplied column. Pass 0 to completely
suppress the wrapping.

.. code-block:: c++

    using llvm::yaml::Output;

    void dumpMyMapDoc(const MyMapType &info) {
      Output yout(llvm::outs());
      yout << info;
    }

The above could produce output like:

.. code-block:: yaml

     ---
     name:      Tom
     hat-size:  7
     ...

On the other hand, if the top level data structure you are streaming as YAML
has a ``DocumentListTraits`` specialization, then Output walks through each element
of your DocumentList and generates a "---" before the start of each element
and ends with a "...".

.. code-block:: c++

    using llvm::yaml::Output;

    void dumpMyMapDoc(const MyDocListType &docList) {
      Output yout(llvm::outs());
      yout << docList;
    }

The above could produce output like:

.. code-block:: yaml

     ---
     name:      Tom
     hat-size:  7
     ---
     name:      Tom
     shoe-size:  11
     ...

Input
=====

The ``llvm::yaml::Input`` class is used to parse YAML document(s) into your native
data structures. To instantiate an ``Input``
object you need a ``StringRef`` to the entire YAML file, and optionally a context
pointer:

.. code-block:: c++

      class Input : public IO {
      public:
        Input(StringRef inputContent, void *context=NULL);

Once you have an ``Input`` object, you can use the C++ stream operator to read
the document(s).  If you expect there might be multiple YAML documents in
one file, you'll need to specialize ``DocumentListTraits`` on a list of your
document type and stream in that document list type.  Otherwise you can
just stream in the document type.  Also, you can check if there was
any syntax errors in the YAML by calling the ``error()`` method on the ``Input``
object.  For example:

.. code-block:: c++

     // Reading a single document
     using llvm::yaml::Input;

     Input yin(mb.getBuffer());

     // Parse the YAML file
     MyDocType theDoc;
     yin >> theDoc;

     // Check for error
     if ( yin.error() )
       return;


.. code-block:: c++

     // Reading multiple documents in one file
     using llvm::yaml::Input;

     LLVM_YAML_IS_DOCUMENT_LIST_VECTOR(MyDocType)

     Input yin(mb.getBuffer());

     // Parse the YAML file
     std::vector<MyDocType> theDocList;
     yin >> theDocList;

     // Check for error
     if ( yin.error() )
       return;
