rapidyaml  0.13.0
parse and emit YAML, and do it fast
c4::yml::Tree Class Reference

#include <tree.hpp>

Classes

struct  lookup_result
 

Public Member Functions

id_type _claim ()
 
construction and assignment
 Tree ()
 
 Tree (Callbacks const &cb)
 
 Tree (id_type node_capacity, size_t arena_capacity=RYML_DEFAULT_TREE_ARENA_CAPACITY)
 
 Tree (id_type node_capacity, size_t arena_capacity, Callbacks const &cb)
 
 ~Tree ()
 
 Tree (Tree const &that)
 
 Tree (Tree &&that) noexcept
 
Treeoperator= (Tree const &that)
 
Treeoperator= (Tree &&that) noexcept
 
memory and sizing
void reserve (id_type node_capacity=RYML_DEFAULT_TREE_CAPACITY)
 
void clear ()
 clear the tree and zero every node More...
 
void clear_arena ()
 
bool empty () const
 
id_type size () const
 
id_type capacity () const
 
id_type slack () const
 
Callbacks const & callbacks () const
 
void callbacks (Callbacks const &cb)
 
node getters
id_type id (NodeData const *n) const
 get the index of a node belonging to this tree. n can be nullptr, in which case NONE is returned More...
 
NodeDataget (id_type node)
 get a pointer to a node's NodeData. i can be NONE, in which case a nullptr is returned More...
 
NodeData const * get (id_type node) const
 get a pointer to a node's NodeData. i can be NONE, in which case a nullptr is returned. More...
 
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. More...
 
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. More...
 
id_type root_id () const
 Get the id of the root node. The tree must not be empty. More...
 
NodeRef ref (id_type node)
 Get a NodeRef of a node by id. More...
 
ConstNodeRef ref (id_type node) const
 Get a NodeRef of a node by id. More...
 
ConstNodeRef cref (id_type node) const
 Get a NodeRef of a node by id. More...
 
NodeRef rootref ()
 Get the root as a NodeRef. More...
 
ConstNodeRef rootref () const
 Get the root as a ConstNodeRef. More...
 
ConstNodeRef crootref () const
 Get the root as a ConstNodeRef. More...
 
NodeRef docref (id_type i)
 get the i-th document of the stream More...
 
ConstNodeRef docref (id_type i) const
 get the i-th document of the stream More...
 
ConstNodeRef cdocref (id_type i) const
 get the i-th document of the stream More...
 
NodeRef operator[] (csubstr key)
 find a root child (ie child of root) by name, return it as a NodeRef More...
 
ConstNodeRef operator[] (csubstr key) const
 find a root child (ie child of root) by name, return it as a NodeRef More...
 
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 More...
 
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 More...
 
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 More...
 
bool key_is_null (id_type node) const
 true if the node key is empty, or its scalar verifies scalar_is_null(). More...
 
bool val_is_null (id_type node) const
 true if the node val is empty, or its scalar verifies scalar_is_null(). More...
 
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) More...
 
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) More...
 
bool is_key_anchor (id_type node) const
 
bool is_val_anchor (id_type node) const
 
bool is_anchor (id_type node) const
 
bool is_anchor_or_ref (id_type node) const
 
hierarchy getters
id_type parent (id_type node) const
 
id_type prev_sibling (id_type node) const
 
id_type next_sibling (id_type node) const
 
id_type num_children (id_type node) const
 O(num_children) More...
 
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) More...
 
id_type num_other_siblings (id_type node) const
 does not count with this More...
 
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. More...
 
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. More...
 
id_type doc (id_type i) const
 gets the i document node index. More...
 
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 More...
 
node style predicates and modifiers. see the corresponding predicate in NodeType
bool is_container_styled (id_type node) const
 
bool is_block (id_type node) const
 
bool is_flow_sl (id_type node) const
 
bool is_flow_ml (id_type node) const
 
bool is_flow (id_type node) const
 
bool is_key_styled (id_type node) const
 
bool is_val_styled (id_type node) const
 
bool is_key_literal (id_type node) const
 
bool is_val_literal (id_type node) const
 
bool is_key_folded (id_type node) const
 
bool is_val_folded (id_type node) const
 
bool is_key_squo (id_type node) const
 
bool is_val_squo (id_type node) const
 
bool is_key_dquo (id_type node) const
 
bool is_val_dquo (id_type node) const
 
bool is_key_plain (id_type node) const
 
bool is_val_plain (id_type node) const
 
bool is_key_quoted (id_type node) const
 
bool is_val_quoted (id_type node) const
 
bool is_quoted (id_type node) const
 
NodeType key_style (id_type node) const
 
NodeType val_style (id_type node) const
 
void set_container_style (id_type node, NodeType_e style)
 
void set_key_style (id_type node, NodeType_e style)
 
void set_val_style (id_type node, NodeType_e style)
 
void clear_style (id_type node, bool recurse=false)
 
void set_style_conditionally (id_type node, NodeType type_mask, NodeType rem_style_flags, NodeType add_style_flags, bool recurse=false)
 
node type modifiers
void to_keyval (id_type node, csubstr key, csubstr val, type_bits more_flags=0)
 
void to_map (id_type node, csubstr key, type_bits more_flags=0)
 
void to_seq (id_type node, csubstr key, type_bits more_flags=0)
 
void to_val (id_type node, csubstr val, type_bits more_flags=0)
 
void to_map (id_type node, type_bits more_flags=0)
 
void to_seq (id_type node, type_bits more_flags=0)
 
void to_doc (id_type node, type_bits more_flags=0)
 
void to_stream (id_type node, type_bits more_flags=0)
 
void set_key (id_type node, csubstr key)
 
void set_val (id_type node, csubstr val)
 
void set_key_tag (id_type node, csubstr tag)
 
void set_val_tag (id_type node, csubstr tag)
 
void set_key_anchor (id_type node, csubstr anchor)
 
void set_val_anchor (id_type node, csubstr anchor)
 
void set_key_ref (id_type node, csubstr ref)
 
void set_val_ref (id_type node, csubstr ref)
 
void rem_key_anchor (id_type node)
 
void rem_val_anchor (id_type node)
 
void rem_key_ref (id_type node)
 
void rem_val_ref (id_type node)
 
void rem_anchor_ref (id_type node)
 
tree modifiers
void reorder ()
 reorder the tree in memory so that all the nodes are stored in a linear sequence when visited in depth-first order. More...
 
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. More...
 
void resolve (bool clear_anchors=true)
 Resolve references (aliases <- anchors), by forwarding to ReferenceResolver::resolve(); refer to ReferenceResolver::resolve() for further details. More...
 
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. More...
 
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. More...
 
csubstr resolve_tag_sub (substr output, csubstr tag, id_type node_id) const
 Wrapper for Tree::resolve_tag(), returning a substring. More...
 
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. More...
 
id_type prepend_child (id_type parent)
 create and insert a node as the first child of parent More...
 
id_type append_child (id_type parent)
 create and insert a node as the last child of parent More...
 
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" More...
 
id_type prepend_sibling (id_type node)
 create and insert a node as the first node of parent More...
 
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 More...
 
void remove_children (id_type node)
 remove all the node's children, but keep the node itself More...
 
bool change_type (id_type node, NodeType type)
 change the type of the node to one of MAP, SEQ or VAL. More...
 
bool change_type (id_type node, type_bits type)
 
void move (id_type node, id_type after)
 change the node's position in the parent More...
 
void move (id_type node, id_type new_parent, id_type after)
 change the node's parent and position More...
 
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 More...
 
void set_root_as_stream ()
 ensure the first node is a stream. More...
 
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 More...
 
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 More...
 
id_type duplicate_children (id_type node, id_type parent, id_type after)
 recursively duplicate the node's children (but not the node) More...
 
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 More...
 
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). More...
 
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 More...
 
size_t arena_capacity () const
 get the current capacity of the tree's internal arena More...
 
size_t arena_slack () const
 get the current slack of the tree's internal arena More...
 
size_t arena_pos () const
 
csubstr arena () const
 get the current arena More...
 
substr arena ()
 get the current arena More...
 
bool in_arena (csubstr s) const
 return true if the given substring is part of the tree's string arena More...
 
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. More...
 
substr copy_to_arena (csubstr s)
 copy the given string to the tree's arena, growing the arena by the required size. More...
 
substr alloc_arena (size_t sz)
 grow the tree's string arena by the given size and return a substr of the added portion More...
 
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 More...
 
lookup
lookup_result lookup_path (csubstr path, id_type start=NONE) const
 for example foo.bar[0].baz More...
 
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. More...
 
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). More...
 

Public Attributes

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

hierarchy predicates

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

locations

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

Detailed Description

Definition at line 247 of file tree.hpp.

Constructor & Destructor Documentation

◆ Tree() [1/6]

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

Definition at line 254 of file tree.hpp.

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

◆ Tree() [2/6]

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

Definition at line 119 of file tree.cpp.

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

◆ Tree() [3/6]

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

Definition at line 256 of file tree.hpp.

256 : 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:876

◆ Tree() [4/6]

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

Definition at line 124 of file tree.cpp.

125  : m_buf(nullptr)
126  , m_cap(0)
127  , m_size(0)
128  , m_free_head(NONE)
129  , m_free_tail(NONE)
130  , m_arena()
131  , m_arena_pos(0)
132  , m_callbacks(cb)
133  , m_tag_directives()
134 {
135  if(node_capacity)
136  reserve(node_capacity);
137  if(arena_capacity)
139 }
NodeData * m_buf
Definition: tree.hpp:1329
id_type m_free_head
Definition: tree.hpp:1333
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:971
size_t m_arena_pos
Definition: tree.hpp:1337
void reserve(id_type node_capacity=RYML_DEFAULT_TREE_CAPACITY)
Definition: tree.cpp:292
TagDirectives m_tag_directives
Definition: tree.hpp:1341
id_type m_size
Definition: tree.hpp:1331
id_type m_cap
Definition: tree.hpp:1330
substr m_arena
Definition: tree.hpp:1336
id_type m_free_tail
Definition: tree.hpp:1334
Callbacks m_callbacks
Definition: tree.hpp:1339
@ NONE
an index to none
Definition: common.hpp:251

◆ ~Tree()

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

Definition at line 141 of file tree.cpp.

142 {
143  _free();
144 }

◆ Tree() [5/6]

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

Definition at line 147 of file tree.cpp.

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

◆ Tree() [6/6]

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

Definition at line 153 of file tree.cpp.

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

Member Function Documentation

◆ operator=() [1/2]

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

Definition at line 159 of file tree.cpp.

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

◆ operator=() [2/2]

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

Definition at line 170 of file tree.cpp.

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

◆ reserve()

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

Definition at line 292 of file tree.cpp.

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

◆ clear()

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

clear the tree and zero every node

Note
does NOT clear the arena
See also
clear_arena()

Definition at line 330 of file tree.cpp.

331 {
332  _clear_range(0, m_cap);
333  m_size = 0;
334  if(m_buf)
335  {
336  _RYML_ASSERT_VISIT_(m_callbacks, m_cap >= 0, this, NONE);
337  m_free_head = 0;
338  m_free_tail = m_cap-1;
339  _claim_root();
340  }
341  else
342  {
343  m_free_head = NONE;
344  m_free_tail = NONE;
345  }
347 }
void clear() noexcept
Definition: tag.cpp:373

◆ clear_arena()

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

Definition at line 280 of file tree.hpp.

280 { m_arena_pos = 0; }

◆ empty() [1/2]

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

Definition at line 282 of file tree.hpp.

282 { return m_size == 0; }

◆ size()

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

Definition at line 284 of file tree.hpp.

284 { return m_size; }

◆ capacity()

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

Definition at line 285 of file tree.hpp.

285 { return m_cap; }

◆ slack()

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

Definition at line 286 of file tree.hpp.

286 { _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 288 of file tree.hpp.

288 { return m_callbacks; }

◆ callbacks() [2/2]

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

Definition at line 289 of file tree.hpp.

289 { m_callbacks = cb; }

◆ id()

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

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

Definition at line 300 of file tree.hpp.

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

◆ get() [1/2]

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

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

Definition at line 310 of file tree.hpp.

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

◆ get() [2/2]

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

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

Definition at line 319 of file tree.hpp.

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

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

329 { _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 332 of file tree.hpp.

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

◆ root_id()

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

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

Definition at line 335 of file tree.hpp.

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

◆ ref() [1/2]

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

Get a NodeRef of a node by id.

Definition at line 70 of file tree.cpp.

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

◆ ref() [2/2]

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

Get a NodeRef of a node by id.

Definition at line 75 of file tree.cpp.

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

◆ cref()

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

Get a NodeRef of a node by id.

Definition at line 80 of file tree.cpp.

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

◆ rootref() [1/2]

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

Get the root as a NodeRef.

Definition at line 56 of file tree.cpp.

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

◆ rootref() [2/2]

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

Get the root as a ConstNodeRef.

Definition at line 60 of file tree.cpp.

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

◆ crootref()

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

Get the root as a ConstNodeRef.

Definition at line 65 of file tree.cpp.

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

◆ docref() [1/2]

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

get the i-th document of the stream

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

Definition at line 104 of file tree.cpp.

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

◆ docref() [2/2]

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

get the i-th document of the stream

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

Definition at line 108 of file tree.cpp.

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

◆ cdocref()

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

get the i-th document of the stream

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

Definition at line 112 of file tree.cpp.

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

◆ operator[]() [1/4]

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

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

Note
requires the root to be a map.

Definition at line 86 of file tree.cpp.

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

◆ operator[]() [2/4]

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

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

Note
requires the root to be a map.

Definition at line 90 of file tree.cpp.

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

◆ operator[]() [3/4]

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

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

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

Definition at line 95 of file tree.cpp.

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

◆ operator[]() [4/4]

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

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

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

Definition at line 99 of file tree.cpp.

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

◆ type()

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

Definition at line 382 of file tree.hpp.

382 { 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:329
NodeType m_type
Definition: tree.hpp:229

◆ type_str()

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

Definition at line 383 of file tree.hpp.

383 { return NodeType::type_str(_p(node)->m_type); }
const char * type_str() const noexcept
return a preset string based on the node type
Definition: node_type.hpp:154

◆ key()

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

Definition at line 385 of file tree.hpp.

385 { _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:413
NodeScalar m_key
Definition: tree.hpp:231
csubstr scalar
Definition: tree.hpp:113

◆ key_tag()

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

Definition at line 386 of file tree.hpp.

386 { _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:417

◆ key_ref()

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

Definition at line 387 of file tree.hpp.

387 { _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:422
csubstr anchor
Definition: tree.hpp:114

◆ key_anchor()

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

Definition at line 388 of file tree.hpp.

388 { _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:419

◆ keysc()

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

Definition at line 389 of file tree.hpp.

389 { _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 391 of file tree.hpp.

391 { _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:414
NodeScalar m_val
Definition: tree.hpp:232

◆ val_tag()

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

Definition at line 392 of file tree.hpp.

392 { _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:418

◆ val_ref()

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

Definition at line 393 of file tree.hpp.

393 { _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:423

◆ val_anchor()

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

Definition at line 394 of file tree.hpp.

394 { _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:420

◆ valsc()

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

Definition at line 395 of file tree.hpp.

395 { _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 404 of file tree.hpp.

404 { return _p(node)->m_type.has_any(bits); }
bool has_any(NodeType_e t) const noexcept
Definition: node_type.hpp:132

◆ type_has_all()

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

Definition at line 405 of file tree.hpp.

405 { return _p(node)->m_type.has_all(bits); }
bool has_all(NodeType_e t) const noexcept
Definition: node_type.hpp:133

◆ type_has_none()

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

Definition at line 406 of file tree.hpp.

406 { return _p(node)->m_type.has_none(bits); }
bool has_none(NodeType_e t) const noexcept
Definition: node_type.hpp:134

◆ is_stream()

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

Definition at line 408 of file tree.hpp.

408 { return _p(node)->m_type.is_stream(); }
bool is_stream() const noexcept
Definition: node_type.hpp:180

◆ is_doc()

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

Definition at line 409 of file tree.hpp.

409 { return _p(node)->m_type.is_doc(); }
bool is_doc() const noexcept
Definition: node_type.hpp:181

◆ is_container()

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

Definition at line 410 of file tree.hpp.

410 { return _p(node)->m_type.is_container(); }
bool is_container() const noexcept
Definition: node_type.hpp:182

◆ is_map()

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

Definition at line 411 of file tree.hpp.

411 { return _p(node)->m_type.is_map(); }
bool is_map() const noexcept
Definition: node_type.hpp:183

◆ is_seq()

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

Definition at line 412 of file tree.hpp.

412 { return _p(node)->m_type.is_seq(); }
bool is_seq() const noexcept
Definition: node_type.hpp:184

◆ has_key()

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

Definition at line 413 of file tree.hpp.

413 { return _p(node)->m_type.has_key(); }
bool has_key() const noexcept
Definition: node_type.hpp:185

◆ has_val()

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

Definition at line 414 of file tree.hpp.

414 { return _p(node)->m_type.has_val(); }
bool has_val() const noexcept
Definition: node_type.hpp:186

◆ is_val()

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

Definition at line 415 of file tree.hpp.

415 { return _p(node)->m_type.is_val(); }
bool is_val() const noexcept
Definition: node_type.hpp:187

◆ is_keyval()

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

Definition at line 416 of file tree.hpp.

416 { return _p(node)->m_type.is_keyval(); }
bool is_keyval() const noexcept
Definition: node_type.hpp:188

◆ has_key_tag()

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

Definition at line 417 of file tree.hpp.

417 { return _p(node)->m_type.has_key_tag(); }
bool has_key_tag() const noexcept
Definition: node_type.hpp:191

◆ has_val_tag()

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

Definition at line 418 of file tree.hpp.

418 { return _p(node)->m_type.has_val_tag(); }
bool has_val_tag() const noexcept
Definition: node_type.hpp:192

◆ has_key_anchor()

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

Definition at line 419 of file tree.hpp.

419 { return _p(node)->m_type.has_key_anchor(); }
bool has_key_anchor() const noexcept
Definition: node_type.hpp:193

◆ has_val_anchor()

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

Definition at line 420 of file tree.hpp.

420 { return _p(node)->m_type.has_val_anchor(); }
bool has_val_anchor() const noexcept
Definition: node_type.hpp:194

◆ has_anchor() [1/2]

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

Definition at line 421 of file tree.hpp.

421 { return _p(node)->m_type.has_anchor(); }
bool has_anchor() const noexcept
Definition: node_type.hpp:195

◆ is_key_ref()

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

Definition at line 422 of file tree.hpp.

422 { return _p(node)->m_type.is_key_ref(); }
bool is_key_ref() const noexcept
Definition: node_type.hpp:196

◆ is_val_ref()

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

Definition at line 423 of file tree.hpp.

423 { return _p(node)->m_type.is_val_ref(); }
bool is_val_ref() const noexcept
Definition: node_type.hpp:197

◆ is_ref()

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

Definition at line 424 of file tree.hpp.

424 { return _p(node)->m_type.is_ref(); }
bool is_ref() const noexcept
Definition: node_type.hpp:198

◆ parent_is_seq()

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

Definition at line 426 of file tree.hpp.

426 { _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:412
bool has_parent(id_type node) const
Definition: tree.hpp:462

◆ parent_is_map()

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

Definition at line 427 of file tree.hpp.

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

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

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

435 { _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.
Definition: node_type.cpp:289

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

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

443 { return _p(node)->m_type.is_key_unfiltered(); }
bool is_key_unfiltered() const noexcept
Definition: node_type.hpp:200

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

446 { return _p(node)->m_type.is_val_unfiltered(); }
bool is_val_unfiltered() const noexcept
Definition: node_type.hpp:201

◆ is_key_anchor()

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

Definition at line 448 of file tree.hpp.

448 { 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 449 of file tree.hpp.

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

◆ is_anchor()

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

Definition at line 450 of file tree.hpp.

450 { 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 451 of file tree.hpp.

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

460 { _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:234

◆ has_parent()

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

Definition at line 462 of file tree.hpp.

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

◆ is_ancestor()

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

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

Definition at line 1317 of file tree.cpp.

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

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

468 { return ! has_children(node) && _p(node)->m_key.empty() && (( ! (_p(node)->m_type & VAL)) || _p(node)->m_val.empty()); }
bool has_children(id_type node) const
true if node has any children key
Definition: tree.hpp:475
@ 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:141

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

471 { 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 473 of file tree.hpp.

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

◆ has_children()

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

true if node has any children key

Definition at line 475 of file tree.hpp.

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

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

478 { 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 480 of file tree.hpp.

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

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

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

◆ has_siblings()

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

Definition at line 493 of file tree.hpp.

493 { return true; }

◆ parent()

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

Definition at line 502 of file tree.hpp.

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

◆ prev_sibling()

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

Definition at line 504 of file tree.hpp.

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

◆ next_sibling()

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

Definition at line 505 of file tree.hpp.

505 { return _p(node)->m_next_sibling; }

◆ num_children()

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

O(num_children)

Definition at line 1212 of file tree.cpp.

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

◆ child_pos()

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

Definition at line 1232 of file tree.cpp.

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

◆ first_child()

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

Definition at line 510 of file tree.hpp.

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

◆ last_child()

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

Definition at line 511 of file tree.hpp.

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

◆ child()

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

Definition at line 1220 of file tree.cpp.

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

◆ find_child()

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

Definition at line 1257 of file tree.cpp.

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

◆ num_siblings()

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

O(num_siblings)

counts with this

Definition at line 517 of file tree.hpp.

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

◆ num_other_siblings()

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

does not count with this

Definition at line 519 of file tree.hpp.

519 { 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:517

◆ sibling_pos()

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

Definition at line 520 of file tree.hpp.

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

◆ first_sibling()

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

Definition at line 521 of file tree.hpp.

521 { 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 522 of file tree.hpp.

522 { 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 523 of file tree.hpp.

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

◆ find_sibling()

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

Definition at line 524 of file tree.hpp.

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

◆ depth_asc()

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

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

Definition at line 1305 of file tree.cpp.

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

◆ depth_desc()

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

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

Definition at line 1299 of file tree.cpp.

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

◆ doc()

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

gets the i document node index.

requires that the root node is a stream.

Definition at line 530 of file tree.hpp.

530 { 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:408

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

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

◆ is_container_styled()

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

Definition at line 553 of file tree.hpp.

553 { return _p(node)->m_type.is_container_styled(); }
bool is_container_styled() const noexcept
Definition: node_type.hpp:214

◆ is_block()

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

Definition at line 554 of file tree.hpp.

554 { return _p(node)->m_type.is_block(); }
bool is_block() const noexcept
Definition: node_type.hpp:215

◆ is_flow_sl()

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

Definition at line 555 of file tree.hpp.

555 { return _p(node)->m_type.is_flow_sl(); }
bool is_flow_sl() const noexcept
Definition: node_type.hpp:216

◆ is_flow_ml()

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

Definition at line 556 of file tree.hpp.

556 { return _p(node)->m_type.is_flow_ml(); }
bool is_flow_ml() const noexcept
Definition: node_type.hpp:217

◆ is_flow()

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

Definition at line 557 of file tree.hpp.

557 { return _p(node)->m_type.is_flow(); }
bool is_flow() const noexcept
Definition: node_type.hpp:218

◆ is_key_styled()

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

Definition at line 559 of file tree.hpp.

559 { return _p(node)->m_type.is_key_styled(); }
bool is_key_styled() const noexcept
Definition: node_type.hpp:220

◆ is_val_styled()

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

Definition at line 560 of file tree.hpp.

560 { return _p(node)->m_type.is_val_styled(); }
bool is_val_styled() const noexcept
Definition: node_type.hpp:221

◆ is_key_literal()

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

Definition at line 561 of file tree.hpp.

561 { return _p(node)->m_type.is_key_literal(); }
bool is_key_literal() const noexcept
Definition: node_type.hpp:222

◆ is_val_literal()

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

Definition at line 562 of file tree.hpp.

562 { return _p(node)->m_type.is_val_literal(); }
bool is_val_literal() const noexcept
Definition: node_type.hpp:223

◆ is_key_folded()

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

Definition at line 563 of file tree.hpp.

563 { return _p(node)->m_type.is_key_folded(); }
bool is_key_folded() const noexcept
Definition: node_type.hpp:224

◆ is_val_folded()

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

Definition at line 564 of file tree.hpp.

564 { return _p(node)->m_type.is_val_folded(); }
bool is_val_folded() const noexcept
Definition: node_type.hpp:225

◆ is_key_squo()

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

Definition at line 565 of file tree.hpp.

565 { return _p(node)->m_type.is_key_squo(); }
bool is_key_squo() const noexcept
Definition: node_type.hpp:226

◆ is_val_squo()

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

Definition at line 566 of file tree.hpp.

566 { return _p(node)->m_type.is_val_squo(); }
bool is_val_squo() const noexcept
Definition: node_type.hpp:227

◆ is_key_dquo()

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

Definition at line 567 of file tree.hpp.

567 { return _p(node)->m_type.is_key_dquo(); }
bool is_key_dquo() const noexcept
Definition: node_type.hpp:228

◆ is_val_dquo()

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

Definition at line 568 of file tree.hpp.

568 { return _p(node)->m_type.is_val_dquo(); }
bool is_val_dquo() const noexcept
Definition: node_type.hpp:229

◆ is_key_plain()

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

Definition at line 569 of file tree.hpp.

569 { return _p(node)->m_type.is_key_plain(); }
bool is_key_plain() const noexcept
Definition: node_type.hpp:230

◆ is_val_plain()

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

Definition at line 570 of file tree.hpp.

570 { return _p(node)->m_type.is_val_plain(); }
bool is_val_plain() const noexcept
Definition: node_type.hpp:231

◆ is_key_quoted()

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

Definition at line 571 of file tree.hpp.

571 { return _p(node)->m_type.is_key_quoted(); }
bool is_key_quoted() const noexcept
Definition: node_type.hpp:232

◆ is_val_quoted()

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

Definition at line 572 of file tree.hpp.

572 { return _p(node)->m_type.is_val_quoted(); }
bool is_val_quoted() const noexcept
Definition: node_type.hpp:233

◆ is_quoted()

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

Definition at line 573 of file tree.hpp.

573 { return _p(node)->m_type.is_quoted(); }
bool is_quoted() const noexcept
Definition: node_type.hpp:234

◆ key_style()

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

Definition at line 575 of file tree.hpp.

575 { _RYML_ASSERT_VISIT_(m_callbacks, has_key(node), this, node); return _p(node)->m_type.key_style(); }
NodeType key_style() const noexcept
Definition: node_type.hpp:236

◆ val_style()

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

Definition at line 576 of file tree.hpp.

576 { _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
Definition: node_type.hpp:237

◆ set_container_style()

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

Definition at line 578 of file tree.hpp.

578 { _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:410
void set_container_style(NodeType_e style) noexcept
Definition: node_type.hpp:239

◆ set_key_style()

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

Definition at line 579 of file tree.hpp.

579 { _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
Definition: node_type.hpp:240

◆ set_val_style()

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

Definition at line 580 of file tree.hpp.

580 { _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
Definition: node_type.hpp:241

◆ clear_style()

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

Definition at line 1406 of file tree.cpp.

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

◆ set_style_conditionally()

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

Definition at line 1416 of file tree.cpp.

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

◆ to_keyval()

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

Definition at line 1342 of file tree.cpp.

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

◆ to_map() [1/2]

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

Definition at line 1360 of file tree.cpp.

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

◆ to_seq() [1/2]

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

Definition at line 1378 of file tree.cpp.

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

◆ to_val()

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

Definition at line 1333 of file tree.cpp.

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

◆ to_map() [2/2]

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

Definition at line 1351 of file tree.cpp.

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

◆ to_seq() [2/2]

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

Definition at line 1369 of file tree.cpp.

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

◆ to_doc()

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

Definition at line 1387 of file tree.cpp.

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

◆ to_stream()

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

Definition at line 1395 of file tree.cpp.

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

◆ set_key()

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

Definition at line 604 of file tree.hpp.

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

◆ set_val()

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

Definition at line 605 of file tree.hpp.

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

◆ set_key_tag()

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

Definition at line 607 of file tree.hpp.

607 { _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 608 of file tree.hpp.

608 { _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 610 of file tree.hpp.

610 { _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

◆ set_val_anchor()

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

Definition at line 611 of file tree.hpp.

611 { _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 612 of file tree.hpp.

612 { _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
bool has_key() const RYML_NOEXCEPT
Forward to Tree::has_key().
Definition: node.hpp:244

◆ set_val_ref()

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

Definition at line 613 of file tree.hpp.

613 { _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
bool has_val() const RYML_NOEXCEPT
Forward to Tree::has_val().
Definition: node.hpp:243

◆ rem_key_anchor()

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

Definition at line 615 of file tree.hpp.

615 { _p(node)->m_key.anchor.clear(); _rem_flags(node, KEYANCH); }

◆ rem_val_anchor()

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

Definition at line 616 of file tree.hpp.

616 { _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 617 of file tree.hpp.

617 { _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 618 of file tree.hpp.

618 { _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 619 of file tree.hpp.

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

◆ reorder()

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

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

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

Definition at line 576 of file tree.cpp.

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

◆ resolve() [1/2]

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

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

Definition at line 1202 of file tree.cpp.

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

◆ resolve() [2/2]

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

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

This overload uses a throwaway resolver object.

Definition at line 1194 of file tree.cpp.

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

◆ resolve_tags()

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

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

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

Definition at line 1555 of file tree.cpp.

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

◆ normalize_tags()

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

Definition at line 1573 of file tree.cpp.

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

◆ normalize_tags_long()

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

Definition at line 1580 of file tree.cpp.

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

◆ num_tag_directives()

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

Definition at line 1436 of file tree.cpp.

1437 {
1438  return m_tag_directives.size();
1439 }
id_type size() const noexcept
Definition: tag.cpp:348

◆ add_tag_directive()

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

Definition at line 1446 of file tree.cpp.

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

◆ clear_tag_directives()

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

Definition at line 1441 of file tree.cpp.

1442 {
1444 }

◆ resolve_tag()

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

resolve the given tag, appearing at node_id.

Write the result into output.

Returns
the number of characters required for the resolved tag

Definition at line 1458 of file tree.cpp.

1459 {
1460  size_t reqsz = 0;
1461  m_tag_directives.resolve(output, &reqsz, tag, node_id, Location{}, callbacks());
1462  return reqsz;
1463 }
csubstr resolve(substr buf, size_t *bufsz, csubstr tag, id_type doc_id, Location const &ymlloc, Callbacks const &callbacks, bool with_brackets=true) const
Definition: tag.cpp:449

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

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

◆ tag_directives()

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

Definition at line 690 of file tree.hpp.

690 { return m_tag_directives.directives(); }
TagDirectiveRange directives() const noexcept
Definition: tag.hpp:137

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

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

◆ prepend_child()

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

create and insert a node as the first child of parent

Definition at line 717 of file tree.hpp.

717 { 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:707

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

719 { 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 720 of file tree.hpp.

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

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

741  {
742  return insert_child(_p(node)->m_parent, after);
743  }

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

745 { 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:717

◆ append_sibling()

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

Definition at line 746 of file tree.hpp.

746 { 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:719

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

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

◆ remove_children()

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

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

Definition at line 918 of file tree.cpp.

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

◆ change_type() [1/2]

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

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

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

Definition at line 939 of file tree.cpp.

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

◆ change_type() [2/2]

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

Definition at line 771 of file tree.hpp.

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

◆ move() [1/3]

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

change the node's position in the parent

Definition at line 819 of file tree.cpp.

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

◆ move() [2/3]

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

change the node's parent and position

Definition at line 832 of file tree.cpp.

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

◆ move() [3/3]

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

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

Returns
the index of the new node in the destination tree

Definition at line 845 of file tree.cpp.

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

◆ set_root_as_stream()

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

ensure the first node is a stream.

Eg, change this tree

DOCMAP MAP KEYVAL KEYVAL SEQ VAL

to

STREAM DOCMAP MAP KEYVAL KEYVAL SEQ VAL

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

Definition at line 857 of file tree.cpp.

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

◆ duplicate() [1/2]

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

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

Returns
the index of the copy

Definition at line 958 of file tree.cpp.

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

◆ duplicate() [2/2]

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

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

Returns
the index of the copy

Definition at line 963 of file tree.cpp.

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

◆ duplicate_children() [1/2]

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

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

Returns
the index of the last duplicated child

Definition at line 980 of file tree.cpp.

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

◆ duplicate_children() [2/2]

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

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

Returns
the index of the last duplicated child

Definition at line 985 of file tree.cpp.

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

◆ duplicate_children_no_rep() [1/2]

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

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

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

Definition at line 1017 of file tree.cpp.

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

◆ duplicate_children_no_rep() [2/2]

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

Definition at line 1022 of file tree.cpp.

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

◆ duplicate_contents() [1/2]

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

Definition at line 1002 of file tree.cpp.

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

◆ duplicate_contents() [2/2]

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

Definition at line 1007 of file tree.cpp.

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

◆ merge_with()

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

Definition at line 1117 of file tree.cpp.

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

◆ location()

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

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

Definition at line 1914 of file tree.cpp.

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

◆ arena_size()

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

get the current size of the tree's internal arena

Definition at line 874 of file tree.hpp.

874 { 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 876 of file tree.hpp.

876 { 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 878 of file tree.hpp.

878 { _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 879 of file tree.hpp.

879 { return m_arena_pos; }

◆ arena() [1/2]

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

get the current arena

Definition at line 882 of file tree.hpp.

882 { return m_arena.first(m_arena_pos); }

◆ arena() [2/2]

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

get the current arena

Definition at line 884 of file tree.hpp.

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

◆ in_arena()

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

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

Definition at line 887 of file tree.hpp.

888  {
889  return m_arena.is_super(s);
890  }

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

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

◆ copy_to_arena()

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

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

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

Definition at line 930 of file tree.hpp.

931  {
932  _RYML_ASSERT_VISIT_(m_callbacks, !s.overlaps(m_arena), this, NONE);
933  substr cp = alloc_arena(s.len);
934  _RYML_ASSERT_VISIT_(m_callbacks, cp.len == s.len, this, NONE);
935  _RYML_ASSERT_VISIT_(m_callbacks, !s.overlaps(cp), this, NONE);
936  #if (!defined(__clang__)) && (defined(__GNUC__) && __GNUC__ >= 10)
937  C4_SUPPRESS_WARNING_GCC_PUSH
938  C4_SUPPRESS_WARNING_GCC("-Wstringop-overflow=") // no need for terminating \0
939  C4_SUPPRESS_WARNING_GCC("-Wrestrict") // there's an assert to ensure no violation of restrict behavior
940  #endif
941  if(s.len)
942  memcpy(cp.str, s.str, s.len);
943  #if (!defined(__clang__)) && (defined(__GNUC__) && __GNUC__ >= 10)
944  C4_SUPPRESS_WARNING_GCC_POP
945  #endif
946  return cp;
947  }
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:959

◆ alloc_arena()

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

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

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

Definition at line 959 of file tree.hpp.

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

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

972  {
973  if(arena_cap > m_arena.len)
974  {
975  substr buf;
976  buf.str = _RYML_CB_ALLOC(m_callbacks, char, arena_cap);
977  buf.len = arena_cap;
978  if(m_arena.str)
979  {
980  _RYML_ASSERT_VISIT_(m_callbacks, m_arena.len >= 0, this, NONE);
981  _relocate(buf); // does a memcpy and changes nodes using the arena
982  _RYML_CB_FREE(m_callbacks, m_arena.str, char, m_arena.len);
983  }
984  m_arena = buf;
985  }
986  }

◆ lookup_path()

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

for example foo.bar[0].baz

Definition at line 1610 of file tree.cpp.

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

◆ lookup_path_or_modify() [1/2]

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

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

See also
lookup_path()

Definition at line 1623 of file tree.cpp.

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

◆ lookup_path_or_modify() [2/2]

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

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

See also
lookup_path()

Definition at line 1633 of file tree.cpp.

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

◆ _claim()

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

Definition at line 414 of file tree.cpp.

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

Member Data Documentation

◆ m_buf

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

Definition at line 1329 of file tree.hpp.

◆ m_cap

id_type c4::yml::Tree::m_cap

Definition at line 1330 of file tree.hpp.

◆ m_size

id_type c4::yml::Tree::m_size

Definition at line 1331 of file tree.hpp.

◆ m_free_head

id_type c4::yml::Tree::m_free_head

Definition at line 1333 of file tree.hpp.

◆ m_free_tail

id_type c4::yml::Tree::m_free_tail

Definition at line 1334 of file tree.hpp.

◆ m_arena

substr c4::yml::Tree::m_arena

Definition at line 1336 of file tree.hpp.

◆ m_arena_pos

size_t c4::yml::Tree::m_arena_pos

Definition at line 1337 of file tree.hpp.

◆ m_callbacks

Callbacks c4::yml::Tree::m_callbacks

Definition at line 1339 of file tree.hpp.

◆ m_tag_directives

TagDirectives c4::yml::Tree::m_tag_directives

Definition at line 1341 of file tree.hpp.


The documentation for this class was generated from the following files: