rapidyaml 0.15.2
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

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 () noexcept
 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
 Query for zero size.
id_type size () const
id_type capacity () const
id_type slack () const
Callbacks const & callbacks () const
void callbacks (Callbacks const &cb)
node getters
NodeDataget (id_type node)
 get a pointer to a node's NodeData. node 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. node 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. The tree can be empty only when constructed with explicitly zero-capacity.
id_type root_id_maybe () const
 Get the id of the root node, or NONE if the tree is empty.
id_type id (NodeData const *n) const
 get the id of a node belonging to this tree. n can be nullptr, in which case NONE is returned n must belong to this tree
NodeRef helpers
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 . Note that a non-const Tree implicitly converts to NodeRef.
ConstNodeRef rootref () const
 Get the root as a ConstNodeRef . Note that Tree implicitly converts to ConstNodeRef.
ConstNodeRef crootref () const
 Get the root as a ConstNodeRef . Note that Tree implicitly converts to 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 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
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
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_ml1 (id_type node) const
bool is_flow_mln (id_type node) const
bool is_flow_mlx (id_type node) const
bool is_flow (id_type node) const
bool has_flow_space (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 set_stream (id_type node)
void set_doc (id_type node)
void set_val (id_type node, csubstr val) RYML_NOEXCEPT
void set_val (id_type node, csubstr val, NodeType more_flags) RYML_NOEXCEPT
void set_key (id_type node, csubstr key) RYML_NOEXCEPT
void set_key (id_type node, csubstr key, NodeType more_flags) RYML_NOEXCEPT
void set_seq (id_type node) RYML_NOEXCEPT
void set_seq (id_type node, NodeType more_flags) RYML_NOEXCEPT
void set_map (id_type node) RYML_NOEXCEPT
void set_map (id_type node, NodeType more_flags) RYML_NOEXCEPT
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
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.
bool change_type (id_type node, NodeType type)
bool change_type (id_type node, type_bits type)
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
csubstr arena_rem () const
 get the free space at the end of the arena
substr arena_rem ()
 get the free space at the end of the 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

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 254 of file tree.hpp.

Constructor & Destructor Documentation

◆ Tree() [1/6]

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

Definition at line 261 of file tree.hpp.

261: 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 127 of file tree.cpp.

129{
130}
#define RYML_DEFAULT_TREE_CAPACITY
default capacity for the tree when not set explicitly
Definition common.hpp:23
#define RYML_DEFAULT_TREE_ARENA_CAPACITY
default capacity for the tree's arena when not set explicitly
Definition common.hpp:28

◆ Tree() [3/6]

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

Definition at line 263 of file tree.hpp.

263: 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:924

◆ Tree() [4/6]

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

Definition at line 132 of file tree.cpp.

133 : m_buf(nullptr)
134 , m_cap(0)
135 , m_size(0)
138 , m_arena()
139 , m_arena_pos(0)
140 , m_callbacks(cb)
142{
143 if(node_capacity)
144 reserve(node_capacity);
147}
NodeData * m_buf
Definition tree.hpp:1293
id_type m_free_head
Definition tree.hpp:1297
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:1022
size_t m_arena_pos
Definition tree.hpp:1301
void reserve(id_type node_capacity=RYML_DEFAULT_TREE_CAPACITY)
Definition tree.cpp:300
TagDirectives m_tag_directives
Definition tree.hpp:1305
id_type m_size
Definition tree.hpp:1295
id_type m_cap
Definition tree.hpp:1294
substr m_arena
Definition tree.hpp:1300
id_type m_free_tail
Definition tree.hpp:1298
Callbacks m_callbacks
Definition tree.hpp:1303
@ NONE
an index to none
Definition common.hpp:312

◆ ~Tree()

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

Definition at line 149 of file tree.cpp.

150{
151 _free();
152}

◆ Tree() [5/6]

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

Definition at line 155 of file tree.cpp.

155 : m_callbacks(that.m_callbacks)
156{
157 _clear();
158 _copy(that);
159}

◆ Tree() [6/6]

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

Definition at line 161 of file tree.cpp.

161 : m_callbacks(that.m_callbacks)
162{
163 _clear();
164 _move(that);
165}

Member Function Documentation

◆ operator=() [1/2]

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

Definition at line 167 of file tree.cpp.

168{
169 if(&that != this)
170 {
171 _free();
172 m_callbacks = that.m_callbacks;
173 _copy(that);
174 }
175 return *this;
176}

◆ operator=() [2/2]

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

Definition at line 178 of file tree.cpp.

179{
180 if(&that != this)
181 {
182 _free();
183 m_callbacks = that.m_callbacks;
184 _move(that);
185 }
186 return *this;
187}

◆ reserve()

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

Definition at line 300 of file tree.cpp.

301{
302 if(cap > m_cap)
303 {
304 NodeData *buf = _RYML_CB_ALLOC_HINT(m_callbacks, NodeData, (size_t)cap, m_buf);
305 if(m_buf)
306 {
307 memcpy(buf, m_buf, (size_t)m_cap * sizeof(NodeData));
308 _RYML_CB_FREE(m_callbacks, m_buf, NodeData, (size_t)m_cap);
309 }
310 id_type first = m_cap, del = cap - m_cap;
311 m_cap = cap;
312 m_buf = buf;
313 _clear_range(first, del);
314 if(m_free_head != NONE)
315 {
316 _RYML_ASSERT_VISIT_(m_callbacks, m_buf != nullptr, this, NONE);
317 _RYML_ASSERT_VISIT_(m_callbacks, m_free_tail != NONE, this, NONE);
318 m_buf[m_free_tail].m_next_sibling = first;
319 m_buf[first].m_prev_sibling = m_free_tail;
320 m_free_tail = cap-1;
321 }
322 else
323 {
324 _RYML_ASSERT_VISIT_(m_callbacks, m_free_tail == NONE, this, NONE);
325 m_free_head = first;
326 m_free_tail = cap-1;
327 }
328 _RYML_ASSERT_VISIT_(m_callbacks, m_free_head == NONE || (m_free_head >= 0 && m_free_head < cap), this, NONE);
329 _RYML_ASSERT_VISIT_(m_callbacks, m_free_tail == NONE || (m_free_tail >= 0 && m_free_tail < cap), this, NONE);
330
331 if( ! m_size)
332 _claim_root();
333 }
334}
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:305

◆ 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 338 of file tree.cpp.

339{
340 _clear_range(0, m_cap);
341 m_size = 0;
342 if(m_buf)
343 {
344 _RYML_ASSERT_VISIT_(m_callbacks, m_cap >= 0, this, NONE);
345 m_free_head = 0;
346 m_free_tail = m_cap-1;
347 _claim_root();
348 }
349 else
350 {
353 }
354 m_tag_directives.clear();
355}

◆ clear_arena()

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

Definition at line 287 of file tree.hpp.

287{ m_arena_pos = 0; }

◆ empty() [1/2]

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

Query for zero size.

The tree can be empty only when constructed with explicitly zero-capacity.

Definition at line 290 of file tree.hpp.

290{ return m_size == 0; }

◆ size()

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

Definition at line 292 of file tree.hpp.

292{ return m_size; }

◆ capacity()

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

Definition at line 293 of file tree.hpp.

293{ return m_cap; }

◆ slack()

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

Definition at line 294 of file tree.hpp.

294{ _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 296 of file tree.hpp.

296{ return m_callbacks; }

◆ callbacks() [2/2]

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

Definition at line 297 of file tree.hpp.

297{ m_callbacks = cb; }

◆ get() [1/2]

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

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

Definition at line 308 of file tree.hpp.

309 {
310 if(node == NONE)
311 return nullptr;
312 _RYML_ASSERT_VISIT_(m_callbacks, node >= 0 && node < m_cap, this, node);
313 return m_buf + node;
314 }

◆ get() [2/2]

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

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

Definition at line 317 of file tree.hpp.

318 {
319 if(node == NONE)
320 return nullptr;
321 _RYML_ASSERT_VISIT_(m_callbacks, node >= 0 && node < m_cap, this, node);
322 return m_buf + node;
323 }

◆ _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 327 of file tree.hpp.

327{ _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 330 of file tree.hpp.

330{ _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. The tree can be empty only when constructed with explicitly zero-capacity.

Definition at line 333 of file tree.hpp.

333{ _RYML_ASSERT_VISIT_(m_callbacks, m_size > 0, this, id_type(0)); return 0; }

◆ root_id_maybe()

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

Get the id of the root node, or NONE if the tree is empty.

Definition at line 335 of file tree.hpp.

335{ return m_size ? 0 : id_type(NONE); }

◆ id()

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

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

Definition at line 339 of file tree.hpp.

340 {
341 if( ! n)
342 return NONE;
343 _RYML_ASSERT_VISIT_(m_callbacks, n >= m_buf && n < m_buf + m_cap, this, NONE);
344 return static_cast<id_type>(n - m_buf);
345 }

◆ ref() [1/2]

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

Get a NodeRef of a node by id.

Definition at line 78 of file tree.cpp.

79{
80 _RYML_ASSERT_VISIT_(m_callbacks, id != NONE && id >= 0 && id < m_cap, this, id);
81 return NodeRef(this, id);
82}

◆ ref() [2/2]

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

Get a NodeRef of a node by id.

Definition at line 83 of file tree.cpp.

84{
85 _RYML_ASSERT_VISIT_(m_callbacks, id != NONE && id >= 0 && id < m_cap, this, id);
86 return ConstNodeRef(this, id);
87}

◆ cref()

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

Get a NodeRef of a node by id.

Definition at line 88 of file tree.cpp.

89{
90 _RYML_ASSERT_VISIT_(m_callbacks, id != NONE && id >= 0 && id < m_cap, this, id);
91 return ConstNodeRef(this, id);
92}

◆ rootref() [1/2]

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

Get the root as a NodeRef . Note that a non-const Tree implicitly converts to NodeRef.

Definition at line 64 of file tree.cpp.

65{
66 return NodeRef(this, root_id());
67}
id_type root_id() const
Get the id of the root node. The tree must not be empty. The tree can be empty only when constructed ...
Definition tree.hpp:333

◆ rootref() [2/2]

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

Get the root as a ConstNodeRef . Note that Tree implicitly converts to ConstNodeRef.

Definition at line 68 of file tree.cpp.

69{
70 return ConstNodeRef(this, root_id());
71}

◆ crootref()

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

Get the root as a ConstNodeRef . Note that Tree implicitly converts to ConstNodeRef.

Definition at line 73 of file tree.cpp.

74{
75 return ConstNodeRef(this, root_id());
76}

◆ 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 112 of file tree.cpp.

113{
114 return ref(doc(i));
115}
NodeRef ref(id_type node)
Get a NodeRef of a node by id.
Definition tree.cpp:78
id_type doc(id_type i) const
gets the i document node index.
Definition tree.hpp:545

◆ 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 116 of file tree.cpp.

117{
118 return cref(doc(i));
119}
ConstNodeRef cref(id_type node) const
Get a NodeRef of a node by id.
Definition tree.cpp:88

◆ 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 120 of file tree.cpp.

121{
122 return cref(doc(i));
123}

◆ 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 94 of file tree.cpp.

95{
96 return rootref()[key];
97}
csubstr const & key(id_type node) const
Definition tree.hpp:402
NodeRef rootref()
Get the root as a NodeRef . Note that a non-const Tree implicitly converts to NodeRef.
Definition tree.cpp:64

◆ 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 98 of file tree.cpp.

99{
100 return rootref()[key];
101}

◆ 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 within the parent

Definition at line 103 of file tree.cpp.

104{
105 return rootref()[i];
106}

◆ 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 within the parent

Definition at line 107 of file tree.cpp.

108{
109 return rootref()[i];
110}

◆ type()

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

Definition at line 399 of file tree.hpp.

399{ 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:327
NodeType m_type
Definition tree.hpp:236

◆ type_str()

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

Definition at line 400 of file tree.hpp.

400{ 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 402 of file tree.hpp.

402{ _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:430
NodeScalar m_key
Definition tree.hpp:238

◆ key_tag()

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

Definition at line 403 of file tree.hpp.

403{ _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:434

◆ key_ref()

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

Definition at line 404 of file tree.hpp.

404{ _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:439

◆ key_anchor()

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

Definition at line 405 of file tree.hpp.

405{ _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:436

◆ keysc()

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

Definition at line 406 of file tree.hpp.

406{ _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 408 of file tree.hpp.

408{ _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:431
NodeScalar m_val
Definition tree.hpp:239

◆ val_tag()

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

Definition at line 409 of file tree.hpp.

409{ _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:435

◆ val_ref()

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

Definition at line 410 of file tree.hpp.

410{ _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:440

◆ val_anchor()

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

Definition at line 411 of file tree.hpp.

411{ _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:437

◆ valsc()

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

Definition at line 412 of file tree.hpp.

412{ _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 421 of file tree.hpp.

421{ 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 422 of file tree.hpp.

422{ 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 423 of file tree.hpp.

423{ 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 425 of file tree.hpp.

425{ 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 426 of file tree.hpp.

426{ 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 427 of file tree.hpp.

427{ 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 428 of file tree.hpp.

428{ 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 429 of file tree.hpp.

429{ 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 430 of file tree.hpp.

430{ 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 431 of file tree.hpp.

431{ 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 432 of file tree.hpp.

432{ 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 433 of file tree.hpp.

433{ 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 434 of file tree.hpp.

434{ 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 435 of file tree.hpp.

435{ 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 436 of file tree.hpp.

436{ 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 437 of file tree.hpp.

437{ 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 438 of file tree.hpp.

438{ 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 439 of file tree.hpp.

439{ 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 440 of file tree.hpp.

440{ 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 441 of file tree.hpp.

441{ 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 443 of file tree.hpp.

443{ _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:429
bool has_parent(id_type node) const
Definition tree.hpp:479

◆ parent_is_map()

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

Definition at line 444 of file tree.hpp.

444{ _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:428

◆ 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 447 of file tree.hpp.

447{ 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 452 of file tree.hpp.

452{ _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 456 of file tree.hpp.

456{ _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 460 of file tree.hpp.

460{ 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 463 of file tree.hpp.

463{ 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 465 of file tree.hpp.

465{ 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 466 of file tree.hpp.

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

◆ is_anchor()

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

Definition at line 467 of file tree.hpp.

467{ 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 468 of file tree.hpp.

468{ 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 477 of file tree.hpp.

477{ _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:241

◆ has_parent()

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

Definition at line 479 of file tree.hpp.

479{ 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 1315 of file tree.cpp.

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

◆ 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 485 of file tree.hpp.

485{ 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
Definition tree.hpp:492
@ 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:147

◆ 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 488 of file tree.hpp.

488{ 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 490 of file tree.hpp.

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

◆ has_children()

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

true if node has any children

Definition at line 492 of file tree.hpp.

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

◆ 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 495 of file tree.hpp.

495{ 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 497 of file tree.hpp.

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

◆ 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 499 of file tree.hpp.

500 {
501 NodeData const *n = _p(node);
502 if(C4_LIKELY(n->m_parent != NONE))
503 {
504 n = _p(n->m_parent);
505 return n->m_first_child != n->m_last_child;
506 }
507 return false;
508 }

◆ parent()

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

Definition at line 517 of file tree.hpp.

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

◆ prev_sibling()

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

Definition at line 519 of file tree.hpp.

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

◆ next_sibling()

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

Definition at line 520 of file tree.hpp.

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

◆ num_children()

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

O(num_children).

Definition at line 1216 of file tree.cpp.

1217{
1218 id_type count = 0;
1219 for(id_type i = first_child(node); i != NONE; i = next_sibling(i))
1220 ++count;
1221 return count;
1222}
id_type first_child(id_type node) const
Definition tree.hpp:525
id_type next_sibling(id_type node) const
Definition tree.hpp:520

◆ child_pos()

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

Definition at line 1236 of file tree.cpp.

1237{
1238 _RYML_ASSERT_VISIT_(m_callbacks, node != NONE, this, node);
1239 id_type count = 0;
1240 for(id_type i = first_child(node); i != NONE; i = next_sibling(i))
1241 {
1242 if(i == ch)
1243 return count;
1244 ++count;
1245 }
1246 return NONE;
1247}

◆ first_child()

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

Definition at line 525 of file tree.hpp.

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

◆ last_child()

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

Definition at line 526 of file tree.hpp.

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

◆ child()

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

Definition at line 1224 of file tree.cpp.

1225{
1226 _RYML_ASSERT_VISIT_(m_callbacks, node != NONE, this, node);
1227 id_type count = 0;
1228 for(id_type i = first_child(node); i != NONE; i = next_sibling(i))
1229 {
1230 if(count++ == pos)
1231 return i;
1232 }
1233 return NONE;
1234}

◆ find_child()

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

Definition at line 1249 of file tree.cpp.

1250{
1251 C4_SUPPRESS_WARNING_PUSH
1252 #if defined(__clang__)
1253 #elif defined(__GNUC__)
1254 # if __GNUC__ >= 6
1255 C4_SUPPRESS_WARNING_GCC("-Wnull-dereference")
1256 # endif
1257 # if __GNUC__ > 9
1258 C4_SUPPRESS_WARNING_GCC("-Wanalyzer-null-dereference")
1259 # endif
1260 #endif
1261 _RYML_ASSERT_VISIT_(m_callbacks, node != NONE, this, node);
1262 _RYML_ASSERT_VISIT_(m_callbacks, is_map(node), this, node);
1263 if(_p(node)->m_first_child == NONE)
1264 {
1265 _RYML_ASSERT_VISIT_(m_callbacks, _p(node)->m_last_child == NONE, this, node);
1266 return NONE;
1267 }
1268 else
1269 {
1270 _RYML_ASSERT_VISIT_(m_callbacks, _p(node)->m_last_child != NONE, this, node);
1271 }
1272 for(id_type i = first_child(node); i != NONE; i = next_sibling(i))
1273 {
1274 if(_p(i)->m_key.scalar == name)
1275 {
1276 return i;
1277 }
1278 }
1279 return NONE;
1280 C4_SUPPRESS_WARNING_POP
1281}

◆ num_siblings()

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

O(num_siblings).

counts with this

Definition at line 532 of file tree.hpp.

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

◆ num_other_siblings()

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

does not count with this

Definition at line 534 of file tree.hpp.

534{ 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:532

◆ sibling_pos()

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

Definition at line 535 of file tree.hpp.

535{ _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:1236

◆ first_sibling()

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

Definition at line 536 of file tree.hpp.

536{ 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 537 of file tree.hpp.

537{ 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 538 of file tree.hpp.

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

◆ find_sibling()

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

Definition at line 539 of file tree.hpp.

539{ 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 1303 of file tree.cpp.

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

◆ 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 1297 of file tree.cpp.

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

◆ 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 545 of file tree.hpp.

545{ 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:425

◆ 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 548 of file tree.hpp.

549 {
550 NodeData const *nd;
551 do
552 {
553 nd = _p(node);
554 if(nd->m_type.is_doc() || nd->m_parent == NONE)
555 break;
556 node = nd->m_parent;
557 } while(nd->m_parent != NONE);
558 return node;
559 }

◆ is_container_styled()

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

Definition at line 568 of file tree.hpp.

568{ 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 569 of file tree.hpp.

569{ 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 570 of file tree.hpp.

570{ 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 572 of file tree.hpp.

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

◆ is_flow_ml1()

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

Definition at line 573 of file tree.hpp.

573{ return _p(node)->m_type.is_flow_ml1(); }

◆ is_flow_mln()

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

Definition at line 574 of file tree.hpp.

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

◆ is_flow_mlx()

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

Definition at line 575 of file tree.hpp.

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

◆ is_flow()

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

Definition at line 576 of file tree.hpp.

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

◆ has_flow_space()

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

Definition at line 577 of file tree.hpp.

577{ return _p(node)->m_type.has_flow_space(); }
bool has_flow_space() const noexcept

◆ is_key_styled()

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

Definition at line 579 of file tree.hpp.

579{ 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 580 of file tree.hpp.

580{ 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 581 of file tree.hpp.

581{ 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 582 of file tree.hpp.

582{ 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 583 of file tree.hpp.

583{ 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 584 of file tree.hpp.

584{ 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 585 of file tree.hpp.

585{ 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 586 of file tree.hpp.

586{ 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 587 of file tree.hpp.

587{ 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 588 of file tree.hpp.

588{ 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 589 of file tree.hpp.

589{ 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 590 of file tree.hpp.

590{ 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 591 of file tree.hpp.

591{ 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 592 of file tree.hpp.

592{ 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 593 of file tree.hpp.

593{ 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 595 of file tree.hpp.

595{ _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 596 of file tree.hpp.

596{ _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 598 of file tree.hpp.

598{ _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:427
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 599 of file tree.hpp.

599{ _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 600 of file tree.hpp.

600{ _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 1408 of file tree.cpp.

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

◆ 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 1418 of file tree.cpp.

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

◆ set_stream()

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

Definition at line 615 of file tree.hpp.

616 {
617 _RYML_ASSERT_VISIT_(m_callbacks, is_root(node), this, node);
618 _RYML_ASSERT_VISIT_(m_callbacks, (_p(node)->m_type & (DOC|MAP|VAL)) == 0, this, node);
619 _p(node)->m_type |= STREAM;
620 }
@ MAP
a map: a parent of KEYVAL/KEYSEQ/KEYMAP nodes
Definition node_type.hpp:39
@ STREAM
a stream: a seq of docs
Definition node_type.hpp:42
@ DOC
a document
Definition node_type.hpp:41

◆ set_doc()

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

Definition at line 622 of file tree.hpp.

623 {
624 _RYML_ASSERT_VISIT_(m_callbacks, is_root(node) || (is_root(parent(node)) && is_stream(parent(node))), this, node);
625 _p(node)->m_type |= DOC;
626 }

◆ set_val() [1/2]

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

Definition at line 628 of file tree.hpp.

629 {
630 _RYML_ASSERT_VISIT_(m_callbacks, (_p(node)->m_type & (SEQ|MAP)) == 0, this, node);
631 _RYML_ASSERT_VISIT_(m_callbacks, (parent(node) == NONE || (_p(parent(node))->m_type & (SEQ|MAP))), this, node);
632 NodeData *C4_RESTRICT nd = _p(node);
633 nd->m_type |= VAL;
634 nd->m_val.scalar = val;
635 }
csubstr const & val(id_type node) const
Definition tree.hpp:408
@ SEQ
a seq: a parent of VAL/SEQ/MAP nodes
Definition node_type.hpp:40

◆ set_val() [2/2]

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

Definition at line 636 of file tree.hpp.

637 {
638 _RYML_ASSERT_VISIT_(m_callbacks, (_p(node)->m_type & (SEQ|MAP)) == 0, this, node);
639 _RYML_ASSERT_VISIT_(m_callbacks, (parent(node) == NONE || (_p(parent(node))->m_type & (SEQ|MAP))), this, node);
640 NodeData *C4_RESTRICT nd = _p(node);
641 nd->m_type |= VAL|more_flags;
642 nd->m_val.scalar = val;
643 }

◆ set_key() [1/2]

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

Definition at line 645 of file tree.hpp.

646 {
647 _RYML_ASSERT_VISIT_(m_callbacks, (parent(node) != NONE && (_p(parent(node))->m_type & MAP)), this, node);
648 NodeData *C4_RESTRICT nd = _p(node);
649 nd->m_type |= KEY;
650 nd->m_key.scalar = key;
651 }
@ KEY
the scalar to the left of : in a map's member
Definition node_type.hpp:37

◆ set_key() [2/2]

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

Definition at line 652 of file tree.hpp.

653 {
654 _RYML_ASSERT_VISIT_(m_callbacks, (parent(node) != NONE && (_p(parent(node))->m_type & MAP)), this, node);
655 NodeData *C4_RESTRICT nd = _p(node);
656 nd->m_type |= KEY|more_flags;
657 nd->m_key.scalar = key;
658 }

◆ set_seq() [1/2]

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

Definition at line 660 of file tree.hpp.

661 {
662 _RYML_ASSERT_VISIT_(m_callbacks, (_p(node)->m_type & (VAL|MAP)) == 0, this, node);
663 _p(node)->m_type |= SEQ;
664 }

◆ set_seq() [2/2]

void c4::yml::Tree::set_seq ( id_type node,
NodeType more_flags )
inline

Definition at line 665 of file tree.hpp.

666 {
667 _RYML_ASSERT_VISIT_(m_callbacks, ((_p(node)->m_type|more_flags) & (VAL|MAP)) == 0, this, node);
668 _p(node)->m_type |= SEQ|more_flags;
669 }

◆ set_map() [1/2]

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

Definition at line 671 of file tree.hpp.

672 {
673 _RYML_ASSERT_VISIT_(m_callbacks, (_p(node)->m_type & (VAL|SEQ)) == 0, this, node);
674 _p(node)->m_type |= MAP;
675 }

◆ set_map() [2/2]

void c4::yml::Tree::set_map ( id_type node,
NodeType more_flags )
inline

Definition at line 676 of file tree.hpp.

677 {
678 _RYML_ASSERT_VISIT_(m_callbacks, ((_p(node)->m_type|more_flags) & (VAL|SEQ)) == 0, this, node);
679 _p(node)->m_type |= MAP|more_flags;
680 }

◆ set_key_tag()

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

Definition at line 682 of file tree.hpp.

682{ _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 683 of file tree.hpp.

683{ _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 685 of file tree.hpp.

685{ _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 686 of file tree.hpp.

686{ _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 687 of file tree.hpp.

687{ _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 688 of file tree.hpp.

688{ _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 690 of file tree.hpp.

690{ _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 691 of file tree.hpp.

691{ _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 692 of file tree.hpp.

692{ _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 693 of file tree.hpp.

693{ _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 694 of file tree.hpp.

694{ _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 581 of file tree.cpp.

582{
583 id_type r = root_id();
584 _do_reorder(&r, 0);
585}

◆ 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 1206 of file tree.cpp.

1207{
1208 if(m_size == 0)
1209 return;
1210 rr->resolve(this, clear_anchors);
1211}

◆ 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 1198 of file tree.cpp.

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

◆ 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 1557 of file tree.cpp.

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

◆ normalize_tags()

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

Definition at line 1575 of file tree.cpp.

1576{
1577 if(empty())
1578 return;
1579 _normalize_tags(this, root_id());
1580}

◆ normalize_tags_long()

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

Definition at line 1582 of file tree.cpp.

1583{
1584 if(empty())
1585 return;
1586 _normalize_tags_long(this, root_id());
1587}

◆ num_tag_directives()

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

Definition at line 1438 of file tree.cpp.

1439{
1440 return m_tag_directives.size();
1441}

◆ add_tag_directive()

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

Definition at line 1448 of file tree.cpp.

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

◆ clear_tag_directives()

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

Definition at line 1443 of file tree.cpp.

1444{
1445 m_tag_directives.clear();
1446}

◆ 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 1460 of file tree.cpp.

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

◆ 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 758 of file tree.hpp.

759 {
760 size_t needed = resolve_tag(output, tag, node_id);
761 return needed <= output.len ? output.first(needed) : output;
762 }
size_t resolve_tag(substr output, csubstr tag, id_type node_id) const
resolve the given tag, appearing at node_id.
Definition tree.cpp:1460

◆ tag_directives()

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

Definition at line 764 of file tree.hpp.

764{ 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 781 of file tree.hpp.

782 {
783 _RYML_ASSERT_VISIT_(m_callbacks, parent != NONE, this, parent);
784 _RYML_ASSERT_VISIT_(m_callbacks, is_container(parent) || is_root(parent), this, parent);
785 _RYML_ASSERT_VISIT_(m_callbacks, after == NONE || (_p(after)->m_parent == parent), this, parent);
786 id_type child = _claim();
787 _set_hierarchy(child, parent, after);
788 return child;
789 }

◆ 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 791 of file tree.hpp.

791{ 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:781

◆ 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 793 of file tree.hpp.

793{ 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 794 of file tree.hpp.

795 {
796 id_type child = _claim();
797 _set_hierarchy(child, parent, _p(parent)->m_last_child);
798 return child;
799 }

◆ 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 804 of file tree.hpp.

805 {
806 return insert_child(_p(node)->m_parent, after);
807 }

◆ 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 809 of file tree.hpp.

809{ 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:791

◆ append_sibling()

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

Definition at line 810 of file tree.hpp.

810{ 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:793

◆ 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 815 of file tree.hpp.

816 {
817 remove_children(node);
818 _release(node);
819 }
void remove_children(id_type node)
remove all the node's children, but keep the node itself
Definition tree.cpp:924

◆ 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 924 of file tree.cpp.

925{
926 _RYML_ASSERT_VISIT_(m_callbacks, get(node) != nullptr, this, node);
927 C4_SUPPRESS_WARNING_GCC_PUSH
928 #if defined(__GNUC__) && __GNUC__ >= 6
929 C4_SUPPRESS_WARNING_GCC("-Wnull-dereference")
930 #endif
931 id_type ich = get(node)->m_first_child;
932 while(ich != NONE)
933 {
934 remove_children(ich);
935 _RYML_ASSERT_VISIT_(m_callbacks, get(ich) != nullptr, this, node);
936 id_type next = get(ich)->m_next_sibling;
937 _release(ich);
938 if(ich == get(node)->m_last_child)
939 break;
940 ich = next;
941 }
942 C4_SUPPRESS_WARNING_GCC_POP
943}
NodeData * get(id_type node)
get a pointer to a node's NodeData. node can be NONE, in which case a nullptr is returned
Definition tree.hpp:308

◆ 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 825 of file tree.cpp.

826{
827 _RYML_ASSERT_VISIT_(m_callbacks, node != NONE, this, node);
828 _RYML_ASSERT_VISIT_(m_callbacks, node != after, this, node);
829 _RYML_ASSERT_VISIT_(m_callbacks, ! is_root(node), this, node);
830 _RYML_ASSERT_VISIT_(m_callbacks, (after == NONE) || (has_sibling(node, after) && has_sibling(after, node)), this, node);
831
832 _rem_hierarchy(node);
833 _set_hierarchy(node, parent(node), after);
834}
bool has_sibling(id_type node, id_type sib) const
true if node has a sibling with id sib
Definition tree.hpp:495

◆ 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 838 of file tree.cpp.

839{
840 _RYML_ASSERT_VISIT_(m_callbacks, node != NONE, this, node);
841 _RYML_ASSERT_VISIT_(m_callbacks, node != after, this, node);
842 _RYML_ASSERT_VISIT_(m_callbacks, new_parent != NONE, this, new_parent);
843 _RYML_ASSERT_VISIT_(m_callbacks, new_parent != node, this, new_parent);
844 _RYML_ASSERT_VISIT_(m_callbacks, new_parent != after, this, new_parent);
845 _RYML_ASSERT_VISIT_(m_callbacks, ! is_root(node), this, node);
846
847 _rem_hierarchy(node);
848 _set_hierarchy(node, new_parent, after);
849}

◆ 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 851 of file tree.cpp.

852{
853 _RYML_ASSERT_VISIT_(m_callbacks, src != nullptr, this, new_parent);
854 _RYML_ASSERT_VISIT_(m_callbacks, node != NONE, this, new_parent);
855 _RYML_ASSERT_VISIT_(m_callbacks, new_parent != NONE, this, new_parent);
856 _RYML_ASSERT_VISIT_(m_callbacks, new_parent != after, this, new_parent);
857
858 id_type dup = duplicate(src, node, new_parent, after);
859 src->remove(node);
860 return dup;
861}
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:964

◆ 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 863 of file tree.cpp.

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

◆ change_type() [1/2]

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

Definition at line 945 of file tree.cpp.

946{
947 _RYML_ASSERT_VISIT_(m_callbacks, type.is_val() || type.is_map() || type.is_seq(), this, node);
948 _RYML_ASSERT_VISIT_(m_callbacks, type.is_val() + type.is_map() + type.is_seq() == 1, this, node);
949 _RYML_ASSERT_VISIT_(m_callbacks, type.has_key() == has_key(node) || (has_key(node) && !type.has_key()), this, node);
950 NodeData *d = _p(node);
951 if(type.is_map() && is_map(node))
952 return false;
953 else if(type.is_seq() && is_seq(node))
954 return false;
955 else if(type.is_val() && is_val(node))
956 return false;
957 d->m_type = (d->m_type & (~(MAP|SEQ|VAL|CONTAINER_STYLE|KEY_STYLE|VAL_STYLE))) | type;
958 remove_children(node);
959 return true;
960}
bool is_val(id_type node) const
Definition tree.hpp:432
@ VAL_STYLE
mask of VALQUO|VAL_PLAIN : all the val scalar styles for val (not container styles!...
@ KEY_STYLE
mask of KEYQUO|KEY_PLAIN : all the key scalar styles for key (not container styles!...
@ CONTAINER_STYLE
mask of CONTAINER_STYLE_FLOW|CONTAINER_STYLE_BLOCK : all container style flags

◆ change_type() [2/2]

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

Definition at line 860 of file tree.hpp.

861 {
862 return change_type(node, (NodeType)type);
863 }
bool change_type(id_type node, NodeType type)
Definition tree.cpp:945

◆ 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 964 of file tree.cpp.

965{
966 return duplicate(this, node, parent, after);
967}

◆ 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 969 of file tree.cpp.

970{
971 _RYML_ASSERT_VISIT_(m_callbacks, src != nullptr, src, node);
972 _RYML_ASSERT_VISIT_(m_callbacks, node != NONE, src, node);
973 _RYML_ASSERT_VISIT_(m_callbacks, parent != NONE, this, parent);
974 _RYML_ASSERT_VISIT_(m_callbacks, ! src->is_root(node), src, node);
975
976 id_type copy = _claim();
977
978 _copy_props(copy, src, node);
979 _set_hierarchy(copy, parent, after);
980 duplicate_children(src, node, copy, NONE);
981
982 return copy;
983}
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:986

◆ 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 986 of file tree.cpp.

987{
988 return duplicate_children(this, node, parent, after);
989}

◆ 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 991 of file tree.cpp.

992{
993 _RYML_ASSERT_VISIT_(m_callbacks, src != nullptr, src, node);
994 _RYML_ASSERT_VISIT_(m_callbacks, node != NONE, src, node);
995 _RYML_ASSERT_VISIT_(m_callbacks, parent != NONE, this, parent);
996 _RYML_ASSERT_VISIT_(m_callbacks, after == NONE || has_child(parent, after), this, parent);
997
998 id_type prev = after;
999 for(id_type i = src->first_child(node); i != NONE; i = src->next_sibling(i))
1000 {
1001 prev = duplicate(src, i, parent, prev);
1002 }
1003
1004 return prev;
1005}
bool has_child(id_type node, id_type ch) const
true if node has a child with id ch
Definition tree.hpp:488

◆ 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 1023 of file tree.cpp.

1024{
1025 return duplicate_children_no_rep(this, node, parent, after);
1026}
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:1023

◆ 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 1028 of file tree.cpp.

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

1009{
1010 duplicate_contents(this, node, where);
1011}
void duplicate_contents(id_type node, id_type where)
Definition tree.cpp:1008

◆ duplicate_contents() [2/2]

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

Definition at line 1013 of file tree.cpp.

1014{
1015 _RYML_ASSERT_VISIT_(m_callbacks, src != nullptr, src, node);
1016 _RYML_ASSERT_VISIT_(m_callbacks, node != NONE, src, node);
1017 _RYML_ASSERT_VISIT_(m_callbacks, where != NONE, this, where);
1018 _copy_props_wo_key(where, src, node);
1019 duplicate_children(src, node, where, last_child(where));
1020}
id_type last_child(id_type node) const
Definition tree.hpp:526

◆ merge_with()

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

Definition at line 1123 of file tree.cpp.

1124{
1125 _RYML_ASSERT_VISIT_(m_callbacks, src != nullptr, src, src_node);
1126 if(src_node == NONE)
1127 src_node = src->root_id();
1128 if(dst_node == NONE)
1129 dst_node = root_id();
1130 _RYML_ASSERT_VISIT_(m_callbacks, src->has_val(src_node) || src->is_seq(src_node) || src->is_map(src_node), src, src_node);
1131 if(src->has_val(src_node))
1132 {
1133 type_bits mask_src = ~STYLE; // keep the existing style if it is already a val
1134 if( ! has_val(dst_node))
1135 {
1136 if(has_children(dst_node))
1137 remove_children(dst_node);
1138 mask_src |= VAL_STYLE; // copy the src style
1139 }
1140 if(src->is_keyval(src_node))
1141 {
1142 _copy_props(dst_node, src, src_node, mask_src);
1143 }
1144 else
1145 {
1146 _RYML_ASSERT_VISIT_(m_callbacks, src->is_val(src_node), src, src_node);
1147 _copy_props_wo_key(dst_node, src, src_node, mask_src);
1148 }
1149 }
1150 else if(src->is_seq(src_node))
1151 {
1152 if( ! is_seq(dst_node))
1153 {
1154 if(has_children(dst_node))
1155 remove_children(dst_node);
1156 _clear_type(dst_node);
1157 if(src->has_key(src_node))
1158 set_key(dst_node, src->key(src_node));
1159 set_seq(dst_node);
1160 _p(dst_node)->m_type = src->_p(src_node)->m_type;
1161 }
1162 for(id_type sch = src->first_child(src_node); sch != NONE; sch = src->next_sibling(sch))
1163 {
1164 id_type dch = append_child(dst_node);
1165 _copy_props_wo_key(dch, src, sch);
1166 merge_with(src, sch, dch);
1167 }
1168 }
1169 else
1170 {
1171 _RYML_ASSERT_VISIT_(m_callbacks, src->is_map(src_node), src, src_node);
1172 if( ! is_map(dst_node))
1173 {
1174 if(has_children(dst_node))
1175 remove_children(dst_node);
1176 _clear_type(dst_node);
1177 if(src->has_key(src_node))
1178 set_key(dst_node, src->key(src_node));
1179 set_map(dst_node);
1180 _p(dst_node)->m_type = src->_p(src_node)->m_type;
1181 }
1182 for(id_type sch = src->first_child(src_node); sch != NONE; sch = src->next_sibling(sch))
1183 {
1184 id_type dch = find_child(dst_node, src->key(sch));
1185 if(dch == NONE)
1186 {
1187 dch = append_child(dst_node);
1188 _copy_props(dch, src, sch);
1189 }
1190 merge_with(src, sch, dch);
1191 }
1192 }
1193}
void set_seq(id_type node) RYML_NOEXCEPT
Definition tree.hpp:660
void set_map(id_type node) RYML_NOEXCEPT
Definition tree.hpp:671
void set_key(id_type node, csubstr key) RYML_NOEXCEPT
Definition tree.hpp:645
void merge_with(Tree const *src, id_type src_node=NONE, id_type dst_root=NONE)
Definition tree.cpp:1123
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 1913 of file tree.cpp.

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

◆ arena_size()

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

get the current size of the tree's internal arena

Definition at line 922 of file tree.hpp.

922{ 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 924 of file tree.hpp.

924{ 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 926 of file tree.hpp.

926{ _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 927 of file tree.hpp.

927{ return m_arena_pos; }

◆ arena() [1/2]

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

get the current arena

Definition at line 930 of file tree.hpp.

930{ return m_arena.first(m_arena_pos); }

◆ arena() [2/2]

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

get the current arena

Definition at line 932 of file tree.hpp.

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

◆ arena_rem() [1/2]

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

get the free space at the end of the arena

Definition at line 935 of file tree.hpp.

935{ return m_arena.sub(m_arena_pos); }

◆ arena_rem() [2/2]

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

get the free space at the end of the arena

Definition at line 937 of file tree.hpp.

937{ return m_arena.sub(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 940 of file tree.hpp.

941 {
942 return m_arena.is_super(s);
943 }

◆ 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 962 of file tree.hpp.

963 {
964 return serialize_to_arena(this, a);
965 }
csubstr serialize_to_arena(Tree *tree, csubstr a)
Definition tree.cpp:27

◆ 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 983 of file tree.hpp.

984 {
985 _RYML_ASSERT_VISIT_(m_callbacks, !s.overlaps(m_arena), this, NONE);
986 substr cp = alloc_arena(s.len);
987 _RYML_ASSERT_VISIT_(m_callbacks, cp.len == s.len, this, NONE);
988 _RYML_ASSERT_VISIT_(m_callbacks, !s.overlaps(cp), this, NONE);
989 C4_SUPPRESS_WARNING_GCC_PUSH
990 #if (!defined(__clang__)) && (defined(__GNUC__) && __GNUC__ >= 10)
991 C4_SUPPRESS_WARNING_GCC("-Wstringop-overflow=") // no need for terminating \0
992 C4_SUPPRESS_WARNING_GCC("-Wrestrict") // there's an assert to ensure no violation of restrict behavior
993 #endif
994 if(s.len)
995 memcpy(cp.str, s.str, s.len);
996 C4_SUPPRESS_WARNING_GCC_POP
997 return cp;
998 }
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:1010
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 Tree::reserve_arena().
See also
reserve_arena()

Definition at line 1010 of file tree.hpp.

1011 {
1012 if(sz > arena_slack())
1013 _grow_arena(sz - arena_slack());
1014 substr s = _request_span(sz);
1015 return s;
1016 }
size_t arena_slack() const
get the current slack of the tree's internal arena
Definition tree.hpp:926

◆ 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 1022 of file tree.hpp.

1023 {
1024 if(arena_cap > m_arena.len)
1025 {
1026 substr buf;
1027 buf.str = _RYML_CB_ALLOC(m_callbacks, char, arena_cap);
1028 buf.len = arena_cap;
1029 if(m_arena.str)
1030 {
1031 _RYML_ASSERT_VISIT_(m_callbacks, m_arena.len >= 0, this, NONE);
1032 _relocate(buf); // does a memcpy and changes nodes using the arena
1033 _RYML_CB_FREE(m_callbacks, m_arena.str, char, m_arena.len);
1034 }
1035 m_arena = buf;
1036 }
1037 }
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 1612 of file tree.cpp.

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

◆ 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 1625 of file tree.cpp.

1626{
1627 id_type target = _lookup_path_or_create(path, start);
1628 set_val(target, default_value);
1629 return target;
1630}
void set_val(id_type node, csubstr val) RYML_NOEXCEPT
Definition tree.hpp:628

◆ 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 1632 of file tree.cpp.

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

Member Data Documentation

◆ m_buf

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

Definition at line 1293 of file tree.hpp.

◆ m_cap

id_type c4::yml::Tree::m_cap

Definition at line 1294 of file tree.hpp.

◆ m_size

id_type c4::yml::Tree::m_size

Definition at line 1295 of file tree.hpp.

◆ m_free_head

id_type c4::yml::Tree::m_free_head

Definition at line 1297 of file tree.hpp.

◆ m_free_tail

id_type c4::yml::Tree::m_free_tail

Definition at line 1298 of file tree.hpp.

◆ m_arena

substr c4::yml::Tree::m_arena

Definition at line 1300 of file tree.hpp.

◆ m_arena_pos

size_t c4::yml::Tree::m_arena_pos

Definition at line 1301 of file tree.hpp.

◆ m_callbacks

Callbacks c4::yml::Tree::m_callbacks

Definition at line 1303 of file tree.hpp.

◆ m_tag_directives

TagDirectives c4::yml::Tree::m_tag_directives

Definition at line 1305 of file tree.hpp.


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