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

#include <tree.hpp>

Classes

struct  lookup_result

Public Member Functions

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

Public Attributes

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

deserialization - checked

These methods raise an error if the deserialization failed or optionally if the node is not readable.

template<class T>
void load (id_type node, T *v, bool check_readable=true) const
 (1) deserialize the node's contents (val or container) to the given variable, forwarding to the user-overrideable read() function (see Read from Tree).
template<class Wrapper>
void load (id_type node, Wrapper const &w, bool check_readable=true) const
 (2) like (1), but for wrapper tag types such as c4::fmt::base64()
template<class T>
void load_key (id_type node, T *k, bool check_readable=true) const
 (1) deserialize the node's key (necessarily a scalar) to the given variable, forwarding to the user-overrideable read_key() function (see Read from ConstNodeRef).
template<class Wrapper>
void load_key (id_type node, Wrapper const &w, bool check_readable=true) const
 (2) like (1), but for wrapper tag types such as c4::fmt::base64()
static ReadResult to_result_ (bool, id_type node) noexcept
static ReadResult to_result_ (ReadResult notlegacy, id_type) noexcept

locations

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

Detailed Description

Definition at line 307 of file tree.hpp.

Constructor & Destructor Documentation

◆ Tree() [1/6]

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

Definition at line 314 of file tree.hpp.

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

Referenced by Tree(), Tree(), Tree(), Tree(), Tree(), duplicate(), duplicate_children(), duplicate_children_no_rep(), duplicate_contents(), lookup_path_or_modify(), merge_with(), move(), operator=(), and operator=().

◆ Tree() [2/6]

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

Definition at line 119 of file tree.cpp.

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

◆ Tree() [3/6]

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

Definition at line 316 of file tree.hpp.

316: 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:1311

◆ Tree() [4/6]

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

Definition at line 124 of file tree.cpp.

125 : m_buf(nullptr)
126 , m_cap(0)
127 , m_size(0)
130 , m_arena()
131 , m_arena_pos(0)
132 , m_callbacks(cb)
134{
135 if(node_capacity)
136 reserve(node_capacity);
139}
NodeData * m_buf
Definition tree.hpp:1676
id_type m_free_head
Definition tree.hpp:1680
void reserve_arena(size_t arena_cap=RYML_DEFAULT_TREE_ARENA_CAPACITY)
ensure the tree's internal string arena is at least the given capacity
Definition tree.hpp:1409
size_t m_arena_pos
Definition tree.hpp:1684
void reserve(id_type node_capacity=RYML_DEFAULT_TREE_CAPACITY)
Definition tree.cpp:292
TagDirectives m_tag_directives
Definition tree.hpp:1688
id_type m_size
Definition tree.hpp:1678
id_type m_cap
Definition tree.hpp:1677
substr m_arena
Definition tree.hpp:1683
id_type m_free_tail
Definition tree.hpp:1681
Callbacks m_callbacks
Definition tree.hpp:1686
@ NONE
an index to none
Definition common.hpp:131

◆ ~Tree()

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

Definition at line 141 of file tree.cpp.

142{
143 _free();
144}

◆ Tree() [5/6]

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

Definition at line 147 of file tree.cpp.

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

◆ Tree() [6/6]

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

Definition at line 153 of file tree.cpp.

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

Member Function Documentation

◆ operator=() [1/2]

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

Definition at line 159 of file tree.cpp.

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

◆ operator=() [2/2]

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

Definition at line 170 of file tree.cpp.

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

◆ reserve()

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

Definition at line 292 of file tree.cpp.

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

Referenced by Tree(), sample_global_allocator(), sample_parse_reuse_tree(), and 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 330 of file tree.cpp.

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

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

◆ clear_arena()

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

Definition at line 340 of file tree.hpp.

340{ m_arena_pos = 0; }

Referenced by clear_arena(), sample_empty_null_values(), and sample_parse_reuse_tree().

◆ empty() [1/2]

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

Query for zero size.

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

Definition at line 343 of file tree.hpp.

343{ return m_size == 0; }

Referenced by c4::yml::Emitter< Writer >::emit_as(), normalize_tags(), normalize_tags_long(), c4::yml::operator<<(), c4::yml::operator<<(), and resolve_tags().

◆ size()

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

Definition at line 345 of file tree.hpp.

345{ return m_size; }

Referenced by sample_quick_overview().

◆ capacity()

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

Definition at line 346 of file tree.hpp.

346{ return m_cap; }

Referenced by c4::yml::EventHandlerTree::reset().

◆ slack()

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

Definition at line 347 of file tree.hpp.

347{ RYML_ASSERT_BASIC_(m_cap >= m_size); return m_cap - m_size; }

◆ callbacks() [1/2]

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

◆ callbacks() [2/2]

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

Definition at line 350 of file tree.hpp.

350{ m_callbacks = cb; }

◆ get() [1/2]

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

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

Definition at line 361 of file tree.hpp.

362 {
363 if(node == NONE)
364 return nullptr;
365 RYML_ASSERT_VISIT_CB_(m_callbacks, node >= 0 && node < m_cap, this, node);
366 return m_buf + node;
367 }

Referenced by remove_children().

◆ get() [2/2]

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

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

Definition at line 370 of file tree.hpp.

371 {
372 if(node == NONE)
373 return nullptr;
374 RYML_ASSERT_VISIT_CB_(m_callbacks, node >= 0 && node < m_cap, this, node);
375 return m_buf + node;
376 }

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

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

Referenced by _append_child__unprotected(), ancestor_doc(), append_child(), append_sibling(), change_type(), clear_style(), deserialize(), deserialize(), empty(), find_child(), find_sibling(), find_sibling_r(), first_child(), first_sibling(), has_anchor(), has_anchor(), has_child(), has_children(), has_flow_space(), has_key(), has_key_anchor(), has_key_tag(), has_other_siblings(), has_parent(), has_sibling(), has_val(), has_val_anchor(), has_val_tag(), insert_child(), insert_sibling(), is_anchor(), is_anchor_or_ref(), is_block(), is_container(), is_container_styled(), is_doc(), is_flow(), is_flow_ml(), is_flow_ml1(), is_flow_mln(), is_flow_mlx(), is_flow_sl(), is_key_anchor(), is_key_dquo(), is_key_folded(), is_key_literal(), is_key_plain(), is_key_quoted(), is_key_ref(), is_key_squo(), is_key_styled(), is_key_unfiltered(), is_keyval(), is_map(), is_quoted(), is_ref(), is_root(), is_seq(), is_stream(), is_val(), is_val_anchor(), is_val_dquo(), is_val_folded(), is_val_literal(), is_val_plain(), is_val_quoted(), is_val_ref(), is_val_squo(), is_val_styled(), is_val_unfiltered(), key(), key_anchor(), key_is_null(), key_ref(), key_style(), key_tag(), keysc(), last_child(), last_sibling(), load(), load(), load_key(), load_key(), merge_with(), next_sibling(), num_siblings(), parent(), parent_is_map(), parent_is_seq(), prepend_sibling(), prev_sibling(), c4::yml::read(), c4::yml::read(), c4::yml::read_key(), c4::yml::read_key(), rem_anchor_ref(), rem_key_anchor(), rem_key_ref(), rem_val_anchor(), rem_val_ref(), save(), save_key(), set_container_style(), set_doc(), set_key(), set_key(), set_key_anchor(), set_key_ref(), set_key_serialized(), set_key_style(), set_key_tag(), set_map(), set_map(), set_root_as_stream(), set_seq(), set_seq(), set_serialized(), set_stream(), set_style_conditionally(), set_val(), set_val(), set_val_anchor(), set_val_ref(), set_val_style(), set_val_tag(), sibling(), sibling_pos(), sibling_r(), type(), type_has_all(), type_has_any(), type_has_none(), val(), val_anchor(), val_is_null(), val_ref(), val_style(), val_tag(), and valsc().

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

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

◆ root_id()

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

Get the id of the root node. The tree must not be empty. The tree can be empty only when constructed with explicitly zero-capacity.

Definition at line 386 of file tree.hpp.

386{ RYML_ASSERT_VISIT_CB_(m_callbacks, m_size > 0, this, id_type(0)); return 0; }

Referenced by crootref(), doc(), c4::yml::Emitter< Writer >::emit_as(), lookup_path(), merge_with(), normalize_tags(), normalize_tags_long(), c4::yml::operator<<(), c4::yml::operator<<(), c4::yml::parse_in_arena(), c4::yml::parse_in_arena(), c4::yml::parse_in_arena(), c4::yml::parse_in_arena(), c4::yml::parse_in_arena(), c4::yml::parse_in_arena(), c4::yml::parse_in_arena(), c4::yml::parse_in_arena(), c4::yml::parse_in_place(), c4::yml::parse_in_place(), c4::yml::parse_in_place(), c4::yml::parse_in_place(), c4::yml::parse_in_place(), c4::yml::parse_in_place(), c4::yml::parse_in_place(), c4::yml::parse_in_place(), c4::yml::parse_json_in_arena(), c4::yml::parse_json_in_arena(), c4::yml::parse_json_in_arena(), c4::yml::parse_json_in_arena(), c4::yml::parse_json_in_arena(), c4::yml::parse_json_in_arena(), c4::yml::parse_json_in_arena(), c4::yml::parse_json_in_arena(), c4::yml::parse_json_in_place(), c4::yml::parse_json_in_place(), c4::yml::parse_json_in_place(), c4::yml::parse_json_in_place(), c4::yml::parse_json_in_place(), c4::yml::parse_json_in_place(), c4::yml::parse_json_in_place(), c4::yml::parse_json_in_place(), reorder(), rootref(), rootref(), sample_docs(), sample_emit_to_container(), sample_emit_to_file(), sample_quick_overview(), sample_user_container_types(), set_root_as_stream(), and sibling_pos().

◆ root_id_maybe()

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

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

Definition at line 388 of file tree.hpp.

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

Referenced by c4::yml::emitrs_json(), c4::yml::emitrs_json(), c4::yml::emitrs_yaml(), and c4::yml::emitrs_yaml().

◆ id()

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

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

Definition at line 392 of file tree.hpp.

393 {
394 if( ! n)
395 return NONE;
396 RYML_ASSERT_VISIT_CB_(m_callbacks, n >= m_buf && n < m_buf + m_cap, this, NONE);
397 return static_cast<id_type>(n - m_buf);
398 }

Referenced by sample_deserialize_error(), sample_error_visit(), sample_error_visit_location(), sample_serialize_basic(), and set_root_as_stream().

◆ ref() [1/2]

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

Get a NodeRef of a node by id.

Definition at line 70 of file tree.cpp.

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

Referenced by docref(), ref(), ref(), set_key_ref(), and set_val_ref().

◆ ref() [2/2]

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

Get a NodeRef of a node by id.

Definition at line 75 of file tree.cpp.

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

◆ cref()

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

Get a NodeRef of a node by id.

Definition at line 80 of file tree.cpp.

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

Referenced by cref().

◆ rootref() [1/2]

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

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

Definition at line 56 of file tree.cpp.

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

Referenced by operator[](), operator[](), rootref(), rootref(), sample_anchors_and_aliases_create(), sample_base64(), sample_create_tree(), sample_docs(), sample_empty_null_values(), sample_float_precision(), sample_json(), sample_location_tracking(), sample_parse_reuse_tree(), sample_parse_style(), sample_quick_overview(), sample_std_types(), sample_style(), sample_style_flow_formatting(), sample_style_flow_ml_indent(), sample_tags(), sample_tree_arena(), and sample_user_scalar_types().

◆ rootref() [2/2]

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

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

Definition at line 60 of file tree.cpp.

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

◆ crootref()

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

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

Definition at line 65 of file tree.cpp.

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

Referenced by crootref(), operator[](), operator[](), sample_iterate_tree(), sample_parse_in_arena(), sample_parse_in_place(), and sample_parse_reuse_tree().

◆ docref() [1/2]

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

get the i-th document of the stream

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

Definition at line 104 of file tree.cpp.

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

Referenced by docref(), docref(), and 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 108 of file tree.cpp.

109{
110 return ConstNodeRef(this, doc(i));
111}

◆ cdocref()

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

get the i-th document of the stream

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

Definition at line 112 of file tree.cpp.

113{
114 return ConstNodeRef(this, doc(i));
115}

Referenced by cdocref().

◆ operator[]() [1/4]

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

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

Note
requires the root to be a map.

Definition at line 86 of file tree.cpp.

87{
88 return rootref()[key];
89}
csubstr const & key(id_type node) const
Definition tree.hpp:454
NodeRef rootref()
Get the root as a NodeRef . Note that a non-const Tree implicitly converts to NodeRef.
Definition tree.cpp:56

◆ operator[]() [2/4]

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

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

Note
requires the root to be a map.

Definition at line 90 of file tree.cpp.

91{
92 return crootref()[key];
93}
ConstNodeRef crootref() const
Get the root as a ConstNodeRef . Note that Tree implicitly converts to ConstNodeRef.
Definition tree.cpp:65

◆ operator[]() [3/4]

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

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

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

Definition at line 95 of file tree.cpp.

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

◆ operator[]() [4/4]

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

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

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

Definition at line 99 of file tree.cpp.

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

◆ type()

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

Definition at line 452 of file tree.hpp.

452{ 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:380
NodeType m_type
Definition tree.hpp:289

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

◆ key()

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

◆ key_tag()

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

Definition at line 455 of file tree.hpp.

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

◆ key_ref()

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

Definition at line 456 of file tree.hpp.

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

◆ key_anchor()

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

Definition at line 457 of file tree.hpp.

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

◆ keysc()

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

Definition at line 458 of file tree.hpp.

458{ RYML_ASSERT_VISIT_CB_(m_callbacks, has_key(node), this, node); return _p(node)->m_key; }

◆ val()

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

Definition at line 460 of file tree.hpp.

460{ RYML_ASSERT_VISIT_CB_(m_callbacks, has_val(node), this, node); return _p(node)->m_val.scalar; }
bool has_val(id_type node) const
Definition tree.hpp:483
NodeScalar m_val
Definition tree.hpp:292

Referenced by c4::yml::read(), sample_base64(), sample_deserialize_error(), sample_docs(), sample_tree_arena(), save(), save(), set_serialized(), set_serialized(), set_val(), and set_val().

◆ val_tag()

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

Definition at line 461 of file tree.hpp.

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

◆ val_ref()

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

Definition at line 462 of file tree.hpp.

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

◆ val_anchor()

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

Definition at line 463 of file tree.hpp.

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

◆ valsc()

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

Definition at line 464 of file tree.hpp.

464{ RYML_ASSERT_VISIT_CB_(m_callbacks, has_val(node), this, node); return _p(node)->m_val; }

◆ type_has_any()

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

Definition at line 473 of file tree.hpp.

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

◆ type_has_all()

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

Definition at line 474 of file tree.hpp.

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

◆ type_has_none()

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

Definition at line 475 of file tree.hpp.

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

◆ is_stream()

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

Definition at line 477 of file tree.hpp.

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

Referenced by doc(), sample_docs(), and set_doc().

◆ is_doc()

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

Definition at line 478 of file tree.hpp.

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

Referenced by sample_docs().

◆ is_container()

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

Definition at line 479 of file tree.hpp.

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

Referenced by deserialize_child(), deserialize_child(), deserialize_child(), insert_child(), set_container_style(), and set_val_tag().

◆ is_map()

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

Definition at line 480 of file tree.hpp.

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

Referenced by parent_is_map(), c4::yml::read(), read(), read(), c4::yml::EventHandlerTree::reset(), sample_docs(), and sample_quick_overview().

◆ is_seq()

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

Definition at line 481 of file tree.hpp.

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

Referenced by parent_is_seq(), c4::yml::read(), c4::yml::read(), read(), sample_docs(), and sample_quick_overview().

◆ has_key()

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

◆ has_val()

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

Definition at line 483 of file tree.hpp.

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

Referenced by set_val_style(), set_val_tag(), val(), val_is_null(), val_style(), and valsc().

◆ is_val()

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

Definition at line 484 of file tree.hpp.

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

◆ is_keyval()

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

Definition at line 485 of file tree.hpp.

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

◆ has_key_tag()

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

Definition at line 486 of file tree.hpp.

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

Referenced by key_tag().

◆ has_val_tag()

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

Definition at line 487 of file tree.hpp.

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

Referenced by val_tag().

◆ has_key_anchor()

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

Definition at line 488 of file tree.hpp.

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

Referenced by key_anchor(), and set_key_ref().

◆ has_val_anchor()

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

Definition at line 489 of file tree.hpp.

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

Referenced by set_val_ref(), and val_anchor().

◆ has_anchor() [1/2]

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

Definition at line 490 of file tree.hpp.

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

◆ is_key_ref()

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

Definition at line 491 of file tree.hpp.

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

Referenced by key_ref(), and set_key_anchor().

◆ is_val_ref()

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

Definition at line 492 of file tree.hpp.

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

Referenced by set_val_anchor(), and val_ref().

◆ is_ref()

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

Definition at line 493 of file tree.hpp.

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

◆ parent_is_seq()

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

Definition at line 495 of file tree.hpp.

495{ RYML_ASSERT_VISIT_CB_(m_callbacks, has_parent(node), this, node); return is_seq(_p(node)->m_parent); }
bool is_seq(id_type node) const
Definition tree.hpp:481
bool has_parent(id_type node) const
Definition tree.hpp:531

◆ parent_is_map()

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

Definition at line 496 of file tree.hpp.

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

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

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

◆ key_is_null()

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

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

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

Definition at line 504 of file tree.hpp.

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

◆ val_is_null()

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

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

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

Definition at line 508 of file tree.hpp.

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

◆ is_key_unfiltered()

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

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

Definition at line 512 of file tree.hpp.

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

◆ is_val_unfiltered()

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

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

Definition at line 515 of file tree.hpp.

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

◆ is_key_anchor()

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

Definition at line 517 of file tree.hpp.

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

Referenced by is_key_anchor().

◆ is_val_anchor()

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

Definition at line 518 of file tree.hpp.

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

Referenced by is_val_anchor().

◆ is_anchor()

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

Definition at line 519 of file tree.hpp.

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

Referenced by is_anchor().

◆ is_anchor_or_ref()

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

Definition at line 520 of file tree.hpp.

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

Referenced by is_anchor_or_ref().

◆ is_root()

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

Definition at line 529 of file tree.hpp.

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

Referenced by depth_asc(), duplicate(), first_sibling(), insert_child(), last_sibling(), move(), move(), num_siblings(), c4::yml::EventHandlerTree::reset(), sample_docs(), set_doc(), set_stream(), sibling_pos(), and val_style().

◆ has_parent()

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

Definition at line 531 of file tree.hpp.

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

Referenced by parent_is_map(), and parent_is_seq().

◆ is_ancestor()

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

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

Definition at line 1304 of file tree.cpp.

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

Referenced by duplicate_children_no_rep().

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

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

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

540{ 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 542 of file tree.hpp.

542{ return find_child(node, key) != NONE; }
id_type find_child(id_type node, csubstr const &key) const
find child by name, or NONE if no child is found with this key like Tree::child(),...
Definition tree.cpp:1249

◆ has_children()

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

true if node has any children

Definition at line 544 of file tree.hpp.

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

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

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

547{ 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 549 of file tree.hpp.

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

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

552 {
553 NodeData const *n = _p(node);
554 if C4_LIKELY(n->m_parent != NONE)
555 {
556 n = _p(n->m_parent);
557 return n->m_first_child != n->m_last_child;
558 }
559 return false;
560 }

◆ parent()

◆ prev_sibling()

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

Definition at line 571 of file tree.hpp.

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

Referenced by duplicate_children_no_rep().

◆ next_sibling()

◆ num_children()

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

O(num_children).

Definition at line 1216 of file tree.cpp.

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

Referenced by num_siblings(), sample_docs(), and sample_user_container_types().

◆ child_pos()

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

Definition at line 1224 of file tree.cpp.

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

Referenced by deserialize_child(), deserialize_child(), deserialize_child(), and sibling_pos().

◆ first_child()

◆ last_child()

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

Definition at line 578 of file tree.hpp.

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

Referenced by duplicate_contents().

◆ child()

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

find child by position, or NONE if there are less than pos children posi

Definition at line 1237 of file tree.cpp.

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

Referenced by _append_child__unprotected(), child_r(), clear_style(), doc(), insert_child(), sample_docs(), set_style_conditionally(), and sibling().

◆ find_child()

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

find child by name, or NONE if no child is found with this key like Tree::child(), but return a ReadResult with the status

Definition at line 1249 of file tree.cpp.

1250{
1251 C4_SUPPRESS_WARNING_PUSH
1252 #if defined(__clang__)
1253 #elif defined(__GNUC__)
1254 # if __GNUC__ >= 6
1255 C4_SUPPRESS_WARNING_GCC("-Wnull-dereference")
1256 # endif
1257 # if __GNUC__ > 9
1258 C4_SUPPRESS_WARNING_GCC("-Wanalyzer-null-dereference")
1259 # endif
1260 #endif
1261 RYML_ASSERT_VISIT_CB_(m_callbacks, node != NONE, this, node);
1262 RYML_ASSERT_VISIT_CB_(m_callbacks, _p(node)->m_type.m_bits & MAP, this, node);
1263 for(id_type i = first_child(node); i != NONE; i = next_sibling(i))
1264 {
1265 if(_p(i)->m_key.scalar == name)
1266 return i;
1267 }
1268 return NONE;
1269 C4_SUPPRESS_WARNING_POP
1270}
@ MAP
a map: a parent of KEYVAL/KEYSEQ/KEYMAP nodes
Definition node_type.hpp:35

Referenced by find_child_r(), find_sibling(), has_child(), merge_with(), sample_docs(), and sample_quick_overview().

◆ child_r()

ReadResult c4::yml::Tree::child_r ( id_type node,
id_type pos,
id_type * child_id ) const
inline

Definition at line 582 of file tree.hpp.

582{ return ReadResult(node, *child_id = child(node, pos)); }
id_type child(id_type node, id_type pos) const
find child by position, or NONE if there are less than pos children posi
Definition tree.cpp:1237

Referenced by deserialize_child(), deserialize_child(), deserialize_child(), and sibling_r().

◆ find_child_r()

ReadResult c4::yml::Tree::find_child_r ( id_type node,
csubstr const & key,
id_type * child_id ) const
inline

like Tree::find_child(), but return a ReadResult with the status

Definition at line 584 of file tree.hpp.

584{ return ReadResult(node, *child_id = find_child(node, key)); }

Referenced by deserialize_child(), deserialize_child(), deserialize_child(), and find_sibling_r().

◆ num_siblings()

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

O(num_siblings).

counts with this

Definition at line 588 of file tree.hpp.

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

Referenced by num_other_siblings().

◆ num_other_siblings()

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

does not count with this

Definition at line 590 of file tree.hpp.

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

◆ sibling_pos()

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

Definition at line 591 of file tree.hpp.

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

◆ first_sibling()

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

Definition at line 592 of file tree.hpp.

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

Referenced by sample_quick_overview().

◆ last_sibling()

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

Definition at line 593 of file tree.hpp.

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

594{ return child(_p(node)->m_parent, pos); }

◆ find_sibling()

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

Definition at line 595 of file tree.hpp.

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

Referenced by has_sibling().

◆ sibling_r()

ReadResult c4::yml::Tree::sibling_r ( id_type node,
id_type pos,
id_type * sibling_id ) const
inline

like Tree::sibling(), but return a ReadResult with the status

Definition at line 597 of file tree.hpp.

597{ return child_r(_p(node)->m_parent, pos, sibling_id); }
ReadResult child_r(id_type node, id_type pos, id_type *child_id) const
Definition tree.hpp:582

◆ find_sibling_r()

ReadResult c4::yml::Tree::find_sibling_r ( id_type node,
csubstr const & key,
id_type * sibling_id ) const
inline

like Tree::find_sibling(), but return a ReadResult if with the status

Definition at line 599 of file tree.hpp.

599{ return find_child_r(_p(node)->m_parent, key, sibling_id); }
ReadResult find_child_r(id_type node, csubstr const &key, id_type *child_id) const
like Tree::find_child(), but return a ReadResult with the status
Definition tree.hpp:584

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

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

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

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

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

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

Referenced by cdocref(), docref(), docref(), and sample_docs().

◆ ancestor_doc()

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

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

Definition at line 608 of file tree.hpp.

609 {
610 NodeData const *nd;
611 do
612 {
613 nd = _p(node);
614 if(nd->m_type.is_doc() || nd->m_parent == NONE)
615 break;
616 node = nd->m_parent;
617 } while(nd->m_parent != NONE);
618 return node;
619 }

Referenced by c4::yml::EventHandlerTree::reset().

◆ is_container_styled()

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

Definition at line 628 of file tree.hpp.

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

◆ is_block()

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

Definition at line 629 of file tree.hpp.

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

◆ is_flow_sl()

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

Definition at line 630 of file tree.hpp.

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

◆ is_flow_ml()

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

Definition at line 632 of file tree.hpp.

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

Referenced by is_flow_ml().

◆ is_flow_ml1()

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

Definition at line 633 of file tree.hpp.

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

◆ is_flow_mln()

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

Definition at line 634 of file tree.hpp.

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

◆ is_flow_mlx()

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

Definition at line 635 of file tree.hpp.

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

◆ is_flow()

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

Definition at line 636 of file tree.hpp.

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

◆ has_flow_space()

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

Definition at line 637 of file tree.hpp.

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

◆ is_key_styled()

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

Definition at line 639 of file tree.hpp.

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

◆ is_val_styled()

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

Definition at line 640 of file tree.hpp.

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

◆ is_key_literal()

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

Definition at line 641 of file tree.hpp.

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

◆ is_val_literal()

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

Definition at line 642 of file tree.hpp.

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

◆ is_key_folded()

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

Definition at line 643 of file tree.hpp.

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

◆ is_val_folded()

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

Definition at line 644 of file tree.hpp.

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

◆ is_key_squo()

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

Definition at line 645 of file tree.hpp.

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

◆ is_val_squo()

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

Definition at line 646 of file tree.hpp.

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

◆ is_key_dquo()

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

Definition at line 647 of file tree.hpp.

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

◆ is_val_dquo()

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

Definition at line 648 of file tree.hpp.

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

◆ is_key_plain()

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

Definition at line 649 of file tree.hpp.

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

◆ is_val_plain()

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

Definition at line 650 of file tree.hpp.

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

◆ is_key_quoted()

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

Definition at line 651 of file tree.hpp.

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

◆ is_val_quoted()

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

Definition at line 652 of file tree.hpp.

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

◆ is_quoted()

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

Definition at line 653 of file tree.hpp.

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

◆ key_style()

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

Definition at line 655 of file tree.hpp.

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

◆ val_style()

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

Definition at line 656 of file tree.hpp.

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

◆ set_container_style()

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

Definition at line 658 of file tree.hpp.

658{ RYML_ASSERT_VISIT_CB_(m_callbacks, is_container(node), this, node); _p(node)->m_type.set_container_style(style); }
bool is_container(id_type node) const
Definition tree.hpp:479
void set_container_style(type_bits style) noexcept

Referenced by sample_style_flow_ml_indent().

◆ set_key_style()

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

Definition at line 659 of file tree.hpp.

659{ RYML_ASSERT_VISIT_CB_(m_callbacks, has_key(node), this, node); _p(node)->m_type.set_key_style(style); }
void set_key_style(type_bits style) noexcept

◆ set_val_style()

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

Definition at line 660 of file tree.hpp.

660{ RYML_ASSERT_VISIT_CB_(m_callbacks, has_val(node), this, node); _p(node)->m_type.set_val_style(style); }
void set_val_style(type_bits style) noexcept

◆ clear_style()

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

Definition at line 1404 of file tree.cpp.

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

Referenced by clear_style(), and sample_style().

◆ set_style_conditionally()

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

Definition at line 1414 of file tree.cpp.

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

Referenced by sample_style(), and set_style_conditionally().

◆ set_stream()

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

Definition at line 675 of file tree.hpp.

676 {
677 RYML_ASSERT_VISIT_CB_(m_callbacks, is_root(node), this, node);
678 RYML_ASSERT_VISIT_CB_(m_callbacks, (_p(node)->m_type & (DOC|MAP|VAL)) == 0, this, node);
679 _p(node)->m_type |= STREAM;
680 }
@ STREAM
a stream: a seq of docs
Definition node_type.hpp:38
@ DOC
a document
Definition node_type.hpp:37

◆ set_doc()

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

Definition at line 682 of file tree.hpp.

683 {
684 RYML_ASSERT_VISIT_CB_(m_callbacks, is_root(node) || (is_root(parent(node)) && is_stream(parent(node))), this, node);
685 _p(node)->m_type |= DOC;
686 }

◆ set_val() [1/2]

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

Definition at line 688 of file tree.hpp.

689 {
690 RYML_ASSERT_VISIT_CB_(m_callbacks, (_p(node)->m_type & (SEQ|MAP)) == 0, this, node);
691 RYML_ASSERT_VISIT_CB_(m_callbacks, (parent(node) == NONE || (_p(parent(node))->m_type & (SEQ|MAP))), this, node);
692 NodeData *C4_RESTRICT nd = _p(node);
693 nd->m_type |= VAL;
694 nd->m_val.scalar = val;
695 }
csubstr const & val(id_type node) const
Definition tree.hpp:460
@ SEQ
a seq: a parent of VAL/SEQ/MAP nodes
Definition node_type.hpp:36

Referenced by lookup_path_or_modify(), sample_anchors_and_aliases_create(), sample_lightning_overview(), sample_tree_arena(), c4::yml::write(), and write().

◆ set_val() [2/2]

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

Definition at line 696 of file tree.hpp.

697 {
698 RYML_ASSERT_VISIT_CB_(m_callbacks, (_p(node)->m_type & (SEQ|MAP)) == 0, this, node);
699 RYML_ASSERT_VISIT_CB_(m_callbacks, (parent(node) == NONE || (_p(parent(node))->m_type & (SEQ|MAP))), this, node);
700 NodeData *C4_RESTRICT nd = _p(node);
701 nd->m_type |= VAL|more_flags;
702 nd->m_val.scalar = val;
703 }

◆ set_key() [1/2]

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

Definition at line 705 of file tree.hpp.

706 {
707 RYML_ASSERT_VISIT_CB_(m_callbacks, (parent(node) != NONE && (_p(parent(node))->m_type & MAP)), this, node);
708 NodeData *C4_RESTRICT nd = _p(node);
709 nd->m_type |= KEY;
710 nd->m_key.scalar = key;
711 }
@ KEY
the scalar to the left of : in a map's member
Definition node_type.hpp:33

Referenced by merge_with(), write(), and c4::yml::write_key().

◆ set_key() [2/2]

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

Definition at line 712 of file tree.hpp.

713 {
714 RYML_ASSERT_VISIT_CB_(m_callbacks, (parent(node) != NONE && (_p(parent(node))->m_type & MAP)), this, node);
715 NodeData *C4_RESTRICT nd = _p(node);
716 nd->m_type |= KEY|more_flags;
717 nd->m_key.scalar = key;
718 }

◆ set_seq() [1/2]

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

Definition at line 720 of file tree.hpp.

721 {
722 RYML_ASSERT_VISIT_CB_(m_callbacks, (_p(node)->m_type & (VAL|MAP)) == 0, this, node);
723 _p(node)->m_type |= SEQ;
724 }

Referenced by merge_with(), write(), and write().

◆ set_seq() [2/2]

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

Definition at line 725 of file tree.hpp.

726 {
727 RYML_ASSERT_VISIT_CB_(m_callbacks, ((_p(node)->m_type|more_flags) & (VAL|MAP)) == 0, this, node);
728 _p(node)->m_type |= SEQ|more_flags;
729 }

◆ set_map() [1/2]

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

Definition at line 731 of file tree.hpp.

732 {
733 RYML_ASSERT_VISIT_CB_(m_callbacks, (_p(node)->m_type & (VAL|SEQ)) == 0, this, node);
734 _p(node)->m_type |= MAP;
735 }

Referenced by merge_with(), c4::yml::write(), write(), and write().

◆ set_map() [2/2]

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

Definition at line 736 of file tree.hpp.

737 {
738 RYML_ASSERT_VISIT_CB_(m_callbacks, ((_p(node)->m_type|more_flags) & (VAL|SEQ)) == 0, this, node);
739 _p(node)->m_type |= MAP|more_flags;
740 }

◆ set_key_tag()

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

Definition at line 742 of file tree.hpp.

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

Referenced by sample_serialize_basic().

◆ set_val_tag()

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

Definition at line 743 of file tree.hpp.

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

Referenced by sample_serialize_basic().

◆ set_key_anchor()

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

Definition at line 745 of file tree.hpp.

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

Referenced by sample_anchors_and_aliases_create(), and sample_serialize_basic().

◆ set_val_anchor()

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

Definition at line 746 of file tree.hpp.

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

Referenced by sample_anchors_and_aliases_create(), and sample_serialize_basic().

◆ set_key_ref()

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

Definition at line 747 of file tree.hpp.

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

◆ set_val_ref()

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

Definition at line 748 of file tree.hpp.

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

Referenced by sample_anchors_and_aliases_create().

◆ rem_key_anchor()

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

Definition at line 750 of file tree.hpp.

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

◆ rem_val_anchor()

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

Definition at line 751 of file tree.hpp.

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

◆ rem_key_ref()

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

Definition at line 752 of file tree.hpp.

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

◆ rem_val_ref()

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

Definition at line 753 of file tree.hpp.

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

◆ rem_anchor_ref()

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

Definition at line 754 of file tree.hpp.

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

◆ save() [1/2]

template<class T>
void c4::yml::Tree::save ( id_type node,
T const & val )
inline

Definition at line 772 of file tree.hpp.

773 {
774 if C4_LIKELY(node != NONE && node < m_cap && node >= 0)
775 {
776 write(this, node, val);
777 return;
778 }
779 err_visit_(node);
780 }
void write(NodeRef *n, T const &v)
Definition node.hpp:2114

Referenced by sample_serialize_basic(), and sample_user_container_types().

◆ save() [2/2]

template<class T>
void c4::yml::Tree::save ( id_type node,
T const & val,
NodeType more_flags )
inline

Definition at line 782 of file tree.hpp.

783 {
784 if C4_LIKELY(node != NONE && node < m_cap && node >= 0)
785 {
786 write(this, node, val);
787 _p(node)->m_type |= more_flags;
788 return;
789 }
790 err_visit_(node);
791 }

◆ save_key() [1/2]

template<class T>
void c4::yml::Tree::save_key ( id_type node,
T const & key )
inline

Definition at line 794 of file tree.hpp.

795 {
796 if C4_LIKELY(node != NONE && node < m_cap && node >= 0)
797 {
798 write_key(this, node, key);
799 return;
800 }
801 err_visit_(node);
802 }
void write_key(NodeRef *n, T const &v)
Definition node.hpp:2119

Referenced by sample_serialize_basic().

◆ save_key() [2/2]

template<class T>
void c4::yml::Tree::save_key ( id_type node,
T const & key,
NodeType more_flags )
inline

Definition at line 804 of file tree.hpp.

805 {
806 if C4_LIKELY(node != NONE && node < m_cap && node >= 0)
807 {
808 write_key(this, node, key);
809 _p(node)->m_type |= more_flags;
810 return;
811 }
812 err_visit_(node);
813 }

◆ set_serialized() [1/2]

template<class T>
void c4::yml::Tree::set_serialized ( id_type node,
T const & val )
inline

Definition at line 823 of file tree.hpp.

824 {
825 RYML_ASSERT_VISIT_CB_(m_callbacks, node != NONE && node >= 0 && node < m_cap, this, node);
826 write(this, node, val);
827 }

Referenced by sample_base64(), sample_empty_null_values(), sample_serialize_basic(), c4::yml::write(), c4::yml::write(), write(), write(), and write().

◆ set_serialized() [2/2]

template<class T>
void c4::yml::Tree::set_serialized ( id_type node,
T const & val,
NodeType more_flags )
inline

Definition at line 829 of file tree.hpp.

830 {
831 RYML_ASSERT_VISIT_CB_(m_callbacks, node != NONE && node >= 0 && node < m_cap, this, node);
832 write(this, node, val);
833 _p(node)->m_type |= more_flags;
834 }

◆ set_key_serialized() [1/2]

template<class T>
void c4::yml::Tree::set_key_serialized ( id_type node,
T const & key )
inline

Definition at line 837 of file tree.hpp.

838 {
839 RYML_ASSERT_VISIT_CB_(m_callbacks, node != NONE && node >= 0 && node < m_cap, this, node);
840 write_key(this, node, key);
841 }

Referenced by sample_serialize_basic(), c4::yml::write(), write(), and c4::yml::write_key().

◆ set_key_serialized() [2/2]

template<class T>
void c4::yml::Tree::set_key_serialized ( id_type node,
T const & key,
NodeType more_flags )
inline

Definition at line 843 of file tree.hpp.

844 {
845 RYML_ASSERT_VISIT_CB_(m_callbacks, node != NONE && node >= 0 && node < m_cap, this, node);
846 write_key(this, node, key);
847 _p(node)->m_type |= more_flags;
848 }

◆ to_result_() [1/2]

ReadResult c4::yml::Tree::to_result_ ( bool ,
id_type node )
inlinestaticnoexcept

Definition at line 861 of file tree.hpp.

861{ return ReadResult(node); }

◆ to_result_() [2/2]

ReadResult c4::yml::Tree::to_result_ ( ReadResult notlegacy,
id_type  )
inlinestaticnoexcept

Definition at line 862 of file tree.hpp.

862{ return notlegacy; }

◆ load() [1/2]

template<class T>
void c4::yml::Tree::load ( id_type node,
T * v,
bool check_readable = true ) const
inline

(1) deserialize the node's contents (val or container) to the given variable, forwarding to the user-overrideable read() function (see Read from Tree).

This function differs from Tree::deserialize() in that here the error callback is called if the deserialization failed, or (optionally) the node is not readable.

Definition at line 871 of file tree.hpp.

872 {
873 const bool can_read_val = (node != NONE && node < m_cap && node >= 0 && (_p(node)->m_type & (VAL|MAP|SEQ)));
874 RYML_ASSERT_VISIT_CB_(m_callbacks, can_read_val, this, node);
875 if C4_LIKELY(!check_readable || can_read_val)
876 {
877 const ReadResult result(read(this, node, v), node);
878 if C4_LIKELY(result)
879 return;
880 else
881 node = result.node;
882 }
883 err_visit_(node);
884 }
ReadResult read(ConstNodeRef const &n, T *v)
Definition node.hpp:2074

Referenced by sample_base64(), sample_error_visit(), sample_error_visit_location(), sample_fundamental_types(), sample_serialize_basic(), and sample_user_container_types().

◆ load() [2/2]

template<class Wrapper>
void c4::yml::Tree::load ( id_type node,
Wrapper const & w,
bool check_readable = true ) const
inline

(2) like (1), but for wrapper tag types such as c4::fmt::base64()

Definition at line 888 of file tree.hpp.

889 {
890 RYML_CHECK_TYPE_IS_WRAPPER_LIKE_(Wrapper);
891 const bool can_read_val = (node != NONE && node < m_cap && node >= 0 && (_p(node)->m_type & (VAL|MAP|SEQ)));
892 RYML_ASSERT_VISIT_CB_(m_callbacks, can_read_val, this, node);
893 if C4_LIKELY(!check_readable || can_read_val)
894 {
895 const ReadResult result(read(this, node, w), node);
896 if C4_LIKELY(result)
897 return;
898 else
899 node = result.node;
900 }
901 err_visit_(node);
902 }

◆ load_key() [1/2]

template<class T>
void c4::yml::Tree::load_key ( id_type node,
T * k,
bool check_readable = true ) const
inline

(1) deserialize the node's key (necessarily a scalar) to the given variable, forwarding to the user-overrideable read_key() function (see Read from ConstNodeRef).

This function differs from Tree::deserialize_key() in that here the error callback is called if the deserialization failed, or (optionally) the node is not readable.

Definition at line 912 of file tree.hpp.

913 {
914 const bool can_read_key = (node != NONE && node < m_cap && node >= 0 && (_p(node)->m_type & KEY));
915 RYML_ASSERT_VISIT_CB_(m_callbacks, can_read_key, this, node);
916 if C4_LIKELY(!check_readable || can_read_key)
917 {
918 const ReadResult result(read_key(this, node, k), node);
919 if C4_LIKELY(result)
920 return;
921 else
922 node = result.node;
923 }
924 err_visit_(node);
925 }
ReadResult read_key(ConstNodeRef const &n, T *v)
Definition node.hpp:2088

Referenced by sample_base64(), and sample_serialize_basic().

◆ load_key() [2/2]

template<class Wrapper>
void c4::yml::Tree::load_key ( id_type node,
Wrapper const & w,
bool check_readable = true ) const
inline

(2) like (1), but for wrapper tag types such as c4::fmt::base64()

Definition at line 929 of file tree.hpp.

930 {
931 RYML_CHECK_TYPE_IS_WRAPPER_LIKE_(Wrapper);
932 bool can_read_key = (node != NONE && node < m_cap && node >= 0 && (_p(node)->m_type & KEY));
933 RYML_ASSERT_VISIT_CB_(m_callbacks, can_read_key, this, node);
934 if C4_LIKELY(!check_readable || can_read_key)
935 {
936 const ReadResult result(read_key(this, node, w), node);
937 if C4_LIKELY(result)
938 return;
939 else
940 node = result.node;
941 }
942 err_visit_(node);
943 }

◆ deserialize() [1/2]

template<class T>
ReadResult c4::yml::Tree::deserialize ( id_type node,
T * v ) const
inline

(1) deserialize a node's contents to a variable

Definition at line 954 of file tree.hpp.

955 {
956 RYML_ASSERT_VISIT_CB_(m_callbacks, node != NONE && node >= 0 && node < m_cap, this, node);
957 RYML_ASSERT_VISIT_CB_(m_callbacks, _p(node)->m_type & (VAL|MAP|SEQ), this, node);
958 // use the adapter ctor to accomodate legacy read() implementations
959 return ReadResult(read(this, node, v), node);
960 }

Referenced by deserialize_child(), deserialize_child(), deserialize_child(), deserialize_child(), deserialize_child(), deserialize_child(), c4::yml::read(), c4::yml::read(), read(), read(), sample_base64(), and sample_serialize_basic().

◆ deserialize() [2/2]

template<class Wrapper>
ReadResult c4::yml::Tree::deserialize ( id_type node,
Wrapper const & w ) const
inline

(2) like (1), but for a wrapper type like those used in tag functions

Definition at line 964 of file tree.hpp.

965 {
966 RYML_CHECK_TYPE_IS_WRAPPER_LIKE_(Wrapper);
967 RYML_ASSERT_VISIT_CB_(m_callbacks, node != NONE && node >= 0 && node < m_cap, this, node);
968 RYML_ASSERT_VISIT_CB_(m_callbacks, _p(node)->m_type & (VAL|MAP|SEQ), this, node);
969 // use the adapter ctor to accomodate legacy read() implementations
970 return ReadResult(read(this, node, w), node);
971 }

◆ deserialize_key() [1/2]

template<class T>
ReadResult c4::yml::Tree::deserialize_key ( id_type node,
T * v ) const
inline

(1) deserialize a node's key to a variable

Definition at line 975 of file tree.hpp.

976 {
977 RYML_ASSERT_VISIT_CB_(m_callbacks, node != NONE && node >= 0 && node < m_cap, this, node);
978 RYML_ASSERT_VISIT_CB_(m_callbacks, has_key(node), this, node);
979 // use the adapter ctor to accomodate legacy read_key() implementations
980 return ReadResult(read_key(this, node, v), node);
981 }

Referenced by c4::yml::read(), read(), and sample_serialize_basic().

◆ deserialize_key() [2/2]

template<class Wrapper>
ReadResult c4::yml::Tree::deserialize_key ( id_type node,
Wrapper const & w ) const
inline

(2) like (1), but for a wrapper type like those used in tag functions

Definition at line 985 of file tree.hpp.

986 {
987 RYML_CHECK_TYPE_IS_WRAPPER_LIKE_(Wrapper);
988 RYML_ASSERT_VISIT_CB_(m_callbacks, node != NONE && node >= 0 && node < m_cap, this, node);
989 RYML_ASSERT_VISIT_CB_(m_callbacks, has_key(node), this, node);
990 // use the adapter ctor to accomodate legacy read_key() implementations
991 return ReadResult(read_key(this, node, w), node);
992 }

◆ deserialize_child() [1/6]

template<class T>
ReadResult c4::yml::Tree::deserialize_child ( id_type node,
csubstr child_key,
T * v ) const
inline

(1) find a child by name and deserialize its contents to the given variable (ie call .deserialize() on the child if it exists).

Otherwise, the variable is kept unchanged.

Returns
a ReadResult set with this node's id if no child exists, or the ReadResult from the deserialization.
See also
see also Tree::find_child_r()

Definition at line 1011 of file tree.hpp.

1012 {
1013 id_type ch;
1014 ReadResult r = find_child_r(node, child_key, &ch);
1015 if(r)
1016 r = deserialize(ch, v);
1017 return r;
1018 }
ReadResult deserialize(id_type node, T *v) const
(1) deserialize a node's contents to a variable
Definition tree.hpp:954

Referenced by read().

◆ deserialize_child() [2/6]

template<class T>
ReadResult c4::yml::Tree::deserialize_child ( id_type node,
csubstr child_key,
T * v,
T const & fallback ) const
inline

(2) like (1), but assign from fallback if no such child exists.

Definition at line 1021 of file tree.hpp.

1022 {
1023 id_type ch;
1024 if(find_child_r(node, child_key, &ch))
1025 return deserialize(ch, v);
1026 *v = fallback;
1027 return ReadResult();
1028 }

◆ deserialize_child() [3/6]

template<class Wrapper>
ReadResult c4::yml::Tree::deserialize_child ( id_type node,
csubstr child_key,
Wrapper const & wrapper ) const
inline

(3) like (1), but for wrapper tag types such as c4::fmt::base64()

Definition at line 1031 of file tree.hpp.

1032 {
1033 id_type ch;
1034 ReadResult r = find_child_r(node, child_key, &ch);
1035 if(r)
1036 r = deserialize(ch, wrapper);
1037 return r;
1038 }

◆ deserialize_child() [4/6]

template<class T>
ReadResult c4::yml::Tree::deserialize_child ( id_type node,
id_type child_pos,
T * v ) const
inline

(1) find a child by position and deserialize its contents to the given variable (ie call .deserialize() on the child if it exists).

Otherwise, the variable is kept unchanged.

Returns
a ReadResult set with this node's id if no child exists, or the ReadResult from the deserialization.
See also
see also Tree::child_r()

Definition at line 1050 of file tree.hpp.

1051 {
1052 RYML_ASSERT_VISIT_CB_(m_callbacks, is_container(node), this, node); // this assertion is needed because child_r() does not assert, contrary to find_child_r()
1053 id_type ch;
1054 ReadResult r = child_r(node, child_pos, &ch);
1055 if(r)
1056 r = deserialize(ch, v);
1057 return r;
1058 }

◆ deserialize_child() [5/6]

template<class T>
ReadResult c4::yml::Tree::deserialize_child ( id_type node,
id_type child_pos,
T * v,
T const & fallback ) const
inline

(2) like (1), but assign from fallback if no such child exists

Definition at line 1061 of file tree.hpp.

1062 {
1063 RYML_ASSERT_VISIT_CB_(m_callbacks, is_container(node), this, node); // this assertion is needed because child_r() does not assert, contrary to find_child_r()
1064 id_type ch;
1065 if(child_r(node, child_pos, &ch))
1066 return deserialize(ch, v);
1067 *v = fallback;
1068 return ReadResult();
1069 }

◆ deserialize_child() [6/6]

template<class Wrapper>
ReadResult c4::yml::Tree::deserialize_child ( id_type node,
id_type child_pos,
Wrapper const & wrapper ) const
inline

(3) like (1), but for wrapper tag types such as c4::fmt::base64()

Definition at line 1073 of file tree.hpp.

1074 {
1075 RYML_ASSERT_VISIT_CB_(m_callbacks, is_container(node), this, node); // this assertion is needed because child_r() does not assert, contrary to find_child_r()
1076 id_type ch;
1077 ReadResult r = child_r(node, child_pos, &ch);
1078 if(r)
1079 r = deserialize(ch, wrapper);
1080 return r;
1081 }

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

574{
575 id_type r = root_id();
576 _do_reorder(&r, 0);
577}

◆ resolve() [1/2]

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

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

Definition at line 1206 of file tree.cpp.

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

Referenced by resolve(), sample_anchors_and_aliases(), and sample_anchors_and_aliases_create().

◆ resolve() [2/2]

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

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

This overload uses a throwaway resolver object.

Definition at line 1198 of file tree.cpp.

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

◆ resolve_tags()

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

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

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

Definition at line 1553 of file tree.cpp.

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

Referenced by sample_tag_directives().

◆ normalize_tags()

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

Definition at line 1571 of file tree.cpp.

1572{
1573 if(empty())
1574 return;
1575 _normalize_tags(this, root_id());
1576}

Referenced by sample_tags().

◆ normalize_tags_long()

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

Definition at line 1578 of file tree.cpp.

1579{
1580 if(empty())
1581 return;
1582 _normalize_tags_long(this, root_id());
1583}

Referenced by sample_tags().

◆ num_tag_directives()

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

Definition at line 1434 of file tree.cpp.

1435{
1436 return m_tag_directives.size();
1437}

◆ add_tag_directive()

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

Definition at line 1444 of file tree.cpp.

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

Referenced by sample_error_basic().

◆ clear_tag_directives()

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

Definition at line 1439 of file tree.cpp.

1440{
1441 m_tag_directives.clear();
1442}

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

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

Referenced by resolve_tag_sub().

◆ resolve_tag_sub()

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

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

Definition at line 1145 of file tree.hpp.

1146 {
1147 size_t needed = resolve_tag(output, tag, node_id);
1148 return needed <= output.len ? output.first(needed) : output;
1149 }
size_t resolve_tag(substr output, csubstr tag, id_type node_id) const
resolve the given tag, appearing at node_id.
Definition tree.cpp:1456

◆ tag_directives()

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

Definition at line 1151 of file tree.hpp.

1151{ return m_tag_directives.directives(); }

◆ insert_child()

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

create and insert a new child of parent.

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

Definition at line 1168 of file tree.hpp.

1169 {
1170 RYML_ASSERT_VISIT_CB_(m_callbacks, parent != NONE, this, parent);
1171 RYML_ASSERT_VISIT_CB_(m_callbacks, is_container(parent) || is_root(parent), this, parent);
1172 RYML_ASSERT_VISIT_CB_(m_callbacks, after == NONE || (_p(after)->m_parent == parent), this, parent);
1173 id_type child = _claim();
1174 _set_hierarchy(child, parent, after);
1175 return child;
1176 }

Referenced by append_child(), insert_child(), insert_sibling(), and prepend_child().

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

1178{ 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:1168

Referenced by prepend_sibling().

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

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

Referenced by append_sibling(), merge_with(), set_root_as_stream(), c4::yml::write(), write(), write(), write(), and write().

◆ _append_child__unprotected()

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

Definition at line 1181 of file tree.hpp.

1182 {
1183 id_type child = _claim();
1184 _set_hierarchy(child, parent, _p(parent)->m_last_child);
1185 return child;
1186 }

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

1192 {
1193 return insert_child(_p(node)->m_parent, after);
1194 }

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

1196{ 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:1178

◆ append_sibling()

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

Definition at line 1197 of file tree.hpp.

1197{ 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:1180

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

1203 {
1204 remove_children(node);
1205 _release(node);
1206 }
void remove_children(id_type node)
remove all the node's children, but keep the node itself
Definition tree.cpp:917

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

918{
919 RYML_ASSERT_VISIT_CB_(m_callbacks, get(node) != nullptr, this, node);
920 C4_SUPPRESS_WARNING_GCC_PUSH
921 #if defined(__GNUC__) && __GNUC__ >= 6
922 C4_SUPPRESS_WARNING_GCC("-Wnull-dereference")
923 #endif
924 id_type ich = get(node)->m_first_child;
925 while(ich != NONE)
926 {
927 remove_children(ich);
928 RYML_ASSERT_VISIT_CB_(m_callbacks, get(ich) != nullptr, this, node);
929 id_type next = get(ich)->m_next_sibling;
930 _release(ich);
931 if(ich == get(node)->m_last_child)
932 break;
933 ich = next;
934 }
935 C4_SUPPRESS_WARNING_GCC_POP
936}
NodeData * get(id_type node)
get a pointer to a node's NodeData. node can be NONE, in which case a nullptr is returned
Definition tree.hpp:361

Referenced by change_type(), merge_with(), remove(), and remove_children().

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

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

Referenced by duplicate_children_no_rep(), 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 830 of file tree.cpp.

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

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

844{
845 RYML_ASSERT_VISIT_CB_(m_callbacks, src != nullptr, this, new_parent);
846 RYML_ASSERT_VISIT_CB_(m_callbacks, node != NONE, this, new_parent);
847 RYML_ASSERT_VISIT_CB_(m_callbacks, new_parent != NONE, this, new_parent);
848 RYML_ASSERT_VISIT_CB_(m_callbacks, new_parent != after, this, new_parent);
849
850 id_type dup = duplicate(src, node, new_parent, after);
851 src->remove(node);
852 return dup;
853}
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:960

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

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

◆ change_type() [1/2]

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

Definition at line 940 of file tree.cpp.

941{
942 NodeType curr = this->type(node);
943 RYML_ASSERT_VISIT_CB_(m_callbacks, next.is_val() || next.is_map() || next.is_seq(), this, node);
944 RYML_ASSERT_VISIT_CB_(m_callbacks, next.is_val() + next.is_map() + next.is_seq() == 1, this, node);
945 RYML_ASSERT_VISIT_CB_(m_callbacks, next.has_key() == curr.has_key() || (curr.has_key() && !next.has_key()), this, node);
946 NodeData *d = _p(node);
947 if(next.is_map() && curr.is_map())
948 return false;
949 else if(next.is_seq() && curr.is_seq())
950 return false;
951 else if(next.is_val() && curr.is_val())
952 return false;
953 d->m_type.m_bits = (d->m_type.m_bits & (~(MAP|SEQ|VAL|CONTAINER_STYLE|KEY_STYLE|VAL_STYLE))) | next;
954 remove_children(node);
955 return true;
956}
@ VAL_STYLE
mask of VALQUO|VAL_PLAIN : all the val scalar styles for val (not container styles!...
@ KEY_STYLE
mask of KEYQUO|KEY_PLAIN : all the key scalar styles for key (not container styles!...
@ CONTAINER_STYLE
mask of CONTAINER_STYLE_FLOW|CONTAINER_STYLE_BLOCK : all container style flags

Referenced by change_type().

◆ change_type() [2/2]

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

Definition at line 1247 of file tree.hpp.

1248 {
1249 return change_type(node, (NodeType)type);
1250 }
bool change_type(id_type node, NodeType type)
Definition tree.cpp:940

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

961{
962 return duplicate(this, node, parent, after);
963}

Referenced by 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 965 of file tree.cpp.

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

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

984{
985 return duplicate_children(this, node, parent, after);
986}

Referenced by duplicate(), 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 988 of file tree.cpp.

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

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

1021{
1022 return duplicate_children_no_rep(this, node, parent, after);
1023}
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:1020

Referenced by duplicate_children_no_rep().

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

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

◆ duplicate_contents() [1/2]

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

Definition at line 1005 of file tree.cpp.

1006{
1007 duplicate_contents(this, node, where);
1008}
void duplicate_contents(id_type node, id_type where)
Definition tree.cpp:1005

Referenced by duplicate_contents().

◆ duplicate_contents() [2/2]

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

Definition at line 1010 of file tree.cpp.

1011{
1012 RYML_ASSERT_VISIT_CB_(m_callbacks, src != nullptr, src, node);
1013 RYML_ASSERT_VISIT_CB_(m_callbacks, node != NONE, src, node);
1014 RYML_ASSERT_VISIT_CB_(m_callbacks, where != NONE, this, where);
1015 _copy_props_wo_key(where, src, node);
1016 duplicate_children(src, node, where, last_child(where));
1017}
id_type last_child(id_type node) const
Definition tree.hpp:578

◆ merge_with()

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

Definition at line 1121 of file tree.cpp.

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

Referenced by lookup_path_or_modify(), and merge_with().

◆ location()

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

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

Definition at line 1913 of file tree.cpp.

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

Referenced by sample_deserialize_error(), sample_error_visit_location(), and sample_location_tracking().

◆ arena_size()

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

get the current size of the tree's internal arena

Definition at line 1309 of file tree.hpp.

1309{ return m_arena_pos; }

◆ arena_capacity()

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

get the current capacity of the tree's internal arena

Definition at line 1311 of file tree.hpp.

1311{ return m_arena.len; }

Referenced by Tree(), Tree(), and 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 1313 of file tree.hpp.

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

Referenced by alloc_arena().

◆ arena_pos()

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

Definition at line 1314 of file tree.hpp.

1314{ return m_arena_pos; }

Referenced by arena_pos().

◆ arena() [1/2]

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

get the current arena

Definition at line 1317 of file tree.hpp.

1317{ return m_arena.first(m_arena_pos); }

Referenced by sample_empty_null_values(), sample_fundamental_types(), sample_quick_overview(), sample_tree_arena(), and sample_user_container_types().

◆ arena() [2/2]

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

get the current arena

Definition at line 1319 of file tree.hpp.

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

◆ arena_rem() [1/2]

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

get the free space at the end of the arena

Definition at line 1322 of file tree.hpp.

1322{ return m_arena.sub(m_arena_pos); }

Referenced by c4::yml::serialize_to_arena_scalar().

◆ arena_rem() [2/2]

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

get the free space at the end of the arena

Definition at line 1324 of file tree.hpp.

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

◆ in_arena()

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

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

Definition at line 1327 of file tree.hpp.

1328 {
1329 return m_arena.is_super(s);
1330 }

Referenced by sample_quick_overview().

◆ to_arena()

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

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

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

Definition at line 1349 of file tree.hpp.

1350 {
1351 return serialize_to_arena(this, a);
1352 }
csubstr serialize_to_arena(Tree *tree, T const &scalar)
Serialize a scalar to a tree's arena, dispatching to either serialize_to_arena_scalar() or serialize_...
Definition tree.hpp:109

Referenced by sample_fundamental_types(), and sample_tree_arena().

◆ copy_to_arena()

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

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

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

Definition at line 1370 of file tree.hpp.

1371 {
1372 RYML_ASSERT_VISIT_CB_(m_callbacks, !s.overlaps(m_arena), this, NONE);
1373 substr cp = alloc_arena(s.len);
1374 RYML_ASSERT_VISIT_CB_(m_callbacks, cp.len == s.len, this, NONE);
1375 RYML_ASSERT_VISIT_CB_(m_callbacks, !s.overlaps(cp), this, NONE);
1376 C4_SUPPRESS_WARNING_GCC_PUSH
1377 #if (!defined(__clang__)) && (defined(__GNUC__) && __GNUC__ >= 10)
1378 C4_SUPPRESS_WARNING_GCC("-Wstringop-overflow=") // no need for terminating \0
1379 C4_SUPPRESS_WARNING_GCC("-Wrestrict") // there's an assert to ensure no violation of restrict behavior
1380 #endif
1381 if(s.len)
1382 memcpy(cp.str, s.str, s.len);
1383 C4_SUPPRESS_WARNING_GCC_POP
1384 return cp;
1385 }
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:1397
basic_substring< char > substr
a mutable string view
Definition substr.hpp:2355

Referenced by 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 Tree::reserve_arena().
See also
reserve_arena()

Definition at line 1397 of file tree.hpp.

1398 {
1399 if(sz > arena_slack())
1400 _grow_arena(sz - arena_slack());
1401 substr s = _request_span(sz);
1402 return s;
1403 }
size_t arena_slack() const
get the current slack of the tree's internal arena
Definition tree.hpp:1313

Referenced by copy_to_arena(), and sample_tree_arena().

◆ reserve_arena()

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

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

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

Definition at line 1409 of file tree.hpp.

1410 {
1411 if(arena_cap > m_arena.len)
1412 {
1413 substr buf;
1414 buf.str = RYML_CB_ALLOC_(m_callbacks, char, arena_cap);
1415 buf.len = arena_cap;
1416 if(m_arena.str)
1417 {
1418 RYML_ASSERT_VISIT_CB_(m_callbacks, m_arena.len >= 0, this, NONE);
1419 _relocate(buf); // does a memcpy and changes nodes using the arena
1420 RYML_CB_FREE_(m_callbacks, m_arena.str, char, m_arena.len);
1421 }
1422 m_arena = buf;
1423 }
1424 }
C * str
a restricted pointer to the first character of the substring
Definition substr.hpp:216

Referenced by Tree(), sample_global_allocator(), sample_parse_reuse_tree(), and 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 1608 of file tree.cpp.

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

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

1622{
1623 id_type target = _lookup_path_or_create(path, start);
1624 set_val(target, default_value);
1625 return target;
1626}
void set_val(id_type node, csubstr val) RYML_NOEXCEPT
Definition tree.hpp:688

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

1629{
1630 id_type target = _lookup_path_or_create(path, start);
1631 merge_with(src, src_node, target);
1632 return target;
1633}

Member Data Documentation

◆ m_buf

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

Definition at line 1676 of file tree.hpp.

Referenced by Tree(), _p(), _p(), clear(), get(), get(), id(), and reserve().

◆ m_cap

◆ m_size

id_type c4::yml::Tree::m_size

Definition at line 1678 of file tree.hpp.

Referenced by Tree(), clear(), empty(), reserve(), resolve(), resolve(), root_id(), root_id_maybe(), size(), and slack().

◆ m_free_head

id_type c4::yml::Tree::m_free_head

Definition at line 1680 of file tree.hpp.

Referenced by Tree(), clear(), reserve(), and set_root_as_stream().

◆ m_free_tail

id_type c4::yml::Tree::m_free_tail

Definition at line 1681 of file tree.hpp.

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

◆ m_arena

◆ m_arena_pos

size_t c4::yml::Tree::m_arena_pos

◆ m_callbacks

◆ m_tag_directives


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