rapidyaml  0.7.1
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=0)
 
 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) RYML_NOEXCEPT
 
memory and sizing
void reserve (id_type node_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 ()
 Get the id of the root node. More...
 
id_type root_id () const
 Get the id of the root node. 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 by name, return it as a NodeRef More...
 
ConstNodeRef operator[] (csubstr key) const
 find a root child by name, return it as a NodeRef More...
 
NodeRef operator[] (id_type i)
 find a root child by index: return the root node's i-th child as a NodeRef More...
 
ConstNodeRef operator[] (id_type i) const
 find a root child 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 does not have any KEYQUO flags, and its scalar verifies scalar_is_null(). More...
 
bool val_is_null (id_type node) const
 true if the node key does not have any VALQUO flags, and 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 predicates
bool is_root (id_type node) const
 
bool has_parent (id_type node) const
 
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...
 
bool has_siblings (id_type) 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
 
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)
 
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...
 
void resolve (ReferenceResolver *rr)
 Resolve references (aliases <- anchors) in the tree. More...
 
void resolve ()
 Resolve references using a throw-away resolver. 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...
 
void duplicate_contents (id_type node, id_type where)
 
void duplicate_contents (Tree const *src, id_type node, id_type where)
 
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 merge_with (Tree const *src, id_type src_node=NONE, id_type dst_root=NONE)
 
internal string arena
size_t arena_pos () const
 get the current size of the tree's internal arena More...
 
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...
 
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 >
std::enable_if< std::is_floating_point< T >::value, csubstr >::type to_arena (T const &a)
 serialize the given floating-point variable to the tree's arena, growing it as needed to accomodate the serialization. More...
 
template<class T >
std::enable_if<!std::is_floating_point< T >::value, csubstr >::type to_arena (T const &a)
 serialize the given non-floating-point variable to the tree's arena, growing it as needed to accomodate the serialization. More...
 
csubstr to_arena (csubstr a)
 serialize the given csubstr to the tree's arena, growing the arena as needed to accomodate the serialization. More...
 
csubstr to_arena (const char *s)
 
csubstr to_arena (std::nullptr_t)
 
substr copy_to_arena (csubstr s)
 copy the given substr to the tree's arena, growing it 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)
 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
 

Detailed Description

Definition at line 241 of file tree.hpp.

Member Typedef Documentation

◆ tag_directive_const_iterator

Definition at line 658 of file tree.hpp.

◆ TagDirectiveProxy

Constructor & Destructor Documentation

◆ Tree() [1/6]

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

Definition at line 248 of file tree.hpp.

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

◆ Tree() [2/6]

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

Definition at line 84 of file tree.cpp.

85  : m_buf(nullptr)
86  , m_cap(0)
87  , m_size(0)
88  , m_free_head(NONE)
89  , m_free_tail(NONE)
90  , m_arena()
91  , m_arena_pos(0)
92  , m_callbacks(cb)
94 {
95 }
NodeData * m_buf
Definition: tree.hpp:1348
id_type m_free_head
Definition: tree.hpp:1353
size_t m_arena_pos
Definition: tree.hpp:1357
TagDirective m_tag_directives[RYML_MAX_TAG_DIRECTIVES]
Definition: tree.hpp:1361
id_type m_size
Definition: tree.hpp:1351
id_type m_cap
Definition: tree.hpp:1349
substr m_arena
Definition: tree.hpp:1356
id_type m_free_tail
Definition: tree.hpp:1354
Callbacks m_callbacks
Definition: tree.hpp:1359
@ NONE
an index to none
Definition: common.hpp:259

◆ Tree() [3/6]

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

Definition at line 250 of file tree.hpp.

250 : 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:827

◆ Tree() [4/6]

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

Definition at line 97 of file tree.cpp.

98  : Tree(cb)
99 {
100  reserve(node_capacity);
102 }
void reserve_arena(size_t arena_cap)
ensure the tree's internal string arena is at least the given capacity
Definition: tree.hpp:994
void reserve(id_type node_capacity)
Definition: tree.cpp:248

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

◆ ~Tree()

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

Definition at line 104 of file tree.cpp.

105 {
106  _free();
107 }

◆ Tree() [5/6]

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

Definition at line 110 of file tree.cpp.

110  : Tree(that.m_callbacks)
111 {
112  _copy(that);
113 }

◆ Tree() [6/6]

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

Definition at line 123 of file tree.cpp.

123  : Tree(that.m_callbacks)
124 {
125  _move(that);
126 }

Member Function Documentation

◆ operator=() [1/2]

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

Definition at line 115 of file tree.cpp.

116 {
117  _free();
118  m_callbacks = that.m_callbacks;
119  _copy(that);
120  return *this;
121 }

References m_callbacks.

◆ operator=() [2/2]

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

Definition at line 128 of file tree.cpp.

129 {
130  _free();
131  m_callbacks = that.m_callbacks;
132  _move(that);
133  return *this;
134 }

◆ reserve()

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

Definition at line 248 of file tree.cpp.

249 {
250  if(cap > m_cap)
251  {
252  NodeData *buf = _RYML_CB_ALLOC_HINT(m_callbacks, NodeData, (size_t)cap, m_buf);
253  if(m_buf)
254  {
255  memcpy(buf, m_buf, (size_t)m_cap * sizeof(NodeData));
256  _RYML_CB_FREE(m_callbacks, m_buf, NodeData, (size_t)m_cap);
257  }
258  id_type first = m_cap, del = cap - m_cap;
259  m_cap = cap;
260  m_buf = buf;
261  _clear_range(first, del);
262  if(m_free_head != NONE)
263  {
264  _RYML_CB_ASSERT(m_callbacks, m_buf != nullptr);
265  _RYML_CB_ASSERT(m_callbacks, m_free_tail != NONE);
268  m_free_tail = cap-1;
269  }
270  else
271  {
272  _RYML_CB_ASSERT(m_callbacks, m_free_tail == NONE);
273  m_free_head = first;
274  m_free_tail = cap-1;
275  }
276  _RYML_CB_ASSERT(m_callbacks, m_free_head == NONE || (m_free_head >= 0 && m_free_head < cap));
277  _RYML_CB_ASSERT(m_callbacks, m_free_tail == NONE || (m_free_tail >= 0 && m_free_tail < cap));
278 
279  if( ! m_size)
280  _claim_root();
281  }
282 }
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:252
id_type m_next_sibling
Definition: tree.hpp:231
id_type m_prev_sibling
Definition: tree.hpp:232

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.

Referenced by Tree(), _claim(), sample::sample_global_allocator(), sample::sample_parse_reuse_tree(), and sample::sample_parse_reuse_tree_and_parser().

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

287 {
288  _clear_range(0, m_cap);
289  m_size = 0;
290  if(m_buf)
291  {
292  _RYML_CB_ASSERT(m_callbacks, m_cap >= 0);
293  m_free_head = 0;
294  m_free_tail = m_cap-1;
295  _claim_root();
296  }
297  else
298  {
299  m_free_head = NONE;
300  m_free_tail = NONE;
301  }
302  for(id_type i = 0; i < RYML_MAX_TAG_DIRECTIVES; ++i)
303  m_tag_directives[i] = {};
304 }
#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.

Referenced by sample::sample_empty_null_values(), sample::sample_parse_reuse_tree(), and sample::sample_parse_reuse_tree_and_parser().

◆ clear_arena()

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

Definition at line 274 of file tree.hpp.

274 { m_arena_pos = 0; }

Referenced by sample::sample_empty_null_values(), and sample::sample_parse_reuse_tree().

◆ empty() [1/2]

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

◆ size()

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

◆ capacity()

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

Definition at line 279 of file tree.hpp.

279 { return m_cap; }

Referenced by c4::yml::Emitter< Writer >::emit_as(), and c4::yml::EventHandlerTree::reset().

◆ slack()

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

Definition at line 280 of file tree.hpp.

280 { RYML_ASSERT(m_cap >= m_size); return m_cap - m_size; }

◆ callbacks() [1/2]

◆ callbacks() [2/2]

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

Definition at line 283 of file tree.hpp.

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

295  {
296  if( ! n)
297  return NONE;
298  _RYML_CB_ASSERT(m_callbacks, n >= m_buf && n < m_buf + m_cap);
299  return static_cast<id_type>(n - m_buf);
300  }

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

305  {
306  if(node == NONE)
307  return nullptr;
308  _RYML_CB_ASSERT(m_callbacks, node >= 0 && node < m_cap);
309  return m_buf + node;
310  }

References c4::yml::NONE.

Referenced by find_child(), and remove_children().

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

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

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

323 { _RYML_CB_ASSERT(m_callbacks, node != NONE && node >= 0 && node < m_cap); return m_buf + node; }

References c4::yml::NONE.

Referenced by change_type(), find_child(), merge_with(), set_root_as_stream(), to_doc(), to_keyval(), to_map(), to_seq(), to_stream(), and to_val().

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

326 { _RYML_CB_ASSERT(m_callbacks, node != NONE && node >= 0 && node < m_cap); return m_buf + node; }

References c4::yml::NONE.

◆ root_id() [1/2]

◆ root_id() [2/2]

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

Get the id of the root node.

Definition at line 331 of file tree.hpp.

331 { _RYML_CB_ASSERT(m_callbacks, m_cap > 0 && m_size > 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 35 of file tree.cpp.

36 {
37  _RYML_CB_ASSERT(m_callbacks, id != NONE && id >= 0 && id < m_cap);
38  return NodeRef(this, id);
39 }

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

41 {
42  _RYML_CB_ASSERT(m_callbacks, id != NONE && id >= 0 && id < m_cap);
43  return ConstNodeRef(this, id);
44 }

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

46 {
47  _RYML_CB_ASSERT(m_callbacks, id != NONE && id >= 0 && id < m_cap);
48  return ConstNodeRef(this, id);
49 }

References c4::yml::NONE.

◆ rootref() [1/2]

◆ rootref() [2/2]

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

Get the root as a ConstNodeRef.

Definition at line 25 of file tree.cpp.

26 {
27  return ConstNodeRef(this, root_id());
28 }

◆ crootref()

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

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

70 {
71  return ref(doc(i));
72 }
NodeRef ref(id_type node)
Get a NodeRef of a node by id.
Definition: tree.cpp:35
id_type doc(id_type i) const
gets the i document node index.
Definition: tree.hpp:519

Referenced by sample::sample_docs().

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

74 {
75  return cref(doc(i));
76 }
ConstNodeRef cref(id_type node) const
Get a NodeRef of a node by id.
Definition: tree.cpp:45

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

78 {
79  return cref(doc(i));
80 }

◆ operator[]() [1/4]

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

find a root child by name, return it as a NodeRef

Note
requires the root to be a map.

Definition at line 51 of file tree.cpp.

52 {
53  return rootref()[key];
54 }
NodeRef rootref()
Get the root as a NodeRef.
Definition: tree.cpp:21
csubstr const & key(id_type node) const
Definition: tree.hpp:381

References c4::yml::key().

◆ operator[]() [2/4]

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

find a root child by name, return it as a NodeRef

Note
requires the root to be a map.

Definition at line 55 of file tree.cpp.

56 {
57  return rootref()[key];
58 }

References c4::yml::key().

◆ operator[]() [3/4]

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

find a root child 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 60 of file tree.cpp.

61 {
62  return rootref()[i];
63 }

◆ operator[]() [4/4]

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

find a root child 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 64 of file tree.cpp.

65 {
66  return rootref()[i];
67 }

◆ type()

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

Definition at line 378 of file tree.hpp.

378 { 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:323
NodeType m_type
Definition: tree.hpp:223

Referenced by change_type(), and c4::yml::TagDirective::create_from_str().

◆ type_str()

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

Definition at line 379 of file tree.hpp.

379 { 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:148

◆ key()

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

Definition at line 381 of file tree.hpp.

381 { _RYML_CB_ASSERT(m_callbacks, has_key(node)); return _p(node)->m_key.scalar; }
bool has_key(id_type node) const
Definition: tree.hpp:409
NodeScalar m_key
Definition: tree.hpp:225
csubstr scalar
Definition: tree.hpp:107

Referenced by duplicate_children_no_rep(), lookup_path_or_modify(), merge_with(), sample::sample_base64(), sample::sample_quick_overview(), sample::sample_tree_arena(), to_keyval(), to_map(), and to_seq().

◆ key_tag()

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

Definition at line 382 of file tree.hpp.

382 { _RYML_CB_ASSERT(m_callbacks, has_key_tag(node)); return _p(node)->m_key.tag; }
bool has_key_tag(id_type node) const
Definition: tree.hpp:413

◆ key_ref()

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

Definition at line 383 of file tree.hpp.

383 { _RYML_CB_ASSERT(m_callbacks, is_key_ref(node)); return _p(node)->m_key.anchor; }
bool is_key_ref(id_type node) const
Definition: tree.hpp:418
csubstr anchor
Definition: tree.hpp:108

◆ key_anchor()

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

Definition at line 384 of file tree.hpp.

384 { _RYML_CB_ASSERT(m_callbacks, has_key_anchor(node)); return _p(node)->m_key.anchor; }
bool has_key_anchor(id_type node) const
Definition: tree.hpp:415

◆ keysc()

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

Definition at line 385 of file tree.hpp.

385 { _RYML_CB_ASSERT(m_callbacks, has_key(node)); return _p(node)->m_key; }

◆ val()

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

Definition at line 387 of file tree.hpp.

387 { _RYML_CB_ASSERT(m_callbacks, has_val(node)); return _p(node)->m_val.scalar; }
bool has_val(id_type node) const
Definition: tree.hpp:410
NodeScalar m_val
Definition: tree.hpp:226

Referenced by sample::sample_base64(), sample::sample_docs(), sample::sample_tree_arena(), to_keyval(), and to_val().

◆ val_tag()

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

Definition at line 388 of file tree.hpp.

388 { _RYML_CB_ASSERT(m_callbacks, has_val_tag(node)); return _p(node)->m_val.tag; }
bool has_val_tag(id_type node) const
Definition: tree.hpp:414

◆ val_ref()

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

Definition at line 389 of file tree.hpp.

389 { _RYML_CB_ASSERT(m_callbacks, is_val_ref(node)); return _p(node)->m_val.anchor; }
bool is_val_ref(id_type node) const
Definition: tree.hpp:419

◆ val_anchor()

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

Definition at line 390 of file tree.hpp.

390 { _RYML_CB_ASSERT(m_callbacks, has_val_anchor(node)); return _p(node)->m_val.anchor; }
bool has_val_anchor(id_type node) const
Definition: tree.hpp:416

◆ valsc()

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

Definition at line 391 of file tree.hpp.

391 { _RYML_CB_ASSERT(m_callbacks, has_val(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 400 of file tree.hpp.

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

◆ type_has_all()

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

Definition at line 401 of file tree.hpp.

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

◆ type_has_none()

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

Definition at line 402 of file tree.hpp.

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

◆ is_stream()

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

Definition at line 404 of file tree.hpp.

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

Referenced by c4::yml::TagDirective::create_from_str(), sample::sample_docs(), and set_root_as_stream().

◆ is_doc()

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

Definition at line 405 of file tree.hpp.

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

Referenced by sample::sample_docs().

◆ is_container()

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

Definition at line 406 of file tree.hpp.

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

◆ is_map()

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

◆ is_seq()

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

Definition at line 408 of file tree.hpp.

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

Referenced by change_type(), duplicate_children_no_rep(), merge_with(), sample::sample_docs(), and sample::sample_quick_overview().

◆ has_key()

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

Definition at line 409 of file tree.hpp.

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

Referenced by change_type(), merge_with(), c4::yml::EventHandlerTree::reset(), and set_root_as_stream().

◆ has_val()

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

Definition at line 410 of file tree.hpp.

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

Referenced by merge_with().

◆ is_val()

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

Definition at line 411 of file tree.hpp.

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

Referenced by change_type(), merge_with(), and set_root_as_stream().

◆ is_keyval()

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

Definition at line 412 of file tree.hpp.

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

Referenced by merge_with().

◆ has_key_tag()

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

Definition at line 413 of file tree.hpp.

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

◆ has_val_tag()

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

Definition at line 414 of file tree.hpp.

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

◆ has_key_anchor()

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

Definition at line 415 of file tree.hpp.

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

◆ has_val_anchor()

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

Definition at line 416 of file tree.hpp.

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

◆ has_anchor() [1/2]

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

Definition at line 417 of file tree.hpp.

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

◆ is_key_ref()

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

Definition at line 418 of file tree.hpp.

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

◆ is_val_ref()

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

Definition at line 419 of file tree.hpp.

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

◆ is_ref()

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

Definition at line 420 of file tree.hpp.

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

◆ parent_is_seq()

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

Definition at line 422 of file tree.hpp.

422 { _RYML_CB_ASSERT(m_callbacks, has_parent(node)); return is_seq(_p(node)->m_parent); }
bool is_seq(id_type node) const
Definition: tree.hpp:408
bool has_parent(id_type node) const
Definition: tree.hpp:458

Referenced by to_seq().

◆ parent_is_map()

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

Definition at line 423 of file tree.hpp.

423 { _RYML_CB_ASSERT(m_callbacks, has_parent(node)); return is_map(_p(node)->m_parent); }
bool is_map(id_type node) const
Definition: tree.hpp:407

Referenced by lookup_path_or_modify(), to_keyval(), to_map(), to_seq(), and to_val().

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

426 { 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 does not have any KEYQUO flags, and its scalar verifies scalar_is_null().

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

Definition at line 431 of file tree.hpp.

431 { _RYML_CB_ASSERT(m_callbacks, has_key(node)); NodeData const* C4_RESTRICT n = _p(node); return !n->m_type.is_key_quoted() && scalar_is_null(n->m_key.scalar); }
bool scalar_is_null(csubstr s) noexcept
YAML-sense query of nullity.
Definition: node_type.hpp:251

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 key does not have any VALQUO flags, and its scalar verifies scalar_is_null().

Warning
the node must verify .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 435 of file tree.hpp.

435 { _RYML_CB_ASSERT(m_callbacks, has_val(node)); NodeData const* C4_RESTRICT n = _p(node); return !n->m_type.is_val_quoted() && 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 439 of file tree.hpp.

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

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

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

◆ is_key_anchor()

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

Definition at line 444 of file tree.hpp.

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

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

◆ is_anchor()

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

Definition at line 446 of file tree.hpp.

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

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

456 { _RYML_CB_ASSERT(m_callbacks, _p(node)->m_parent != NONE || node == 0); return _p(node)->m_parent == NONE; }
id_type m_parent
Definition: tree.hpp:228

References c4::yml::NONE.

Referenced by c4::yml::TagDirective::create_from_str(), depth_asc(), duplicate(), move(), c4::yml::EventHandlerTree::reset(), and sample::sample_docs().

◆ has_parent()

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

Definition at line 458 of file tree.hpp.

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

References c4::yml::NONE.

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

461 { 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:468
@ 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:34
bool empty() const noexcept
Definition: tree.hpp:135

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

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

Referenced by duplicate_children(), and duplicate_children_no_rep().

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

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

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

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

References c4::yml::NONE.

Referenced by merge_with(), set_root_as_stream(), to_doc(), to_keyval(), to_map(), to_seq(), to_stream(), and to_val().

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

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

Referenced by move().

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

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

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

476  {
477  NodeData const *n = _p(node);
478  if(C4_LIKELY(n->m_parent != NONE))
479  {
480  n = _p(n->m_parent);
481  return n->m_first_child != n->m_last_child;
482  }
483  return false;
484  }

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

◆ has_siblings()

bool c4::yml::Tree::has_siblings ( id_type  ) const
inline

Definition at line 486 of file tree.hpp.

486 { return true; }

◆ parent()

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

◆ prev_sibling()

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

Definition at line 497 of file tree.hpp.

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

◆ next_sibling()

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

◆ num_children()

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

O(num_children)

Definition at line 1121 of file tree.cpp.

1122 {
1123  id_type count = 0;
1124  for(id_type i = first_child(node); i != NONE; i = next_sibling(i))
1125  ++count;
1126  return count;
1127 }
id_type first_child(id_type node) const
Definition: tree.hpp:503
id_type next_sibling(id_type node) const
Definition: tree.hpp:498

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

Referenced by sample::sample_docs().

◆ child_pos()

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

Definition at line 1141 of file tree.cpp.

1142 {
1143  _RYML_CB_ASSERT(m_callbacks, node != NONE);
1144  id_type count = 0;
1145  for(id_type i = first_child(node); i != NONE; i = next_sibling(i))
1146  {
1147  if(i == ch)
1148  return count;
1149  ++count;
1150  }
1151  return NONE;
1152 }

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

◆ last_child()

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

Definition at line 504 of file tree.hpp.

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

Referenced by duplicate_contents().

◆ child()

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

Definition at line 1129 of file tree.cpp.

1130 {
1131  _RYML_CB_ASSERT(m_callbacks, node != NONE);
1132  id_type count = 0;
1133  for(id_type i = first_child(node); i != NONE; i = next_sibling(i))
1134  {
1135  if(count++ == pos)
1136  return i;
1137  }
1138  return NONE;
1139 }

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

Referenced by _claim(), and sample::sample_docs().

◆ find_child()

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

Definition at line 1167 of file tree.cpp.

1168 {
1169  _RYML_CB_ASSERT(m_callbacks, node != NONE);
1170  _RYML_CB_ASSERT(m_callbacks, is_map(node));
1171  if(get(node)->m_first_child == NONE)
1172  {
1173  _RYML_CB_ASSERT(m_callbacks, _p(node)->m_last_child == NONE);
1174  return NONE;
1175  }
1176  else
1177  {
1178  _RYML_CB_ASSERT(m_callbacks, _p(node)->m_last_child != NONE);
1179  }
1180  for(id_type i = first_child(node); i != NONE; i = next_sibling(i))
1181  {
1182  if(_p(i)->m_key.scalar == name)
1183  {
1184  return i;
1185  }
1186  }
1187  return NONE;
1188 }
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:304

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

Referenced by merge_with(), sample::sample_docs(), and sample::sample_quick_overview().

◆ num_siblings()

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

O(num_siblings)

counts with this

Definition at line 510 of file tree.hpp.

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

◆ num_other_siblings()

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

does not count with this

Definition at line 512 of file tree.hpp.

512 { id_type ns = num_siblings(node); _RYML_CB_ASSERT(m_callbacks, ns > 0); return ns-1; }
id_type num_siblings(id_type node) const
O(num_siblings)
Definition: tree.hpp:510

◆ sibling_pos()

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

Definition at line 513 of file tree.hpp.

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

◆ first_sibling()

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

Definition at line 514 of file tree.hpp.

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

Referenced by sample::sample_quick_overview().

◆ last_sibling()

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

Definition at line 515 of file tree.hpp.

515 { 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 516 of file tree.hpp.

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

◆ find_sibling()

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

Definition at line 517 of file tree.hpp.

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

Referenced by sample::sample_docs().

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

1216 {
1217  _RYML_CB_ASSERT(m_callbacks, node != NONE);
1218  id_type depth = 0;
1219  while(!is_root(node))
1220  {
1221  ++depth;
1222  node = parent(node);
1223  }
1224  return depth;
1225 }
id_type parent(id_type node) const
Definition: tree.hpp:495

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

1210 {
1211  _RYML_CB_ASSERT(m_callbacks, node != NONE);
1212  return depth_desc_(*this, node);
1213 }

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

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

◆ is_block()

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

Definition at line 532 of file tree.hpp.

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

◆ is_flow_sl()

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

Definition at line 533 of file tree.hpp.

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

◆ is_flow_ml()

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

Definition at line 534 of file tree.hpp.

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

◆ is_flow()

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

Definition at line 535 of file tree.hpp.

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

◆ is_key_styled()

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

Definition at line 537 of file tree.hpp.

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

◆ is_val_styled()

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

Definition at line 538 of file tree.hpp.

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

◆ is_key_literal()

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

Definition at line 539 of file tree.hpp.

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

◆ is_val_literal()

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

Definition at line 540 of file tree.hpp.

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

◆ is_key_folded()

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

Definition at line 541 of file tree.hpp.

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

◆ is_val_folded()

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

Definition at line 542 of file tree.hpp.

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

◆ is_key_squo()

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

Definition at line 543 of file tree.hpp.

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

◆ is_val_squo()

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

Definition at line 544 of file tree.hpp.

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

◆ is_key_dquo()

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

Definition at line 545 of file tree.hpp.

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

◆ is_val_dquo()

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

Definition at line 546 of file tree.hpp.

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

◆ is_key_plain()

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

Definition at line 547 of file tree.hpp.

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

◆ is_val_plain()

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

Definition at line 548 of file tree.hpp.

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

◆ is_key_quoted()

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

Definition at line 549 of file tree.hpp.

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

◆ is_val_quoted()

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

Definition at line 550 of file tree.hpp.

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

◆ is_quoted()

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

Definition at line 551 of file tree.hpp.

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

◆ set_container_style()

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

Definition at line 553 of file tree.hpp.

553 { _RYML_CB_ASSERT(m_callbacks, is_container(node)); _p(node)->m_type.set_container_style(style); }
bool is_container(id_type node) const
Definition: tree.hpp:406
void set_container_style(NodeType_e style) noexcept
Definition: node_type.hpp:217

◆ set_key_style()

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

Definition at line 554 of file tree.hpp.

554 { _RYML_CB_ASSERT(m_callbacks, has_key(node)); _p(node)->m_type.set_key_style(style); }
void set_key_style(NodeType_e style) noexcept
Definition: node_type.hpp:218

◆ set_val_style()

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

Definition at line 555 of file tree.hpp.

555 { _RYML_CB_ASSERT(m_callbacks, has_val(node)); _p(node)->m_type.set_val_style(style); }
void set_val_style(NodeType_e style) noexcept
Definition: node_type.hpp:219

◆ to_keyval()

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

Definition at line 1239 of file tree.cpp.

1240 {
1241  _RYML_CB_ASSERT(m_callbacks, ! has_children(node));
1242  _RYML_CB_ASSERT(m_callbacks, parent(node) == NONE || parent_is_map(node));
1243  _set_flags(node, KEYVAL|more_flags);
1244  _p(node)->m_key = key;
1245  _p(node)->m_val = val;
1246 }
csubstr const & val(id_type node) const
Definition: tree.hpp:387
bool parent_is_map(id_type node) const
Definition: tree.hpp:423

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().

Referenced by lookup_path_or_modify().

◆ to_map() [1/2]

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

Definition at line 1257 of file tree.cpp.

1258 {
1259  _RYML_CB_ASSERT(m_callbacks, ! has_children(node));
1260  _RYML_CB_ASSERT(m_callbacks, parent(node) == NONE || parent_is_map(node));
1261  _set_flags(node, KEY|MAP|more_flags);
1262  _p(node)->m_key = key;
1263  _p(node)->m_val.clear();
1264 }
@ MAP
a map: a parent of KEYVAL/KEYSEQ/KEYMAP nodes
Definition: node_type.hpp:35
@ KEY
is member of a map, must have non-empty key
Definition: node_type.hpp:33
void clear() noexcept
Definition: tree.hpp:137

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().

Referenced by merge_with().

◆ to_seq() [1/2]

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

Definition at line 1275 of file tree.cpp.

1276 {
1277  _RYML_CB_ASSERT(m_callbacks, ! has_children(node));
1278  _RYML_CB_ASSERT(m_callbacks, parent(node) == NONE || parent_is_map(node));
1279  _set_flags(node, KEY|SEQ|more_flags);
1280  _p(node)->m_key = key;
1281  _p(node)->m_val.clear();
1282 }
@ SEQ
a seq: a parent of VAL/SEQ/MAP nodes
Definition: node_type.hpp:36

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.

Referenced by merge_with().

◆ to_val()

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

Definition at line 1230 of file tree.cpp.

1231 {
1232  _RYML_CB_ASSERT(m_callbacks, ! has_children(node));
1233  _RYML_CB_ASSERT(m_callbacks, parent(node) == NONE || ! parent_is_map(node));
1234  _set_flags(node, VAL|more_flags);
1235  _p(node)->m_key.clear();
1236  _p(node)->m_val = val;
1237 }

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().

Referenced by lookup_path_or_modify().

◆ to_map() [2/2]

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

Definition at line 1248 of file tree.cpp.

1249 {
1250  _RYML_CB_ASSERT(m_callbacks, ! has_children(node));
1251  _RYML_CB_ASSERT(m_callbacks, parent(node) == NONE || ! parent_is_map(node)); // parent must not have children with keys
1252  _set_flags(node, MAP|more_flags);
1253  _p(node)->m_key.clear();
1254  _p(node)->m_val.clear();
1255 }

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

1267 {
1268  _RYML_CB_ASSERT(m_callbacks, ! has_children(node));
1269  _RYML_CB_ASSERT(m_callbacks, parent(node) == NONE || parent_is_seq(node));
1270  _set_flags(node, SEQ|more_flags);
1271  _p(node)->m_key.clear();
1272  _p(node)->m_val.clear();
1273 }
bool parent_is_seq(id_type node) const
Definition: tree.hpp:422

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

1285 {
1286  _RYML_CB_ASSERT(m_callbacks, ! has_children(node));
1287  _set_flags(node, DOC|more_flags);
1288  _p(node)->m_key.clear();
1289  _p(node)->m_val.clear();
1290 }
@ DOC
a document
Definition: node_type.hpp:37

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

1293 {
1294  _RYML_CB_ASSERT(m_callbacks, ! has_children(node));
1295  _set_flags(node, STREAM|more_flags);
1296  _p(node)->m_key.clear();
1297  _p(node)->m_val.clear();
1298 }
@ STREAM
a stream: a seq of docs
Definition: node_type.hpp:38

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

573 { _RYML_CB_ASSERT(m_callbacks, has_key(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 574 of file tree.hpp.

574 { _RYML_CB_ASSERT(m_callbacks, has_val(node)); _p(node)->m_val.scalar = val; }

Referenced by sample::sample_tree_arena().

◆ set_key_tag()

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

Definition at line 576 of file tree.hpp.

576 { _RYML_CB_ASSERT(m_callbacks, has_key(node)); _p(node)->m_key.tag = tag; _add_flags(node, KEYTAG); }
@ KEYTAG
the key has a tag
Definition: node_type.hpp:43

References c4::yml::KEYTAG.

◆ set_val_tag()

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

Definition at line 577 of file tree.hpp.

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

References c4::yml::VALTAG.

◆ set_key_anchor()

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

Definition at line 579 of file tree.hpp.

579 { _RYML_CB_ASSERT(m_callbacks, ! is_key_ref(node)); _p(node)->m_key.anchor = anchor.triml('&'); _add_flags(node, KEYANCH); }
@ KEYANCH
the key has an &anchor
Definition: node_type.hpp:41

References c4::yml::KEYANCH.

◆ set_val_anchor()

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

Definition at line 580 of file tree.hpp.

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

References c4::yml::VALANCH.

◆ set_key_ref()

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

Definition at line 581 of file tree.hpp.

581 { _RYML_CB_ASSERT(m_callbacks, ! has_key_anchor(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:39
bool has_key() const RYML_NOEXCEPT
Forward to Tree::has_key().
Definition: node.hpp:242

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

582 { _RYML_CB_ASSERT(m_callbacks, ! has_val_anchor(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:40
bool has_val() const RYML_NOEXCEPT
Forward to Tree::has_val().
Definition: node.hpp:241

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

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

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

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

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

588 { _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 531 of file tree.cpp.

532 {
533  id_type r = root_id();
534  _do_reorder(&r, 0);
535 }

References root_id().

◆ resolve() [1/2]

void c4::yml::Tree::resolve ( ReferenceResolver rr)

Resolve references (aliases <- anchors) in the tree.

Dereferencing is opt-in; after parsing, Tree::resolve() has to be called explicitly for obtaining resolved references in the tree. This method will ReferenceResolver::resolve() to resolve all references and substitute the anchored values in place of the reference.

This method first does a full traversal of the tree to gather all anchors and references in a separate collection, then it goes through that collection to locate the names, which it does by obeying the YAML standard diktat that "an alias node refers to the most recent node in the serialization having the specified anchor"

So, depending on the number of anchor/alias nodes, this is a potentially expensive operation, with a best-case linear complexity (from the initial traversal). This potential cost is the reason for requiring an explicit call.

See also
ReferenceResolver::resolve()

Definition at line 1111 of file tree.cpp.

1112 {
1113  if(m_size == 0)
1114  return;
1115  rr->resolve(this);
1116 }

References m_size.

Referenced by sample::sample_anchors_and_aliases().

◆ resolve() [2/2]

void c4::yml::Tree::resolve ( )

Resolve references using a throw-away resolver.

Definition at line 1103 of file tree.cpp.

1104 {
1105  if(m_size == 0)
1106  return;
1107  ReferenceResolver rr;
1108  resolve(&rr);
1109 }
void resolve()
Resolve references using a throw-away resolver.
Definition: tree.cpp:1103

References m_size.

◆ resolve_tags()

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

Definition at line 1429 of file tree.cpp.

1430 {
1431  if(empty())
1432  return;
1433  size_t needed_size = _count_resolved_tags_size(this, root_id());
1434  if(needed_size)
1435  reserve_arena(arena_size() + needed_size);
1436  _resolve_tags(this, root_id());
1437 }
bool empty() const
Definition: tree.hpp:276
size_t arena_size() const
get the current size of the tree's internal arena
Definition: tree.hpp:825

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

Referenced by sample::sample_tag_directives().

◆ normalize_tags()

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

Definition at line 1439 of file tree.cpp.

1440 {
1441  if(empty())
1442  return;
1443  _normalize_tags(this, root_id());
1444 }

References empty(), and root_id().

Referenced by sample::sample_tags().

◆ normalize_tags_long()

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

Definition at line 1446 of file tree.cpp.

1447 {
1448  if(empty())
1449  return;
1450  _normalize_tags_long(this, root_id());
1451 }

References empty(), and root_id().

Referenced by sample::sample_tags().

◆ num_tag_directives()

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

Definition at line 1302 of file tree.cpp.

1303 {
1304  // this assumes we have a very small number of tag directives
1305  for(id_type i = 0; i < RYML_MAX_TAG_DIRECTIVES; ++i)
1306  if(m_tag_directives[i].handle.empty())
1307  return i;
1308  return RYML_MAX_TAG_DIRECTIVES;
1309 }

References m_tag_directives, and RYML_MAX_TAG_DIRECTIVES.

Referenced by add_tag_directive().

◆ add_tag_directive() [1/2]

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

Definition at line 1331 of file tree.cpp.

1332 {
1333  TagDirective td;
1334  if(td.create_from_str(directive_, this))
1335  {
1336  add_tag_directive(td);
1337  return true;
1338  }
1339  return false;
1340 }
bool add_tag_directive(csubstr directive)
Definition: tree.cpp:1331

References c4::yml::TagDirective::create_from_str().

◆ add_tag_directive() [2/2]

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

Definition at line 1317 of file tree.cpp.

1318 {
1319  _RYML_CB_CHECK(m_callbacks, !td.handle.empty());
1320  _RYML_CB_CHECK(m_callbacks, !td.prefix.empty());
1321  _RYML_CB_CHECK(m_callbacks, td.handle.begins_with('!'));
1322  _RYML_CB_CHECK(m_callbacks, td.handle.ends_with('!'));
1323  // https://yaml.org/spec/1.2.2/#rule-ns-word-char
1324  _RYML_CB_CHECK(m_callbacks, td.handle == '!' || td.handle == "!!" || td.handle.trim('!').first_not_of("01234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-") == npos);
1325  id_type pos = num_tag_directives();
1326  _RYML_CB_CHECK(m_callbacks, pos < RYML_MAX_TAG_DIRECTIVES);
1327  m_tag_directives[pos] = td;
1328  return pos;
1329 }
id_type num_tag_directives() const
Definition: tree.cpp:1302
@ npos
a null string position
Definition: common.hpp:266

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

1312 {
1313  for(TagDirective &td : m_tag_directives)
1314  td = {};
1315 }

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

1343 {
1344  // lookup from the end. We want to find the first directive that
1345  // matches the tag and has a target node id leq than the given
1346  // node_id.
1347  for(id_type i = RYML_MAX_TAG_DIRECTIVES-1; i != (id_type)-1; --i)
1348  {
1349  auto const& td = m_tag_directives[i];
1350  if(td.handle.empty())
1351  continue;
1352  if(tag.begins_with(td.handle) && td.next_node_id <= node_id)
1353  return td.transform(tag, output, m_callbacks);
1354  }
1355  if(tag.begins_with('!'))
1356  {
1357  if(is_custom_tag(tag))
1358  {
1359  _RYML_CB_ERR(m_callbacks, "tag directive not found");
1360  }
1361  }
1362  return 0; // return 0 to signal that the tag is local and cannot be resolved
1363 }
bool is_custom_tag(csubstr tag)
Definition: tag.cpp:9
size_t transform(csubstr tag, substr output, Callbacks const &callbacks) const
Definition: tag.cpp:243

References c4::yml::is_custom_tag(), m_callbacks, m_tag_directives, 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 648 of file tree.hpp.

649  {
650  size_t needed = resolve_tag(output, tag, node_id);
651  return needed <= output.len ? output.first(needed) : output;
652  }
size_t resolve_tag(substr output, csubstr tag, id_type node_id) const
resolve the given tag, appearing at node_id.
Definition: tree.cpp:1342

◆ begin_tag_directives()

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

Definition at line 654 of file tree.hpp.

654 { return m_tag_directives; }

◆ end_tag_directives()

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

Definition at line 655 of file tree.hpp.

655 { return m_tag_directives + num_tag_directives(); }

◆ tag_directives()

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

Definition at line 656 of file tree.hpp.

TagDirective const * end_tag_directives() const
Definition: tree.hpp:655
TagDirective const * begin_tag_directives() const
Definition: tree.hpp:654

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

672  {
673  _RYML_CB_ASSERT(m_callbacks, parent != NONE);
674  _RYML_CB_ASSERT(m_callbacks, is_container(parent) || is_root(parent));
675  _RYML_CB_ASSERT(m_callbacks, after == NONE || (_p(after)->m_parent == parent));
676  id_type child = _claim();
677  _set_hierarchy(child, parent, after);
678  return child;
679  }
id_type _claim()
Definition: tree.cpp:371

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

681 { 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:671

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

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

Referenced by merge_with(), and set_root_as_stream().

◆ _append_child__unprotected()

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

Definition at line 684 of file tree.hpp.

685  {
686  id_type child = _claim();
687  _set_hierarchy(child, parent, _p(parent)->m_last_child);
688  return child;
689  }

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

705  {
706  return insert_child(_p(node)->m_parent, after);
707  }

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

709 { 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:681

◆ append_sibling()

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

Definition at line 710 of file tree.hpp.

710 { 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:683

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

716  {
717  remove_children(node);
718  _release(node);
719  }
void remove_children(id_type node)
remove all the node's children, but keep the node itself
Definition: tree.cpp:847

Referenced by duplicate_children_no_rep(), and move().

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

848 {
849  _RYML_CB_ASSERT(m_callbacks, get(node) != nullptr);
850  id_type ich = get(node)->m_first_child;
851  while(ich != NONE)
852  {
853  remove_children(ich);
854  _RYML_CB_ASSERT(m_callbacks, get(ich) != nullptr);
855  id_type next = get(ich)->m_next_sibling;
856  _release(ich);
857  if(ich == get(node)->m_last_child)
858  break;
859  ich = next;
860  }
861 }

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

Referenced by change_type(), and merge_with().

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

864 {
865  _RYML_CB_ASSERT(m_callbacks, type.is_val() || type.is_map() || type.is_seq());
866  _RYML_CB_ASSERT(m_callbacks, type.is_val() + type.is_map() + type.is_seq() == 1);
867  _RYML_CB_ASSERT(m_callbacks, type.has_key() == has_key(node) || (has_key(node) && !type.has_key()));
868  NodeData *d = _p(node);
869  if(type.is_map() && is_map(node))
870  return false;
871  else if(type.is_seq() && is_seq(node))
872  return false;
873  else if(type.is_val() && is_val(node))
874  return false;
875  d->m_type = (d->m_type & (~(MAP|SEQ|VAL))) | type;
876  remove_children(node);
877  return true;
878 }
NodeType type(id_type node) const
Definition: tree.hpp:378
bool is_val(id_type node) const
Definition: tree.hpp:411

References _p(), 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(), m_callbacks, c4::yml::NodeData::m_type, c4::yml::MAP, remove_children(), c4::yml::SEQ, type(), and c4::yml::VAL.

◆ change_type() [2/2]

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

Definition at line 735 of file tree.hpp.

736  {
737  return change_type(node, (NodeType)type);
738  }
bool change_type(id_type node, NodeType type)
change the type of the node to one of MAP, SEQ or VAL.
Definition: tree.cpp:863

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

773 {
774  _RYML_CB_ASSERT(m_callbacks, node != NONE);
775  _RYML_CB_ASSERT(m_callbacks, node != after);
776  _RYML_CB_ASSERT(m_callbacks, ! is_root(node));
777  _RYML_CB_ASSERT(m_callbacks, (after == NONE) || (has_sibling(node, after) && has_sibling(after, node)));
778 
779  _rem_hierarchy(node);
780  _set_hierarchy(node, parent(node), after);
781 }
bool has_sibling(id_type node, id_type sib) const
true if node has a sibling with id sib
Definition: tree.hpp:471

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

Referenced by duplicate_children_no_rep(), c4::yml::NodeRef::move(), and set_root_as_stream().

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

786 {
787  _RYML_CB_ASSERT(m_callbacks, node != NONE);
788  _RYML_CB_ASSERT(m_callbacks, node != after);
789  _RYML_CB_ASSERT(m_callbacks, new_parent != NONE);
790  _RYML_CB_ASSERT(m_callbacks, new_parent != node);
791  _RYML_CB_ASSERT(m_callbacks, new_parent != after);
792  _RYML_CB_ASSERT(m_callbacks, ! is_root(node));
793 
794  _rem_hierarchy(node);
795  _set_hierarchy(node, new_parent, after);
796 }

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

799 {
800  _RYML_CB_ASSERT(m_callbacks, src != nullptr);
801  _RYML_CB_ASSERT(m_callbacks, node != NONE);
802  _RYML_CB_ASSERT(m_callbacks, new_parent != NONE);
803  _RYML_CB_ASSERT(m_callbacks, new_parent != after);
804 
805  id_type dup = duplicate(src, node, new_parent, after);
806  src->remove(node);
807  return dup;
808 }
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:882

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

811 {
812  id_type root = root_id();
813  if(is_stream(root))
814  return;
815  // don't use _add_flags() because it's checked and will fail
816  if(!has_children(root))
817  {
818  if(is_val(root))
819  {
820  _p(root)->m_type.add(SEQ);
821  id_type next_doc = append_child(root);
822  _copy_props_wo_key(next_doc, root);
823  _p(next_doc)->m_type.add(DOC);
824  _p(next_doc)->m_type.rem(SEQ);
825  }
826  _p(root)->m_type = STREAM;
827  return;
828  }
829  _RYML_CB_ASSERT(m_callbacks, !has_key(root));
830  id_type next_doc = append_child(root);
831  _copy_props_wo_key(next_doc, root);
832  _add_flags(next_doc, DOC);
833  for(id_type prev = NONE, ch = first_child(root), next = next_sibling(ch); ch != NONE; )
834  {
835  if(ch == next_doc)
836  break;
837  move(ch, next_doc, prev);
838  prev = ch;
839  ch = next;
840  next = next_sibling(next);
841  }
842  _p(root)->m_type = STREAM;
843 }
void move(id_type node, id_type after)
change the node's position in the parent
Definition: tree.cpp:772
bool is_stream(id_type node) const
Definition: tree.hpp:404
void rem(NodeType_e t) noexcept
Definition: node_type.hpp:132
void add(NodeType_e t) noexcept
Definition: node_type.hpp:131

References _p(), c4::yml::NodeType::add(), append_child(), c4::yml::DOC, first_child(), has_children(), has_key(), is_stream(), is_val(), 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 882 of file tree.cpp.

883 {
884  return duplicate(this, node, parent, after);
885 }

References parent().

Referenced by c4::yml::NodeRef::duplicate(), duplicate_children(), duplicate_children_no_rep(), and move().

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

888 {
889  _RYML_CB_ASSERT(m_callbacks, src != nullptr);
890  _RYML_CB_ASSERT(m_callbacks, node != NONE);
891  _RYML_CB_ASSERT(m_callbacks, parent != NONE);
892  _RYML_CB_ASSERT(m_callbacks, ! src->is_root(node));
893 
894  id_type copy = _claim();
895 
896  _copy_props(copy, src, node);
897  _set_hierarchy(copy, parent, after);
898  duplicate_children(src, node, copy, NONE);
899 
900  return copy;
901 }
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:904

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

905 {
906  return duplicate_children(this, node, parent, after);
907 }

References parent().

Referenced by duplicate(), c4::yml::NodeRef::duplicate_children(), and duplicate_contents().

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

910 {
911  _RYML_CB_ASSERT(m_callbacks, src != nullptr);
912  _RYML_CB_ASSERT(m_callbacks, node != NONE);
913  _RYML_CB_ASSERT(m_callbacks, parent != NONE);
914  _RYML_CB_ASSERT(m_callbacks, after == NONE || has_child(parent, after));
915 
916  id_type prev = after;
917  for(id_type i = src->first_child(node); i != NONE; i = src->next_sibling(i))
918  {
919  prev = duplicate(src, i, parent, prev);
920  }
921 
922  return prev;
923 }
bool has_child(id_type node, id_type ch) const
true if node has a child with id ch
Definition: tree.hpp:464

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

◆ duplicate_contents() [1/2]

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

Definition at line 926 of file tree.cpp.

927 {
928  duplicate_contents(this, node, where);
929 }
void duplicate_contents(id_type node, id_type where)
Definition: tree.cpp:926

◆ duplicate_contents() [2/2]

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

Definition at line 931 of file tree.cpp.

932 {
933  _RYML_CB_ASSERT(m_callbacks, src != nullptr);
934  _RYML_CB_ASSERT(m_callbacks, node != NONE);
935  _RYML_CB_ASSERT(m_callbacks, where != NONE);
936  _copy_props_wo_key(where, src, node);
937  duplicate_children(src, node, where, last_child(where));
938 }
id_type last_child(id_type node) const
Definition: tree.hpp:504

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

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

942 {
943  return duplicate_children_no_rep(this, node, parent, after);
944 }
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:941

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

947 {
948  _RYML_CB_ASSERT(m_callbacks, node != NONE);
949  _RYML_CB_ASSERT(m_callbacks, parent != NONE);
950  _RYML_CB_ASSERT(m_callbacks, after == NONE || has_child(parent, after));
951 
952  // don't loop using pointers as there may be a relocation
953 
954  // find the position where "after" is
955  id_type after_pos = NONE;
956  if(after != NONE)
957  {
958  for(id_type i = first_child(parent), icount = 0; i != NONE; ++icount, i = next_sibling(i))
959  {
960  if(i == after)
961  {
962  after_pos = icount;
963  break;
964  }
965  }
966  _RYML_CB_ASSERT(m_callbacks, after_pos != NONE);
967  }
968 
969  // for each child to be duplicated...
970  id_type prev = after;
971  for(id_type i = src->first_child(node); i != NONE; i = src->next_sibling(i))
972  {
973  if(is_seq(parent))
974  {
975  prev = duplicate(i, parent, prev);
976  }
977  else
978  {
979  _RYML_CB_ASSERT(m_callbacks, is_map(parent));
980  // does the parent already have a node with key equal to that of the current duplicate?
981  id_type rep = NONE, rep_pos = NONE;
982  for(id_type j = first_child(parent), jcount = 0; j != NONE; ++jcount, j = next_sibling(j))
983  {
984  if(key(j) == key(i))
985  {
986  rep = j;
987  rep_pos = jcount;
988  break;
989  }
990  }
991  if(rep == NONE) // there is no repetition; just duplicate
992  {
993  prev = duplicate(src, i, parent, prev);
994  }
995  else // yes, there is a repetition
996  {
997  if(after_pos != NONE && rep_pos < after_pos)
998  {
999  // rep is located before the node which will be inserted,
1000  // and will be overridden by the duplicate. So replace it.
1001  remove(rep);
1002  prev = duplicate(src, i, parent, prev);
1003  }
1004  else if(prev == NONE)
1005  {
1006  // first iteration with prev = after = NONE and repetition
1007  prev = rep;
1008  }
1009  else if(rep != prev)
1010  {
1011  // rep is located after the node which will be inserted
1012  // and overrides it. So move the rep into this node's place.
1013  move(rep, prev);
1014  prev = rep;
1015  }
1016  } // there's a repetition
1017  }
1018  }
1019 
1020  return prev;
1021 }
void remove(id_type node)
remove an entire branch at once: ie remove the children and the node itself
Definition: tree.hpp:715

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

◆ merge_with()

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

Definition at line 1026 of file tree.cpp.

1027 {
1028  _RYML_CB_ASSERT(m_callbacks, src != nullptr);
1029  if(src_node == NONE)
1030  src_node = src->root_id();
1031  if(dst_node == NONE)
1032  dst_node = root_id();
1033  _RYML_CB_ASSERT(m_callbacks, src->has_val(src_node) || src->is_seq(src_node) || src->is_map(src_node));
1034  if(src->has_val(src_node))
1035  {
1036  type_bits mask_src = ~STYLE; // keep the existing style if it is already a val
1037  if( ! has_val(dst_node))
1038  {
1039  if(has_children(dst_node))
1040  remove_children(dst_node);
1041  mask_src |= VAL_STYLE; // copy the src style
1042  }
1043  if(src->is_keyval(src_node))
1044  {
1045  _copy_props(dst_node, src, src_node, mask_src);
1046  }
1047  else
1048  {
1049  _RYML_CB_ASSERT(m_callbacks, src->is_val(src_node));
1050  _copy_props_wo_key(dst_node, src, src_node, mask_src);
1051  }
1052  }
1053  else if(src->is_seq(src_node))
1054  {
1055  if( ! is_seq(dst_node))
1056  {
1057  if(has_children(dst_node))
1058  remove_children(dst_node);
1059  _clear_type(dst_node);
1060  if(src->has_key(src_node))
1061  to_seq(dst_node, src->key(src_node));
1062  else
1063  to_seq(dst_node);
1064  _p(dst_node)->m_type = src->_p(src_node)->m_type;
1065  }
1066  for(id_type sch = src->first_child(src_node); sch != NONE; sch = src->next_sibling(sch))
1067  {
1068  id_type dch = append_child(dst_node);
1069  _copy_props_wo_key(dch, src, sch);
1070  merge_with(src, sch, dch);
1071  }
1072  }
1073  else
1074  {
1075  _RYML_CB_ASSERT(m_callbacks, src->is_map(src_node));
1076  if( ! is_map(dst_node))
1077  {
1078  if(has_children(dst_node))
1079  remove_children(dst_node);
1080  _clear_type(dst_node);
1081  if(src->has_key(src_node))
1082  to_map(dst_node, src->key(src_node));
1083  else
1084  to_map(dst_node);
1085  _p(dst_node)->m_type = src->_p(src_node)->m_type;
1086  }
1087  for(id_type sch = src->first_child(src_node); sch != NONE; sch = src->next_sibling(sch))
1088  {
1089  id_type dch = find_child(dst_node, src->key(sch));
1090  if(dch == NONE)
1091  {
1092  dch = append_child(dst_node);
1093  _copy_props(dch, src, sch);
1094  }
1095  merge_with(src, sch, dch);
1096  }
1097  }
1098 }
void to_seq(id_type node, csubstr key, type_bits more_flags=0)
Definition: tree.cpp:1275
void to_map(id_type node, csubstr key, type_bits more_flags=0)
Definition: tree.cpp:1257
void merge_with(Tree const *src, id_type src_node=NONE, id_type dst_root=NONE)
Definition: tree.cpp:1026
uint32_t type_bits
the integral type necessary to cover all the bits for NodeType_e
Definition: node_type.hpp:26
@ VAL_STYLE
mask of all the scalar styles for val (not container styles!)
Definition: node_type.hpp:87

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.

Referenced by lookup_path_or_modify().

◆ arena_pos()

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

get the current size of the tree's internal arena

Definition at line 823 of file tree.hpp.

823 { return m_arena_pos; }

◆ arena_size()

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

get the current size of the tree's internal arena

Definition at line 825 of file tree.hpp.

825 { return m_arena_pos; }

Referenced by resolve_tags().

◆ arena_capacity()

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

get the current capacity of the tree's internal arena

Definition at line 827 of file tree.hpp.

827 { return m_arena.len; }

Referenced by Tree(), and sample::sample_tree_arena().

◆ arena_slack()

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

get the current slack of the tree's internal arena

Definition at line 829 of file tree.hpp.

829 { _RYML_CB_ASSERT(m_callbacks, m_arena.len >= m_arena_pos); return m_arena.len - m_arena_pos; }

◆ arena() [1/2]

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

get the current arena

Definition at line 832 of file tree.hpp.

832 { return m_arena.first(m_arena_pos); }

Referenced by sample::sample_empty_null_values(), sample::sample_fundamental_types(), sample::sample_quick_overview(), and sample::sample_tree_arena().

◆ arena() [2/2]

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

get the current arena

Definition at line 834 of file tree.hpp.

834 { return m_arena.first(m_arena_pos); }

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

838  {
839  return m_arena.is_super(s);
840  }

Referenced by sample::sample_quick_overview().

◆ to_arena() [1/5]

template<class T >
std::enable_if<std::is_floating_point<T>::value, csubstr>::type c4::yml::Tree::to_arena ( T const &  a)
inline

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

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
alloc_arena()

Definition at line 854 of file tree.hpp.

855  {
856  substr rem(m_arena.sub(m_arena_pos));
857  size_t num = to_chars_float(rem, a);
858  if(num > rem.len)
859  {
860  rem = _grow_arena(num);
861  num = to_chars_float(rem, a);
862  _RYML_CB_ASSERT(m_callbacks, num <= rem.len);
863  }
864  rem = _request_span(num);
865  return rem;
866  }
size_t to_chars_float(substr buf, T val)
encode a floating point value to a string.
Definition: tree.hpp:42

References c4::yml::to_chars_float().

Referenced by sample::sample_fundamental_types(), and sample::sample_tree_arena().

◆ to_arena() [2/5]

template<class T >
std::enable_if<!std::is_floating_point<T>::value, csubstr>::type c4::yml::Tree::to_arena ( T const &  a)
inline

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

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
alloc_arena()

Definition at line 880 of file tree.hpp.

881  {
882  substr rem(m_arena.sub(m_arena_pos));
883  size_t num = to_chars(rem, a);
884  if(num > rem.len)
885  {
886  rem = _grow_arena(num);
887  num = to_chars(rem, a);
888  _RYML_CB_ASSERT(m_callbacks, num <= rem.len);
889  }
890  rem = _request_span(num);
891  return rem;
892  }
size_t to_chars(substr buf, uint8_t v) noexcept
Definition: charconv.hpp:2328

References sample::to_chars().

◆ to_arena() [3/5]

csubstr c4::yml::Tree::to_arena ( csubstr  a)
inline

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

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
alloc_arena()

Definition at line 904 of file tree.hpp.

905  {
906  if(a.len > 0)
907  {
908  substr rem(m_arena.sub(m_arena_pos));
909  size_t num = to_chars(rem, a);
910  if(num > rem.len)
911  {
912  rem = _grow_arena(num);
913  num = to_chars(rem, a);
914  _RYML_CB_ASSERT(m_callbacks, num <= rem.len);
915  }
916  return _request_span(num);
917  }
918  else
919  {
920  if(a.str == nullptr)
921  {
922  return csubstr{};
923  }
924  else if(m_arena.str == nullptr)
925  {
926  // Arena is empty and we want to store a non-null
927  // zero-length string.
928  // Even though the string has zero length, we need
929  // some "memory" to store a non-nullptr string
930  _grow_arena(1);
931  }
932  return _request_span(0);
933  }
934  }

References sample::to_chars().

◆ to_arena() [4/5]

csubstr c4::yml::Tree::to_arena ( const char *  s)
inline

Definition at line 935 of file tree.hpp.

936  {
937  return to_arena(to_csubstr(s));
938  }
std::enable_if< std::is_floating_point< T >::value, csubstr >::type to_arena(T const &a)
serialize the given floating-point variable to the tree's arena, growing it as needed to accomodate t...
Definition: tree.hpp:854
csubstr to_csubstr(substr s) noexcept
neutral version for use in generic code
Definition: substr.hpp:2189

References c4::to_csubstr().

◆ to_arena() [5/5]

csubstr c4::yml::Tree::to_arena ( std::nullptr_t  )
inline

Definition at line 939 of file tree.hpp.

940  {
941  return csubstr{};
942  }

◆ copy_to_arena()

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

copy the given substr to the tree's arena, growing it by the required size

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
alloc_arena()

Definition at line 954 of file tree.hpp.

955  {
956  substr cp = alloc_arena(s.len);
957  _RYML_CB_ASSERT(m_callbacks, cp.len == s.len);
958  _RYML_CB_ASSERT(m_callbacks, !s.overlaps(cp));
959  #if (!defined(__clang__)) && (defined(__GNUC__) && __GNUC__ >= 10)
960  C4_SUPPRESS_WARNING_GCC_PUSH
961  C4_SUPPRESS_WARNING_GCC("-Wstringop-overflow=") // no need for terminating \0
962  C4_SUPPRESS_WARNING_GCC( "-Wrestrict") // there's an assert to ensure no violation of restrict behavior
963  #endif
964  if(s.len)
965  memcpy(cp.str, s.str, s.len);
966  #if (!defined(__clang__)) && (defined(__GNUC__) && __GNUC__ >= 10)
967  C4_SUPPRESS_WARNING_GCC_POP
968  #endif
969  return cp;
970  }
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:982

Referenced by c4::yml::parse_in_arena(), c4::yml::parse_json_in_arena(), and sample::sample_tree_arena().

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

983  {
984  if(sz > arena_slack())
985  _grow_arena(sz - arena_slack());
986  substr s = _request_span(sz);
987  return s;
988  }
size_t arena_slack() const
get the current slack of the tree's internal arena
Definition: tree.hpp:829

Referenced by sample::sample_tree_arena().

◆ reserve_arena()

void c4::yml::Tree::reserve_arena ( size_t  arena_cap)
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 994 of file tree.hpp.

995  {
996  if(arena_cap > m_arena.len)
997  {
998  substr buf;
999  buf.str = (char*) m_callbacks.m_allocate(arena_cap, m_arena.str, m_callbacks.m_user_data);
1000  buf.len = arena_cap;
1001  if(m_arena.str)
1002  {
1003  _RYML_CB_ASSERT(m_callbacks, m_arena.len >= 0);
1004  _relocate(buf); // does a memcpy and changes nodes using the arena
1006  }
1007  m_arena = buf;
1008  }
1009  }
void * m_user_data
Definition: common.hpp:376
pfn_allocate m_allocate
Definition: common.hpp:377
pfn_free m_free
Definition: common.hpp:378

Referenced by Tree(), resolve_tags(), sample::sample_global_allocator(), sample::sample_parse_reuse_tree(), and sample::sample_tree_arena().

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

1477 {
1478  if(start == NONE)
1479  start = root_id();
1480  lookup_result r(path, start);
1481  if(path.empty())
1482  return r;
1483  _lookup_path(&r);
1484  if(r.target == NONE && r.closest == start)
1485  r.closest = NONE;
1486  return r;
1487 }

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

1490 {
1491  id_type target = _lookup_path_or_create(path, start);
1492  if(parent_is_map(target))
1493  to_keyval(target, key(target), default_value);
1494  else
1495  to_val(target, default_value);
1496  return target;
1497 }
void to_keyval(id_type node, csubstr key, csubstr val, type_bits more_flags=0)
Definition: tree.cpp:1239
void to_val(id_type node, csubstr val, type_bits more_flags=0)
Definition: tree.cpp:1230

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

1500 {
1501  id_type target = _lookup_path_or_create(path, start);
1502  merge_with(src, src_node, target);
1503  return target;
1504 }

References merge_with().

◆ _claim()

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

Definition at line 371 of file tree.cpp.

372 {
373  if(m_free_head == NONE || m_buf == nullptr)
374  {
375  id_type sz = 2 * m_cap;
376  sz = sz ? sz : 16;
377  reserve(sz);
378  _RYML_CB_ASSERT(m_callbacks, m_free_head != NONE);
379  }
380 
381  _RYML_CB_ASSERT(m_callbacks, m_size < m_cap);
382  _RYML_CB_ASSERT(m_callbacks, m_free_head >= 0 && m_free_head < m_cap);
383 
384  id_type ichild = m_free_head;
385  NodeData *child = m_buf + ichild;
386 
387  ++m_size;
388  m_free_head = child->m_next_sibling;
389  if(m_free_head == NONE)
390  {
391  m_free_tail = NONE;
392  _RYML_CB_ASSERT(m_callbacks, m_size == m_cap);
393  }
394 
395  _clear(ichild);
396 
397  return ichild;
398 }

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

Referenced by duplicate().

Member Data Documentation

◆ m_buf

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

Definition at line 1348 of file tree.hpp.

Referenced by _claim(), clear(), and reserve().

◆ m_cap

id_type c4::yml::Tree::m_cap

Definition at line 1349 of file tree.hpp.

Referenced by _claim(), clear(), and reserve().

◆ m_size

id_type c4::yml::Tree::m_size

Definition at line 1351 of file tree.hpp.

Referenced by _claim(), clear(), reserve(), and resolve().

◆ m_free_head

id_type c4::yml::Tree::m_free_head

Definition at line 1353 of file tree.hpp.

Referenced by _claim(), clear(), and reserve().

◆ m_free_tail

id_type c4::yml::Tree::m_free_tail

Definition at line 1354 of file tree.hpp.

Referenced by _claim(), clear(), and reserve().

◆ m_arena

substr c4::yml::Tree::m_arena

Definition at line 1356 of file tree.hpp.

◆ m_arena_pos

size_t c4::yml::Tree::m_arena_pos

Definition at line 1357 of file tree.hpp.

◆ m_callbacks

◆ m_tag_directives

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

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