Class yaml

Nested Relationships

Nested Types

Class Documentation

class yaml

Powerful YAML-like container for possibly-nested blocks of parameters or any arbitrary structured data contents, including documentation in the form of comments attached to each node. Supports parsing from YAML or JSON streams, files, or text strings.

This class holds the root “node” in a YAML-like tree structure. Each tree node can be of one of these types:

  • Scalar values (“leaf nodes”): Can hold any type, stored as C++17 std::any.

  • Sequence container.

  • Map (“dictionary”): pairs of name: value.

  • Null, empty nodes: yaml ~ or null.

Sequences and dictionaries can hold, in turn, any of the four types above, leading to arbitrarialy-complex nested structures.

This class was designed as a lightweight, while structured, way to pass arbitrarialy-complex parameter blocks but can be used to load and save YAML files or as a database.

yaml can be used to parse YAML (v1.2) or JSON streams, and to emit YAML. It does not support event-based parsing. The parser uses Pantelis Antoniou’s awesome libfyaml, which passes the full YAML testsuite.

Known limitations:

  • Parsing comments is limited to right-hand comments for sequence or map entries.

See examples below (containers_yaml_example/main.cpp):


Output:

Verbose debug information on YAML document parsing is emitted if the environment variable MRPT_YAML_PARSER_VERBOSE is set to 1.

Note

[New in MRPT 2.1.0]

Types

using scalar_t = std::any
using sequence_t = std::vector<node_t>
using map_t = std::map<node_t, node_t>
using comments_t = std::array<std::optional<std::string>, static_cast<size_t>(CommentPosition::MAX)>

Constructors and initializers

yaml() = default
inline yaml(std::initializer_list<map_t::value_type> init)

Constructor for maps, from list of pairs of values. See examples in yaml above.

inline yaml(std::initializer_list<sequence_t::value_type> init)

Constructor for sequences, from list of values. See examples in yaml above.

yaml(const yaml &v)
inline yaml(node_t s)
void loadFromText(const std::string &yamlTextBlock)

Parses a text as YAML or JSON (autodetected) and stores the contents into this document.

Throws:

std::exception – Upon format errors

void loadFromFile(const std::string &fileName)

Parses a text as YAML or JSON (autodetected) and stores the contents into this document.

Throws:

std::exception – Upon I/O or format errors

void loadFromStream(std::istream &i)

Parses the stream as YAML or JSON (autodetected) and stores the contents into this document.

Throws:

std::exception – Upon format errors

template<typename YAML_NODE>
void loadFromYAMLCPP(const YAML_NODE &n)
template<typename MATRIX>
void toMatrix(MATRIX &m) const

Fills in a matrix from a yaml dictionary node. The matrix can be either an Eigen or mrpt::math matrix. Example yaml node (compatible with OpenCV & ROS YAML formats):

rows: 2
cols: 3
data: [11, 12, 13, 21, 22, 23]

See also

FromMatrix()

template<typename Scalar>
std::vector<Scalar> toStdVector() const

Converts a sequence yaml node into a std::vector, trying to convert all nodes to the same given Scalar type.

Note

(New in MRPT 2.3.3)

static inline node_t Sequence(std::initializer_list<sequence_t::value_type> init)
static inline node_t Sequence()
static inline node_t Map(std::initializer_list<map_t::value_type> init)
static inline node_t Map()
static yaml FromText(const std::string &yamlTextBlock)

Parses a text as YAML or JSON (autodetected) and returns a document.

Throws:

std::exception – Upon format errors

static yaml FromStream(std::istream &i)

Parses the stream as YAML or JSON (autodetected) and returns a document.

Throws:

std::exception – Upon format errors

static yaml FromFile(const std::string &fileName)

Parses the filename as YAML or JSON (autodetected) and returns a document.

Throws:

std::exception – Upon I/O or format errors.

template<typename YAML_NODE>
static yaml FromYAMLCPP(const YAML_NODE &n)

Builds an object copying the structure and contents from an existing YAMLCPP Node. Requires user to #include yamlcpp from your calling program (does NOT requires yamlcpp while compiling mrpt itself).

Template Parameters:

YAML_NODE – Must be YAML::Node. Made a template just to avoid build-time depedencies.

template<typename MATRIX>
static yaml FromMatrix(const MATRIX &m)

Creates a yaml dictionary node from an Eigen or mrpt::math matrix. Example (compatible with OpenCV & ROS YAML formats):

rows: 2
cols: 3
data: [11, 12, 13, 21, 22, 23]

See also

toMatrix()

Content and type checkers

bool has(const std::string &key) const

For map nodes, checks if the given key name exists. Returns false if the node is a null node. Throws if the node is not a map or null.

bool empty() const

For map or sequence nodes, checks if the container is empty. Also returns true for null(empty) nodes.

void clear()

Resets to empty (can be called on a root node or any other node to clear that subtree only).

bool isNullNode() const
bool isScalar() const
bool isSequence() const
bool isMap() const
const std::type_info &scalarType() const

For scalar nodes, returns its type, or typeid(void) if an empty node.

Throws:

std::exception – If called on a map or sequence.

Range-for and conversion helpers

sequence_t &asSequence()

Use: for (auto &kv: n.asSequence()) {...}

Throws:

std::exception – If called on a non-sequence node.

const sequence_t &asSequence() const
inline sequence_t asSequenceRange() const

Returns a copy of asSequence(), suitable for range-based loops.

map_t &asMap()

Use: for (auto &kv: n.asMap()) {...}

Throws:

std::exception – If called on a non-map node.

const map_t &asMap() const
inline map_t asMapRange() const

Returns a copy of asMap(), suitable for range-based loops.

scalar_t &asScalar()
Throws:

std::exception – If called on a non-scalar node.

const scalar_t &asScalar() const
size_t size() const

Returns 1 for null or scalar nodes, the number of children for sequence or map nodes.

inline node_t &node()

For a master yaml document, returns the root node; otherwise, the referenced node.

inline const node_t &node() const

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

const node_t &keyNode(const std::string &keyName) const

Maps only: returns a reference to the key node of a key-value pair.

Throws:

std::exception – If called on a non-map node or key does not exist.

node_t &keyNode(const std::string &keyName)

Print and export

void printAsYAML(std::ostream &o, const YamlEmitOptions &eo = {}) const

Prints the document in YAML format to the given stream.

void printAsYAML() const
void printDebugStructure(std::ostream &o) const

Prints a tree-like representation of all nodes in the document in a custom format (nor YAML neither JSON).

Read/write to maps (dictionaries)

yaml operator[](const std::string &key)

Write access for maps

inline yaml operator[](const char *key)

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

yaml operator[](const std::string &key) const

Read access for maps

Throws:

std::runtime_error – if key does not exist.

inline yaml operator[](const char *key) const

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

template<typename T>
inline T getOrDefault(const std::string &key, const T &defaultValue) const

Scalar read access for maps, with default value if key does not exist.

Getters / setters

template<typename T>
inline T as() const

Returns a copy of the existing value of the given type, or tries to convert it between easily-compatible types (e.g. double<->int, string<->int).

Throws:

std::exception – If the contained type does not match and there is no obvious conversion.

template<typename T>
T &asRef()

Returns a ref to the existing or new value of the given type. If types do not match, the old content will be discarded and a new variable created into this scalar node.

Throws:

std::exception – If accessing to a non-scalar node.

template<typename T>
const T &asRef() const

const version of asRef(). Unlike as<T>(), this version will NOT try to convert between types if T does not match exactly the stored type, and will raise an exception instead.

yaml &operator=(bool v)
yaml &operator=(float v)
yaml &operator=(double v)
yaml &operator=(int8_t v)
yaml &operator=(uint8_t v)
yaml &operator=(int16_t v)
yaml &operator=(uint16_t v)
yaml &operator=(int32_t v)
yaml &operator=(uint32_t v)
yaml &operator=(int64_t v)
yaml &operator=(uint64_t v)
template<typename = std::enable_if<!std::is_same_v<std::size_t, uint64_t> && !std::is_same_v<std::size_t, int64_t> && !std::is_same_v<std::size_t, uint32_t> && !std::is_same_v<std::size_t, int32_t>>>
inline yaml &operator=(std::size_t v)
yaml &operator=(const std::string &v)
inline yaml &operator=(const char *v)
inline yaml &operator=(const std::string_view &v)
yaml &operator=(const yaml &v)
template<typename T>
inline yaml &operator=(const ValueCommentPair<T> &vc)

vcp (value-comment) wrapper

template<typename T>
inline yaml &operator<<(const ValueKeyCommentPair<T> &vc)

vkcp (value-keyComment) wrapper

inline operator bool() const
inline operator double() const
inline operator float() const
inline operator int8_t() const
inline operator uint8_t() const
inline operator int16_t() const
inline operator uint16_t() const
inline operator int32_t() const
inline operator uint32_t() const
inline operator int64_t() const
inline operator uint64_t() const
inline operator std::string() const

Leaf node comments API

bool hasComment() const

Returns true if the proxied node has an associated comment block, at any location

bool hasComment(CommentPosition pos) const

Returns true if the proxied node has an associated comment block at a particular position

const std::string &comment() const

Gets the comment associated to the proxied node. This version returns the first comment, of all possible (top, right).

See also

hasComment()

Throws:

std::exception – If there is no comment attached.

const std::string &comment(CommentPosition pos) const

Gets the comment associated to the proxied node, at the particular position. See code examples in mrpt::containers::yaml.

See also

hasComment()

Throws:

std::exception – If there is no comment attached.

void comment(const std::string &c, CommentPosition position = CommentPosition::RIGHT)

Sets the comment attached to a given proxied node. See code examples in mrpt::containers::yaml

See also

hasComment()

Map key node comments API

bool keyHasComment(const std::string &key) const

Maps only: returns true if the given key node has an associated comment block, at any location.

Throws:

std::exception – If called on a non-map or key does not exist.

bool keyHasComment(const std::string &key, CommentPosition pos) const

Maps only: Returns true if the given key has an associated comment block at a particular position.

Throws:

std::exception – If called on a non-map or key does not exist.

const std::string &keyComment(const std::string &key) const

Maps only: Gets the comment associated to the given key. This version returns the first comment, of all possible (top, right).

See also

hasComment()

Throws:
  • std::exception – If called on a non-map or key does not exist.

  • std::exception – If there is no comment attached.

const std::string &keyComment(const std::string &key, CommentPosition pos) const

Maps only: Gets the comment associated to the given key, at the particular position. See code examples in mrpt::containers::yaml.

See also

hasComment()

Throws:
  • std::exception – If called on a non-map or key does not exist.

  • std::exception – If there is no comment attached.

void keyComment(const std::string &key, const std::string &c, CommentPosition position = CommentPosition::TOP)

Maps only: Sets the comment attached to a given key. See code examples in mrpt::containers::yaml

See also

hasComment()

Throws:

std::exception – If called on a non-map or key does not exist.

Public Functions

yaml operator()(int index)

Write into an existing index of a sequence.

Throws:

std::out_of_range – if index is out of range.

const yaml operator()(int index) const

Read from an existing index of a sequence.

Throws:

std::out_of_range – if index is out of range.

inline void push_back(double v)

Append a new value to a sequence.

Throws:

std::exception – If this is not a sequence

inline void push_back(const std::string &v)

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

inline void push_back(uint64_t v)

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

inline void push_back(bool v)

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

inline void push_back(const yaml &v)

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

struct mark_t

Public Members

std::size_t input_pos = 0

Position from the start of the input file.

int line = 0

Line position (0-based index)

int column = 0

Column position (0-based index)

struct node_t

Data

std::variant<std::monostate, sequence_t, map_t, scalar_t> d

Node data

comments_t comments

Optional comment block

bool printInShortFormat = false

Optional flag to print collections in short form (e.g. [A,B] for sequences)

Note

(New in MRPT 2.1.8)

mark_t marks

Positioning information about the placement of the element in the original input file/stream, i.e. line and column number

Note

(New in MRPT 2.5.0)

Public Functions

template<typename T, typename = std::enable_if_t<!std::is_constructible_v<std::initializer_list<map_t::value_type>, T>>, typename = std::enable_if_t<!std::is_constructible_v<std::initializer_list<sequence_t::value_type>, T>>>
inline node_t(const T &scalar)
inline node_t(const char *str)

Specialization for literals

node_t() = default
inline node_t(std::initializer_list<map_t::value_type> init)
inline node_t(std::initializer_list<sequence_t::value_type> init)
bool isNullNode() const
bool isScalar() const
bool isSequence() const
bool isMap() const
std::string typeName() const

Returns: “null”, “sequence”, “map”, “scalar(<TYPE>)”

sequence_t &asSequence()

Use: for (auto &kv: n.asSequence()) {...}

Throws:

std::exception – If called on a non-sequence node.

const sequence_t &asSequence() const
map_t &asMap()

Use: for (auto &kv: n.asMap()) {...}

Throws:

std::exception – If called on a non-map node.

const map_t &asMap() const
scalar_t &asScalar()
Throws:

std::exception – If called on a non-scalar node.

const scalar_t &asScalar() const
size_t size() const

Returns 1 for null or scalar nodes, the number of children for sequence or map nodes.

template<typename T>
inline T as() const

Returns a copy of the existing value of the given type, or tries to convert it between easily-compatible types (e.g. double<->int, string<->int).

Throws:

std::exception – If the contained type does not match and there is no obvious conversion.

inline std::string_view internalAsStr() const
inline bool hasComment() const
inline bool hasComment(CommentPosition pos) const
inline const std::string &comment() const
inline const std::string &comment(CommentPosition pos) const