rapidyaml  0.11.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 doc (id_type i) const
 gets the i document node index. More...
 
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...
 
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...
 
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
 
TagDirective m_tag_directives [RYML_MAX_TAG_DIRECTIVES]
 

tag directives

typedef TagDirective const * tag_directive_const_iterator
 
typedef c4::yml::TagDirectiveRange TagDirectiveProxy
 
void resolve_tags ()
 
void normalize_tags ()
 
void normalize_tags_long ()
 
id_type num_tag_directives () const
 
bool add_tag_directive (csubstr directive)
 
id_type add_tag_directive (TagDirective const &td)
 
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
 
TagDirective const * begin_tag_directives () const
 
TagDirective const * end_tag_directives () const
 
c4::yml::TagDirectiveRange tag_directives () const
 

hierarchy predicates

bool is_root (id_type node) const
 
bool has_parent (id_type node) const
 
bool is_ancestor (id_type node, id_type ancestor) const
 true when ancestor is parent or parent of a parent of node 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 244 of file tree.hpp.

Member Typedef Documentation

◆ tag_directive_const_iterator

Definition at line 663 of file tree.hpp.

◆ TagDirectiveProxy

Constructor & Destructor Documentation

◆ Tree() [1/6]

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

Definition at line 251 of file tree.hpp.

251 : 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 118 of file tree.cpp.

120 {
121 }
#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 253 of file tree.hpp.

253 : 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:845

◆ Tree() [4/6]

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

Definition at line 123 of file tree.cpp.

124  : m_buf(nullptr)
125  , m_cap(0)
126  , m_size(0)
127  , m_free_head(NONE)
128  , m_free_tail(NONE)
129  , m_arena()
130  , m_arena_pos(0)
131  , m_callbacks(cb)
132  , m_tag_directives()
133 {
134  if(node_capacity)
135  reserve(node_capacity);
136  if(arena_capacity)
138 }
NodeData * m_buf
Definition: tree.hpp:1298
id_type m_free_head
Definition: tree.hpp:1302
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:940
size_t m_arena_pos
Definition: tree.hpp:1306
void reserve(id_type node_capacity=RYML_DEFAULT_TREE_CAPACITY)
Definition: tree.cpp:294
TagDirective m_tag_directives[RYML_MAX_TAG_DIRECTIVES]
Definition: tree.hpp:1310
id_type m_size
Definition: tree.hpp:1300
id_type m_cap
Definition: tree.hpp:1299
substr m_arena
Definition: tree.hpp:1305
id_type m_free_tail
Definition: tree.hpp:1303
Callbacks m_callbacks
Definition: tree.hpp:1308
@ NONE
an index to none
Definition: common.hpp:251

References arena_capacity(), reserve(), and reserve_arena().

◆ ~Tree()

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

Definition at line 140 of file tree.cpp.

141 {
142  _free();
143 }

◆ Tree() [5/6]

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

Definition at line 146 of file tree.cpp.

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

◆ Tree() [6/6]

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

Definition at line 152 of file tree.cpp.

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

Member Function Documentation

◆ operator=() [1/2]

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

Definition at line 158 of file tree.cpp.

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

References m_callbacks.

◆ operator=() [2/2]

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

Definition at line 169 of file tree.cpp.

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

◆ reserve()

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

Definition at line 294 of file tree.cpp.

295 {
296  if(cap > m_cap)
297  {
298  NodeData *buf = _RYML_CB_ALLOC_HINT(m_callbacks, NodeData, (size_t)cap, m_buf);
299  if(m_buf)
300  {
301  memcpy(buf, m_buf, (size_t)m_cap * sizeof(NodeData));
302  _RYML_CB_FREE(m_callbacks, m_buf, NodeData, (size_t)m_cap);
303  }
304  id_type first = m_cap, del = cap - m_cap;
305  m_cap = cap;
306  m_buf = buf;
307  _clear_range(first, del);
308  if(m_free_head != NONE)
309  {
310  _RYML_ASSERT_VISIT_(m_callbacks, m_buf != nullptr, this, NONE);
311  _RYML_ASSERT_VISIT_(m_callbacks, m_free_tail != NONE, this, NONE);
314  m_free_tail = cap-1;
315  }
316  else
317  {
318  _RYML_ASSERT_VISIT_(m_callbacks, m_free_tail == NONE, this, NONE);
319  m_free_head = first;
320  m_free_tail = cap-1;
321  }
322  _RYML_ASSERT_VISIT_(m_callbacks, m_free_head == NONE || (m_free_head >= 0 && m_free_head < cap), this, NONE);
323  _RYML_ASSERT_VISIT_(m_callbacks, m_free_tail == NONE || (m_free_tail >= 0 && m_free_tail < cap), this, NONE);
324 
325  if( ! m_size)
326  _claim_root();
327  }
328 }
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:234
id_type m_prev_sibling
Definition: tree.hpp:235

References m_buf, m_callbacks, m_cap, m_free_head, m_free_tail, c4::yml::NodeData::m_next_sibling, c4::yml::NodeData::m_prev_sibling, m_size, and c4::yml::NONE.

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

333 {
334  _clear_range(0, m_cap);
335  m_size = 0;
336  if(m_buf)
337  {
338  _RYML_ASSERT_VISIT_(m_callbacks, m_cap >= 0, this, NONE);
339  m_free_head = 0;
340  m_free_tail = m_cap-1;
341  _claim_root();
342  }
343  else
344  {
345  m_free_head = NONE;
346  m_free_tail = NONE;
347  }
348  for(id_type i = 0; i < RYML_MAX_TAG_DIRECTIVES; ++i)
349  m_tag_directives[i] = {};
350 }
#define RYML_MAX_TAG_DIRECTIVES
the maximum number of tag directives in a Tree
Definition: tag.hpp:19

References m_buf, m_callbacks, m_cap, m_free_head, m_free_tail, m_size, m_tag_directives, c4::yml::NONE, and RYML_MAX_TAG_DIRECTIVES.

◆ clear_arena()

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

Definition at line 277 of file tree.hpp.

277 { m_arena_pos = 0; }

◆ empty() [1/2]

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

Definition at line 279 of file tree.hpp.

279 { return m_size == 0; }

◆ size()

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

Definition at line 281 of file tree.hpp.

281 { return m_size; }

◆ capacity()

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

Definition at line 282 of file tree.hpp.

282 { return m_cap; }

◆ slack()

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

Definition at line 283 of file tree.hpp.

283 { _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 285 of file tree.hpp.

285 { return m_callbacks; }

◆ callbacks() [2/2]

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

Definition at line 286 of file tree.hpp.

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

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

References c4::yml::NONE.

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

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

References c4::yml::NONE.

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

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

References c4::yml::NONE.

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

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

References c4::yml::NONE.

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

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

References c4::yml::NONE.

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

332 { _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 69 of file tree.cpp.

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

References c4::yml::NONE.

◆ ref() [2/2]

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

Get a NodeRef of a node by id.

Definition at line 74 of file tree.cpp.

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

References c4::yml::NONE.

◆ cref()

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

Get a NodeRef of a node by id.

Definition at line 79 of file tree.cpp.

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

References c4::yml::NONE.

◆ rootref() [1/2]

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

Get the root as a NodeRef.

Definition at line 55 of file tree.cpp.

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

◆ rootref() [2/2]

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

Get the root as a ConstNodeRef.

Definition at line 59 of file tree.cpp.

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

◆ crootref()

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

Get the root as a ConstNodeRef.

Definition at line 64 of file tree.cpp.

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

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

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

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

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

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

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

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

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

References c4::yml::key().

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

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

References c4::yml::key().

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

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

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

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

◆ type()

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

Definition at line 379 of file tree.hpp.

379 { 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:326
NodeType m_type
Definition: tree.hpp:226

◆ type_str()

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

Definition at line 380 of file tree.hpp.

380 { 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:153

◆ key()

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

Definition at line 382 of file tree.hpp.

382 { _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:410
NodeScalar m_key
Definition: tree.hpp:228
csubstr scalar
Definition: tree.hpp:110

◆ key_tag()

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

Definition at line 383 of file tree.hpp.

383 { _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:414

◆ key_ref()

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

Definition at line 384 of file tree.hpp.

384 { _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:419
csubstr anchor
Definition: tree.hpp:111

◆ key_anchor()

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

Definition at line 385 of file tree.hpp.

385 { _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:416

◆ keysc()

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

Definition at line 386 of file tree.hpp.

386 { _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 388 of file tree.hpp.

388 { _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:411
NodeScalar m_val
Definition: tree.hpp:229

◆ val_tag()

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

Definition at line 389 of file tree.hpp.

389 { _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:415

◆ val_ref()

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

Definition at line 390 of file tree.hpp.

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

◆ val_anchor()

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

Definition at line 391 of file tree.hpp.

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

◆ valsc()

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

Definition at line 392 of file tree.hpp.

392 { _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 401 of file tree.hpp.

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

◆ type_has_all()

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

Definition at line 402 of file tree.hpp.

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

◆ type_has_none()

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

Definition at line 403 of file tree.hpp.

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

◆ is_stream()

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

Definition at line 405 of file tree.hpp.

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

◆ is_doc()

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

Definition at line 406 of file tree.hpp.

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

◆ is_container()

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

Definition at line 407 of file tree.hpp.

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

◆ is_map()

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

Definition at line 408 of file tree.hpp.

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

◆ is_seq()

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

Definition at line 409 of file tree.hpp.

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

◆ has_key()

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

Definition at line 410 of file tree.hpp.

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

◆ has_val()

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

Definition at line 411 of file tree.hpp.

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

◆ is_val()

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

Definition at line 412 of file tree.hpp.

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

◆ is_keyval()

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

Definition at line 413 of file tree.hpp.

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

◆ has_key_tag()

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

Definition at line 414 of file tree.hpp.

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

◆ has_val_tag()

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

Definition at line 415 of file tree.hpp.

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

◆ has_key_anchor()

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

Definition at line 416 of file tree.hpp.

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

◆ has_val_anchor()

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

Definition at line 417 of file tree.hpp.

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

◆ has_anchor() [1/2]

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

Definition at line 418 of file tree.hpp.

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

◆ is_key_ref()

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

Definition at line 419 of file tree.hpp.

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

◆ is_val_ref()

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

Definition at line 420 of file tree.hpp.

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

◆ is_ref()

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

Definition at line 421 of file tree.hpp.

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

◆ parent_is_seq()

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

Definition at line 423 of file tree.hpp.

423 { _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:409
bool has_parent(id_type node) const
Definition: tree.hpp:459

◆ parent_is_map()

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

Definition at line 424 of file tree.hpp.

424 { _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:408

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

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

432 { _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.hpp:262

References c4::yml::scalar_is_null().

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

436 { _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)); }

References c4::yml::scalar_is_null().

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

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

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

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

◆ is_key_anchor()

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

Definition at line 445 of file tree.hpp.

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

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

◆ is_anchor()

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

Definition at line 447 of file tree.hpp.

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

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

457 { _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:231

References c4::yml::NONE.

◆ has_parent()

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

Definition at line 459 of file tree.hpp.

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

References c4::yml::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 1303 of file tree.cpp.

1304 {
1305  _RYML_ASSERT_VISIT_(m_callbacks, node != NONE, this, node);
1306  id_type p = parent(node);
1307  while(p != NONE)
1308  {
1309  if(p == ancestor)
1310  return true;
1311  p = parent(p);
1312  }
1313  return false;
1314 }
id_type parent(id_type node) const
Definition: tree.hpp:499

References m_callbacks, c4::yml::NONE, and parent().

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

465 { 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:472
@ 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:37
bool empty() const noexcept
Definition: tree.hpp:138

References c4::yml::VAL.

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

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

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

References c4::yml::key(), and c4::yml::NONE.

◆ has_children()

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

true if node has any children key

Definition at line 472 of file tree.hpp.

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

References c4::yml::NONE.

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

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

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

References c4::yml::key(), and c4::yml::NONE.

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

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

References c4::yml::NodeData::m_first_child, c4::yml::NodeData::m_last_child, c4::yml::NodeData::m_parent, and c4::yml::NONE.

◆ has_siblings()

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

Definition at line 490 of file tree.hpp.

490 { return true; }

◆ parent()

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

Definition at line 499 of file tree.hpp.

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

◆ prev_sibling()

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

Definition at line 501 of file tree.hpp.

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

◆ next_sibling()

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

Definition at line 502 of file tree.hpp.

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

1199 {
1200  id_type count = 0;
1201  for(id_type i = first_child(node); i != NONE; i = next_sibling(i))
1202  ++count;
1203  return count;
1204 }
id_type first_child(id_type node) const
Definition: tree.hpp:507
id_type next_sibling(id_type node) const
Definition: tree.hpp:502

References first_child(), next_sibling(), and c4::yml::NONE.

◆ child_pos()

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

Definition at line 1218 of file tree.cpp.

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

References first_child(), m_callbacks, next_sibling(), and c4::yml::NONE.

◆ first_child()

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

Definition at line 507 of file tree.hpp.

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

◆ last_child()

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

Definition at line 508 of file tree.hpp.

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

◆ child()

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

Definition at line 1206 of file tree.cpp.

1207 {
1208  _RYML_ASSERT_VISIT_(m_callbacks, node != NONE, this, node);
1209  id_type count = 0;
1210  for(id_type i = first_child(node); i != NONE; i = next_sibling(i))
1211  {
1212  if(count++ == pos)
1213  return i;
1214  }
1215  return NONE;
1216 }

References first_child(), m_callbacks, next_sibling(), and c4::yml::NONE.

◆ find_child()

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

Definition at line 1243 of file tree.cpp.

1244 {
1245  _RYML_ASSERT_VISIT_(m_callbacks, node != NONE, this, node);
1246  _RYML_ASSERT_VISIT_(m_callbacks, is_map(node), this, node);
1247  if(get(node)->m_first_child == NONE)
1248  {
1249  _RYML_ASSERT_VISIT_(m_callbacks, _p(node)->m_last_child == NONE, this, node);
1250  return NONE;
1251  }
1252  else
1253  {
1254  _RYML_ASSERT_VISIT_(m_callbacks, _p(node)->m_last_child != NONE, this, node);
1255  }
1256  for(id_type i = first_child(node); i != NONE; i = next_sibling(i))
1257  {
1258  if(_p(i)->m_key.scalar == name)
1259  {
1260  return i;
1261  }
1262  }
1263  return NONE;
1264 }
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:307

References _p(), first_child(), get(), is_map(), m_callbacks, c4::yml::NodeData::m_key, next_sibling(), c4::yml::NONE, and c4::yml::NodeScalar::scalar.

◆ num_siblings()

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

O(num_siblings)

counts with this

Definition at line 514 of file tree.hpp.

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

◆ num_other_siblings()

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

does not count with this

Definition at line 516 of file tree.hpp.

516 { 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:514

◆ sibling_pos()

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

Definition at line 517 of file tree.hpp.

517 { _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:1218

◆ first_sibling()

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

Definition at line 518 of file tree.hpp.

518 { 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 519 of file tree.hpp.

519 { 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 520 of file tree.hpp.

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

◆ find_sibling()

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

Definition at line 521 of file tree.hpp.

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

References c4::yml::key().

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

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

1292 {
1293  _RYML_ASSERT_VISIT_(m_callbacks, node != NONE, this, node);
1294  id_type depth = 0;
1295  while(!is_root(node))
1296  {
1297  ++depth;
1298  node = parent(node);
1299  }
1300  return depth;
1301 }

References is_root(), m_callbacks, c4::yml::NONE, and parent().

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

1286 {
1287  _RYML_ASSERT_VISIT_(m_callbacks, node != NONE, this, node);
1288  return depth_desc_(*this, node);
1289 }

References m_callbacks, and c4::yml::NONE.

◆ is_container_styled()

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

Definition at line 535 of file tree.hpp.

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

◆ is_block()

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

Definition at line 536 of file tree.hpp.

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

◆ is_flow_sl()

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

Definition at line 537 of file tree.hpp.

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

◆ is_flow_ml()

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

Definition at line 538 of file tree.hpp.

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

◆ is_flow()

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

Definition at line 539 of file tree.hpp.

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

◆ is_key_styled()

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

Definition at line 541 of file tree.hpp.

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

◆ is_val_styled()

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

Definition at line 542 of file tree.hpp.

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

◆ is_key_literal()

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

Definition at line 543 of file tree.hpp.

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

◆ is_val_literal()

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

Definition at line 544 of file tree.hpp.

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

◆ is_key_folded()

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

Definition at line 545 of file tree.hpp.

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

◆ is_val_folded()

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

Definition at line 546 of file tree.hpp.

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

◆ is_key_squo()

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

Definition at line 547 of file tree.hpp.

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

◆ is_val_squo()

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

Definition at line 548 of file tree.hpp.

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

◆ is_key_dquo()

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

Definition at line 549 of file tree.hpp.

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

◆ is_val_dquo()

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

Definition at line 550 of file tree.hpp.

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

◆ is_key_plain()

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

Definition at line 551 of file tree.hpp.

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

◆ is_val_plain()

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

Definition at line 552 of file tree.hpp.

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

◆ is_key_quoted()

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

Definition at line 553 of file tree.hpp.

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

◆ is_val_quoted()

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

Definition at line 554 of file tree.hpp.

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

◆ is_quoted()

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

Definition at line 555 of file tree.hpp.

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

◆ key_style()

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

Definition at line 557 of file tree.hpp.

557 { _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:224

◆ val_style()

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

Definition at line 558 of file tree.hpp.

558 { _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:225

◆ set_container_style()

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

Definition at line 560 of file tree.hpp.

560 { _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:407
void set_container_style(NodeType_e style) noexcept
Definition: node_type.hpp:227

◆ set_key_style()

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

Definition at line 561 of file tree.hpp.

561 { _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:228

◆ set_val_style()

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

Definition at line 562 of file tree.hpp.

562 { _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:229

◆ clear_style()

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

Definition at line 1392 of file tree.cpp.

1393 {
1394  NodeData *C4_RESTRICT d = _p(node);
1395  d->m_type.clear_style();
1396  if(!recurse)
1397  return;
1398  for(id_type child = d->m_first_child; child != NONE; child = next_sibling(child))
1399  clear_style(child, recurse);
1400 }
void clear_style(id_type node, bool recurse=false)
Definition: tree.cpp:1392

References _p(), child(), next_sibling(), and c4::yml::NONE.

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

1407 {
1408  NodeData *C4_RESTRICT d = _p(node);
1409  if((d->m_type & type_mask) == type_mask)
1410  {
1411  d->m_type &= ~(NodeType)rem_style_flags;
1412  d->m_type |= (NodeType)add_style_flags;
1413  }
1414  if(!recurse)
1415  return;
1416  for(id_type child = d->m_first_child; child != NONE; child = next_sibling(child))
1417  set_style_conditionally(child, type_mask, rem_style_flags, add_style_flags, recurse);
1418 }
void set_style_conditionally(id_type node, NodeType type_mask, NodeType rem_style_flags, NodeType add_style_flags, bool recurse=false)
Definition: tree.cpp:1402

References _p(), child(), next_sibling(), and c4::yml::NONE.

◆ to_keyval()

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

Definition at line 1328 of file tree.cpp.

1329 {
1330  _RYML_ASSERT_VISIT_(m_callbacks, ! has_children(node), this, node);
1331  _RYML_ASSERT_VISIT_(m_callbacks, parent(node) == NONE || parent_is_map(node), this, node);
1332  _set_flags(node, KEYVAL|more_flags);
1333  _p(node)->m_key = key;
1334  _p(node)->m_val = val;
1335 }
csubstr const & val(id_type node) const
Definition: tree.hpp:388
bool parent_is_map(id_type node) const
Definition: tree.hpp:424

References _p(), has_children(), key(), c4::yml::KEYVAL, m_callbacks, c4::yml::NodeData::m_key, c4::yml::NodeData::m_val, c4::yml::NONE, parent(), parent_is_map(), and val().

◆ to_map() [1/2]

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

Definition at line 1346 of file tree.cpp.

1347 {
1348  _RYML_ASSERT_VISIT_(m_callbacks, ! has_children(node), this, node);
1349  _RYML_ASSERT_VISIT_(m_callbacks, parent(node) == NONE || parent_is_map(node), this, node);
1350  _set_flags(node, KEY|MAP|more_flags);
1351  _p(node)->m_key = key;
1352  _p(node)->m_val.clear();
1353 }
@ MAP
a map: a parent of KEYVAL/KEYSEQ/KEYMAP nodes
Definition: node_type.hpp:38
@ KEY
is member of a map
Definition: node_type.hpp:36
void clear() noexcept
Definition: tree.hpp:140

References _p(), c4::yml::NodeScalar::clear(), has_children(), c4::yml::KEY, key(), m_callbacks, c4::yml::NodeData::m_key, c4::yml::NodeData::m_val, c4::yml::MAP, c4::yml::NONE, parent(), and parent_is_map().

◆ to_seq() [1/2]

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

Definition at line 1364 of file tree.cpp.

1365 {
1366  _RYML_ASSERT_VISIT_(m_callbacks, ! has_children(node), this, node);
1367  _RYML_ASSERT_VISIT_(m_callbacks, parent(node) == NONE || parent_is_map(node), this, node);
1368  _set_flags(node, KEY|SEQ|more_flags);
1369  _p(node)->m_key = key;
1370  _p(node)->m_val.clear();
1371 }
@ SEQ
a seq: a parent of VAL/SEQ/MAP nodes
Definition: node_type.hpp:39

References _p(), c4::yml::NodeScalar::clear(), has_children(), c4::yml::KEY, key(), m_callbacks, c4::yml::NodeData::m_key, c4::yml::NodeData::m_val, c4::yml::NONE, parent(), parent_is_map(), and c4::yml::SEQ.

◆ to_val()

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

Definition at line 1319 of file tree.cpp.

1320 {
1321  _RYML_ASSERT_VISIT_(m_callbacks, ! has_children(node), this, node);
1322  _RYML_ASSERT_VISIT_(m_callbacks, parent(node) == NONE || ! parent_is_map(node), this, node);
1323  _set_flags(node, VAL|more_flags);
1324  _p(node)->m_key.clear();
1325  _p(node)->m_val = val;
1326 }

References _p(), c4::yml::NodeScalar::clear(), has_children(), m_callbacks, c4::yml::NodeData::m_key, c4::yml::NodeData::m_val, c4::yml::NONE, parent(), parent_is_map(), c4::yml::VAL, and val().

◆ to_map() [2/2]

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

Definition at line 1337 of file tree.cpp.

1338 {
1339  _RYML_ASSERT_VISIT_(m_callbacks, ! has_children(node), this, node);
1340  _RYML_ASSERT_VISIT_(m_callbacks, parent(node) == NONE || ! parent_is_map(node), this, node); // parent must not have children with keys
1341  _set_flags(node, MAP|more_flags);
1342  _p(node)->m_key.clear();
1343  _p(node)->m_val.clear();
1344 }

References _p(), c4::yml::NodeScalar::clear(), has_children(), m_callbacks, c4::yml::NodeData::m_key, c4::yml::NodeData::m_val, c4::yml::MAP, c4::yml::NONE, parent(), and parent_is_map().

◆ to_seq() [2/2]

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

Definition at line 1355 of file tree.cpp.

1356 {
1357  _RYML_ASSERT_VISIT_(m_callbacks, ! has_children(node), this, node);
1358  _RYML_ASSERT_VISIT_(m_callbacks, parent(node) == NONE || parent_is_seq(node), this, node);
1359  _set_flags(node, SEQ|more_flags);
1360  _p(node)->m_key.clear();
1361  _p(node)->m_val.clear();
1362 }
bool parent_is_seq(id_type node) const
Definition: tree.hpp:423

References _p(), c4::yml::NodeScalar::clear(), has_children(), m_callbacks, c4::yml::NodeData::m_key, c4::yml::NodeData::m_val, c4::yml::NONE, parent(), parent_is_seq(), and c4::yml::SEQ.

◆ to_doc()

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

Definition at line 1373 of file tree.cpp.

1374 {
1375  _RYML_ASSERT_VISIT_(m_callbacks, ! has_children(node), this, node);
1376  _set_flags(node, DOC|more_flags);
1377  _p(node)->m_key.clear();
1378  _p(node)->m_val.clear();
1379 }
@ DOC
a document
Definition: node_type.hpp:40

References _p(), c4::yml::NodeScalar::clear(), c4::yml::DOC, has_children(), m_callbacks, c4::yml::NodeData::m_key, and c4::yml::NodeData::m_val.

◆ to_stream()

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

Definition at line 1381 of file tree.cpp.

1382 {
1383  _RYML_ASSERT_VISIT_(m_callbacks, ! has_children(node), this, node);
1384  _set_flags(node, STREAM|more_flags);
1385  _p(node)->m_key.clear();
1386  _p(node)->m_val.clear();
1387 }
@ STREAM
a stream: a seq of docs
Definition: node_type.hpp:41

References _p(), c4::yml::NodeScalar::clear(), has_children(), m_callbacks, c4::yml::NodeData::m_key, c4::yml::NodeData::m_val, and c4::yml::STREAM.

◆ set_key()

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

Definition at line 586 of file tree.hpp.

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

References c4::yml::key().

◆ set_val()

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

Definition at line 587 of file tree.hpp.

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

589 { _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:46

References c4::yml::KEYTAG.

◆ set_val_tag()

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

Definition at line 590 of file tree.hpp.

590 { _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:47

References c4::yml::VALTAG.

◆ set_key_anchor()

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

Definition at line 592 of file tree.hpp.

592 { _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:44

References c4::yml::KEYANCH.

◆ set_val_anchor()

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

Definition at line 593 of file tree.hpp.

593 { _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:45

References c4::yml::VALANCH.

◆ set_key_ref()

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

Definition at line 594 of file tree.hpp.

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

References c4::yml::KEY, and c4::yml::KEYREF.

◆ set_val_ref()

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

Definition at line 595 of file tree.hpp.

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

References c4::yml::VAL, and c4::yml::VALREF.

◆ rem_key_anchor()

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

Definition at line 597 of file tree.hpp.

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

References c4::yml::KEYANCH.

◆ rem_val_anchor()

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

Definition at line 598 of file tree.hpp.

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

References c4::yml::VALANCH.

◆ rem_key_ref()

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

Definition at line 599 of file tree.hpp.

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

References c4::yml::KEYREF.

◆ rem_val_ref()

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

Definition at line 600 of file tree.hpp.

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

References c4::yml::VALREF.

◆ rem_anchor_ref()

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

Definition at line 601 of file tree.hpp.

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

References c4::yml::KEYANCH, c4::yml::KEYREF, c4::yml::VALANCH, and c4::yml::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 579 of file tree.cpp.

580 {
581  id_type r = root_id();
582  _do_reorder(&r, 0);
583 }

References root_id().

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

1189 {
1190  if(m_size == 0)
1191  return;
1192  rr->resolve(this, clear_anchors);
1193 }

References m_size.

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

1181 {
1182  if(m_size == 0)
1183  return;
1184  ReferenceResolver rr;
1185  resolve(&rr, clear_anchors);
1186 }
void resolve(ReferenceResolver *rr, bool clear_anchors=true)
Resolve references (aliases <- anchors), by forwarding to ReferenceResolver::resolve(); refer to Refe...
Definition: tree.cpp:1188

References m_size, and resolve().

◆ resolve_tags()

void c4::yml::Tree::resolve_tags ( )

Definition at line 1569 of file tree.cpp.

1570 {
1571  if(empty())
1572  return;
1573  size_t needed_size = _count_resolved_tags_size(this, root_id());
1574  if(needed_size)
1575  reserve_arena(arena_size() + needed_size);
1576  _resolve_tags(this, root_id());
1577 }
bool empty() const
Definition: tree.hpp:279
size_t arena_size() const
get the current size of the tree's internal arena
Definition: tree.hpp:843

References arena_size(), empty(), reserve_arena(), and root_id().

◆ normalize_tags()

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

Definition at line 1579 of file tree.cpp.

1580 {
1581  if(empty())
1582  return;
1583  _normalize_tags(this, root_id());
1584 }

References empty(), and root_id().

◆ normalize_tags_long()

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

Definition at line 1586 of file tree.cpp.

1587 {
1588  if(empty())
1589  return;
1590  _normalize_tags_long(this, root_id());
1591 }

References empty(), and root_id().

◆ num_tag_directives()

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

Definition at line 1422 of file tree.cpp.

1423 {
1424  // this assumes we have a very small number of tag directives
1425  for(id_type i = 0; i < RYML_MAX_TAG_DIRECTIVES; ++i)
1426  if(m_tag_directives[i].handle.empty())
1427  return i;
1428  return RYML_MAX_TAG_DIRECTIVES;
1429 }

References m_tag_directives, and RYML_MAX_TAG_DIRECTIVES.

◆ add_tag_directive() [1/2]

bool c4::yml::Tree::add_tag_directive ( csubstr  directive)

Definition at line 1471 of file tree.cpp.

1472 {
1473  TagDirective td;
1474  if(_create_tag_directive_from_str(directive_, &td, this))
1475  {
1476  add_tag_directive(td);
1477  return true;
1478  }
1479  return false;
1480 }
bool add_tag_directive(csubstr directive)
Definition: tree.cpp:1471

◆ add_tag_directive() [2/2]

id_type c4::yml::Tree::add_tag_directive ( TagDirective const &  td)

Definition at line 1437 of file tree.cpp.

1438 {
1439  _RYML_CHECK_BASIC_(m_callbacks, !td.handle.empty());
1440  _RYML_CHECK_BASIC_(m_callbacks, !td.prefix.empty());
1441  _RYML_CHECK_BASIC_(m_callbacks, td.handle.begins_with('!'));
1442  _RYML_CHECK_BASIC_(m_callbacks, td.handle.ends_with('!'));
1443  // https://yaml.org/spec/1.2.2/#rule-ns-word-char
1444  _RYML_CHECK_BASIC_(m_callbacks, td.handle == '!' || td.handle == "!!" || td.handle.trim('!').first_not_of("01234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-") == npos);
1445  id_type pos = num_tag_directives();
1446  _RYML_CHECK_BASIC_(m_callbacks, pos < RYML_MAX_TAG_DIRECTIVES);
1447  m_tag_directives[pos] = td;
1448  return pos;
1449 }
id_type num_tag_directives() const
Definition: tree.cpp:1422
@ npos
a null string position
Definition: common.hpp:258

References c4::yml::TagDirective::handle, m_callbacks, m_tag_directives, c4::yml::npos, num_tag_directives(), c4::yml::TagDirective::prefix, and RYML_MAX_TAG_DIRECTIVES.

◆ clear_tag_directives()

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

Definition at line 1431 of file tree.cpp.

1432 {
1433  for(TagDirective &td : m_tag_directives)
1434  td = {};
1435 }

References m_tag_directives.

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

1483 {
1484  // lookup from the end. We want to find the first directive that
1485  // matches the tag and has a target node id leq than the given
1486  // node_id.
1487  for(id_type i = RYML_MAX_TAG_DIRECTIVES-1; i != (id_type)-1; --i)
1488  {
1489  auto const& td = m_tag_directives[i];
1490  if(td.handle.empty())
1491  continue;
1492  if(tag.begins_with(td.handle) && td.next_node_id <= node_id)
1493  return td.transform(tag, output, m_callbacks);
1494  }
1495  if(tag.begins_with('!'))
1496  {
1497  if(is_custom_tag(tag))
1498  {
1499  _RYML_ERR_VISIT_(m_callbacks, this, node_id, "tag directive not found");
1500  }
1501  }
1502  return 0; // return 0 to signal that the tag is local and cannot be resolved
1503 }
bool is_custom_tag(csubstr tag)
Definition: tag.cpp:9
size_t transform(csubstr tag, substr output, Callbacks const &callbacks, bool with_brackets=true) const
Definition: tag.cpp:230

References c4::yml::TagDirective::handle, c4::yml::is_custom_tag(), m_callbacks, m_tag_directives, c4::yml::TagDirective::next_node_id, RYML_MAX_TAG_DIRECTIVES, and c4::yml::TagDirective::transform().

◆ resolve_tag_sub()

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

Definition at line 653 of file tree.hpp.

654  {
655  size_t needed = resolve_tag(output, tag, node_id);
656  return needed <= output.len ? output.first(needed) : output;
657  }
size_t resolve_tag(substr output, csubstr tag, id_type node_id) const
resolve the given tag, appearing at node_id.
Definition: tree.cpp:1482

◆ begin_tag_directives()

TagDirective const* c4::yml::Tree::begin_tag_directives ( ) const
inline

Definition at line 659 of file tree.hpp.

659 { return m_tag_directives; }

◆ end_tag_directives()

TagDirective const* c4::yml::Tree::end_tag_directives ( ) const
inline

Definition at line 660 of file tree.hpp.

660 { return m_tag_directives + num_tag_directives(); }

◆ tag_directives()

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

Definition at line 661 of file tree.hpp.

TagDirective const * end_tag_directives() const
Definition: tree.hpp:660
TagDirective const * begin_tag_directives() const
Definition: tree.hpp:659

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

677  {
678  _RYML_ASSERT_VISIT_(m_callbacks, parent != NONE, this, parent);
679  _RYML_ASSERT_VISIT_(m_callbacks, is_container(parent) || is_root(parent), this, parent);
680  _RYML_ASSERT_VISIT_(m_callbacks, after == NONE || (_p(after)->m_parent == parent), this, parent);
681  id_type child = _claim();
682  _set_hierarchy(child, parent, after);
683  return child;
684  }
id_type _claim()
Definition: tree.cpp:417

References c4::yml::NONE.

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

686 { 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:676

References c4::yml::NONE.

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

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

690  {
691  id_type child = _claim();
692  _set_hierarchy(child, parent, _p(parent)->m_last_child);
693  return child;
694  }

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

710  {
711  return insert_child(_p(node)->m_parent, after);
712  }

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

714 { 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:686

◆ append_sibling()

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

Definition at line 715 of file tree.hpp.

715 { 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:688

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

721  {
722  remove_children(node);
723  _release(node);
724  }
void remove_children(id_type node)
remove all the node's children, but keep the node itself
Definition: tree.cpp:903

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

904 {
905  _RYML_ASSERT_VISIT_(m_callbacks, get(node) != nullptr, this, node);
906  #if __GNUC__ >= 6
907  C4_SUPPRESS_WARNING_GCC_WITH_PUSH("-Wnull-dereference")
908  #endif
909  id_type ich = get(node)->m_first_child;
910  #if __GNUC__ >= 6
911  C4_SUPPRESS_WARNING_GCC_POP
912  #endif
913  while(ich != NONE)
914  {
915  remove_children(ich);
916  _RYML_ASSERT_VISIT_(m_callbacks, get(ich) != nullptr, this, node);
917  id_type next = get(ich)->m_next_sibling;
918  _release(ich);
919  if(ich == get(node)->m_last_child)
920  break;
921  ich = next;
922  }
923 }

References get(), m_callbacks, c4::yml::NodeData::m_first_child, c4::yml::NodeData::m_next_sibling, and c4::yml::NONE.

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

926 {
927  _RYML_ASSERT_VISIT_(m_callbacks, type.is_val() || type.is_map() || type.is_seq(), this, node);
928  _RYML_ASSERT_VISIT_(m_callbacks, type.is_val() + type.is_map() + type.is_seq() == 1, this, node);
929  _RYML_ASSERT_VISIT_(m_callbacks, type.has_key() == has_key(node) || (has_key(node) && !type.has_key()), this, node);
930  NodeData *d = _p(node);
931  if(type.is_map() && is_map(node))
932  return false;
933  else if(type.is_seq() && is_seq(node))
934  return false;
935  else if(type.is_val() && is_val(node))
936  return false;
937  d->m_type = (d->m_type & (~(MAP|SEQ|VAL|CONTAINER_STYLE|KEY_STYLE|VAL_STYLE))) | type;
938  remove_children(node);
939  return true;
940 }
NodeType type(id_type node) const
Definition: tree.hpp:379
bool is_val(id_type node) const
Definition: tree.hpp:412
@ VAL_STYLE
mask of all the scalar styles for val (not container styles!)
Definition: node_type.hpp:92
@ KEY_STYLE
mask of all the scalar styles for key (not container styles!)
Definition: node_type.hpp:91
@ CONTAINER_STYLE
Definition: node_type.hpp:96

References _p(), c4::yml::CONTAINER_STYLE, c4::yml::NodeType::has_key(), has_key(), c4::yml::NodeType::is_map(), is_map(), c4::yml::NodeType::is_seq(), is_seq(), c4::yml::NodeType::is_val(), is_val(), c4::yml::KEY_STYLE, m_callbacks, c4::yml::NodeData::m_type, c4::yml::MAP, remove_children(), c4::yml::SEQ, type(), c4::yml::VAL, and c4::yml::VAL_STYLE.

◆ change_type() [2/2]

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

Definition at line 740 of file tree.hpp.

741  {
742  return change_type(node, (NodeType)type);
743  }
bool change_type(id_type node, NodeType type)
change the type of the node to one of MAP, SEQ or VAL.
Definition: tree.cpp:925

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

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

References has_sibling(), is_root(), m_callbacks, c4::yml::NONE, and parent().

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

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

References is_root(), m_callbacks, and c4::yml::NONE.

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

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

References duplicate(), m_callbacks, c4::yml::NONE, and remove().

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

861 {
862  id_type root = root_id();
863  if(is_stream(root))
864  return;
865  // don't use _add_flags() because it's checked and will fail
866  if(!has_children(root))
867  {
868  if(is_container(root))
869  {
870  id_type next_doc = append_child(root);
871  _copy_props_wo_key(next_doc, root);
872  _p(next_doc)->m_type.add(DOC);
873  }
874  else
875  {
876  _p(root)->m_type.add(SEQ);
877  id_type next_doc = append_child(root);
878  _copy_props_wo_key(next_doc, root);
879  _p(next_doc)->m_type.add(DOC);
880  _p(next_doc)->m_type.rem(SEQ);
881  }
882  _p(root)->m_type = STREAM;
883  return;
884  }
885  _RYML_ASSERT_VISIT_(m_callbacks, !has_key(root), this, root);
886  id_type next_doc = append_child(root);
887  _copy_props_wo_key(next_doc, root);
888  _add_flags(next_doc, DOC);
889  for(id_type prev = NONE, ch = first_child(root), next = next_sibling(ch); ch != NONE; )
890  {
891  if(ch == next_doc)
892  break;
893  move(ch, next_doc, prev);
894  prev = ch;
895  ch = next;
896  next = next_sibling(next);
897  }
898  _p(root)->m_type = STREAM;
899 }
void move(id_type node, id_type after)
change the node's position in the parent
Definition: tree.cpp:822
bool is_stream(id_type node) const
Definition: tree.hpp:405
void rem(NodeType_e t) noexcept
Definition: node_type.hpp:137
void add(NodeType_e t) noexcept
Definition: node_type.hpp:136

References _p(), c4::yml::NodeType::add(), append_child(), c4::yml::DOC, first_child(), has_children(), has_key(), is_container(), is_stream(), m_callbacks, c4::yml::NodeData::m_type, move(), next_sibling(), c4::yml::NONE, c4::yml::NodeType::rem(), root_id(), c4::yml::SEQ, and c4::yml::STREAM.

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

945 {
946  return duplicate(this, node, parent, after);
947 }

References parent().

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

950 {
951  _RYML_ASSERT_VISIT_(m_callbacks, src != nullptr, src, node);
952  _RYML_ASSERT_VISIT_(m_callbacks, node != NONE, src, node);
953  _RYML_ASSERT_VISIT_(m_callbacks, parent != NONE, this, parent);
954  _RYML_ASSERT_VISIT_(m_callbacks, ! src->is_root(node), src, node);
955 
956  id_type copy = _claim();
957 
958  _copy_props(copy, src, node);
959  _set_hierarchy(copy, parent, after);
960  duplicate_children(src, node, copy, NONE);
961 
962  return copy;
963 }
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:966

References _claim(), duplicate_children(), is_root(), m_callbacks, c4::yml::NONE, and parent().

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

967 {
968  return duplicate_children(this, node, parent, after);
969 }

References parent().

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

972 {
973  _RYML_ASSERT_VISIT_(m_callbacks, src != nullptr, src, node);
974  _RYML_ASSERT_VISIT_(m_callbacks, node != NONE, src, node);
975  _RYML_ASSERT_VISIT_(m_callbacks, parent != NONE, this, parent);
976  _RYML_ASSERT_VISIT_(m_callbacks, after == NONE || has_child(parent, after), this, parent);
977 
978  id_type prev = after;
979  for(id_type i = src->first_child(node); i != NONE; i = src->next_sibling(i))
980  {
981  prev = duplicate(src, i, parent, prev);
982  }
983 
984  return prev;
985 }
bool has_child(id_type node, id_type ch) const
true if node has a child with id ch
Definition: tree.hpp:468

References duplicate(), first_child(), has_child(), m_callbacks, next_sibling(), c4::yml::NONE, and parent().

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

1004 {
1005  return duplicate_children_no_rep(this, node, parent, after);
1006 }
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:1003

References parent().

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

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

References duplicate(), first_child(), has_child(), is_ancestor(), is_map(), is_seq(), key(), m_callbacks, move(), next_sibling(), c4::yml::NONE, parent(), prev_sibling(), and remove().

◆ duplicate_contents() [1/2]

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

Definition at line 988 of file tree.cpp.

989 {
990  duplicate_contents(this, node, where);
991 }
void duplicate_contents(id_type node, id_type where)
Definition: tree.cpp:988

◆ duplicate_contents() [2/2]

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

Definition at line 993 of file tree.cpp.

994 {
995  _RYML_ASSERT_VISIT_(m_callbacks, src != nullptr, src, node);
996  _RYML_ASSERT_VISIT_(m_callbacks, node != NONE, src, node);
997  _RYML_ASSERT_VISIT_(m_callbacks, where != NONE, this, where);
998  _copy_props_wo_key(where, src, node);
999  duplicate_children(src, node, where, last_child(where));
1000 }
id_type last_child(id_type node) const
Definition: tree.hpp:508

References duplicate_children(), last_child(), m_callbacks, and c4::yml::NONE.

◆ merge_with()

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

Definition at line 1103 of file tree.cpp.

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

References _p(), append_child(), find_child(), first_child(), has_children(), has_key(), has_val(), is_keyval(), is_map(), is_seq(), is_val(), key(), m_callbacks, c4::yml::NodeData::m_type, next_sibling(), c4::yml::NONE, remove_children(), root_id(), c4::yml::STYLE, to_map(), to_seq(), and c4::yml::VAL_STYLE.

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

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

References c4::yml::ParseEngine< EventHandler >::source(), and c4::yml::ParseEngine< EventHandler >::val_location().

◆ arena_size()

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

get the current size of the tree's internal arena

Definition at line 843 of file tree.hpp.

843 { 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 845 of file tree.hpp.

845 { 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 847 of file tree.hpp.

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

References c4::yml::NONE.

◆ arena_pos()

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

Definition at line 848 of file tree.hpp.

848 { return m_arena_pos; }

◆ arena() [1/2]

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

get the current arena

Definition at line 851 of file tree.hpp.

851 { return m_arena.first(m_arena_pos); }

◆ arena() [2/2]

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

get the current arena

Definition at line 853 of file tree.hpp.

853 { 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 856 of file tree.hpp.

857  {
858  return m_arena.is_super(s);
859  }

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

879  {
880  return serialize_to_arena(this, a);
881  }
csubstr serialize_to_arena(Tree *tree, csubstr a)
Definition: tree.cpp:18

References c4::yml::serialize_to_arena().

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

900  {
901  _RYML_ASSERT_VISIT_(m_callbacks, !s.overlaps(m_arena), this, NONE);
902  substr cp = alloc_arena(s.len);
903  _RYML_ASSERT_VISIT_(m_callbacks, cp.len == s.len, this, NONE);
904  _RYML_ASSERT_VISIT_(m_callbacks, !s.overlaps(cp), this, NONE);
905  #if (!defined(__clang__)) && (defined(__GNUC__) && __GNUC__ >= 10)
906  C4_SUPPRESS_WARNING_GCC_PUSH
907  C4_SUPPRESS_WARNING_GCC("-Wstringop-overflow=") // no need for terminating \0
908  C4_SUPPRESS_WARNING_GCC("-Wrestrict") // there's an assert to ensure no violation of restrict behavior
909  #endif
910  if(s.len)
911  memcpy(cp.str, s.str, s.len);
912  #if (!defined(__clang__)) && (defined(__GNUC__) && __GNUC__ >= 10)
913  C4_SUPPRESS_WARNING_GCC_POP
914  #endif
915  return cp;
916  }
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:928

References c4::yml::NONE.

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

929  {
930  if(sz > arena_slack())
931  _grow_arena(sz - arena_slack());
932  substr s = _request_span(sz);
933  return s;
934  }
size_t arena_slack() const
get the current slack of the tree's internal arena
Definition: tree.hpp:847

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

941  {
942  if(arena_cap > m_arena.len)
943  {
944  substr buf;
945  buf.str = _RYML_CB_ALLOC(m_callbacks, char, arena_cap);
946  buf.len = arena_cap;
947  if(m_arena.str)
948  {
949  _RYML_ASSERT_VISIT_(m_callbacks, m_arena.len >= 0, this, NONE);
950  _relocate(buf); // does a memcpy and changes nodes using the arena
951  _RYML_CB_FREE(m_callbacks, m_arena.str, char, m_arena.len);
952  }
953  m_arena = buf;
954  }
955  }

References c4::yml::NONE.

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

1617 {
1618  if(start == NONE)
1619  start = root_id();
1620  lookup_result r(path, start);
1621  if(path.empty())
1622  return r;
1623  _lookup_path(&r);
1624  if(r.target == NONE && r.closest == start)
1625  r.closest = NONE;
1626  return r;
1627 }

References c4::yml::Tree::lookup_result::closest, c4::yml::NONE, root_id(), and c4::yml::Tree::lookup_result::target.

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

1630 {
1631  id_type target = _lookup_path_or_create(path, start);
1632  if(parent_is_map(target))
1633  to_keyval(target, key(target), default_value);
1634  else
1635  to_val(target, default_value);
1636  return target;
1637 }
void to_keyval(id_type node, csubstr key, csubstr val, type_bits more_flags=0)
Definition: tree.cpp:1328
void to_val(id_type node, csubstr val, type_bits more_flags=0)
Definition: tree.cpp:1319

References key(), parent_is_map(), to_keyval(), and to_val().

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

1640 {
1641  id_type target = _lookup_path_or_create(path, start);
1642  merge_with(src, src_node, target);
1643  return target;
1644 }

References merge_with().

◆ _claim()

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

Definition at line 417 of file tree.cpp.

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

References child(), m_buf, m_callbacks, m_cap, m_free_head, m_free_tail, m_size, c4::yml::NONE, and reserve().

Member Data Documentation

◆ m_buf

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

Definition at line 1298 of file tree.hpp.

◆ m_cap

id_type c4::yml::Tree::m_cap

Definition at line 1299 of file tree.hpp.

◆ m_size

id_type c4::yml::Tree::m_size

Definition at line 1300 of file tree.hpp.

◆ m_free_head

id_type c4::yml::Tree::m_free_head

Definition at line 1302 of file tree.hpp.

◆ m_free_tail

id_type c4::yml::Tree::m_free_tail

Definition at line 1303 of file tree.hpp.

◆ m_arena

substr c4::yml::Tree::m_arena

Definition at line 1305 of file tree.hpp.

◆ m_arena_pos

size_t c4::yml::Tree::m_arena_pos

Definition at line 1306 of file tree.hpp.

◆ m_callbacks

Callbacks c4::yml::Tree::m_callbacks

Definition at line 1308 of file tree.hpp.

◆ m_tag_directives

TagDirective c4::yml::Tree::m_tag_directives[RYML_MAX_TAG_DIRECTIVES]

Definition at line 1310 of file tree.hpp.


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