1#ifndef _C4_YML_NODE_HPP_
2#define _C4_YML_NODE_HPP_
6#ifndef _C4_YML_TREE_HPP_
10C4_SUPPRESS_WARNING_PUSH
11C4_SUPPRESS_WARNING_GCC_CLANG(
"-Wtype-limits")
12C4_SUPPRESS_WARNING_GCC_CLANG(
"-Wold-style-cast")
13C4_SUPPRESS_WARNING_GCC(
"-Wuseless-cast")
14C4_SUPPRESS_WARNING_CLANG(
"-Wnull-dereference")
15#if defined(__GNUC__) && __GNUC__ >= 6
16C4_SUPPRESS_WARNING_GCC(
"-Wnull-dereference")
18C4_SUPPRESS_WARNING_MSVC(4251)
19C4_SUPPRESS_WARNING_MSVC(4296)
20C4_SUPPRESS_WARNING_MSVC(4996)
37template<
class K>
struct Key { K &&
k; };
39template<
class K> C4_ALWAYS_INLINE
Key<K> key(K && k) {
return Key<K>{std::forward<K>(k)}; }
42template<
class T>
void write(NodeRef *n, T
const& v);
44template<
class T>
inline bool read(ConstNodeRef
const& C4_RESTRICT n, T *v);
45template<
class T>
inline bool read(ConstNodeRef
const& C4_RESTRICT n, T
const& wrapper);
46template<
class T>
inline bool read(NodeRef
const& C4_RESTRICT n, T *v);
47template<
class T>
inline bool read(NodeRef
const& C4_RESTRICT n, T
const& wrapper);
48template<
class T>
inline bool readkey(ConstNodeRef
const& C4_RESTRICT n, T *v);
49template<
class T>
inline bool readkey(ConstNodeRef
const& C4_RESTRICT n, T
const& wrapper);
50template<
class T>
inline bool readkey(NodeRef
const& C4_RESTRICT n, T *v);
51template<
class T>
inline bool readkey(NodeRef
const& C4_RESTRICT n, T
const& wrapper);
72template<
class NodeRefType>
75 using value_type = NodeRefType;
76 using tree_type =
typename NodeRefType::tree_type;
77 tree_type * C4_RESTRICT m_tree;
79 child_iterator(tree_type * t, id_type
id) noexcept : m_tree(t), m_child_id(
id) {}
80 child_iterator& operator++ ()
RYML_NOEXCEPT { _RYML_ASSERT_VISIT_(m_tree->m_callbacks, m_child_id != NONE, m_tree, NONE); m_child_id = m_tree->next_sibling(m_child_id);
return *
this; }
81 NodeRefType operator* () const
RYML_NOEXCEPT {
return NodeRefType(m_tree, m_child_id); }
82 bool operator!= (child_iterator that)
const RYML_NOEXCEPT { _RYML_ASSERT_VISIT(m_tree == that.m_tree, m_tree, NONE);
return m_child_id != that.m_child_id; }
85template<
class NodeRefType>
88 using iterator = child_iterator<NodeRefType>;
89 using tree_type =
typename NodeRefType::tree_type;
92 children_view(tree_type *t, id_type b_, id_type e_) noexcept : tree(t), b(b_), e(e_) {}
93 C4_ALWAYS_INLINE iterator begin() const noexcept {
return {tree, b}; }
94 C4_ALWAYS_INLINE iterator end () const noexcept {
return {tree, e}; }
97template<
class ViewType,
class TreeType>
98static ViewType make_children_view(TreeType *C4_RESTRICT tree, id_type
id)
RYML_NOEXCEPT
100 return ViewType(tree, tree->get(
id)->m_first_child, NONE);
103template<
class ViewType,
class TreeType>
104static ViewType make_siblings_view(TreeType *C4_RESTRICT tree, id_type
id)
RYML_NOEXCEPT
106 NodeData
const *nd = tree->get(
id);
107 id_type first = (nd->m_parent !=
NONE) ? tree->get(nd->m_parent)->m_first_child :
NONE;
108 return ViewType(tree, first, NONE);
113template<
class NodeRefType,
class Visitor>
114RYML_DEPRECATED(
"") bool _visit(NodeRefType &node, Visitor fn, id_type indentation_level,
bool skip_root=false)
117 if( ! (node.is_root() && skip_root))
119 if(fn(node, indentation_level))
123 if(node.has_children())
125 for(auto ch : node.children())
127 if(_visit(ch, fn, indentation_level + increment, false))
136template<
class NodeRefType,
class Visitor>
137RYML_DEPRECATED(
"") bool _visit_stacked(NodeRefType &node, Visitor fn, id_type indentation_level,
bool skip_root=false)
140 if( ! (node.is_root() && skip_root))
142 if(fn(node, indentation_level))
148 if(node.has_children())
150 fn.push(node, indentation_level);
151 for(auto ch : node.children())
153 if(_visit_stacked(ch, fn, indentation_level + increment, false))
155 fn.pop(node, indentation_level);
159 fn.pop(node, indentation_level);
176template<
class Impl,
class ConstImpl>
181 #define tree_ ((ConstImpl const* C4_RESTRICT)this)->m_tree
182 #define id_ ((ConstImpl const* C4_RESTRICT)this)->m_id
183 #define tree__ ((Impl const* C4_RESTRICT)this)->m_tree
184 #define id__ ((Impl const* C4_RESTRICT)this)->m_id
185 #define assert_readable__() ((Impl const* C4_RESTRICT)this)->assert_readable_()
186 C4_SUPPRESS_WARNING_GCC_CLANG_WITH_PUSH(
"-Wcast-align")
213 C4_ALWAYS_INLINE
bool is_key_unfiltered() const noexcept { assert_readable__();
return tree_->is_key_unfiltered(id_); }
214 C4_ALWAYS_INLINE
bool is_val_unfiltered() const noexcept { assert_readable__();
return tree_->is_val_unfiltered(id_); }
244 RYML_DEPRECATED(
"use has_key_anchor()") bool
is_key_anchor() const noexcept { assert_readable__();
return tree_->has_key_anchor(id_); }
245 RYML_DEPRECATED(
"use has_val_anchor()") bool
is_val_hanchor() const noexcept { assert_readable__();
return tree_->has_val_anchor(id_); }
246 RYML_DEPRECATED(
"use has_anchor()") bool
is_anchor() const noexcept { assert_readable__();
return tree_->has_anchor(id_); }
247 RYML_DEPRECATED(
"use has_anchor() || is_ref()") bool
is_anchor_or_ref() const noexcept { assert_readable__();
return tree_->is_anchor_or_ref(id_); }
269 RYML_DEPRECATED(
"use one of .is_flow_ml{1,x,n}()")
303 C4_ALWAYS_INLINE
bool is_ancestor(ConstImpl
const& ancestor)
const RYML_NOEXCEPT { assert_readable__();
return tree_->is_ancestor(id_, ancestor.m_id); }
305 C4_ALWAYS_INLINE
bool has_child(ConstImpl
const& n)
const RYML_NOEXCEPT { assert_readable__();
return n.readable() ? tree_->has_child(id_, n.m_id) :
false; }
310 C4_ALWAYS_INLINE
bool has_sibling(ConstImpl
const& n)
const RYML_NOEXCEPT { assert_readable__();
return n.readable() ? tree_->has_sibling(id_, n.m_id) :
false; }
315 RYML_DEPRECATED(
"use has_other_siblings()") bool
has_siblings() const
RYML_NOEXCEPT { assert_readable__();
return tree_->has_siblings(id_); }
329 C4_ALWAYS_INLINE
id_type child_pos(ConstImpl
const& n)
const RYML_NOEXCEPT { assert_readable__(); _RYML_ASSERT_VISIT_(tree_->m_callbacks, n.readable(), n.tree(), n.id());
return tree_->child_pos(id_, n.m_id); }
330 C4_ALWAYS_INLINE
id_type sibling_pos(ConstImpl
const& n)
const RYML_NOEXCEPT { assert_readable__(); _RYML_ASSERT_VISIT_(tree_->callbacks(), n.readable(), n.tree(), n.id());
return tree_->child_pos(tree_->parent(id_), n.m_id); }
345 return tree_->location(parser, id_);
358 ConstImpl
const& operator>> (T &v)
const
361 if( !
read((ConstImpl
const&)*
this, &v))
362 _RYML_ERR_VISIT_(tree_->m_callbacks, tree_, id_,
"could not deserialize value");
363 return *((ConstImpl
const*)
this);
366 ConstImpl
const& operator>> (T
const& wrapper)
const
369 if( !
read((ConstImpl
const&)*
this, wrapper))
370 _RYML_ERR_VISIT_(tree_->m_callbacks, tree_, id_,
"could not deserialize value");
371 return *((ConstImpl
const*)
this);
378 ConstImpl
const& operator>> (
Key<T> v)
const
381 if( !
readkey((ConstImpl
const&)*
this, &v.
k))
382 _RYML_ERR_VISIT_(tree_->m_callbacks, tree_, id_,
"could not deserialize key");
383 return *((ConstImpl
const*)
this);
392 ConstImpl ch = ((ConstImpl
const*)
this)->find_child(name);
406 ConstImpl ch = ((ConstImpl
const*)
this)->find_child(name);
423 C4_SUPPRESS_WARNING_PUSH
424 C4_SUPPRESS_WARNING_GCC_CLANG(
"-Wdeprecated")
425 C4_SUPPRESS_WARNING_GCC_CLANG(
"-Wdeprecated-declarations")
426 C4_SUPPRESS_WARNING_MSVC(4996)
428 template<class Visitor>
429 RYML_DEPRECATED(
"")
bool visit(Visitor fn,
id_type indentation_level=0,
bool skip_root=true) const
RYML_NOEXCEPT
432 return detail::_visit(*(ConstImpl
const*)
this, fn, indentation_level, skip_root);
434 template <
class Visitor,
class U = Impl>
437 -> typename std ::enable_if<!std ::is_same<U, ConstImpl>::value,
bool>::type
440 return detail::_visit(*(Impl *)
this, fn, indentation_level, skip_root);
442 template<
class Visitor>
443 RYML_DEPRECATED(
"") bool visit_stacked(Visitor fn, id_type indentation_level=0,
bool skip_root=true) const
RYML_NOEXCEPT
446 return detail::_visit_stacked(*(ConstImpl
const*)
this, fn, indentation_level, skip_root);
448 template<
class Visitor,
class U=Impl>
449 RYML_DEPRECATED(
"") auto visit_stacked(Visitor fn, id_type indentation_level=0,
bool skip_root=true)
RYML_NOEXCEPT
450 -> typename std ::enable_if<!std ::is_same<U, ConstImpl>::value,
bool>::type
453 return detail::_visit_stacked(*(Impl*)
this, fn, indentation_level, skip_root);
456 C4_SUPPRESS_WARNING_POP
458 #undef assert_readable__
464 C4_SUPPRESS_WARNING_GCC_CLANG_POP
538 constexpr static C4_ALWAYS_INLINE
bool is_seed() noexcept {
return false; }
544 void assert_readable_()
const
546 _RYML_ASSERT_BASIC(m_tree !=
nullptr);
547 _RYML_ASSERT_VISIT_(m_tree->m_callbacks, m_id !=
NONE && (m_id < m_tree->capacity()), m_tree, m_id);
550 void check_readable_()
const
552 if(C4_UNLIKELY(!m_tree))
553 _RYML_ERR_BASIC(
"invalid node");
554 if(C4_UNLIKELY(!m_tree || m_id == NONE || (m_id > m_tree->capacity())))
555 _RYML_ERR_VISIT_(m_tree->m_callbacks, m_tree, m_id,
"invalid node");
696 _RYML_CHECK_VISIT_(
m_tree->m_callbacks, (pos >= 0 && pos < cap),
m_tree,
m_id);
710 using iterator = detail::child_iterator<ConstNodeRef>;
734 RYML_DEPRECATED(
"use one of readable(), is_seed() or !invalid()") bool valid() const noexcept {
return m_tree !=
nullptr && m_id !=
NONE; }
735 RYML_DEPRECATED(
"use invalid()") bool operator== (std::nullptr_t) const noexcept {
return m_tree ==
nullptr || m_id == NONE; }
736 RYML_DEPRECATED(
"use !invalid()") bool operator!= (std::nullptr_t) const noexcept {
return !(m_tree ==
nullptr || m_id == NONE); }
737 RYML_DEPRECATED(
"use (this->val() == s)") bool operator== (csubstr s) const
RYML_NOEXCEPT { _RYML_ASSERT_BASIC(m_tree); _RYML_ASSERT_VISIT_(m_tree->m_callbacks, m_id != NONE, m_tree, NONE);
return m_tree->val(m_id) == s; }
738 RYML_DEPRECATED(
"use (this->val() != s)") bool operator!= (csubstr s) const
RYML_NOEXCEPT { _RYML_ASSERT_BASIC(m_tree); _RYML_ASSERT_VISIT_(m_tree->m_callbacks, m_id != NONE, m_tree, NONE);
return m_tree->val(m_id) != s; }
795 Tree *C4_RESTRICT m_tree;
818 NodeRef() noexcept : m_tree(
nullptr), m_id(
NONE), m_seed() { _clear_seed(); }
819 NodeRef(
Tree &t) noexcept : m_tree(&t), m_id(t .root_id()), m_seed() { _clear_seed(); }
820 NodeRef(
Tree *t) noexcept : m_tree(t ), m_id(t->root_id()), m_seed() { _clear_seed(); }
822 NodeRef(
Tree *t,
id_type id,
id_type seed_pos) noexcept : m_tree(t), m_id(
id), m_seed() { m_seed.str =
nullptr; m_seed.len = (size_t)seed_pos; }
824 NodeRef(std::nullptr_t) noexcept : m_tree(
nullptr), m_id(
NONE), m_seed() {}
830 void _clear_seed() noexcept { m_seed.
str =
nullptr; m_seed.
len =
npos; }
851 bool invalid() const noexcept {
return m_tree ==
nullptr || m_id ==
NONE; }
853 bool is_seed() const noexcept {
return (m_tree !=
nullptr && m_id !=
NONE) && (m_seed.str !=
nullptr || m_seed.len != (size_t)
NONE); }
855 bool readable() const noexcept {
return (m_tree !=
nullptr && m_id !=
NONE) && (m_seed.str ==
nullptr && m_seed.len == (size_t)
NONE); }
861 C4_ALWAYS_INLINE
bool valid_id_() const noexcept {
return m_id !=
NONE && m_id < m_tree->capacity(); }
862 C4_ALWAYS_INLINE
bool has_seed_() const noexcept {
return m_seed.
str !=
nullptr || m_seed.
len != (size_t)NONE; }
864 void assert_readable_()
const
866 _RYML_ASSERT_BASIC(m_tree !=
nullptr);
867 _RYML_ASSERT_VISIT_(m_tree->m_callbacks, valid_id_() && !has_seed_(), m_tree, m_id);
870 void check_readable_()
const
872 if(C4_UNLIKELY(!m_tree))
873 _RYML_ERR_BASIC(
"invalid node");
874 if(C4_UNLIKELY((m_id == NONE || (m_id > m_tree->capacity())) ||
875 (m_seed.
str !=
nullptr || m_seed.
len != (
size_t)NONE)))
876 _RYML_ERR_VISIT_(m_tree->m_callbacks, m_tree, m_id,
"invalid node");
886 if(m_tree == that.m_tree && m_id == that.m_id)
893 return (m_seed.len == that.m_seed.
len)
894 && (m_seed.str == that.m_seed.
str
895 || m_seed == that.m_seed);
914 C4_ALWAYS_INLINE
Tree *
tree() noexcept {
return m_tree; }
915 C4_ALWAYS_INLINE
Tree const*
tree() const noexcept {
return m_tree; }
917 C4_ALWAYS_INLINE
id_type id() const noexcept {
return m_id; }
932 _RYML_ASSERT_BASIC(m_tree !=
nullptr);
933 _RYML_ASSERT_VISIT_(m_tree->m_callbacks, m_id !=
NONE && m_id < m_tree->capacity(), m_tree, m_id);
936 m_id = m_tree->append_child(m_id);
937 m_tree->set_key(m_id, m_seed);
938 m_seed.str =
nullptr;
939 m_seed.len = (size_t)
NONE;
941 else if(m_seed.len != (
size_t)
NONE)
943 _RYML_ASSERT_VISIT_(m_tree->m_callbacks, (
size_t)m_tree->num_children(m_id) == m_seed.len, m_tree, m_id);
944 m_id = m_tree->append_child(m_id);
945 m_seed.str =
nullptr;
946 m_seed.len = (size_t)
NONE;
988 m_tree->remove_children(m_id);
989 m_tree->_clear(m_id);
995 m_tree->_clear_key(m_id);
1001 m_tree->_clear_val(m_id);
1007 m_tree->remove_children(m_id);
1013 m_tree->clear_style(m_id, recurse);
1022 m_tree->set_style_conditionally(m_id, type_mask, rem_style_flags, add_style_flags, recurse);
1036 _RYML_ASSERT_BASIC(m_tree);
1037 return m_tree->to_arena(s);
1044 csubstr s = m_tree->to_arena(k);
1045 m_tree->set_key(m_id, s);
1051 m_tree->set_key(m_id,
csubstr{});
1059 csubstr s = m_tree->to_arena(v);
1060 m_tree->set_val(m_id, s);
1066 m_tree->set_val(m_id,
csubstr{});
1077 _RYML_ASSERT_VISIT_(m_tree->m_callbacks,
val() == s, m_tree, m_id);
1118 C4_ALWAYS_INLINE ConstNodeRef
parent() const
RYML_NOEXCEPT { assert_readable_();
return {m_tree, m_tree->parent(m_id)}; }
1124 C4_ALWAYS_INLINE ConstNodeRef
last_child() const
RYML_NOEXCEPT { assert_readable_();
return {m_tree, m_tree->last_child (m_id)}; }
1210 id_type ch = m_tree->child(m_id, pos);
1227 _RYML_ASSERT_VISIT_(m_tree->m_callbacks, ch !=
NONE, m_tree, m_id);
1228 return {m_tree, ch};
1243 id_type ch = m_tree->child(m_id, pos);
1244 _RYML_ASSERT_VISIT_(m_tree->m_callbacks, ch !=
NONE, m_tree, m_id);
1245 return {m_tree, ch};
1289 _RYML_CHECK_BASIC(m_tree !=
nullptr);
1290 _RYML_CHECK_VISIT_(m_tree->m_callbacks, (m_id >= 0 && m_id < m_tree->capacity()), m_tree, m_id);
1291 _RYML_CHECK_VISIT_(m_tree->m_callbacks,
readable(), m_tree, m_id);
1292 _RYML_CHECK_VISIT_(m_tree->m_callbacks, m_tree->is_map(m_id), m_tree, m_id);
1324 _RYML_CHECK_BASIC(m_tree !=
nullptr);
1325 const id_type cap = m_tree->capacity();
1326 _RYML_CHECK_VISIT_(m_tree->m_callbacks, (m_id >= 0 && m_id < cap), m_tree, m_id);
1327 _RYML_CHECK_VISIT_(m_tree->m_callbacks, (pos >= 0 && pos < cap), m_tree, m_id);
1328 _RYML_CHECK_VISIT_(m_tree->m_callbacks,
readable(), m_tree, m_id);
1329 _RYML_CHECK_VISIT_(m_tree->m_callbacks, m_tree->is_container(m_id), m_tree, m_id);
1330 id_type ch = m_tree->child(m_id, pos);
1345 _RYML_CHECK_BASIC(m_tree !=
nullptr);
1346 _RYML_CHECK_VISIT_(m_tree->m_callbacks, (m_id >= 0 && m_id < m_tree->capacity()), m_tree, m_id);
1347 _RYML_CHECK_VISIT_(m_tree->m_callbacks,
readable(), m_tree, m_id);
1348 _RYML_CHECK_VISIT_(m_tree->m_callbacks, m_tree->is_map(m_id), m_tree, m_id);
1350 _RYML_CHECK_VISIT_(m_tree->m_callbacks, ch !=
NONE, m_tree, m_id);
1351 return {m_tree, ch};
1365 _RYML_CHECK_BASIC(m_tree !=
nullptr);
1366 const id_type cap = m_tree->capacity();
1367 _RYML_CHECK_VISIT_(m_tree->m_callbacks, (m_id >= 0 && m_id < cap), m_tree, m_id);
1368 _RYML_CHECK_VISIT_(m_tree->m_callbacks, (pos >= 0 && pos < cap), m_tree, m_id);
1369 _RYML_CHECK_VISIT_(m_tree->m_callbacks,
readable(), m_tree, m_id);
1370 _RYML_CHECK_VISIT_(m_tree->m_callbacks, m_tree->is_container(m_id), m_tree, m_id);
1371 const id_type ch = m_tree->child(m_id, pos);
1372 _RYML_CHECK_VISIT_(m_tree->m_callbacks, ch !=
NONE, m_tree, m_id);
1373 return {m_tree, ch};
1386 _RYML_ASSERT_VISIT_(m_tree->m_callbacks, after.m_tree == m_tree, m_tree, m_id);
1387 NodeRef r(m_tree, m_tree->insert_child(m_id, after.m_id));
1394 NodeRef r(m_tree, m_tree->insert_child(m_id,
NONE));
1401 NodeRef r(m_tree, m_tree->append_child(m_id));
1408 _RYML_ASSERT_VISIT_(m_tree->m_callbacks, after.
m_tree == m_tree, m_tree, m_id);
1409 NodeRef r(m_tree, m_tree->insert_sibling(m_id, after.
m_id));
1416 NodeRef r(m_tree, m_tree->prepend_sibling(m_id));
1423 NodeRef r(m_tree, m_tree->append_sibling(m_id));
1432 _RYML_ASSERT_VISIT_(m_tree->m_callbacks,
has_child(
child), m_tree, m_id);
1433 _RYML_ASSERT_VISIT_(m_tree->m_callbacks,
child.parent().id() ==
id(), m_tree, m_id);
1434 m_tree->remove(
child.id());
1442 _RYML_ASSERT_VISIT_(m_tree->m_callbacks, pos >= 0 && pos <
num_children(), m_tree, m_id);
1444 _RYML_ASSERT_VISIT_(m_tree->m_callbacks,
child !=
NONE, m_tree, m_id);
1445 m_tree->remove(
child);
1453 _RYML_ASSERT_VISIT_(m_tree->m_callbacks,
child !=
NONE, m_tree, m_id);
1454 m_tree->remove(
child);
1466 parent.assert_readable_();
1467 _RYML_ASSERT_VISIT_(m_tree->m_callbacks,
parent.m_tree == after.
m_tree || after.
m_id ==
NONE, m_tree, m_id);
1468 if(
parent.m_tree == m_tree)
1487 parent.assert_readable_();
1488 _RYML_ASSERT_VISIT_(m_tree->m_callbacks,
parent.m_tree == after.
m_tree || after.
m_id ==
NONE, m_tree, m_id);
1497 parent.assert_readable_();
1498 _RYML_ASSERT_VISIT_(m_tree->m_callbacks,
parent.m_tree == after.
m_tree || after.
m_id ==
NONE, m_tree, m_id);
1544 C4_SUPPRESS_WARNING_PUSH
1545 C4_SUPPRESS_WARNING_GCC_CLANG(
"-Wdeprecated")
1546 C4_SUPPRESS_WARNING_GCC_CLANG(
"-Wdeprecated-declarations")
1547 C4_SUPPRESS_WARNING_MSVC(4996)
1549 RYML_DEPRECATED(
"use one of readable(), is_seed() or !invalid()") inline
bool valid()
const {
return m_tree !=
nullptr && m_id !=
NONE; }
1550 RYML_DEPRECATED(
"use !readable()") bool operator== (std::nullptr_t)
const {
return m_tree ==
nullptr || m_id == NONE || is_seed(); }
1551 RYML_DEPRECATED(
"use readable()") bool operator!= (std::nullptr_t)
const {
return !(m_tree ==
nullptr || m_id == NONE || is_seed()); }
1552 RYML_DEPRECATED(
"use `this->val() == s`") bool operator== (csubstr s)
const { assert_readable_(); _RYML_ASSERT_VISIT_(m_tree->m_callbacks, has_val(), m_tree, m_id);
return m_tree->val(m_id) == s; }
1553 RYML_DEPRECATED(
"use `this->val() != s`") bool operator!= (csubstr s)
const { assert_readable_(); _RYML_ASSERT_VISIT_(m_tree->m_callbacks, has_val(), m_tree, m_id);
return m_tree->val(m_id) != s; }
1555 RYML_DEPRECATED(
"") void operator= (NodeType_e t)
1558 m_tree->_add_flags(m_id, t);
1561 RYML_DEPRECATED(
"") void operator|= (NodeType_e t)
1564 m_tree->_add_flags(m_id, t);
1567 RYML_DEPRECATED(
"use .set_val()") NodeRef& operator= (csubstr v)
1574 RYML_DEPRECATED(
"use .set_val()") NodeRef& operator= (const
char (&v)[N])
1582 RYML_DEPRECATED(
"use .set_val()") void operator= (std::nullptr_t)
1589 RYML_DEPRECATED(
"use .set_key()") NodeRef& operator= (Key<T> const& C4_RESTRICT v)
1595 RYML_DEPRECATED(
"") void operator= (NodeInit const& v)
1601 RYML_DEPRECATED(
"") void _apply(csubstr v)
1603 m_tree->set_val(m_id, v);
1606 RYML_DEPRECATED(
"") void _apply(NodeScalar const& v)
1608 m_tree->_set_val(m_id, v);
1611 RYML_DEPRECATED(
"") void operator= (NodeScalar const& v)
1617 RYML_DEPRECATED(
"") void _apply(NodeInit const& i)
1619 m_tree->_set(m_id, i);
1622 RYML_DEPRECATED(
"") NodeRef insert_child(NodeInit const& i, NodeRef after)
1625 _RYML_ASSERT_VISIT_(m_tree->m_callbacks, after.m_tree == m_tree, m_tree, m_id);
1626 NodeRef r(m_tree, m_tree->insert_child(m_id, after.m_id));
1631 RYML_DEPRECATED(
"") NodeRef prepend_child(NodeInit const& i)
1634 NodeRef r(m_tree, m_tree->insert_child(m_id, NONE));
1639 RYML_DEPRECATED(
"") NodeRef append_child(NodeInit const& i)
1642 NodeRef r(m_tree, m_tree->append_child(m_id));
1647 RYML_DEPRECATED(
"") NodeRef insert_sibling(NodeInit const& i, ConstNodeRef const& after)
1650 _RYML_ASSERT_VISIT_(m_tree->m_callbacks, after.m_tree == m_tree, m_tree, m_id);
1651 NodeRef r(m_tree, m_tree->insert_sibling(m_id, after.m_id));
1656 RYML_DEPRECATED(
"") NodeRef prepend_sibling(NodeInit const& i)
1659 NodeRef r(m_tree, m_tree->prepend_sibling(m_id));
1664 RYML_DEPRECATED(
"") NodeRef append_sibling(NodeInit const& i)
1667 NodeRef r(m_tree, m_tree->append_sibling(m_id));
1672 RYML_DEPRECATED(
"") void move(ConstNodeRef const& after)
1675 m_tree->move(m_id, after.m_id);
1678 RYML_DEPRECATED(
"") NodeRef duplicate(ConstNodeRef const& after)
const
1681 _RYML_ASSERT_VISIT_(m_tree->m_callbacks, m_tree == after.m_tree || after.m_id == NONE, m_tree, m_id);
1682 id_type dup = m_tree->duplicate(m_id, m_tree->parent(m_id), after.m_id);
1683 NodeRef r(m_tree, dup);
1687 C4_SUPPRESS_WARNING_POP
1741 return read(n.m_tree, n.m_id, v);
1746 return read(n.m_tree, n.m_id, wrapper);
1752 return read(n.tree(), n.id(), v);
1755C4_ALWAYS_INLINE
bool read(
NodeRef const& C4_RESTRICT n, T
const& wrapper)
1757 return read(n.tree(), n.id(), wrapper);
1763 return readkey(n.m_tree, n.m_id, v);
1768 return readkey(n.m_tree, n.m_id, wrapper);
1774 return readkey(n.tree(), n.id(), v);
1779 return readkey(n.tree(), n.id(), wrapper);
1792C4_SUPPRESS_WARNING_POP
Holds a pointer to an existing tree, and a node id.
detail::children_view< ConstNodeRef > children_view
NodeData const * get() const RYML_NOEXCEPT
Forward to Tree::type().
ConstNodeRef parent() const RYML_NOEXCEPT
Forward to Tree::parent().
const_iterator cend() const RYML_NOEXCEPT
get an iterator to after the last child
const_iterator cbegin() const RYML_NOEXCEPT
get an iterator to the first child
const_children_view cchildren() const RYML_NOEXCEPT
get an iterable view over children
ConstNodeRef child(id_type pos) const RYML_NOEXCEPT
Forward to Tree::child().
ConstNodeRef first_sibling() const RYML_NOEXCEPT
Forward to Tree::first_sibling().
ConstNodeRef(ConstNodeRef const &) noexcept=default
id_type id() const noexcept
ConstNodeRef ancestor_doc() const RYML_NOEXCEPT
Forward to Tree::ancestor_doc().
ConstNodeRef first_child() const RYML_NOEXCEPT
Forward to Tree::first_child().
ConstNodeRef find_child(csubstr name) const RYML_NOEXCEPT
Forward to Tree::find_child().
ConstNodeRef last_child() const RYML_NOEXCEPT
Forward to Tree::last_child().
ConstNodeRef(ConstNodeRef &&) noexcept=default
ConstNodeRef(Tree const *t) noexcept
detail::child_iterator< ConstNodeRef > iterator
ConstNodeRef(std::nullptr_t) noexcept
ConstNodeRef at(id_type pos) const
Get a child by position, with error checking; complexity is O(pos).
bool invalid() const noexcept
ConstNodeRef find_sibling(csubstr name) const RYML_NOEXCEPT
Forward to Tree::find_sibling().
const_iterator begin() const RYML_NOEXCEPT
get an iterator to the first child
detail::child_iterator< ConstNodeRef > const_iterator
const_children_view children() const RYML_NOEXCEPT
get an iterable view over children
ConstNodeRef last_sibling() const RYML_NOEXCEPT
Forward to Tree::last_sibling().
ConstNodeRef at(csubstr key) const
Get a child by name, with error checking; complexity is O(num_children).
ConstNodeRef(Tree const *t, id_type id) noexcept
ConstNodeRef(Tree const &t) noexcept
Tree const * tree() const noexcept
detail::children_view< ConstNodeRef > const_children_view
ConstNodeRef next_sibling() const RYML_NOEXCEPT
Forward to Tree::next_sibling().
ConstNodeRef doc(id_type i) const RYML_NOEXCEPT
Forward to Tree::doc().
static constexpr bool is_seed() noexcept
because a ConstNodeRef cannot be used to write to the tree, it can never be a seed.
ConstNodeRef prev_sibling() const RYML_NOEXCEPT
Forward to Tree::prev_sibling().
ConstNodeRef sibling(id_type pos) const RYML_NOEXCEPT
Forward to Tree::sibling().
const_children_view siblings() const RYML_NOEXCEPT
const_iterator end() const RYML_NOEXCEPT
get an iterator to after the last child
bool readable() const noexcept
because a ConstNodeRef cannot be used to write to the tree, readable() has the same meaning as !...
const_children_view csiblings() const RYML_NOEXCEPT
get an iterable view over all siblings (including the calling node)
A reference to a node in an existing yaml tree, offering a more convenient API than the index-based A...
void set_val_anchor(csubstr val_anchor)
NodeRef parent() RYML_NOEXCEPT
Forward to Tree::parent().
const_iterator begin() const RYML_NOEXCEPT
get an iterator to the first child
void set_key_style(NodeType_e style)
void set_style_conditionally(NodeType type_mask, NodeType rem_style_flags, NodeType add_style_flags, bool recurse=false)
detail::children_view< NodeRef > children_view
ConstNodeRef prev_sibling() const RYML_NOEXCEPT
Forward to Tree::prev_sibling().
NodeRef last_sibling() RYML_NOEXCEPT
Forward to Tree::last_sibling().
NodeRef prev_sibling() RYML_NOEXCEPT
Forward to Tree::prev_sibling().
detail::child_iterator< NodeRef > iterator
ConstNodeRef find_sibling(csubstr name) const RYML_NOEXCEPT
Forward to Tree::find_sibling().
detail::RoNodeMethods< NodeRef, ConstNodeRef > base_type
NodeRef insert_sibling(ConstNodeRef const &after)
NodeRef child(id_type pos) RYML_NOEXCEPT
Forward to Tree::child().
void set_val(csubstr val, NodeType more_flags)
iterator begin() RYML_NOEXCEPT
get a mutable iterator to the first child.
ConstNodeRef last_child() const RYML_NOEXCEPT
Forward to Tree::last_child().
NodeRef(Tree *t, id_type id, csubstr seed_key) noexcept
detail::child_iterator< ConstNodeRef > const_iterator
void set_val_tag(csubstr val_tag)
NodeRef next_sibling() RYML_NOEXCEPT
Forward to Tree::next_sibling().
void clear_style(bool recurse=false)
Tree const * tree() const noexcept
NodeRef(NodeRef &&) noexcept=default
const_iterator cbegin() const RYML_NOEXCEPT
get an iterator to the first child
NodeRef(Tree *t, id_type id, id_type seed_pos) noexcept
NodeRef at(id_type pos)
Find child by position; complexity is O(pos).
NodeRef at(csubstr key)
Find child by key; complexity is O(num_children).
csubstr to_arena(T const &s)
serialize a variable to the arena
children_view children() RYML_NOEXCEPT
get an iterable view over children
NodeRef insert_child(NodeRef after)
void set_val(csubstr val)
NodeRef prepend_sibling()
size_t set_key_serialized(T const &k)
ConstNodeRef first_child() const RYML_NOEXCEPT
Forward to Tree::first_child().
void set_val_style(NodeType_e style)
NodeRef(Tree *t, id_type id) noexcept
void set_map(NodeType more_flags)
ConstNodeRef last_sibling() const RYML_NOEXCEPT
Forward to Tree::last_sibling().
ConstNodeRef at(csubstr key) const
Get a child by name, with error checking; complexity is O(num_children).
ConstNodeRef find_child(csubstr name) const RYML_NOEXCEPT
Forward to Tree::find_child().
ConstNodeRef at(id_type pos) const
Get a child by position, with error checking; complexity is O(pos).
NodeRef ancestor_doc() RYML_NOEXCEPT
Forward to Tree::ancestor_doc().
ConstNodeRef first_sibling() const RYML_NOEXCEPT
Forward to Tree::first_sibling().
const_iterator end() const RYML_NOEXCEPT
get an iterator to after the last child
const_children_view children() const RYML_NOEXCEPT
get an iterable view over children
void set_key(csubstr key, NodeType more_flags)
NodeData * get() RYML_NOEXCEPT
Forward to Tree::type().
children_view siblings() RYML_NOEXCEPT
NodeData const * get() const RYML_NOEXCEPT
Forward to Tree::type().
NodeRef last_child() RYML_NOEXCEPT
Forward to Tree::last_child().
size_t set_val_serialized(std::nullptr_t)
id_type id() const noexcept
ConstNodeRef parent() const RYML_NOEXCEPT
Forward to Tree::parent().
bool invalid() const noexcept
true if the object is not referring to any existing or seed node.
detail::children_view< ConstNodeRef > const_children_view
ConstNodeRef child(id_type pos) const RYML_NOEXCEPT
Forward to Tree::child().
NodeRef doc(id_type i) RYML_NOEXCEPT
Forward to Tree::doc().
void move(NodeRef const &parent, ConstNodeRef const &after)
move the node to a different parent (which may belong to a different tree), placing it after after.
void set_container_style(NodeType_e style)
void set_seq(NodeType more_flags)
bool readable() const noexcept
true if the object is not invalid and not in seed state.
ConstNodeRef sibling(id_type pos) const RYML_NOEXCEPT
Forward to Tree::sibling().
NodeRef sibling(id_type pos) RYML_NOEXCEPT
Forward to Tree::sibling().
NodeRef(Tree *t) noexcept
ConstNodeRef ancestor_doc() const RYML_NOEXCEPT
Forward to Tree::ancestor_doc().
NodeRef first_sibling() RYML_NOEXCEPT
Forward to Tree::first_sibling().
size_t set_val_serialized(T const &v)
void create()
if this node is in seed state, create the node in the tree
NodeRef duplicate(NodeRef const &parent, ConstNodeRef const &after) const
duplicate the current node somewhere into a different parent (possibly from a different tree),...
ConstNodeRef doc(id_type i) const RYML_NOEXCEPT
Forward to Tree::doc().
const_iterator cend() const RYML_NOEXCEPT
get an iterator to after the last child
NodeRef duplicate_children(NodeRef const &parent, ConstNodeRef const &after) const
void remove_child(csubstr key)
remove a child by name
NodeRef(NodeRef const &) noexcept=default
void set_key_tag(csubstr key_tag)
size_t set_key_serialized(std::nullptr_t)
ConstNodeRef next_sibling() const RYML_NOEXCEPT
Forward to Tree::next_sibling().
const_children_view siblings() const RYML_NOEXCEPT
get an iterable view over all siblings (including the calling node)
NodeRef(std::nullptr_t) noexcept
void set_key_ref(csubstr key_ref)
NodeRef find_sibling(csubstr name) RYML_NOEXCEPT
Forward to Tree::find_sibling().
void remove_child(NodeRef &child)
NodeRef first_child() RYML_NOEXCEPT
Forward to Tree::first_child().
void set_key_anchor(csubstr key_anchor)
const_children_view cchildren() const RYML_NOEXCEPT
get an iterable view over children
void change_type(NodeType t)
NodeRef(Tree &t) noexcept
iterator end() RYML_NOEXCEPT
get an iterator to after the last child.
bool is_seed() const noexcept
true if the object is not invalid and in seed state.
void set_key(csubstr key)
void set_val_ref(csubstr val_ref)
NodeRef find_child(csubstr name) RYML_NOEXCEPT
Forward to Tree::find_child().
void remove_child(id_type pos)
remove the nth child of this node
const_children_view csiblings() const RYML_NOEXCEPT
get an iterable view over all siblings (including the calling node)
#define RYML_NOEXCEPT
Conditionally expands to noexcept when RYML_USE_ASSERT is 0 and is empty otherwise.
OStream & operator<<(OStream &stream, Tree const &tree)
emit YAML to an STL-like ostream
NodeType_e
a bit mask for marking node types and styles
ParseEngine< EventHandlerTree > Parser
This is the main ryml parser, where the parser events are handled to create a ryml tree (see Event Ha...
void write(ryml::NodeRef *n, my_seq_type< T > const &seq)
bool read(ryml::ConstNodeRef const &n, my_seq_type< T > *seq)
bool readkey(ConstNodeRef const &n, T *v)
void write(NodeRef *n, T const &v)
bool operator!=(const char c, basic_substring< C > const that) noexcept
bool operator==(const char c, basic_substring< C > const that) noexcept
basic_substring< const char > csubstr
an immutable string view
@ npos
a null string position
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...
(Undefined by default) Use shorter error message from checks/asserts: do not show the check condition...
size_t len
the length of the substring
void assign(C(&s_)[N]) noexcept
Assign from an array.
C * str
a restricted pointer to the first character of the substring
holds a source or yaml file position, for example when an error is detected; See also location_format...
contains the data for each YAML node.
a node scalar is a csubstr, which may be tagged and anchored.
wraps a NodeType_e element with some syntactic sugar and predicates
a CRTP base providing read-only methods for ConstNodeRef and NodeRef
bool type_has_none(NodeType_e bits) const RYML_NOEXCEPT
Forward to Tree::type_has_none().
bool is_key_anchor() const noexcept
id_type depth_asc() const RYML_NOEXCEPT
bool get_if(csubstr name, T *var) const
look for a child by name, if it exists assign to var.
id_type depth_desc() const RYML_NOEXCEPT
O(log(num_nodes)).
bool has_anchor() const RYML_NOEXCEPT
Forward to Tree::has_anchor().
NodeScalar const & valsc() const RYML_NOEXCEPT
Forward to Tree::valsc().
bool is_flow_ml() const RYML_NOEXCEPT
bool is_val() const RYML_NOEXCEPT
Forward to Tree::is_val().
bool is_key_styled() const RYML_NOEXCEPT
Forward to Tree::is_key_styled().
bool is_root() const RYML_NOEXCEPT
Forward to Tree::is_root().
csubstr key_anchor() const RYML_NOEXCEPT
Forward to Tree::key_anchor().
bool has_val_anchor() const RYML_NOEXCEPT
Forward to Tree::has_val_anchor().
bool has_siblings() const RYML_NOEXCEPT
bool is_key_plain() const RYML_NOEXCEPT
Forward to Tree::is_key_plain().
bool is_key_quoted() const RYML_NOEXCEPT
Forward to Tree::is_key_quoted().
bool is_stream() const RYML_NOEXCEPT
Forward to Tree::is_stream().
NodeType type() const RYML_NOEXCEPT
Forward to Tree::type().
bool empty() const RYML_NOEXCEPT
Forward to Tree::empty().
bool has_key_anchor() const RYML_NOEXCEPT
Forward to Tree::has_key_anchor().
bool is_key_unfiltered() const noexcept
Forward to Tree::is_key_unfiltered().
id_type sibling_pos(ConstImpl const &n) const RYML_NOEXCEPT
O(num_siblings).
bool is_key_literal() const RYML_NOEXCEPT
Forward to Tree::is_key_literal().
csubstr key_ref() const RYML_NOEXCEPT
Forward to Tree::key_ref().
bool has_child(ConstImpl const &n) const RYML_NOEXCEPT
Forward to Tree::has_child().
bool is_quoted() const RYML_NOEXCEPT
Forward to Tree::is_quoted().
bool parent_is_map() const RYML_NOEXCEPT
Forward to Tree::parent_is_map().
bool has_child(csubstr name) const RYML_NOEXCEPT
Forward to Tree::has_child().
bool get_if(csubstr name, T *var, T const &fallback) const
look for a child by name, if it exists assign to var, otherwise default to fallback.
bool is_map() const RYML_NOEXCEPT
Forward to Tree::is_map().
bool is_flow_ml1() const RYML_NOEXCEPT
Forward to Tree::is_flow_ml1().
bool type_has_any(NodeType_e bits) const RYML_NOEXCEPT
Forward to Tree::type_has_any().
NodeScalar const & keysc() const RYML_NOEXCEPT
Forward to Tree::keysc().
bool is_container() const RYML_NOEXCEPT
Forward to Tree::is_container().
id_type num_siblings() const RYML_NOEXCEPT
O(num_children).
bool has_key() const RYML_NOEXCEPT
Forward to Tree::has_key().
csubstr key_tag() const RYML_NOEXCEPT
Forward to Tree::key_tag().
csubstr val_ref() const RYML_NOEXCEPT
Forward to Tree::val_ref().
csubstr key() const RYML_NOEXCEPT
Forward to Tree::key().
bool has_sibling(csubstr name) const RYML_NOEXCEPT
Forward to Tree::has_sibling().
NodeType key_style() const RYML_NOEXCEPT
Forward to Tree::key_style().
bool has_key_tag() const RYML_NOEXCEPT
Forward to Tree::has_key_tag().
bool is_anchor() const noexcept
csubstr val_tag() const RYML_NOEXCEPT
Forward to Tree::val_tag().
bool is_ancestor(ConstImpl const &ancestor) const RYML_NOEXCEPT
Forward to Tree::is_ancestor() Node must be readable.
bool is_anchor_or_ref() const noexcept
csubstr val_anchor() const RYML_NOEXCEPT
Forward to Tree::val_anchor().
bool has_parent() const RYML_NOEXCEPT
Forward to Tree::has_parent() Node must be readable.
bool is_val_squo() const RYML_NOEXCEPT
Forward to Tree::is_val_squo().
bool is_val_ref() const RYML_NOEXCEPT
Forward to Tree::is_val_ref().
bool has_other_siblings() const RYML_NOEXCEPT
Forward to Tree::has_other_siblings().
bool has_flow_space() const RYML_NOEXCEPT
Forward to Tree::has_flow_space().
bool is_val_styled() const RYML_NOEXCEPT
Forward to Tree::is_val_styled().
bool val_is_null() const RYML_NOEXCEPT
Forward to Tree::val_is_null().
bool has_sibling(id_type node) const RYML_NOEXCEPT
Forward to Tree::has_sibling().
id_type child_pos(ConstImpl const &n) const RYML_NOEXCEPT
O(num_children).
bool is_container_styled() const RYML_NOEXCEPT
Forward to Tree::is_container_styled().
csubstr val() const RYML_NOEXCEPT
Forward to Tree::val().
bool type_has_all(NodeType_e bits) const RYML_NOEXCEPT
Forward to Tree::type_has_all().
bool is_key_ref() const RYML_NOEXCEPT
Forward to Tree::is_key_ref().
bool key_is_null() const RYML_NOEXCEPT
Forward to Tree::key_is_null().
NodeType val_style() const RYML_NOEXCEPT
Forward to Tree::val_style().
bool parent_is_seq() const RYML_NOEXCEPT
Forward to Tree::parent_is_seq().
bool is_doc() const RYML_NOEXCEPT
Forward to Tree::is_doc().
bool is_key_dquo() const RYML_NOEXCEPT
Forward to Tree::is_key_dquo().
id_type num_children() const RYML_NOEXCEPT
O(num_children).
bool is_val_unfiltered() const noexcept
Forward to Tree::is_val_unfiltered().
bool is_flow_mlx() const RYML_NOEXCEPT
Forward to Tree::is_flow_mlx().
bool is_flow_sl() const RYML_NOEXCEPT
Forward to Tree::is_flow_sl().
bool is_flow() const RYML_NOEXCEPT
Forward to Tree::is_flow().
bool is_block() const RYML_NOEXCEPT
Forward to Tree::is_block().
bool is_key_folded() const RYML_NOEXCEPT
Forward to Tree::is_key_folded().
Location location(Parser const &parser) const
bool is_val_plain() const RYML_NOEXCEPT
Forward to Tree::is_val_plain().
bool is_seq() const RYML_NOEXCEPT
Forward to Tree::is_seq().
bool is_val_folded() const RYML_NOEXCEPT
Forward to Tree::is_val_folded().
bool has_children() const RYML_NOEXCEPT
Forward to Tree::has_children().
bool is_val_quoted() const RYML_NOEXCEPT
Forward to Tree::is_val_quoted().
bool is_val_literal() const RYML_NOEXCEPT
Forward to Tree::is_val_literal().
bool has_child(id_type node) const RYML_NOEXCEPT
Forward to Tree::has_child().
bool is_key_squo() const RYML_NOEXCEPT
Forward to Tree::is_key_squo().
bool is_flow_mln() const RYML_NOEXCEPT
Forward to Tree::is_flow_mln().
const char * type_str() const RYML_NOEXCEPT
Forward to Tree::type_str().
bool is_val_hanchor() const noexcept
bool has_val() const RYML_NOEXCEPT
Forward to Tree::has_val().
bool has_sibling(ConstImpl const &n) const RYML_NOEXCEPT
Forward to Tree::has_sibling().
bool is_keyval() const RYML_NOEXCEPT
Forward to Tree::is_keyval().
bool has_val_tag() const RYML_NOEXCEPT
Forward to Tree::has_val_tag().
id_type num_other_siblings() const RYML_NOEXCEPT
O(num_siblings).
bool is_val_dquo() const RYML_NOEXCEPT
Forward to Tree::is_val_dquo().
bool is_ref() const RYML_NOEXCEPT
Forward to Tree::is_ref().