rapidyaml 0.14.0
parse and emit YAML, and do it fast
Loading...
Searching...
No Matches
c4::yml::Tree Class Reference

#include <tree.hpp>

Classes

struct  lookup_result

Public Member Functions

id_type _claim ()
construction and assignment
 Tree ()
 Tree (Callbacks const &cb)
 Tree (id_type node_capacity, size_t arena_capacity=RYML_DEFAULT_TREE_ARENA_CAPACITY)
 Tree (id_type node_capacity, size_t arena_capacity, Callbacks const &cb)
 ~Tree ()
 Tree (Tree const &that)
 Tree (Tree &&that) noexcept
Treeoperator= (Tree const &that)
Treeoperator= (Tree &&that) noexcept
memory and sizing
void reserve (id_type node_capacity=RYML_DEFAULT_TREE_CAPACITY)
void clear ()
 clear the tree and zero every node
void clear_arena ()
bool empty () const
id_type size () const
id_type capacity () const
id_type slack () const
Callbacks const & callbacks () const
void callbacks (Callbacks const &cb)
node getters
id_type id (NodeData const *n) const
 get the index of a node belonging to this tree. n can be nullptr, in which case NONE is returned
NodeDataget (id_type node)
 get a pointer to a node's NodeData. i can be NONE, in which case a nullptr is returned
NodeData const * get (id_type node) const
 get a pointer to a node's NodeData. i can be NONE, in which case a nullptr is returned.
NodeData_p (id_type node)
 An if-less form of get() that demands a valid node index. This function is implementation only; use at your own risk.
NodeData const * _p (id_type node) const
 An if-less form of get() that demands a valid node index. This function is implementation only; use at your own risk.
id_type root_id () const
 Get the id of the root node. The tree must not be empty.
NodeRef ref (id_type node)
 Get a NodeRef of a node by id.
ConstNodeRef ref (id_type node) const
 Get a NodeRef of a node by id.
ConstNodeRef cref (id_type node) const
 Get a NodeRef of a node by id.
NodeRef rootref ()
 Get the root as a NodeRef.
ConstNodeRef rootref () const
 Get the root as a ConstNodeRef.
ConstNodeRef crootref () const
 Get the root as a ConstNodeRef.
NodeRef docref (id_type i)
 get the i-th document of the stream
ConstNodeRef docref (id_type i) const
 get the i-th document of the stream
ConstNodeRef cdocref (id_type i) const
 get the i-th document of the stream
NodeRef operator[] (csubstr key)
 find a root child (ie child of root) by name, return it as a NodeRef
ConstNodeRef operator[] (csubstr key) const
 find a root child (ie child of root) by name, return it as a NodeRef
NodeRef operator[] (id_type i)
 find a root child (ie child of root) by index: return the root node's i-th child as a NodeRef
ConstNodeRef operator[] (id_type i) const
 find a root child (ie child of root) by index: return the root node's i-th child as a NodeRef
node property getters
NodeType type (id_type node) const
const char * type_str (id_type node) const
csubstr const & key (id_type node) const
csubstr const & key_tag (id_type node) const
csubstr const & key_ref (id_type node) const
csubstr const & key_anchor (id_type node) const
NodeScalar const & keysc (id_type node) const
csubstr const & val (id_type node) const
csubstr const & val_tag (id_type node) const
csubstr const & val_ref (id_type node) const
csubstr const & val_anchor (id_type node) const
NodeScalar const & valsc (id_type node) const
node type predicates
bool type_has_any (id_type node, NodeType_e bits) const
bool type_has_all (id_type node, NodeType_e bits) const
bool type_has_none (id_type node, NodeType_e bits) const
bool is_stream (id_type node) const
bool is_doc (id_type node) const
bool is_container (id_type node) const
bool is_map (id_type node) const
bool is_seq (id_type node) const
bool has_key (id_type node) const
bool has_val (id_type node) const
bool is_val (id_type node) const
bool is_keyval (id_type node) const
bool has_key_tag (id_type node) const
bool has_val_tag (id_type node) const
bool has_key_anchor (id_type node) const
bool has_val_anchor (id_type node) const
bool has_anchor (id_type node) const
bool is_key_ref (id_type node) const
bool is_val_ref (id_type node) const
bool is_ref (id_type node) const
bool parent_is_seq (id_type node) const
bool parent_is_map (id_type node) const
bool has_anchor (id_type node, csubstr a) const
 true when the node has an anchor named a
bool key_is_null (id_type node) const
 true if the node key is empty, or its scalar verifies scalar_is_null().
bool val_is_null (id_type node) const
 true if the node val is empty, or its scalar verifies scalar_is_null().
bool is_key_unfiltered (id_type node) const
 true if the key was a scalar requiring filtering and was left unfiltered during the parsing (see ParserOptions)
bool is_val_unfiltered (id_type node) const
 true if the val was a scalar requiring filtering and was left unfiltered during the parsing (see ParserOptions)
bool is_key_anchor (id_type node) const
bool is_val_anchor (id_type node) const
bool is_anchor (id_type node) const
bool is_anchor_or_ref (id_type node) const
hierarchy getters
id_type parent (id_type node) const
id_type prev_sibling (id_type node) const
id_type next_sibling (id_type node) const
id_type num_children (id_type node) const
 O(num_children).
id_type child_pos (id_type node, id_type ch) const
id_type first_child (id_type node) const
id_type last_child (id_type node) const
id_type child (id_type node, id_type pos) const
id_type find_child (id_type node, csubstr const &key) const
id_type num_siblings (id_type node) const
 O(num_siblings).
id_type num_other_siblings (id_type node) const
 does not count with this
id_type sibling_pos (id_type node, id_type sib) const
id_type first_sibling (id_type node) const
id_type last_sibling (id_type node) const
id_type sibling (id_type node, id_type pos) const
id_type find_sibling (id_type node, csubstr const &key) const
id_type depth_asc (id_type node) const
 O(log(num_tree_nodes)) get the ascending depth of the node: number of levels between root and node.
id_type depth_desc (id_type node) const
 O(num_tree_nodes) get the descending depth of the node: number of levels between node and deepest child.
id_type doc (id_type i) const
 gets the i document node index.
id_type ancestor_doc (id_type node) const
 get the document which is a parent document of node i, or the root if the tree is not a stream
node style predicates and modifiers. see the corresponding predicate in NodeType
bool is_container_styled (id_type node) const
bool is_block (id_type node) const
bool is_flow_sl (id_type node) const
bool is_flow_ml (id_type node) const
bool is_flow (id_type node) const
bool is_key_styled (id_type node) const
bool is_val_styled (id_type node) const
bool is_key_literal (id_type node) const
bool is_val_literal (id_type node) const
bool is_key_folded (id_type node) const
bool is_val_folded (id_type node) const
bool is_key_squo (id_type node) const
bool is_val_squo (id_type node) const
bool is_key_dquo (id_type node) const
bool is_val_dquo (id_type node) const
bool is_key_plain (id_type node) const
bool is_val_plain (id_type node) const
bool is_key_quoted (id_type node) const
bool is_val_quoted (id_type node) const
bool is_quoted (id_type node) const
NodeType key_style (id_type node) const
NodeType val_style (id_type node) const
void set_container_style (id_type node, NodeType_e style)
void set_key_style (id_type node, NodeType_e style)
void set_val_style (id_type node, NodeType_e style)
void clear_style (id_type node, bool recurse=false)
void set_style_conditionally (id_type node, NodeType type_mask, NodeType rem_style_flags, NodeType add_style_flags, bool recurse=false)
node type modifiers
void to_keyval (id_type node, csubstr key, csubstr val, type_bits more_flags=0)
void to_map (id_type node, csubstr key, type_bits more_flags=0)
void to_seq (id_type node, csubstr key, type_bits more_flags=0)
void to_val (id_type node, csubstr val, type_bits more_flags=0)
void to_map (id_type node, type_bits more_flags=0)
void to_seq (id_type node, type_bits more_flags=0)
void to_doc (id_type node, type_bits more_flags=0)
void to_stream (id_type node, type_bits more_flags=0)
void set_key (id_type node, csubstr key)
void set_val (id_type node, csubstr val)
void set_key_tag (id_type node, csubstr tag)
void set_val_tag (id_type node, csubstr tag)
void set_key_anchor (id_type node, csubstr anchor)
void set_val_anchor (id_type node, csubstr anchor)
void set_key_ref (id_type node, csubstr ref)
void set_val_ref (id_type node, csubstr ref)
void rem_key_anchor (id_type node)
void rem_val_anchor (id_type node)
void rem_key_ref (id_type node)
void rem_val_ref (id_type node)
void rem_anchor_ref (id_type node)
tree modifiers
void reorder ()
 reorder the tree in memory so that all the nodes are stored in a linear sequence when visited in depth-first order.
anchors and references/aliases
void resolve (ReferenceResolver *rr, bool clear_anchors=true)
 Resolve references (aliases <- anchors), by forwarding to ReferenceResolver::resolve(); refer to ReferenceResolver::resolve() for further details.
void resolve (bool clear_anchors=true)
 Resolve references (aliases <- anchors), by forwarding to ReferenceResolver::resolve(); refer to ReferenceResolver::resolve() for further details.
tags and tag directives
void resolve_tags (TagCache &cache, bool all=true)
 Resolve tags in the tree such as "!!str" -> "<tag:yaml.org,2002:str>", "!foo" -> "<!foo>" and custom tags as well, ie tags of the form "!handle!tag" for which there is a corresponding "%TAG" directive.
void normalize_tags ()
void normalize_tags_long ()
id_type num_tag_directives () const
void add_tag_directive (csubstr handle, csubstr prefix, id_type id)
void clear_tag_directives ()
size_t resolve_tag (substr output, csubstr tag, id_type node_id) const
 resolve the given tag, appearing at node_id.
csubstr resolve_tag_sub (substr output, csubstr tag, id_type node_id) const
 Wrapper for Tree::resolve_tag(), returning a substring.
c4::yml::TagDirectiveRange tag_directives () const
modifying hierarchy
id_type insert_child (id_type parent, id_type after)
 create and insert a new child of parent.
id_type prepend_child (id_type parent)
 create and insert a node as the first child of parent
id_type append_child (id_type parent)
 create and insert a node as the last child of parent
id_type _append_child__unprotected (id_type parent)
id_type insert_sibling (id_type node, id_type after)
 create and insert a new sibling of n. insert after "after"
id_type prepend_sibling (id_type node)
 create and insert a node as the first node of parent
id_type append_sibling (id_type node)
void remove (id_type node)
 remove an entire branch at once: ie remove the children and the node itself
void remove_children (id_type node)
 remove all the node's children, but keep the node itself
bool change_type (id_type node, NodeType type)
 change the type of the node to one of MAP, SEQ or VAL.
bool change_type (id_type node, type_bits type)
void move (id_type node, id_type after)
 change the node's position in the parent
void move (id_type node, id_type new_parent, id_type after)
 change the node's parent and position
id_type move (Tree *src, id_type node, id_type new_parent, id_type after)
 change the node's parent and position to a different tree
void set_root_as_stream ()
 ensure the first node is a stream.
id_type duplicate (id_type node, id_type new_parent, id_type after)
 recursively duplicate a node from this tree into a new parent, placing it after one of its children
id_type duplicate (Tree const *src, id_type node, id_type new_parent, id_type after)
 recursively duplicate a node from a different tree into a new parent, placing it after one of its children
id_type duplicate_children (id_type node, id_type parent, id_type after)
 recursively duplicate the node's children (but not the node)
id_type duplicate_children (Tree const *src, id_type node, id_type parent, id_type after)
 recursively duplicate the node's children (but not the node), where the node is from a different tree
id_type duplicate_children_no_rep (id_type node, id_type parent, id_type after)
 duplicate the node's children (but not the node) in a new parent, but omit repetitions where a duplicated node has the same key (in maps) or value (in seqs).
id_type duplicate_children_no_rep (Tree const *src, id_type node, id_type parent, id_type after)
void duplicate_contents (id_type node, id_type where)
void duplicate_contents (Tree const *src, id_type node, id_type where)
void merge_with (Tree const *src, id_type src_node=NONE, id_type dst_root=NONE)
internal string arena
size_t arena_size () const
 get the current size of the tree's internal arena
size_t arena_capacity () const
 get the current capacity of the tree's internal arena
size_t arena_slack () const
 get the current slack of the tree's internal arena
size_t arena_pos () const
csubstr arena () const
 get the current arena
substr arena ()
 get the current arena
bool in_arena (csubstr s) const
 return true if the given substring is part of the tree's string arena
template<class T>
csubstr to_arena (T const &a)
 serialize the given variable to the tree's arena, growing it as needed to accomodate the serialization.
substr copy_to_arena (csubstr s)
 copy the given string to the tree's arena, growing the arena by the required size.
substr alloc_arena (size_t sz)
 grow the tree's string arena by the given size and return a substr of the added portion
void reserve_arena (size_t arena_cap=RYML_DEFAULT_TREE_ARENA_CAPACITY)
 ensure the tree's internal string arena is at least the given capacity
lookup
lookup_result lookup_path (csubstr path, id_type start=NONE) const
 for example foo.bar[0].baz
id_type lookup_path_or_modify (csubstr default_value, csubstr path, id_type start=NONE)
 defaulted lookup: lookup path; if the lookup fails, recursively modify the tree so that the corresponding lookup_path() would return the default value.
id_type lookup_path_or_modify (Tree const *src, id_type src_node, csubstr path, id_type start=NONE)
 defaulted lookup: lookup path; if the lookup fails, recursively modify the tree so that the corresponding lookup_path() would return the branch src_node (from the tree src).

Public Attributes

NodeDatam_buf
id_type m_cap
id_type m_size
id_type m_free_head
id_type m_free_tail
substr m_arena
size_t m_arena_pos
Callbacks m_callbacks
TagDirectives m_tag_directives

hierarchy predicates

bool is_root (id_type node) const
bool has_parent (id_type node) const
bool is_ancestor (id_type node, id_type ancestor) const
 true when ancestor is parent or parent of a parent of node
bool empty (id_type node) const
 true when key and val are empty, and has no children
bool has_child (id_type node, id_type ch) const
 true if node has a child with id ch
bool has_child (id_type node, csubstr key) const
 true if node has a child with key key
bool has_children (id_type node) const
 true if node has any children key
bool has_sibling (id_type node, id_type sib) const
 true if node has a sibling with id sib
bool has_sibling (id_type node, csubstr key) const
 true if one of the node's siblings has the given key
bool has_other_siblings (id_type node) const
 true if node is not a single child
static bool has_siblings (id_type)

locations

Location location (Parser const &p, id_type node) const
 Get the location of a node from the parse used to parse this tree.

Detailed Description

Definition at line 249 of file tree.hpp.

Constructor & Destructor Documentation

◆ Tree() [1/6]

c4::yml::Tree::Tree ( )
inline

Definition at line 256 of file tree.hpp.

256: Tree(get_callbacks()) {}
Callbacks const & get_callbacks()
get the global callbacks
Definition common.cpp:94

◆ Tree() [2/6]

c4::yml::Tree::Tree ( Callbacks const & cb)

Definition at line 119 of file tree.cpp.

121{
122}
#define RYML_DEFAULT_TREE_CAPACITY
default capacity for the tree when not set explicitly
Definition common.hpp:16
#define RYML_DEFAULT_TREE_ARENA_CAPACITY
default capacity for the tree's arena when not set explicitly
Definition common.hpp:21

◆ Tree() [3/6]

c4::yml::Tree::Tree ( id_type node_capacity,
size_t arena_capacity = RYML_DEFAULT_TREE_ARENA_CAPACITY )
inline

Definition at line 258 of file tree.hpp.

258: Tree(node_capacity, arena_capacity, get_callbacks()) {}
size_t arena_capacity() const
get the current capacity of the tree's internal arena
Definition tree.hpp:878

◆ Tree() [4/6]

c4::yml::Tree::Tree ( id_type node_capacity,
size_t arena_capacity,
Callbacks const & cb )

Definition at line 124 of file tree.cpp.

125 : m_buf(nullptr)
126 , m_cap(0)
127 , m_size(0)
130 , m_arena()
131 , m_arena_pos(0)
132 , m_callbacks(cb)
134{
135 if(node_capacity)
136 reserve(node_capacity);
139}
NodeData * m_buf
Definition tree.hpp:1331
id_type m_free_head
Definition tree.hpp:1335
void reserve_arena(size_t arena_cap=RYML_DEFAULT_TREE_ARENA_CAPACITY)
ensure the tree's internal string arena is at least the given capacity
Definition tree.hpp:973
size_t m_arena_pos
Definition tree.hpp:1339
void reserve(id_type node_capacity=RYML_DEFAULT_TREE_CAPACITY)
Definition tree.cpp:292
TagDirectives m_tag_directives
Definition tree.hpp:1343
id_type m_size
Definition tree.hpp:1333
id_type m_cap
Definition tree.hpp:1332
substr m_arena
Definition tree.hpp:1338
id_type m_free_tail
Definition tree.hpp:1336
Callbacks m_callbacks
Definition tree.hpp:1341
@ NONE
an index to none
Definition common.hpp:256

◆ ~Tree()

c4::yml::Tree::~Tree ( )

Definition at line 141 of file tree.cpp.

142{
143 _free();
144}

◆ Tree() [5/6]

c4::yml::Tree::Tree ( Tree const & that)

Definition at line 147 of file tree.cpp.

147 : m_callbacks(that.m_callbacks)
148{
149 _clear();
150 _copy(that);
151}

◆ Tree() [6/6]

c4::yml::Tree::Tree ( Tree && that)
noexcept

Definition at line 153 of file tree.cpp.

153 : m_callbacks(that.m_callbacks)
154{
155 _clear();
156 _move(that);
157}

Member Function Documentation

◆ operator=() [1/2]

Tree & c4::yml::Tree::operator= ( Tree const & that)

Definition at line 159 of file tree.cpp.

160{
161 if(&that != this)
162 {
163 _free();
164 m_callbacks = that.m_callbacks;
165 _copy(that);
166 }
167 return *this;
168}

◆ operator=() [2/2]

Tree & c4::yml::Tree::operator= ( Tree && that)
noexcept

Definition at line 170 of file tree.cpp.

171{
172 if(&that != this)
173 {
174 _free();
175 m_callbacks = that.m_callbacks;
176 _move(that);
177 }
178 return *this;
179}

◆ reserve()

void c4::yml::Tree::reserve ( id_type node_capacity = RYML_DEFAULT_TREE_CAPACITY)

Definition at line 292 of file tree.cpp.

293{
294 if(cap > m_cap)
295 {
296 NodeData *buf = _RYML_CB_ALLOC_HINT(m_callbacks, NodeData, (size_t)cap, m_buf);
297 if(m_buf)
298 {
299 memcpy(buf, m_buf, (size_t)m_cap * sizeof(NodeData));
300 _RYML_CB_FREE(m_callbacks, m_buf, NodeData, (size_t)m_cap);
301 }
302 id_type first = m_cap, del = cap - m_cap;
303 m_cap = cap;
304 m_buf = buf;
305 _clear_range(first, del);
306 if(m_free_head != NONE)
307 {
308 _RYML_ASSERT_VISIT_(m_callbacks, m_buf != nullptr, this, NONE);
309 _RYML_ASSERT_VISIT_(m_callbacks, m_free_tail != NONE, this, NONE);
310 m_buf[m_free_tail].m_next_sibling = first;
311 m_buf[first].m_prev_sibling = m_free_tail;
312 m_free_tail = cap-1;
313 }
314 else
315 {
316 _RYML_ASSERT_VISIT_(m_callbacks, m_free_tail == NONE, this, NONE);
317 m_free_head = first;
318 m_free_tail = cap-1;
319 }
320 _RYML_ASSERT_VISIT_(m_callbacks, m_free_head == NONE || (m_free_head >= 0 && m_free_head < cap), this, NONE);
321 _RYML_ASSERT_VISIT_(m_callbacks, m_free_tail == NONE || (m_free_tail >= 0 && m_free_tail < cap), this, NONE);
322
323 if( ! m_size)
324 _claim_root();
325 }
326}
RYML_ID_TYPE id_type
The type of a node id in the YAML tree; to override the default type, define the macro RYML_ID_TYPE t...
Definition common.hpp:249

◆ clear()

void c4::yml::Tree::clear ( )

clear the tree and zero every node

Note
does NOT clear the arena
See also
clear_arena()

Definition at line 330 of file tree.cpp.

331{
332 _clear_range(0, m_cap);
333 m_size = 0;
334 if(m_buf)
335 {
336 _RYML_ASSERT_VISIT_(m_callbacks, m_cap >= 0, this, NONE);
337 m_free_head = 0;
338 m_free_tail = m_cap-1;
339 _claim_root();
340 }
341 else
342 {
345 }
346 m_tag_directives.clear();
347}

◆ clear_arena()

void c4::yml::Tree::clear_arena ( )
inline

Definition at line 282 of file tree.hpp.

282{ m_arena_pos = 0; }

◆ empty() [1/2]

bool c4::yml::Tree::empty ( ) const
inline

Definition at line 284 of file tree.hpp.

284{ return m_size == 0; }

◆ size()

id_type c4::yml::Tree::size ( ) const
inline

Definition at line 286 of file tree.hpp.

286{ return m_size; }

◆ capacity()

id_type c4::yml::Tree::capacity ( ) const
inline

Definition at line 287 of file tree.hpp.

287{ return m_cap; }

◆ slack()

id_type c4::yml::Tree::slack ( ) const
inline

Definition at line 288 of file tree.hpp.

288{ _RYML_ASSERT_BASIC(m_cap >= m_size); return m_cap - m_size; }

◆ callbacks() [1/2]

Callbacks const & c4::yml::Tree::callbacks ( ) const
inline

Definition at line 290 of file tree.hpp.

290{ return m_callbacks; }

◆ callbacks() [2/2]

void c4::yml::Tree::callbacks ( Callbacks const & cb)
inline

Definition at line 291 of file tree.hpp.

291{ m_callbacks = cb; }

◆ id()

id_type c4::yml::Tree::id ( NodeData const * n) const
inline

get the index of a node belonging to this tree. n can be nullptr, in which case NONE is returned

Definition at line 302 of file tree.hpp.

303 {
304 if( ! n)
305 return NONE;
306 _RYML_ASSERT_VISIT_(m_callbacks, n >= m_buf && n < m_buf + m_cap, this, NONE);
307 return static_cast<id_type>(n - m_buf);
308 }

◆ get() [1/2]

NodeData * c4::yml::Tree::get ( id_type node)
inline

get a pointer to a node's NodeData. i can be NONE, in which case a nullptr is returned

Definition at line 312 of file tree.hpp.

313 {
314 if(node == NONE)
315 return nullptr;
316 _RYML_ASSERT_VISIT_(m_callbacks, node >= 0 && node < m_cap, this, node);
317 return m_buf + node;
318 }

◆ get() [2/2]

NodeData const * c4::yml::Tree::get ( id_type node) const
inline

get a pointer to a node's NodeData. i can be NONE, in which case a nullptr is returned.

Definition at line 321 of file tree.hpp.

322 {
323 if(node == NONE)
324 return nullptr;
325 _RYML_ASSERT_VISIT_(m_callbacks, node >= 0 && node < m_cap, this, node);
326 return m_buf + node;
327 }

◆ _p() [1/2]

NodeData * c4::yml::Tree::_p ( id_type node)
inline

An if-less form of get() that demands a valid node index. This function is implementation only; use at your own risk.

Definition at line 331 of file tree.hpp.

331{ _RYML_ASSERT_VISIT_(m_callbacks, node != NONE && node >= 0 && node < m_cap, this, node); return m_buf + node; } // NOLINT(readability-make-member-function-const)

◆ _p() [2/2]

NodeData const * c4::yml::Tree::_p ( id_type node) const
inline

An if-less form of get() that demands a valid node index. This function is implementation only; use at your own risk.

Definition at line 334 of file tree.hpp.

334{ _RYML_ASSERT_VISIT_(m_callbacks, node != NONE && node >= 0 && node < m_cap, this, node); return m_buf + node; }

◆ root_id()

id_type c4::yml::Tree::root_id ( ) const
inline

Get the id of the root node. The tree must not be empty.

Definition at line 337 of file tree.hpp.

337{ _RYML_ASSERT_VISIT_(m_callbacks, m_cap > 0 && m_size > 0, this, id_type(0)); return 0; }

◆ ref() [1/2]

NodeRef c4::yml::Tree::ref ( id_type node)

Get a NodeRef of a node by id.

Definition at line 70 of file tree.cpp.

71{
72 _RYML_ASSERT_VISIT_(m_callbacks, id != NONE && id >= 0 && id < m_cap, this, id);
73 return NodeRef(this, id);
74}

◆ ref() [2/2]

ConstNodeRef c4::yml::Tree::ref ( id_type node) const

Get a NodeRef of a node by id.

Definition at line 75 of file tree.cpp.

76{
77 _RYML_ASSERT_VISIT_(m_callbacks, id != NONE && id >= 0 && id < m_cap, this, id);
78 return ConstNodeRef(this, id);
79}

◆ cref()

ConstNodeRef c4::yml::Tree::cref ( id_type node) const

Get a NodeRef of a node by id.

Definition at line 80 of file tree.cpp.

81{
82 _RYML_ASSERT_VISIT_(m_callbacks, id != NONE && id >= 0 && id < m_cap, this, id);
83 return ConstNodeRef(this, id);
84}

◆ rootref() [1/2]

NodeRef c4::yml::Tree::rootref ( )

Get the root as a NodeRef.

Definition at line 56 of file tree.cpp.

57{
58 return NodeRef(this, root_id());
59}
id_type root_id() const
Get the id of the root node. The tree must not be empty.
Definition tree.hpp:337

◆ rootref() [2/2]

ConstNodeRef c4::yml::Tree::rootref ( ) const

Get the root as a ConstNodeRef.

Definition at line 60 of file tree.cpp.

61{
62 return ConstNodeRef(this, root_id());
63}

◆ crootref()

ConstNodeRef c4::yml::Tree::crootref ( ) const

Get the root as a ConstNodeRef.

Definition at line 65 of file tree.cpp.

66{
67 return ConstNodeRef(this, root_id());
68}

◆ docref() [1/2]

NodeRef c4::yml::Tree::docref ( id_type i)

get the i-th document of the stream

Note
i is NOT the node id, but the doc position within the stream

Definition at line 104 of file tree.cpp.

105{
106 return ref(doc(i));
107}
NodeRef ref(id_type node)
Get a NodeRef of a node by id.
Definition tree.cpp:70
id_type doc(id_type i) const
gets the i document node index.
Definition tree.hpp:532

◆ docref() [2/2]

ConstNodeRef c4::yml::Tree::docref ( id_type i) const

get the i-th document of the stream

Note
i is NOT the node id, but the doc position within the stream

Definition at line 108 of file tree.cpp.

109{
110 return cref(doc(i));
111}
ConstNodeRef cref(id_type node) const
Get a NodeRef of a node by id.
Definition tree.cpp:80

◆ cdocref()

ConstNodeRef c4::yml::Tree::cdocref ( id_type i) const

get the i-th document of the stream

Note
i is NOT the node id, but the doc position within the stream

Definition at line 112 of file tree.cpp.

113{
114 return cref(doc(i));
115}

◆ operator[]() [1/4]

NodeRef c4::yml::Tree::operator[] ( csubstr key)

find a root child (ie child of root) by name, return it as a NodeRef

Note
requires the root to be a map.

Definition at line 86 of file tree.cpp.

87{
88 return rootref()[key];
89}
csubstr const & key(id_type node) const
Definition tree.hpp:387
NodeRef rootref()
Get the root as a NodeRef.
Definition tree.cpp:56

◆ operator[]() [2/4]

ConstNodeRef c4::yml::Tree::operator[] ( csubstr key) const

find a root child (ie child of root) by name, return it as a NodeRef

Note
requires the root to be a map.

Definition at line 90 of file tree.cpp.

91{
92 return rootref()[key];
93}

◆ operator[]() [3/4]

NodeRef c4::yml::Tree::operator[] ( id_type i)

find a root child (ie child of root) by index: return the root node's i-th child as a NodeRef

Note
i is NOT the node id, but the child's position

Definition at line 95 of file tree.cpp.

96{
97 return rootref()[i];
98}

◆ operator[]() [4/4]

ConstNodeRef c4::yml::Tree::operator[] ( id_type i) const

find a root child (ie child of root) by index: return the root node's i-th child as a NodeRef

Note
i is NOT the node id, but the child's position

Definition at line 99 of file tree.cpp.

100{
101 return rootref()[i];
102}

◆ type()

NodeType c4::yml::Tree::type ( id_type node) const
inline

Definition at line 384 of file tree.hpp.

384{ return _p(node)->m_type; }
NodeData * _p(id_type node)
An if-less form of get() that demands a valid node index. This function is implementation only; use a...
Definition tree.hpp:331
NodeType m_type
Definition tree.hpp:231

◆ type_str()

const char * c4::yml::Tree::type_str ( id_type node) const
inline

Definition at line 385 of file tree.hpp.

385{ return NodeType::type_str(_p(node)->m_type); }
const char * type_str() const noexcept
return a preset string based on the node type

◆ key()

csubstr const & c4::yml::Tree::key ( id_type node) const
inline

Definition at line 387 of file tree.hpp.

387{ _RYML_ASSERT_VISIT_(m_callbacks, has_key(node), this, node); return _p(node)->m_key.scalar; }
bool has_key(id_type node) const
Definition tree.hpp:415
NodeScalar m_key
Definition tree.hpp:233

◆ key_tag()

csubstr const & c4::yml::Tree::key_tag ( id_type node) const
inline

Definition at line 388 of file tree.hpp.

388{ _RYML_ASSERT_VISIT_(m_callbacks, has_key_tag(node), this, node); return _p(node)->m_key.tag; }
bool has_key_tag(id_type node) const
Definition tree.hpp:419

◆ key_ref()

csubstr const & c4::yml::Tree::key_ref ( id_type node) const
inline

Definition at line 389 of file tree.hpp.

389{ _RYML_ASSERT_VISIT_(m_callbacks, is_key_ref(node), this, node); return _p(node)->m_key.anchor; }
bool is_key_ref(id_type node) const
Definition tree.hpp:424

◆ key_anchor()

csubstr const & c4::yml::Tree::key_anchor ( id_type node) const
inline

Definition at line 390 of file tree.hpp.

390{ _RYML_ASSERT_VISIT_(m_callbacks, has_key_anchor(node), this, node); return _p(node)->m_key.anchor; }
bool has_key_anchor(id_type node) const
Definition tree.hpp:421

◆ keysc()

NodeScalar const & c4::yml::Tree::keysc ( id_type node) const
inline

Definition at line 391 of file tree.hpp.

391{ _RYML_ASSERT_VISIT_(m_callbacks, has_key(node), this, node); return _p(node)->m_key; }

◆ val()

csubstr const & c4::yml::Tree::val ( id_type node) const
inline

Definition at line 393 of file tree.hpp.

393{ _RYML_ASSERT_VISIT_(m_callbacks, has_val(node), this, node); return _p(node)->m_val.scalar; }
bool has_val(id_type node) const
Definition tree.hpp:416
NodeScalar m_val
Definition tree.hpp:234

◆ val_tag()

csubstr const & c4::yml::Tree::val_tag ( id_type node) const
inline

Definition at line 394 of file tree.hpp.

394{ _RYML_ASSERT_VISIT_(m_callbacks, has_val_tag(node), this, node); return _p(node)->m_val.tag; }
bool has_val_tag(id_type node) const
Definition tree.hpp:420

◆ val_ref()

csubstr const & c4::yml::Tree::val_ref ( id_type node) const
inline

Definition at line 395 of file tree.hpp.

395{ _RYML_ASSERT_VISIT_(m_callbacks, is_val_ref(node), this, node); return _p(node)->m_val.anchor; }
bool is_val_ref(id_type node) const
Definition tree.hpp:425

◆ val_anchor()

csubstr const & c4::yml::Tree::val_anchor ( id_type node) const
inline

Definition at line 396 of file tree.hpp.

396{ _RYML_ASSERT_VISIT_(m_callbacks, has_val_anchor(node), this, node); return _p(node)->m_val.anchor; }
bool has_val_anchor(id_type node) const
Definition tree.hpp:422

◆ valsc()

NodeScalar const & c4::yml::Tree::valsc ( id_type node) const
inline

Definition at line 397 of file tree.hpp.

397{ _RYML_ASSERT_VISIT_(m_callbacks, has_val(node), this, node); return _p(node)->m_val; }

◆ type_has_any()

bool c4::yml::Tree::type_has_any ( id_type node,
NodeType_e bits ) const
inline

Definition at line 406 of file tree.hpp.

406{ return _p(node)->m_type.has_any(bits); }
bool has_any(NodeType_e t) const noexcept

◆ type_has_all()

bool c4::yml::Tree::type_has_all ( id_type node,
NodeType_e bits ) const
inline

Definition at line 407 of file tree.hpp.

407{ return _p(node)->m_type.has_all(bits); }
bool has_all(NodeType_e t) const noexcept

◆ type_has_none()

bool c4::yml::Tree::type_has_none ( id_type node,
NodeType_e bits ) const
inline

Definition at line 408 of file tree.hpp.

408{ return _p(node)->m_type.has_none(bits); }
bool has_none(NodeType_e t) const noexcept

◆ is_stream()

bool c4::yml::Tree::is_stream ( id_type node) const
inline

Definition at line 410 of file tree.hpp.

410{ return _p(node)->m_type.is_stream(); }
bool is_stream() const noexcept

◆ is_doc()

bool c4::yml::Tree::is_doc ( id_type node) const
inline

Definition at line 411 of file tree.hpp.

411{ return _p(node)->m_type.is_doc(); }
bool is_doc() const noexcept

◆ is_container()

bool c4::yml::Tree::is_container ( id_type node) const
inline

Definition at line 412 of file tree.hpp.

412{ return _p(node)->m_type.is_container(); }
bool is_container() const noexcept

◆ is_map()

bool c4::yml::Tree::is_map ( id_type node) const
inline

Definition at line 413 of file tree.hpp.

413{ return _p(node)->m_type.is_map(); }
bool is_map() const noexcept

◆ is_seq()

bool c4::yml::Tree::is_seq ( id_type node) const
inline

Definition at line 414 of file tree.hpp.

414{ return _p(node)->m_type.is_seq(); }
bool is_seq() const noexcept

◆ has_key()

bool c4::yml::Tree::has_key ( id_type node) const
inline

Definition at line 415 of file tree.hpp.

415{ return _p(node)->m_type.has_key(); }
bool has_key() const noexcept

◆ has_val()

bool c4::yml::Tree::has_val ( id_type node) const
inline

Definition at line 416 of file tree.hpp.

416{ return _p(node)->m_type.has_val(); }
bool has_val() const noexcept

◆ is_val()

bool c4::yml::Tree::is_val ( id_type node) const
inline

Definition at line 417 of file tree.hpp.

417{ return _p(node)->m_type.is_val(); }
bool is_val() const noexcept

◆ is_keyval()

bool c4::yml::Tree::is_keyval ( id_type node) const
inline

Definition at line 418 of file tree.hpp.

418{ return _p(node)->m_type.is_keyval(); }
bool is_keyval() const noexcept

◆ has_key_tag()

bool c4::yml::Tree::has_key_tag ( id_type node) const
inline

Definition at line 419 of file tree.hpp.

419{ return _p(node)->m_type.has_key_tag(); }
bool has_key_tag() const noexcept

◆ has_val_tag()

bool c4::yml::Tree::has_val_tag ( id_type node) const
inline

Definition at line 420 of file tree.hpp.

420{ return _p(node)->m_type.has_val_tag(); }
bool has_val_tag() const noexcept

◆ has_key_anchor()

bool c4::yml::Tree::has_key_anchor ( id_type node) const
inline

Definition at line 421 of file tree.hpp.

421{ return _p(node)->m_type.has_key_anchor(); }
bool has_key_anchor() const noexcept

◆ has_val_anchor()

bool c4::yml::Tree::has_val_anchor ( id_type node) const
inline

Definition at line 422 of file tree.hpp.

422{ return _p(node)->m_type.has_val_anchor(); }
bool has_val_anchor() const noexcept

◆ has_anchor() [1/2]

bool c4::yml::Tree::has_anchor ( id_type node) const
inline

Definition at line 423 of file tree.hpp.

423{ return _p(node)->m_type.has_anchor(); }
bool has_anchor() const noexcept

◆ is_key_ref()

bool c4::yml::Tree::is_key_ref ( id_type node) const
inline

Definition at line 424 of file tree.hpp.

424{ return _p(node)->m_type.is_key_ref(); }
bool is_key_ref() const noexcept

◆ is_val_ref()

bool c4::yml::Tree::is_val_ref ( id_type node) const
inline

Definition at line 425 of file tree.hpp.

425{ return _p(node)->m_type.is_val_ref(); }
bool is_val_ref() const noexcept

◆ is_ref()

bool c4::yml::Tree::is_ref ( id_type node) const
inline

Definition at line 426 of file tree.hpp.

426{ return _p(node)->m_type.is_ref(); }
bool is_ref() const noexcept

◆ parent_is_seq()

bool c4::yml::Tree::parent_is_seq ( id_type node) const
inline

Definition at line 428 of file tree.hpp.

428{ _RYML_ASSERT_VISIT_(m_callbacks, has_parent(node), this, node); return is_seq(_p(node)->m_parent); }
bool is_seq(id_type node) const
Definition tree.hpp:414
bool has_parent(id_type node) const
Definition tree.hpp:464

◆ parent_is_map()

bool c4::yml::Tree::parent_is_map ( id_type node) const
inline

Definition at line 429 of file tree.hpp.

429{ _RYML_ASSERT_VISIT_(m_callbacks, has_parent(node), this, node); return is_map(_p(node)->m_parent); }
bool is_map(id_type node) const
Definition tree.hpp:413

◆ has_anchor() [2/2]

bool c4::yml::Tree::has_anchor ( id_type node,
csubstr a ) const
inline

true when the node has an anchor named a

Definition at line 432 of file tree.hpp.

432{ return _p(node)->m_key.anchor == a || _p(node)->m_val.anchor == a; }

◆ key_is_null()

bool c4::yml::Tree::key_is_null ( id_type node) const
inline

true if the node key is empty, or its scalar verifies scalar_is_null().

Warning
the node must verify Tree::has_key() (asserted) (ie must be a member of a map)
See also
https://github.com/biojppm/rapidyaml/issues/413

Definition at line 437 of file tree.hpp.

437{ _RYML_ASSERT_VISIT_(m_callbacks, has_key(node), this, node); NodeData const* C4_RESTRICT n = _p(node); return !n->m_type.is_key_quoted() && (n->m_type.key_is_null() || scalar_is_null(n->m_key.scalar)); }
bool scalar_is_null(csubstr s) noexcept
YAML-sense query of nullity.

◆ val_is_null()

bool c4::yml::Tree::val_is_null ( id_type node) const
inline

true if the node val is empty, or its scalar verifies scalar_is_null().

Warning
the node must verify Tree::has_val() (asserted) (ie must be a scalar / must not be a container)
See also
https://github.com/biojppm/rapidyaml/issues/413

Definition at line 441 of file tree.hpp.

441{ _RYML_ASSERT_VISIT_(m_callbacks, has_val(node), this, node); NodeData const* C4_RESTRICT n = _p(node); return !n->m_type.is_val_quoted() && (n->m_type.val_is_null() || scalar_is_null(n->m_val.scalar)); }

◆ is_key_unfiltered()

bool c4::yml::Tree::is_key_unfiltered ( id_type node) const
inline

true if the key was a scalar requiring filtering and was left unfiltered during the parsing (see ParserOptions)

Definition at line 445 of file tree.hpp.

445{ return _p(node)->m_type.is_key_unfiltered(); }
bool is_key_unfiltered() const noexcept

◆ is_val_unfiltered()

bool c4::yml::Tree::is_val_unfiltered ( id_type node) const
inline

true if the val was a scalar requiring filtering and was left unfiltered during the parsing (see ParserOptions)

Definition at line 448 of file tree.hpp.

448{ return _p(node)->m_type.is_val_unfiltered(); }
bool is_val_unfiltered() const noexcept

◆ is_key_anchor()

bool c4::yml::Tree::is_key_anchor ( id_type node) const
inline

Definition at line 450 of file tree.hpp.

450{ return _p(node)->m_type.has_key_anchor(); }

◆ is_val_anchor()

bool c4::yml::Tree::is_val_anchor ( id_type node) const
inline

Definition at line 451 of file tree.hpp.

451{ return _p(node)->m_type.has_val_anchor(); }

◆ is_anchor()

bool c4::yml::Tree::is_anchor ( id_type node) const
inline

Definition at line 452 of file tree.hpp.

452{ return _p(node)->m_type.has_anchor(); }

◆ is_anchor_or_ref()

bool c4::yml::Tree::is_anchor_or_ref ( id_type node) const
inline

Definition at line 453 of file tree.hpp.

453{ return _p(node)->m_type.has_anchor() || _p(node)->m_type.is_ref(); }

◆ is_root()

bool c4::yml::Tree::is_root ( id_type node) const
inline

Definition at line 462 of file tree.hpp.

462{ _RYML_ASSERT_VISIT_(m_callbacks, _p(node)->m_parent != NONE || node == 0, this, node); return _p(node)->m_parent == NONE; }
id_type m_parent
Definition tree.hpp:236

◆ has_parent()

bool c4::yml::Tree::has_parent ( id_type node) const
inline

Definition at line 464 of file tree.hpp.

464{ return _p(node)->m_parent != NONE; }

◆ is_ancestor()

bool c4::yml::Tree::is_ancestor ( id_type node,
id_type ancestor ) const

true when ancestor is parent or parent of a parent of node

Definition at line 1317 of file tree.cpp.

1318{
1319 _RYML_ASSERT_VISIT_(m_callbacks, node != NONE, this, node);
1320 id_type p = parent(node);
1321 while(p != NONE)
1322 {
1323 if(p == ancestor)
1324 return true;
1325 p = parent(p);
1326 }
1327 return false;
1328}
id_type parent(id_type node) const
Definition tree.hpp:504

◆ empty() [2/2]

bool c4::yml::Tree::empty ( id_type node) const
inline

true when key and val are empty, and has no children

Definition at line 470 of file tree.hpp.

470{ return ! has_children(node) && _p(node)->m_key.empty() && (( ! (_p(node)->m_type & VAL)) || _p(node)->m_val.empty()); }
bool has_children(id_type node) const
true if node has any children key
Definition tree.hpp:477
@ VAL
a scalar: has a scalar (ie string) value, possibly empty. must be a leaf node, and cannot be MAP or S...
Definition node_type.hpp:38
bool empty() const noexcept
Definition tree.hpp:143

◆ has_child() [1/2]

bool c4::yml::Tree::has_child ( id_type node,
id_type ch ) const
inline

true if node has a child with id ch

Definition at line 473 of file tree.hpp.

473{ return _p(ch)->m_parent == node; }

◆ has_child() [2/2]

bool c4::yml::Tree::has_child ( id_type node,
csubstr key ) const
inline

true if node has a child with key key

Definition at line 475 of file tree.hpp.

475{ return find_child(node, key) != NONE; }
id_type find_child(id_type node, csubstr const &key) const
Definition tree.cpp:1257

◆ has_children()

bool c4::yml::Tree::has_children ( id_type node) const
inline

true if node has any children key

Definition at line 477 of file tree.hpp.

477{ return _p(node)->m_first_child != NONE; }
id_type m_first_child
Definition tree.hpp:237

◆ has_sibling() [1/2]

bool c4::yml::Tree::has_sibling ( id_type node,
id_type sib ) const
inline

true if node has a sibling with id sib

Definition at line 480 of file tree.hpp.

480{ return _p(node)->m_parent == _p(sib)->m_parent; }

◆ has_sibling() [2/2]

bool c4::yml::Tree::has_sibling ( id_type node,
csubstr key ) const
inline

true if one of the node's siblings has the given key

Definition at line 482 of file tree.hpp.

482{ return find_sibling(node, key) != NONE; }
id_type find_sibling(id_type node, csubstr const &key) const
Definition tree.hpp:526

◆ has_other_siblings()

bool c4::yml::Tree::has_other_siblings ( id_type node) const
inline

true if node is not a single child

Definition at line 484 of file tree.hpp.

485 {
486 NodeData const *n = _p(node);
487 if(C4_LIKELY(n->m_parent != NONE))
488 {
489 n = _p(n->m_parent);
490 return n->m_first_child != n->m_last_child;
491 }
492 return false;
493 }

◆ has_siblings()

bool c4::yml::Tree::has_siblings ( id_type )
inlinestatic

Definition at line 495 of file tree.hpp.

495{ return true; }

◆ parent()

id_type c4::yml::Tree::parent ( id_type node) const
inline

Definition at line 504 of file tree.hpp.

504{ return _p(node)->m_parent; }

◆ prev_sibling()

id_type c4::yml::Tree::prev_sibling ( id_type node) const
inline

Definition at line 506 of file tree.hpp.

506{ return _p(node)->m_prev_sibling; }
id_type m_prev_sibling
Definition tree.hpp:240

◆ next_sibling()

id_type c4::yml::Tree::next_sibling ( id_type node) const
inline

Definition at line 507 of file tree.hpp.

507{ return _p(node)->m_next_sibling; }
id_type m_next_sibling
Definition tree.hpp:239

◆ num_children()

id_type c4::yml::Tree::num_children ( id_type node) const

O(num_children).

Definition at line 1212 of file tree.cpp.

1213{
1214 id_type count = 0;
1215 for(id_type i = first_child(node); i != NONE; i = next_sibling(i))
1216 ++count;
1217 return count;
1218}
id_type first_child(id_type node) const
Definition tree.hpp:512
id_type next_sibling(id_type node) const
Definition tree.hpp:507

◆ child_pos()

id_type c4::yml::Tree::child_pos ( id_type node,
id_type ch ) const

Definition at line 1232 of file tree.cpp.

1233{
1234 _RYML_ASSERT_VISIT_(m_callbacks, node != NONE, this, node);
1235 id_type count = 0;
1236 for(id_type i = first_child(node); i != NONE; i = next_sibling(i))
1237 {
1238 if(i == ch)
1239 return count;
1240 ++count;
1241 }
1242 return NONE;
1243}

◆ first_child()

id_type c4::yml::Tree::first_child ( id_type node) const
inline

Definition at line 512 of file tree.hpp.

512{ return _p(node)->m_first_child; }

◆ last_child()

id_type c4::yml::Tree::last_child ( id_type node) const
inline

Definition at line 513 of file tree.hpp.

513{ return _p(node)->m_last_child; }
id_type m_last_child
Definition tree.hpp:238

◆ child()

id_type c4::yml::Tree::child ( id_type node,
id_type pos ) const

Definition at line 1220 of file tree.cpp.

1221{
1222 _RYML_ASSERT_VISIT_(m_callbacks, node != NONE, this, node);
1223 id_type count = 0;
1224 for(id_type i = first_child(node); i != NONE; i = next_sibling(i))
1225 {
1226 if(count++ == pos)
1227 return i;
1228 }
1229 return NONE;
1230}

◆ find_child()

id_type c4::yml::Tree::find_child ( id_type node,
csubstr const & key ) const

Definition at line 1257 of file tree.cpp.

1258{
1259 _RYML_ASSERT_VISIT_(m_callbacks, node != NONE, this, node);
1260 _RYML_ASSERT_VISIT_(m_callbacks, is_map(node), this, node);
1261 if(get(node)->m_first_child == NONE)
1262 {
1263 _RYML_ASSERT_VISIT_(m_callbacks, _p(node)->m_last_child == NONE, this, node);
1264 return NONE;
1265 }
1266 else
1267 {
1268 _RYML_ASSERT_VISIT_(m_callbacks, _p(node)->m_last_child != NONE, this, node);
1269 }
1270 for(id_type i = first_child(node); i != NONE; i = next_sibling(i))
1271 {
1272 if(_p(i)->m_key.scalar == name)
1273 {
1274 return i;
1275 }
1276 }
1277 return NONE;
1278}
NodeData * get(id_type node)
get a pointer to a node's NodeData. i can be NONE, in which case a nullptr is returned
Definition tree.hpp:312

◆ num_siblings()

id_type c4::yml::Tree::num_siblings ( id_type node) const
inline

O(num_siblings).

counts with this

Definition at line 519 of file tree.hpp.

519{ return is_root(node) ? 1 : num_children(_p(node)->m_parent); }
bool is_root(id_type node) const
Definition tree.hpp:462
id_type num_children(id_type node) const
O(num_children).
Definition tree.cpp:1212

◆ num_other_siblings()

id_type c4::yml::Tree::num_other_siblings ( id_type node) const
inline

does not count with this

Definition at line 521 of file tree.hpp.

521{ id_type ns = num_siblings(node); _RYML_ASSERT_VISIT_(m_callbacks, ns > 0, this, node); return ns-1; }
id_type num_siblings(id_type node) const
O(num_siblings).
Definition tree.hpp:519

◆ sibling_pos()

id_type c4::yml::Tree::sibling_pos ( id_type node,
id_type sib ) const
inline

Definition at line 522 of file tree.hpp.

522{ _RYML_ASSERT_VISIT_(m_callbacks, ! is_root(node) || node == root_id(), this, node); return child_pos(_p(node)->m_parent, sib); }
id_type child_pos(id_type node, id_type ch) const
Definition tree.cpp:1232

◆ first_sibling()

id_type c4::yml::Tree::first_sibling ( id_type node) const
inline

Definition at line 523 of file tree.hpp.

523{ return is_root(node) ? node : _p(_p(node)->m_parent)->m_first_child; }

◆ last_sibling()

id_type c4::yml::Tree::last_sibling ( id_type node) const
inline

Definition at line 524 of file tree.hpp.

524{ return is_root(node) ? node : _p(_p(node)->m_parent)->m_last_child; }

◆ sibling()

id_type c4::yml::Tree::sibling ( id_type node,
id_type pos ) const
inline

Definition at line 525 of file tree.hpp.

525{ return child(_p(node)->m_parent, pos); }
id_type child(id_type node, id_type pos) const
Definition tree.cpp:1220

◆ find_sibling()

id_type c4::yml::Tree::find_sibling ( id_type node,
csubstr const & key ) const
inline

Definition at line 526 of file tree.hpp.

526{ return find_child(_p(node)->m_parent, key); }

◆ depth_asc()

id_type c4::yml::Tree::depth_asc ( id_type node) const

O(log(num_tree_nodes)) get the ascending depth of the node: number of levels between root and node.

Definition at line 1305 of file tree.cpp.

1306{
1307 _RYML_ASSERT_VISIT_(m_callbacks, node != NONE, this, node);
1308 id_type depth = 0;
1309 while(!is_root(node))
1310 {
1311 ++depth;
1312 node = parent(node);
1313 }
1314 return depth;
1315}

◆ depth_desc()

id_type c4::yml::Tree::depth_desc ( id_type node) const

O(num_tree_nodes) get the descending depth of the node: number of levels between node and deepest child.

Definition at line 1299 of file tree.cpp.

1300{
1301 _RYML_ASSERT_VISIT_(m_callbacks, node != NONE, this, node);
1302 return depth_desc_(*this, node);
1303}

◆ doc()

id_type c4::yml::Tree::doc ( id_type i) const
inline

gets the i document node index.

requires that the root node is a stream.

Definition at line 532 of file tree.hpp.

532{ id_type rid = root_id(); _RYML_ASSERT_VISIT_(m_callbacks, is_stream(rid), this, rid); return child(rid, i); }
bool is_stream(id_type node) const
Definition tree.hpp:410

◆ ancestor_doc()

id_type c4::yml::Tree::ancestor_doc ( id_type node) const
inline

get the document which is a parent document of node i, or the root if the tree is not a stream

Definition at line 535 of file tree.hpp.

536 {
537 NodeData const *nd;
538 do
539 {
540 nd = _p(node);
541 if(nd->m_type.is_doc() || nd->m_parent == NONE)
542 break;
543 node = nd->m_parent;
544 } while(nd->m_parent != NONE);
545 return node;
546 }

◆ is_container_styled()

bool c4::yml::Tree::is_container_styled ( id_type node) const
inline

Definition at line 555 of file tree.hpp.

555{ return _p(node)->m_type.is_container_styled(); }
bool is_container_styled() const noexcept

◆ is_block()

bool c4::yml::Tree::is_block ( id_type node) const
inline

Definition at line 556 of file tree.hpp.

556{ return _p(node)->m_type.is_block(); }
bool is_block() const noexcept

◆ is_flow_sl()

bool c4::yml::Tree::is_flow_sl ( id_type node) const
inline

Definition at line 557 of file tree.hpp.

557{ return _p(node)->m_type.is_flow_sl(); }
bool is_flow_sl() const noexcept

◆ is_flow_ml()

bool c4::yml::Tree::is_flow_ml ( id_type node) const
inline

Definition at line 558 of file tree.hpp.

558{ return _p(node)->m_type.is_flow_ml(); }
bool is_flow_ml() const noexcept

◆ is_flow()

bool c4::yml::Tree::is_flow ( id_type node) const
inline

Definition at line 559 of file tree.hpp.

559{ return _p(node)->m_type.is_flow(); }
bool is_flow() const noexcept

◆ is_key_styled()

bool c4::yml::Tree::is_key_styled ( id_type node) const
inline

Definition at line 561 of file tree.hpp.

561{ return _p(node)->m_type.is_key_styled(); }
bool is_key_styled() const noexcept

◆ is_val_styled()

bool c4::yml::Tree::is_val_styled ( id_type node) const
inline

Definition at line 562 of file tree.hpp.

562{ return _p(node)->m_type.is_val_styled(); }
bool is_val_styled() const noexcept

◆ is_key_literal()

bool c4::yml::Tree::is_key_literal ( id_type node) const
inline

Definition at line 563 of file tree.hpp.

563{ return _p(node)->m_type.is_key_literal(); }
bool is_key_literal() const noexcept

◆ is_val_literal()

bool c4::yml::Tree::is_val_literal ( id_type node) const
inline

Definition at line 564 of file tree.hpp.

564{ return _p(node)->m_type.is_val_literal(); }
bool is_val_literal() const noexcept

◆ is_key_folded()

bool c4::yml::Tree::is_key_folded ( id_type node) const
inline

Definition at line 565 of file tree.hpp.

565{ return _p(node)->m_type.is_key_folded(); }
bool is_key_folded() const noexcept

◆ is_val_folded()

bool c4::yml::Tree::is_val_folded ( id_type node) const
inline

Definition at line 566 of file tree.hpp.

566{ return _p(node)->m_type.is_val_folded(); }
bool is_val_folded() const noexcept

◆ is_key_squo()

bool c4::yml::Tree::is_key_squo ( id_type node) const
inline

Definition at line 567 of file tree.hpp.

567{ return _p(node)->m_type.is_key_squo(); }
bool is_key_squo() const noexcept

◆ is_val_squo()

bool c4::yml::Tree::is_val_squo ( id_type node) const
inline

Definition at line 568 of file tree.hpp.

568{ return _p(node)->m_type.is_val_squo(); }
bool is_val_squo() const noexcept

◆ is_key_dquo()

bool c4::yml::Tree::is_key_dquo ( id_type node) const
inline

Definition at line 569 of file tree.hpp.

569{ return _p(node)->m_type.is_key_dquo(); }
bool is_key_dquo() const noexcept

◆ is_val_dquo()

bool c4::yml::Tree::is_val_dquo ( id_type node) const
inline

Definition at line 570 of file tree.hpp.

570{ return _p(node)->m_type.is_val_dquo(); }
bool is_val_dquo() const noexcept

◆ is_key_plain()

bool c4::yml::Tree::is_key_plain ( id_type node) const
inline

Definition at line 571 of file tree.hpp.

571{ return _p(node)->m_type.is_key_plain(); }
bool is_key_plain() const noexcept

◆ is_val_plain()

bool c4::yml::Tree::is_val_plain ( id_type node) const
inline

Definition at line 572 of file tree.hpp.

572{ return _p(node)->m_type.is_val_plain(); }
bool is_val_plain() const noexcept

◆ is_key_quoted()

bool c4::yml::Tree::is_key_quoted ( id_type node) const
inline

Definition at line 573 of file tree.hpp.

573{ return _p(node)->m_type.is_key_quoted(); }
bool is_key_quoted() const noexcept

◆ is_val_quoted()

bool c4::yml::Tree::is_val_quoted ( id_type node) const
inline

Definition at line 574 of file tree.hpp.

574{ return _p(node)->m_type.is_val_quoted(); }
bool is_val_quoted() const noexcept

◆ is_quoted()

bool c4::yml::Tree::is_quoted ( id_type node) const
inline

Definition at line 575 of file tree.hpp.

575{ return _p(node)->m_type.is_quoted(); }
bool is_quoted() const noexcept

◆ key_style()

NodeType c4::yml::Tree::key_style ( id_type node) const
inline

Definition at line 577 of file tree.hpp.

577{ _RYML_ASSERT_VISIT_(m_callbacks, has_key(node), this, node); return _p(node)->m_type.key_style(); }
NodeType key_style() const noexcept

◆ val_style()

NodeType c4::yml::Tree::val_style ( id_type node) const
inline

Definition at line 578 of file tree.hpp.

578{ _RYML_ASSERT_VISIT_(m_callbacks, has_val(node) || is_root(node), this, node); return _p(node)->m_type.val_style(); }
NodeType val_style() const noexcept

◆ set_container_style()

void c4::yml::Tree::set_container_style ( id_type node,
NodeType_e style )
inline

Definition at line 580 of file tree.hpp.

580{ _RYML_ASSERT_VISIT_(m_callbacks, is_container(node), this, node); _p(node)->m_type.set_container_style(style); }
bool is_container(id_type node) const
Definition tree.hpp:412
void set_container_style(NodeType_e style) noexcept

◆ set_key_style()

void c4::yml::Tree::set_key_style ( id_type node,
NodeType_e style )
inline

Definition at line 581 of file tree.hpp.

581{ _RYML_ASSERT_VISIT_(m_callbacks, has_key(node), this, node); _p(node)->m_type.set_key_style(style); }
void set_key_style(NodeType_e style) noexcept

◆ set_val_style()

void c4::yml::Tree::set_val_style ( id_type node,
NodeType_e style )
inline

Definition at line 582 of file tree.hpp.

582{ _RYML_ASSERT_VISIT_(m_callbacks, has_val(node), this, node); _p(node)->m_type.set_val_style(style); }
void set_val_style(NodeType_e style) noexcept

◆ clear_style()

void c4::yml::Tree::clear_style ( id_type node,
bool recurse = false )

Definition at line 1406 of file tree.cpp.

1407{
1408 NodeData *C4_RESTRICT d = _p(node);
1409 d->m_type.clear_style();
1410 if(!recurse)
1411 return;
1412 for(id_type child = d->m_first_child; child != NONE; child = next_sibling(child))
1413 clear_style(child, recurse);
1414}
void clear_style(id_type node, bool recurse=false)
Definition tree.cpp:1406

◆ set_style_conditionally()

void c4::yml::Tree::set_style_conditionally ( id_type node,
NodeType type_mask,
NodeType rem_style_flags,
NodeType add_style_flags,
bool recurse = false )

Definition at line 1416 of file tree.cpp.

1421{
1422 NodeData *C4_RESTRICT d = _p(node);
1423 if((d->m_type & type_mask) == type_mask)
1424 {
1425 d->m_type &= ~(NodeType)rem_style_flags;
1426 d->m_type |= (NodeType)add_style_flags;
1427 }
1428 if(!recurse)
1429 return;
1430 for(id_type child = d->m_first_child; child != NONE; child = next_sibling(child))
1431 set_style_conditionally(child, type_mask, rem_style_flags, add_style_flags, recurse);
1432}
void set_style_conditionally(id_type node, NodeType type_mask, NodeType rem_style_flags, NodeType add_style_flags, bool recurse=false)
Definition tree.cpp:1416

◆ to_keyval()

void c4::yml::Tree::to_keyval ( id_type node,
csubstr key,
csubstr val,
type_bits more_flags = 0 )

Definition at line 1342 of file tree.cpp.

1343{
1344 _RYML_ASSERT_VISIT_(m_callbacks, ! has_children(node), this, node);
1345 _RYML_ASSERT_VISIT_(m_callbacks, parent(node) == NONE || parent_is_map(node), this, node);
1346 _set_flags(node, KEYVAL|more_flags);
1347 _p(node)->m_key = key;
1348 _p(node)->m_val = val;
1349}
csubstr const & val(id_type node) const
Definition tree.hpp:393
bool parent_is_map(id_type node) const
Definition tree.hpp:429

◆ to_map() [1/2]

void c4::yml::Tree::to_map ( id_type node,
csubstr key,
type_bits more_flags = 0 )

Definition at line 1360 of file tree.cpp.

1361{
1362 _RYML_ASSERT_VISIT_(m_callbacks, ! has_children(node), this, node);
1363 _RYML_ASSERT_VISIT_(m_callbacks, parent(node) == NONE || parent_is_map(node), this, node);
1364 _set_flags(node, KEY|MAP|more_flags);
1365 _p(node)->m_key = key;
1366 _p(node)->m_val.clear();
1367}
@ MAP
a map: a parent of KEYVAL/KEYSEQ/KEYMAP nodes
Definition node_type.hpp:39
@ KEY
is member of a map
Definition node_type.hpp:37
void clear() noexcept
Definition tree.hpp:145

◆ to_seq() [1/2]

void c4::yml::Tree::to_seq ( id_type node,
csubstr key,
type_bits more_flags = 0 )

Definition at line 1378 of file tree.cpp.

1379{
1380 _RYML_ASSERT_VISIT_(m_callbacks, ! has_children(node), this, node);
1381 _RYML_ASSERT_VISIT_(m_callbacks, parent(node) == NONE || parent_is_map(node), this, node);
1382 _set_flags(node, KEY|SEQ|more_flags);
1383 _p(node)->m_key = key;
1384 _p(node)->m_val.clear();
1385}
@ SEQ
a seq: a parent of VAL/SEQ/MAP nodes
Definition node_type.hpp:40

◆ to_val()

void c4::yml::Tree::to_val ( id_type node,
csubstr val,
type_bits more_flags = 0 )

Definition at line 1333 of file tree.cpp.

1334{
1335 _RYML_ASSERT_VISIT_(m_callbacks, ! has_children(node), this, node);
1336 _RYML_ASSERT_VISIT_(m_callbacks, parent(node) == NONE || ! parent_is_map(node), this, node);
1337 _set_flags(node, VAL|more_flags);
1338 _p(node)->m_key.clear();
1339 _p(node)->m_val = val;
1340}

◆ to_map() [2/2]

void c4::yml::Tree::to_map ( id_type node,
type_bits more_flags = 0 )

Definition at line 1351 of file tree.cpp.

1352{
1353 _RYML_ASSERT_VISIT_(m_callbacks, ! has_children(node), this, node);
1354 _RYML_ASSERT_VISIT_(m_callbacks, parent(node) == NONE || ! parent_is_map(node), this, node); // parent must not have children with keys
1355 _set_flags(node, MAP|more_flags);
1356 _p(node)->m_key.clear();
1357 _p(node)->m_val.clear();
1358}

◆ to_seq() [2/2]

void c4::yml::Tree::to_seq ( id_type node,
type_bits more_flags = 0 )

Definition at line 1369 of file tree.cpp.

1370{
1371 _RYML_ASSERT_VISIT_(m_callbacks, ! has_children(node), this, node);
1372 _RYML_ASSERT_VISIT_(m_callbacks, parent(node) == NONE || parent_is_seq(node), this, node);
1373 _set_flags(node, SEQ|more_flags);
1374 _p(node)->m_key.clear();
1375 _p(node)->m_val.clear();
1376}
bool parent_is_seq(id_type node) const
Definition tree.hpp:428

◆ to_doc()

void c4::yml::Tree::to_doc ( id_type node,
type_bits more_flags = 0 )

Definition at line 1387 of file tree.cpp.

1388{
1389 _RYML_ASSERT_VISIT_(m_callbacks, ! has_children(node), this, node);
1390 _set_flags(node, DOC|more_flags);
1391 _p(node)->m_key.clear();
1392 _p(node)->m_val.clear();
1393}
@ DOC
a document
Definition node_type.hpp:41

◆ to_stream()

void c4::yml::Tree::to_stream ( id_type node,
type_bits more_flags = 0 )

Definition at line 1395 of file tree.cpp.

1396{
1397 _RYML_ASSERT_VISIT_(m_callbacks, ! has_children(node), this, node);
1398 _set_flags(node, STREAM|more_flags);
1399 _p(node)->m_key.clear();
1400 _p(node)->m_val.clear();
1401}
@ STREAM
a stream: a seq of docs
Definition node_type.hpp:42

◆ set_key()

void c4::yml::Tree::set_key ( id_type node,
csubstr key )
inline

Definition at line 606 of file tree.hpp.

606{ _RYML_ASSERT_VISIT_(m_callbacks, has_key(node), this, node); _p(node)->m_key.scalar = key; }

◆ set_val()

void c4::yml::Tree::set_val ( id_type node,
csubstr val )
inline

Definition at line 607 of file tree.hpp.

607{ _RYML_ASSERT_VISIT_(m_callbacks, has_val(node), this, node); _p(node)->m_val.scalar = val; }

◆ set_key_tag()

void c4::yml::Tree::set_key_tag ( id_type node,
csubstr tag )
inline

Definition at line 609 of file tree.hpp.

609{ _RYML_ASSERT_VISIT_(m_callbacks, has_key(node), this, node); _p(node)->m_key.tag = tag; _add_flags(node, KEYTAG); }
@ KEYTAG
the key has a tag
Definition node_type.hpp:47

◆ set_val_tag()

void c4::yml::Tree::set_val_tag ( id_type node,
csubstr tag )
inline

Definition at line 610 of file tree.hpp.

610{ _RYML_ASSERT_VISIT_(m_callbacks, has_val(node) || is_container(node), this, node); _p(node)->m_val.tag = tag; _add_flags(node, VALTAG); }
@ VALTAG
the val has a tag
Definition node_type.hpp:48

◆ set_key_anchor()

void c4::yml::Tree::set_key_anchor ( id_type node,
csubstr anchor )
inline

Definition at line 612 of file tree.hpp.

612{ _RYML_ASSERT_VISIT_(m_callbacks, ! is_key_ref(node), this, node); _p(node)->m_key.anchor = anchor.triml('&'); _add_flags(node, KEYANCH); }
@ KEYANCH
the key has an &anchor
Definition node_type.hpp:45
basic_substring triml(const C c) const
trim left
Definition substr.hpp:630

◆ set_val_anchor()

void c4::yml::Tree::set_val_anchor ( id_type node,
csubstr anchor )
inline

Definition at line 613 of file tree.hpp.

613{ _RYML_ASSERT_VISIT_(m_callbacks, ! is_val_ref(node), this, node); _p(node)->m_val.anchor = anchor.triml('&'); _add_flags(node, VALANCH); }
@ VALANCH
the val has an &anchor
Definition node_type.hpp:46

◆ set_key_ref()

void c4::yml::Tree::set_key_ref ( id_type node,
csubstr ref )
inline

Definition at line 614 of file tree.hpp.

614{ _RYML_ASSERT_VISIT_(m_callbacks, ! has_key_anchor(node), this, node); NodeData* C4_RESTRICT n = _p(node); n->m_key.set_ref_maybe_replacing_scalar(ref, n->m_type.has_key()); _add_flags(node, KEY|KEYREF); }
@ KEYREF
a *reference: the key references an &anchor
Definition node_type.hpp:43

◆ set_val_ref()

void c4::yml::Tree::set_val_ref ( id_type node,
csubstr ref )
inline

Definition at line 615 of file tree.hpp.

615{ _RYML_ASSERT_VISIT_(m_callbacks, ! has_val_anchor(node), this, node); NodeData* C4_RESTRICT n = _p(node); n->m_val.set_ref_maybe_replacing_scalar(ref, n->m_type.has_val()); _add_flags(node, VAL|VALREF); }
@ VALREF
a *reference: the val references an &anchor
Definition node_type.hpp:44

◆ rem_key_anchor()

void c4::yml::Tree::rem_key_anchor ( id_type node)
inline

Definition at line 617 of file tree.hpp.

617{ _p(node)->m_key.anchor.clear(); _rem_flags(node, KEYANCH); }
void clear() noexcept
Definition substr.hpp:265

◆ rem_val_anchor()

void c4::yml::Tree::rem_val_anchor ( id_type node)
inline

Definition at line 618 of file tree.hpp.

618{ _p(node)->m_val.anchor.clear(); _rem_flags(node, VALANCH); }

◆ rem_key_ref()

void c4::yml::Tree::rem_key_ref ( id_type node)
inline

Definition at line 619 of file tree.hpp.

619{ _p(node)->m_key.anchor.clear(); _rem_flags(node, KEYREF); }

◆ rem_val_ref()

void c4::yml::Tree::rem_val_ref ( id_type node)
inline

Definition at line 620 of file tree.hpp.

620{ _p(node)->m_val.anchor.clear(); _rem_flags(node, VALREF); }

◆ rem_anchor_ref()

void c4::yml::Tree::rem_anchor_ref ( id_type node)
inline

Definition at line 621 of file tree.hpp.

621{ _p(node)->m_key.anchor.clear(); _p(node)->m_val.anchor.clear(); _rem_flags(node, KEYANCH|VALANCH|KEYREF|VALREF); }

◆ reorder()

void c4::yml::Tree::reorder ( )

reorder the tree in memory so that all the nodes are stored in a linear sequence when visited in depth-first order.

This will invalidate existing ids, since the node id is its position in the tree's node array.

Definition at line 576 of file tree.cpp.

577{
578 id_type r = root_id();
579 _do_reorder(&r, 0);
580}

◆ resolve() [1/2]

void c4::yml::Tree::resolve ( ReferenceResolver * rr,
bool clear_anchors = true )

Resolve references (aliases <- anchors), by forwarding to ReferenceResolver::resolve(); refer to ReferenceResolver::resolve() for further details.

Definition at line 1202 of file tree.cpp.

1203{
1204 if(m_size == 0)
1205 return;
1206 rr->resolve(this, clear_anchors);
1207}

◆ resolve() [2/2]

void c4::yml::Tree::resolve ( bool clear_anchors = true)

Resolve references (aliases <- anchors), by forwarding to ReferenceResolver::resolve(); refer to ReferenceResolver::resolve() for further details.

This overload uses a throwaway resolver object.

Definition at line 1194 of file tree.cpp.

1195{
1196 if(m_size == 0)
1197 return;
1198 ReferenceResolver rr;
1199 resolve(&rr, clear_anchors);
1200}
void resolve(ReferenceResolver *rr, bool clear_anchors=true)
Resolve references (aliases <- anchors), by forwarding to ReferenceResolver::resolve(); refer to Refe...
Definition tree.cpp:1202

◆ resolve_tags()

void c4::yml::Tree::resolve_tags ( TagCache & cache,
bool all = true )

Resolve tags in the tree such as "!!str" -> "<tag:yaml.org,2002:str>", "!foo" -> "<!foo>" and custom tags as well, ie tags of the form "!handle!tag" for which there is a corresponding "%TAG" directive.

Parameters
cachean object of type TagCache to minimize memory usage by avoiding repeated instantiation of the resolved tags in the tree's arena.
allif true, resolve all tags; if false resolve only custom tags, ie those that have a prefix such as "!m!tag" with a matching "TAG" directive

Definition at line 1555 of file tree.cpp.

1556{
1557 if(empty())
1558 return;
1559 // try to resolve. While doing so, get the extra size needed for
1560 // the arena, if the arena is currently too small.
1561 size_t extra_size = _resolve_tags(this, cache, all);
1562 // if the arena requires extra size, grow it and then resolve the
1563 // missing entries
1564 if(extra_size)
1565 {
1566 _c4dbgpf("tag: extrasize={} -- retry! {}->{}", extra_size, m_arena.len, m_arena.len + extra_size);
1567 _grow_arena(extra_size);
1568 extra_size = _resolve_tags(this, cache, all);
1569 _RYML_ASSERT_BASIC_(callbacks(), extra_size == 0);
1570 }
1571}
bool empty() const
Definition tree.hpp:284
Callbacks const & callbacks() const
Definition tree.hpp:290

◆ normalize_tags()

void c4::yml::Tree::normalize_tags ( )

Definition at line 1573 of file tree.cpp.

1574{
1575 if(empty())
1576 return;
1577 _normalize_tags(this, root_id());
1578}

◆ normalize_tags_long()

void c4::yml::Tree::normalize_tags_long ( )

Definition at line 1580 of file tree.cpp.

1581{
1582 if(empty())
1583 return;
1584 _normalize_tags_long(this, root_id());
1585}

◆ num_tag_directives()

id_type c4::yml::Tree::num_tag_directives ( ) const

Definition at line 1436 of file tree.cpp.

1437{
1438 return m_tag_directives.size();
1439}

◆ add_tag_directive()

void c4::yml::Tree::add_tag_directive ( csubstr handle,
csubstr prefix,
id_type id )

Definition at line 1446 of file tree.cpp.

1447{
1448 _RYML_CHECK_BASIC_(m_callbacks,
1449 !handle.empty()
1450 &&
1451 !prefix.empty()
1452 &&
1453 is_valid_tag_handle(handle)
1454 &&
1455 m_tag_directives.add(handle, prefix, id));
1456}
bool is_valid_tag_handle(csubstr handle)
Definition tag.cpp:210

◆ clear_tag_directives()

void c4::yml::Tree::clear_tag_directives ( )

Definition at line 1441 of file tree.cpp.

1442{
1443 m_tag_directives.clear();
1444}

◆ resolve_tag()

size_t c4::yml::Tree::resolve_tag ( substr output,
csubstr tag,
id_type node_id ) const

resolve the given tag, appearing at node_id.

Write the result into output.

Returns
the number of characters required for the resolved tag

Definition at line 1458 of file tree.cpp.

1459{
1460 size_t reqsz = 0;
1461 m_tag_directives.resolve(output, &reqsz, tag, node_id, Location{}, callbacks());
1462 return reqsz;
1463}

◆ resolve_tag_sub()

csubstr c4::yml::Tree::resolve_tag_sub ( substr output,
csubstr tag,
id_type node_id ) const
inline

Wrapper for Tree::resolve_tag(), returning a substring.

Definition at line 686 of file tree.hpp.

687 {
688 size_t needed = resolve_tag(output, tag, node_id);
689 return needed <= output.len ? output.first(needed) : output;
690 }
size_t resolve_tag(substr output, csubstr tag, id_type node_id) const
resolve the given tag, appearing at node_id.
Definition tree.cpp:1458

◆ tag_directives()

c4::yml::TagDirectiveRange c4::yml::Tree::tag_directives ( ) const
inline

Definition at line 692 of file tree.hpp.

692{ return m_tag_directives.directives(); }

◆ insert_child()

id_type c4::yml::Tree::insert_child ( id_type parent,
id_type after )
inline

create and insert a new child of parent.

insert after the (to-be) sibling after, which must be a child of parent. To insert as the first child, set after to NONE

Definition at line 709 of file tree.hpp.

710 {
711 _RYML_ASSERT_VISIT_(m_callbacks, parent != NONE, this, parent);
712 _RYML_ASSERT_VISIT_(m_callbacks, is_container(parent) || is_root(parent), this, parent);
713 _RYML_ASSERT_VISIT_(m_callbacks, after == NONE || (_p(after)->m_parent == parent), this, parent);
714 id_type child = _claim();
715 _set_hierarchy(child, parent, after);
716 return child;
717 }
id_type _claim()
Definition tree.cpp:414

◆ prepend_child()

id_type c4::yml::Tree::prepend_child ( id_type parent)
inline

create and insert a node as the first child of parent

Definition at line 719 of file tree.hpp.

719{ return insert_child(parent, NONE); }
id_type insert_child(id_type parent, id_type after)
create and insert a new child of parent.
Definition tree.hpp:709

◆ append_child()

id_type c4::yml::Tree::append_child ( id_type parent)
inline

create and insert a node as the last child of parent

Definition at line 721 of file tree.hpp.

721{ return insert_child(parent, _p(parent)->m_last_child); }

◆ _append_child__unprotected()

id_type c4::yml::Tree::_append_child__unprotected ( id_type parent)
inline

Definition at line 722 of file tree.hpp.

723 {
724 id_type child = _claim();
725 _set_hierarchy(child, parent, _p(parent)->m_last_child);
726 return child;
727 }

◆ insert_sibling()

id_type c4::yml::Tree::insert_sibling ( id_type node,
id_type after )
inline

create and insert a new sibling of n. insert after "after"

Definition at line 742 of file tree.hpp.

743 {
744 return insert_child(_p(node)->m_parent, after);
745 }

◆ prepend_sibling()

id_type c4::yml::Tree::prepend_sibling ( id_type node)
inline

create and insert a node as the first node of parent

Definition at line 747 of file tree.hpp.

747{ return prepend_child(_p(node)->m_parent); }
id_type prepend_child(id_type parent)
create and insert a node as the first child of parent
Definition tree.hpp:719

◆ append_sibling()

id_type c4::yml::Tree::append_sibling ( id_type node)
inline

Definition at line 748 of file tree.hpp.

748{ return append_child(_p(node)->m_parent); }
id_type append_child(id_type parent)
create and insert a node as the last child of parent
Definition tree.hpp:721

◆ remove()

void c4::yml::Tree::remove ( id_type node)
inline

remove an entire branch at once: ie remove the children and the node itself

Definition at line 753 of file tree.hpp.

754 {
755 remove_children(node);
756 _release(node);
757 }
void remove_children(id_type node)
remove all the node's children, but keep the node itself
Definition tree.cpp:918

◆ remove_children()

void c4::yml::Tree::remove_children ( id_type node)

remove all the node's children, but keep the node itself

Definition at line 918 of file tree.cpp.

919{
920 _RYML_ASSERT_VISIT_(m_callbacks, get(node) != nullptr, this, node);
921 C4_SUPPRESS_WARNING_GCC_PUSH
922 #if defined(__GNUC__) && __GNUC__ >= 6
923 C4_SUPPRESS_WARNING_GCC("-Wnull-dereference")
924 #endif
925 id_type ich = get(node)->m_first_child;
926 while(ich != NONE)
927 {
928 remove_children(ich);
929 _RYML_ASSERT_VISIT_(m_callbacks, get(ich) != nullptr, this, node);
930 id_type next = get(ich)->m_next_sibling;
931 _release(ich);
932 if(ich == get(node)->m_last_child)
933 break;
934 ich = next;
935 }
936 C4_SUPPRESS_WARNING_GCC_POP
937}

◆ change_type() [1/2]

bool c4::yml::Tree::change_type ( id_type node,
NodeType type )

change the type of the node to one of MAP, SEQ or VAL.

type must have one and only one of MAP,SEQ,VAL; type may possibly have KEY, but if it does, then the node must also have KEY. Changing to the same type is a no-op. Otherwise, changing to a different type will initialize the node with an empty value of the desired type: changing to VAL will initialize with a null scalar (~), changing to MAP will initialize with an empty map ({}), and changing to SEQ will initialize with an empty seq ([]).

Definition at line 939 of file tree.cpp.

940{
941 _RYML_ASSERT_VISIT_(m_callbacks, type.is_val() || type.is_map() || type.is_seq(), this, node);
942 _RYML_ASSERT_VISIT_(m_callbacks, type.is_val() + type.is_map() + type.is_seq() == 1, this, node);
943 _RYML_ASSERT_VISIT_(m_callbacks, type.has_key() == has_key(node) || (has_key(node) && !type.has_key()), this, node);
944 NodeData *d = _p(node);
945 if(type.is_map() && is_map(node))
946 return false;
947 else if(type.is_seq() && is_seq(node))
948 return false;
949 else if(type.is_val() && is_val(node))
950 return false;
951 d->m_type = (d->m_type & (~(MAP|SEQ|VAL|CONTAINER_STYLE|KEY_STYLE|VAL_STYLE))) | type;
952 remove_children(node);
953 return true;
954}
NodeType type(id_type node) const
Definition tree.hpp:384
bool is_val(id_type node) const
Definition tree.hpp:417
@ VAL_STYLE
mask of all the scalar styles for val (not container styles!)
Definition node_type.hpp:93
@ KEY_STYLE
mask of all the scalar styles for key (not container styles!)
Definition node_type.hpp:92
@ CONTAINER_STYLE
Definition node_type.hpp:97

◆ change_type() [2/2]

bool c4::yml::Tree::change_type ( id_type node,
type_bits type )
inline

Definition at line 773 of file tree.hpp.

774 {
775 return change_type(node, (NodeType)type);
776 }
bool change_type(id_type node, NodeType type)
change the type of the node to one of MAP, SEQ or VAL.
Definition tree.cpp:939

◆ move() [1/3]

void c4::yml::Tree::move ( id_type node,
id_type after )

change the node's position in the parent

Definition at line 819 of file tree.cpp.

820{
821 _RYML_ASSERT_VISIT_(m_callbacks, node != NONE, this, node);
822 _RYML_ASSERT_VISIT_(m_callbacks, node != after, this, node);
823 _RYML_ASSERT_VISIT_(m_callbacks, ! is_root(node), this, node);
824 _RYML_ASSERT_VISIT_(m_callbacks, (after == NONE) || (has_sibling(node, after) && has_sibling(after, node)), this, node);
825
826 _rem_hierarchy(node);
827 _set_hierarchy(node, parent(node), after);
828}
bool has_sibling(id_type node, id_type sib) const
true if node has a sibling with id sib
Definition tree.hpp:480

◆ move() [2/3]

void c4::yml::Tree::move ( id_type node,
id_type new_parent,
id_type after )

change the node's parent and position

Definition at line 832 of file tree.cpp.

833{
834 _RYML_ASSERT_VISIT_(m_callbacks, node != NONE, this, node);
835 _RYML_ASSERT_VISIT_(m_callbacks, node != after, this, node);
836 _RYML_ASSERT_VISIT_(m_callbacks, new_parent != NONE, this, new_parent);
837 _RYML_ASSERT_VISIT_(m_callbacks, new_parent != node, this, new_parent);
838 _RYML_ASSERT_VISIT_(m_callbacks, new_parent != after, this, new_parent);
839 _RYML_ASSERT_VISIT_(m_callbacks, ! is_root(node), this, node);
840
841 _rem_hierarchy(node);
842 _set_hierarchy(node, new_parent, after);
843}

◆ move() [3/3]

id_type c4::yml::Tree::move ( Tree * src,
id_type node,
id_type new_parent,
id_type after )

change the node's parent and position to a different tree

Returns
the index of the new node in the destination tree

Definition at line 845 of file tree.cpp.

846{
847 _RYML_ASSERT_VISIT_(m_callbacks, src != nullptr, this, new_parent);
848 _RYML_ASSERT_VISIT_(m_callbacks, node != NONE, this, new_parent);
849 _RYML_ASSERT_VISIT_(m_callbacks, new_parent != NONE, this, new_parent);
850 _RYML_ASSERT_VISIT_(m_callbacks, new_parent != after, this, new_parent);
851
852 id_type dup = duplicate(src, node, new_parent, after);
853 src->remove(node);
854 return dup;
855}
id_type duplicate(id_type node, id_type new_parent, id_type after)
recursively duplicate a node from this tree into a new parent, placing it after one of its children
Definition tree.cpp:958

◆ set_root_as_stream()

void c4::yml::Tree::set_root_as_stream ( )

ensure the first node is a stream.

Eg, change this tree

DOCMAP MAP KEYVAL KEYVAL SEQ VAL

to

STREAM DOCMAP MAP KEYVAL KEYVAL SEQ VAL

If the root is already a stream, this is a no-op.

Definition at line 857 of file tree.cpp.

858{
859 id_type root = root_id();
860 if(is_stream(root))
861 return;
862 _c4dbgpf("set_root_as_stream. rootty={}", type(root).type);
863 bool empty_root = ((type(root) & (SEQ|MAP|VAL)) == 0);
864 for(TagDirective &C4_RESTRICT td : m_tag_directives)
865 {
866 if(td.doc_id >= m_cap || _p(td.doc_id)->m_parent == NONE)
867 {
868 _c4dbgpf("tagd[{}]: id={}->NONE", &td-m_tag_directives.m_directives, td.doc_id);
869 td.doc_id = NONE;
870 }
871 }
872 // don't use _add_flags() because it's checked and will fail
873 id_type next_doc;
874 if(!has_children(root))
875 {
876 if(is_container(root))
877 {
878 next_doc = append_child(root);
879 _copy_props_wo_key(next_doc, root);
880 _p(next_doc)->m_type.add(DOC);
881 }
882 else
883 {
884 _p(root)->m_type.add(SEQ);
885 next_doc = append_child(root);
886 _copy_props_wo_key(next_doc, root);
887 _p(next_doc)->m_type.add(DOC);
888 _p(next_doc)->m_type.rem(SEQ);
889 }
890 }
891 else
892 {
893 _RYML_ASSERT_VISIT_(m_callbacks, !has_key(root), this, root);
894 next_doc = append_child(root);
895 _copy_props_wo_key(next_doc, root);
896 _add_flags(next_doc, DOC);
897 for(id_type prev = NONE, ch = first_child(root), next = next_sibling(ch); ch != NONE; )
898 {
899 if(ch == next_doc)
900 break;
901 move(ch, next_doc, prev);
902 prev = ch;
903 ch = next;
904 next = next_sibling(next);
905 }
906 }
907 _p(root)->m_type = STREAM;
908 for(TagDirective &C4_RESTRICT td : m_tag_directives)
909 {
910 id_type id = (td.doc_id != NONE) ? next_doc : (empty_root ? first_child(root) : m_free_head);
911 _c4dbgpf("tagd[{}]: id={}->{}", &td-m_tag_directives.m_directives, td.doc_id, id);
912 td.doc_id = id;
913 }
914}
void move(id_type node, id_type after)
change the node's position in the parent
Definition tree.cpp:819
id_type id(NodeData const *n) const
get the index of a node belonging to this tree. n can be nullptr, in which case NONE is returned
Definition tree.hpp:302
void rem(NodeType_e t) noexcept
void add(NodeType_e t) noexcept

◆ duplicate() [1/2]

id_type c4::yml::Tree::duplicate ( id_type node,
id_type new_parent,
id_type after )

recursively duplicate a node from this tree into a new parent, placing it after one of its children

Returns
the index of the copy

Definition at line 958 of file tree.cpp.

959{
960 return duplicate(this, node, parent, after);
961}

◆ duplicate() [2/2]

id_type c4::yml::Tree::duplicate ( Tree const * src,
id_type node,
id_type new_parent,
id_type after )

recursively duplicate a node from a different tree into a new parent, placing it after one of its children

Returns
the index of the copy

Definition at line 963 of file tree.cpp.

964{
965 _RYML_ASSERT_VISIT_(m_callbacks, src != nullptr, src, node);
966 _RYML_ASSERT_VISIT_(m_callbacks, node != NONE, src, node);
967 _RYML_ASSERT_VISIT_(m_callbacks, parent != NONE, this, parent);
968 _RYML_ASSERT_VISIT_(m_callbacks, ! src->is_root(node), src, node);
969
970 id_type copy = _claim();
971
972 _copy_props(copy, src, node);
973 _set_hierarchy(copy, parent, after);
974 duplicate_children(src, node, copy, NONE);
975
976 return copy;
977}
id_type duplicate_children(id_type node, id_type parent, id_type after)
recursively duplicate the node's children (but not the node)
Definition tree.cpp:980

◆ duplicate_children() [1/2]

id_type c4::yml::Tree::duplicate_children ( id_type node,
id_type parent,
id_type after )

recursively duplicate the node's children (but not the node)

Returns
the index of the last duplicated child

Definition at line 980 of file tree.cpp.

981{
982 return duplicate_children(this, node, parent, after);
983}

◆ duplicate_children() [2/2]

id_type c4::yml::Tree::duplicate_children ( Tree const * src,
id_type node,
id_type parent,
id_type after )

recursively duplicate the node's children (but not the node), where the node is from a different tree

Returns
the index of the last duplicated child

Definition at line 985 of file tree.cpp.

986{
987 _RYML_ASSERT_VISIT_(m_callbacks, src != nullptr, src, node);
988 _RYML_ASSERT_VISIT_(m_callbacks, node != NONE, src, node);
989 _RYML_ASSERT_VISIT_(m_callbacks, parent != NONE, this, parent);
990 _RYML_ASSERT_VISIT_(m_callbacks, after == NONE || has_child(parent, after), this, parent);
991
992 id_type prev = after;
993 for(id_type i = src->first_child(node); i != NONE; i = src->next_sibling(i))
994 {
995 prev = duplicate(src, i, parent, prev);
996 }
997
998 return prev;
999}
bool has_child(id_type node, id_type ch) const
true if node has a child with id ch
Definition tree.hpp:473

◆ duplicate_children_no_rep() [1/2]

id_type c4::yml::Tree::duplicate_children_no_rep ( id_type node,
id_type parent,
id_type after )

duplicate the node's children (but not the node) in a new parent, but omit repetitions where a duplicated node has the same key (in maps) or value (in seqs).

If one of the duplicated children has the same key (in maps) or value (in seqs) as one of the parent's children, the one that is placed closest to the end will prevail.

Definition at line 1017 of file tree.cpp.

1018{
1019 return duplicate_children_no_rep(this, node, parent, after);
1020}
id_type duplicate_children_no_rep(id_type node, id_type parent, id_type after)
duplicate the node's children (but not the node) in a new parent, but omit repetitions where a duplic...
Definition tree.cpp:1017

◆ duplicate_children_no_rep() [2/2]

id_type c4::yml::Tree::duplicate_children_no_rep ( Tree const * src,
id_type node,
id_type parent,
id_type after )

Definition at line 1022 of file tree.cpp.

1023{
1024 _RYML_ASSERT_VISIT_(m_callbacks, node != NONE, src, node);
1025 _RYML_ASSERT_VISIT_(m_callbacks, parent != NONE, this, parent);
1026 _RYML_ASSERT_VISIT_(m_callbacks, after == NONE || has_child(parent, after), this, parent);
1027
1028 // don't loop using pointers as there may be a relocation
1029
1030 // find the position where "after" is
1031 id_type after_pos = NONE;
1032 if(after != NONE)
1033 {
1034 for(id_type i = first_child(parent), icount = 0; i != NONE; ++icount, i = next_sibling(i))
1035 {
1036 if(i == after)
1037 {
1038 after_pos = icount;
1039 break;
1040 }
1041 }
1042 _RYML_ASSERT_VISIT_(m_callbacks, after_pos != NONE, this, node);
1043 }
1044
1045 // for each child to be duplicated...
1046 id_type prev = after;
1047 for(id_type i = src->first_child(node); i != NONE; i = src->next_sibling(i))
1048 {
1049 _c4dbgpf("duplicate_no_rep: {} -> {}/{}", i, parent, prev);
1050 _RYML_CHECK_VISIT_(m_callbacks, this != src || (parent != i && !is_ancestor(parent, i)), this, parent);
1051 if(is_seq(parent))
1052 {
1053 _c4dbgpf("duplicate_no_rep: {} is seq", parent);
1054 prev = duplicate(src, i, parent, prev);
1055 }
1056 else
1057 {
1058 _c4dbgpf("duplicate_no_rep: {} is map", parent);
1059 _RYML_ASSERT_VISIT_(m_callbacks, is_map(parent), this, parent);
1060 // does the parent already have a node with key equal to that of the current duplicate?
1061 id_type dstnode_dup = NONE, dstnode_dup_pos = NONE;
1062 {
1063 csubstr srckey = src->key(i);
1064 for(id_type j = first_child(parent), jcount = 0; j != NONE; ++jcount, j = next_sibling(j))
1065 {
1066 if(key(j) == srckey)
1067 {
1068 _c4dbgpf("duplicate_no_rep: found matching key '{}' src={}/{} dst={}/{}", srckey, node, i, parent, j);
1069 dstnode_dup = j;
1070 dstnode_dup_pos = jcount;
1071 break;
1072 }
1073 }
1074 }
1075 _c4dbgpf("duplicate_no_rep: dstnode_dup={} dstnode_dup_pos={} after_pos={}", dstnode_dup, dstnode_dup_pos, after_pos);
1076 if(dstnode_dup == NONE) // there is no repetition; just duplicate
1077 {
1078 _c4dbgpf("duplicate_no_rep: no repetition, just duplicate i={} parent={} prev={}", i, parent, prev);
1079 prev = duplicate(src, i, parent, prev);
1080 }
1081 else // yes, there is a repetition
1082 {
1083 if(after_pos != NONE && dstnode_dup_pos <= after_pos)
1084 {
1085 // the dst duplicate is located before the node which will be inserted,
1086 // and will be overridden by the duplicate. So replace it.
1087 _c4dbgpf("duplicate_no_dstnode_dup: replace {}/{} with {}/{}", parent, dstnode_dup, node, i);
1088 if(prev == dstnode_dup)
1089 prev = prev_sibling(dstnode_dup);
1090 remove(dstnode_dup);
1091 prev = duplicate(src, i, parent, prev);
1092 }
1093 else if(prev == NONE)
1094 {
1095 _c4dbgpf("duplicate_no_dstnode_dup: {}=prev <- {}", prev, dstnode_dup);
1096 // first iteration with prev = after = NONE and dstnode_dupetition
1097 prev = dstnode_dup;
1098 }
1099 else if(dstnode_dup != prev)
1100 {
1101 // dstnode_dup is located after the node which will be inserted
1102 // and overrides it. So move the dstnode_dup into this node's place.
1103 _c4dbgpf("duplicate_no_dstnode_dup: move({}, {})", dstnode_dup, prev);
1104 move(dstnode_dup, prev);
1105 prev = dstnode_dup;
1106 }
1107 } // there's a dstnode_dupetition
1108 }
1109 }
1110
1111 return prev;
1112}
id_type prev_sibling(id_type node) const
Definition tree.hpp:506
bool is_ancestor(id_type node, id_type ancestor) const
true when ancestor is parent or parent of a parent of node
Definition tree.cpp:1317
void remove(id_type node)
remove an entire branch at once: ie remove the children and the node itself
Definition tree.hpp:753
basic_substring< const char > csubstr
an immutable string view
Definition substr.hpp:2357

◆ duplicate_contents() [1/2]

void c4::yml::Tree::duplicate_contents ( id_type node,
id_type where )

Definition at line 1002 of file tree.cpp.

1003{
1004 duplicate_contents(this, node, where);
1005}
void duplicate_contents(id_type node, id_type where)
Definition tree.cpp:1002

◆ duplicate_contents() [2/2]

void c4::yml::Tree::duplicate_contents ( Tree const * src,
id_type node,
id_type where )

Definition at line 1007 of file tree.cpp.

1008{
1009 _RYML_ASSERT_VISIT_(m_callbacks, src != nullptr, src, node);
1010 _RYML_ASSERT_VISIT_(m_callbacks, node != NONE, src, node);
1011 _RYML_ASSERT_VISIT_(m_callbacks, where != NONE, this, where);
1012 _copy_props_wo_key(where, src, node);
1013 duplicate_children(src, node, where, last_child(where));
1014}
id_type last_child(id_type node) const
Definition tree.hpp:513

◆ merge_with()

void c4::yml::Tree::merge_with ( Tree const * src,
id_type src_node = NONE,
id_type dst_root = NONE )

Definition at line 1117 of file tree.cpp.

1118{
1119 _RYML_ASSERT_VISIT_(m_callbacks, src != nullptr, src, src_node);
1120 if(src_node == NONE)
1121 src_node = src->root_id();
1122 if(dst_node == NONE)
1123 dst_node = root_id();
1124 _RYML_ASSERT_VISIT_(m_callbacks, src->has_val(src_node) || src->is_seq(src_node) || src->is_map(src_node), src, src_node);
1125 if(src->has_val(src_node))
1126 {
1127 type_bits mask_src = ~STYLE; // keep the existing style if it is already a val
1128 if( ! has_val(dst_node))
1129 {
1130 if(has_children(dst_node))
1131 remove_children(dst_node);
1132 mask_src |= VAL_STYLE; // copy the src style
1133 }
1134 if(src->is_keyval(src_node))
1135 {
1136 _copy_props(dst_node, src, src_node, mask_src);
1137 }
1138 else
1139 {
1140 _RYML_ASSERT_VISIT_(m_callbacks, src->is_val(src_node), src, src_node);
1141 _copy_props_wo_key(dst_node, src, src_node, mask_src);
1142 }
1143 }
1144 else if(src->is_seq(src_node))
1145 {
1146 if( ! is_seq(dst_node))
1147 {
1148 if(has_children(dst_node))
1149 remove_children(dst_node);
1150 _clear_type(dst_node);
1151 if(src->has_key(src_node))
1152 to_seq(dst_node, src->key(src_node));
1153 else
1154 to_seq(dst_node);
1155 _p(dst_node)->m_type = src->_p(src_node)->m_type;
1156 }
1157 for(id_type sch = src->first_child(src_node); sch != NONE; sch = src->next_sibling(sch))
1158 {
1159 id_type dch = append_child(dst_node);
1160 _copy_props_wo_key(dch, src, sch);
1161 merge_with(src, sch, dch);
1162 }
1163 }
1164 else
1165 {
1166 _RYML_ASSERT_VISIT_(m_callbacks, src->is_map(src_node), src, src_node);
1167 if( ! is_map(dst_node))
1168 {
1169 if(has_children(dst_node))
1170 remove_children(dst_node);
1171 _clear_type(dst_node);
1172 if(src->has_key(src_node))
1173 to_map(dst_node, src->key(src_node));
1174 else
1175 to_map(dst_node);
1176 _p(dst_node)->m_type = src->_p(src_node)->m_type;
1177 }
1178 for(id_type sch = src->first_child(src_node); sch != NONE; sch = src->next_sibling(sch))
1179 {
1180 id_type dch = find_child(dst_node, src->key(sch));
1181 if(dch == NONE)
1182 {
1183 dch = append_child(dst_node);
1184 _copy_props(dch, src, sch);
1185 }
1186 merge_with(src, sch, dch);
1187 }
1188 }
1189}
void to_seq(id_type node, csubstr key, type_bits more_flags=0)
Definition tree.cpp:1378
void to_map(id_type node, csubstr key, type_bits more_flags=0)
Definition tree.cpp:1360
void merge_with(Tree const *src, id_type src_node=NONE, id_type dst_root=NONE)
Definition tree.cpp:1117
uint32_t type_bits
the integral type necessary to cover all the bits for NodeType_e
Definition node_type.hpp:30

◆ location()

Location c4::yml::Tree::location ( Parser const & p,
id_type node ) const

Get the location of a node from the parse used to parse this tree.

Definition at line 1914 of file tree.cpp.

1915{
1916 // try hard to avoid getting the location from a null string.
1917 Location loc;
1918 if(_location_from_node(parser, node, &loc, 0))
1919 return loc;
1920 return parser.val_location(parser.source().str);
1921}

◆ arena_size()

size_t c4::yml::Tree::arena_size ( ) const
inline

get the current size of the tree's internal arena

Definition at line 876 of file tree.hpp.

876{ return m_arena_pos; }

◆ arena_capacity()

size_t c4::yml::Tree::arena_capacity ( ) const
inline

get the current capacity of the tree's internal arena

Definition at line 878 of file tree.hpp.

878{ return m_arena.len; }

◆ arena_slack()

size_t c4::yml::Tree::arena_slack ( ) const
inline

get the current slack of the tree's internal arena

Definition at line 880 of file tree.hpp.

880{ _RYML_ASSERT_VISIT_(m_callbacks, m_arena.len >= m_arena_pos, this, NONE); return m_arena.len - m_arena_pos; }

◆ arena_pos()

size_t c4::yml::Tree::arena_pos ( ) const
inline

Definition at line 881 of file tree.hpp.

881{ return m_arena_pos; }

◆ arena() [1/2]

csubstr c4::yml::Tree::arena ( ) const
inline

get the current arena

Definition at line 884 of file tree.hpp.

884{ return m_arena.first(m_arena_pos); }

◆ arena() [2/2]

substr c4::yml::Tree::arena ( )
inline

get the current arena

Definition at line 886 of file tree.hpp.

886{ return m_arena.first(m_arena_pos); } // NOLINT(readability-make-member-function-const)

◆ in_arena()

bool c4::yml::Tree::in_arena ( csubstr s) const
inline

return true if the given substring is part of the tree's string arena

Definition at line 889 of file tree.hpp.

890 {
891 return m_arena.is_super(s);
892 }

◆ to_arena()

template<class T>
csubstr c4::yml::Tree::to_arena ( T const & a)
inline

serialize the given variable to the tree's arena, growing it as needed to accomodate the serialization.

Note
To customize how the type gets serialized to a string, you can overload c4::to_chars(substr, T const&)
To customize how the type gets serialized to the arena, you can overload serialize_scalar()
Growing the arena may cause relocation of the entire existing arena, and thus change the contents of individual nodes, and thus cost O(numnodes)+O(arenasize). To avoid this cost, ensure that the arena is reserved to an appropriate size using Tree::reserve_arena().
See also
alloc_arena()

Definition at line 911 of file tree.hpp.

912 {
913 return serialize_to_arena(this, a);
914 }
csubstr serialize_to_arena(Tree *tree, csubstr a)
Definition tree.cpp:19

◆ copy_to_arena()

substr c4::yml::Tree::copy_to_arena ( csubstr s)
inline

copy the given string to the tree's arena, growing the arena by the required size.

Note
this method differs from to_arena() in that it returns a mutable substr, and further it does not deal with some corner cases for null/empty strings
Growing the arena may cause relocation of the entire existing arena, and thus change the contents of individual nodes, and thus cost O(numnodes)+O(arenasize). To avoid this cost, ensure that the arena is reserved to an appropriate size before using Tree::reserve_arena()
See also
reserve_arena()
alloc_arena()

Definition at line 932 of file tree.hpp.

933 {
934 _RYML_ASSERT_VISIT_(m_callbacks, !s.overlaps(m_arena), this, NONE);
935 substr cp = alloc_arena(s.len);
936 _RYML_ASSERT_VISIT_(m_callbacks, cp.len == s.len, this, NONE);
937 _RYML_ASSERT_VISIT_(m_callbacks, !s.overlaps(cp), this, NONE);
938 #if (!defined(__clang__)) && (defined(__GNUC__) && __GNUC__ >= 10)
939 C4_SUPPRESS_WARNING_GCC_PUSH
940 C4_SUPPRESS_WARNING_GCC("-Wstringop-overflow=") // no need for terminating \0
941 C4_SUPPRESS_WARNING_GCC("-Wrestrict") // there's an assert to ensure no violation of restrict behavior
942 #endif
943 if(s.len)
944 memcpy(cp.str, s.str, s.len);
945 #if (!defined(__clang__)) && (defined(__GNUC__) && __GNUC__ >= 10)
946 C4_SUPPRESS_WARNING_GCC_POP
947 #endif
948 return cp;
949 }
substr alloc_arena(size_t sz)
grow the tree's string arena by the given size and return a substr of the added portion
Definition tree.hpp:961
basic_substring< char > substr
a mutable string view
Definition substr.hpp:2356

◆ alloc_arena()

substr c4::yml::Tree::alloc_arena ( size_t sz)
inline

grow the tree's string arena by the given size and return a substr of the added portion

Note
Growing the arena may cause relocation of the entire existing arena, and thus change the contents of individual nodes, and thus cost O(numnodes)+O(arenasize). To avoid this cost, ensure that the arena is reserved to an appropriate size using .reserve_arena().
See also
reserve_arena()

Definition at line 961 of file tree.hpp.

962 {
963 if(sz > arena_slack())
964 _grow_arena(sz - arena_slack());
965 substr s = _request_span(sz);
966 return s;
967 }
size_t arena_slack() const
get the current slack of the tree's internal arena
Definition tree.hpp:880

◆ reserve_arena()

void c4::yml::Tree::reserve_arena ( size_t arena_cap = RYML_DEFAULT_TREE_ARENA_CAPACITY)
inline

ensure the tree's internal string arena is at least the given capacity

Warning
This operation may be expensive, with a potential complexity of O(numNodes)+O(arenasize).
Growing the arena may cause relocation of the entire existing arena, and thus change the contents of individual nodes.

Definition at line 973 of file tree.hpp.

974 {
975 if(arena_cap > m_arena.len)
976 {
977 substr buf;
978 buf.str = _RYML_CB_ALLOC(m_callbacks, char, arena_cap);
979 buf.len = arena_cap;
980 if(m_arena.str)
981 {
982 _RYML_ASSERT_VISIT_(m_callbacks, m_arena.len >= 0, this, NONE);
983 _relocate(buf); // does a memcpy and changes nodes using the arena
984 _RYML_CB_FREE(m_callbacks, m_arena.str, char, m_arena.len);
985 }
986 m_arena = buf;
987 }
988 }
C * str
a restricted pointer to the first character of the substring
Definition substr.hpp:216

◆ lookup_path()

Tree::lookup_result c4::yml::Tree::lookup_path ( csubstr path,
id_type start = NONE ) const

for example foo.bar[0].baz

Definition at line 1610 of file tree.cpp.

1611{
1612 if(start == NONE)
1613 start = root_id();
1614 lookup_result r(path, start);
1615 if(path.empty())
1616 return r;
1617 _lookup_path(&r);
1618 if(r.target == NONE && r.closest == start)
1619 r.closest = NONE;
1620 return r;
1621}

◆ lookup_path_or_modify() [1/2]

id_type c4::yml::Tree::lookup_path_or_modify ( csubstr default_value,
csubstr path,
id_type start = NONE )

defaulted lookup: lookup path; if the lookup fails, recursively modify the tree so that the corresponding lookup_path() would return the default value.

See also
lookup_path()

Definition at line 1623 of file tree.cpp.

1624{
1625 id_type target = _lookup_path_or_create(path, start);
1626 if(parent_is_map(target))
1627 to_keyval(target, key(target), default_value);
1628 else
1629 to_val(target, default_value);
1630 return target;
1631}
void to_keyval(id_type node, csubstr key, csubstr val, type_bits more_flags=0)
Definition tree.cpp:1342
void to_val(id_type node, csubstr val, type_bits more_flags=0)
Definition tree.cpp:1333

◆ lookup_path_or_modify() [2/2]

id_type c4::yml::Tree::lookup_path_or_modify ( Tree const * src,
id_type src_node,
csubstr path,
id_type start = NONE )

defaulted lookup: lookup path; if the lookup fails, recursively modify the tree so that the corresponding lookup_path() would return the branch src_node (from the tree src).

See also
lookup_path()

Definition at line 1633 of file tree.cpp.

1634{
1635 id_type target = _lookup_path_or_create(path, start);
1636 merge_with(src, src_node, target);
1637 return target;
1638}

◆ _claim()

id_type c4::yml::Tree::_claim ( )

Definition at line 414 of file tree.cpp.

415{
416 if(m_free_head == NONE || m_buf == nullptr)
417 {
418 id_type sz = 2 * m_cap;
419 sz = sz ? sz : 16;
420 reserve(sz);
421 _RYML_ASSERT_VISIT_(m_callbacks, m_free_head != NONE, this, NONE);
422 }
423
424 _RYML_ASSERT_VISIT_(m_callbacks, m_size < m_cap, this, NONE);
425 _RYML_ASSERT_VISIT_(m_callbacks, m_free_head >= 0 && m_free_head < m_cap, this, NONE);
426
427 id_type ichild = m_free_head;
428 NodeData *child = m_buf + ichild;
429
430 ++m_size;
431 m_free_head = child->m_next_sibling;
432 if(m_free_head == NONE)
433 {
435 _RYML_ASSERT_VISIT_(m_callbacks, m_size == m_cap, this, NONE);
436 }
437
438 _clear(ichild);
439
440 return ichild;
441}

Member Data Documentation

◆ m_buf

NodeData* c4::yml::Tree::m_buf

Definition at line 1331 of file tree.hpp.

◆ m_cap

id_type c4::yml::Tree::m_cap

Definition at line 1332 of file tree.hpp.

◆ m_size

id_type c4::yml::Tree::m_size

Definition at line 1333 of file tree.hpp.

◆ m_free_head

id_type c4::yml::Tree::m_free_head

Definition at line 1335 of file tree.hpp.

◆ m_free_tail

id_type c4::yml::Tree::m_free_tail

Definition at line 1336 of file tree.hpp.

◆ m_arena

substr c4::yml::Tree::m_arena

Definition at line 1338 of file tree.hpp.

◆ m_arena_pos

size_t c4::yml::Tree::m_arena_pos

Definition at line 1339 of file tree.hpp.

◆ m_callbacks

Callbacks c4::yml::Tree::m_callbacks

Definition at line 1341 of file tree.hpp.

◆ m_tag_directives

TagDirectives c4::yml::Tree::m_tag_directives

Definition at line 1343 of file tree.hpp.


The documentation for this class was generated from the following files:
  • /home/docs/checkouts/readthedocs.org/user_builds/rapidyaml/checkouts/v0.14.0/src/c4/yml/tree.hpp
  • /home/docs/checkouts/readthedocs.org/user_builds/rapidyaml/checkouts/v0.14.0/src/c4/yml/tree.cpp