1 #ifndef _C4_YML_NODE_HPP_
2 #define _C4_YML_NODE_HPP_
12 # pragma clang diagnostic push
13 # pragma clang diagnostic ignored "-Wtype-limits"
14 # pragma clang diagnostic ignored "-Wold-style-cast"
15 #elif defined(__GNUC__)
16 # pragma GCC diagnostic push
17 # pragma GCC diagnostic ignored "-Wtype-limits"
18 # pragma GCC diagnostic ignored "-Wold-style-cast"
19 # pragma GCC diagnostic ignored "-Wuseless-cast"
20 #elif defined(_MSC_VER)
21 # pragma warning(push)
22 # pragma warning(disable: 4251)
23 # pragma warning(disable: 4296)
24 # pragma warning(disable: 4996)
42 template<
class K>
struct Key { K &
k; };
51 template<
class T>
void write(NodeRef *n, T
const& v);
53 template<
class T>
inline bool read(ConstNodeRef
const& C4_RESTRICT n, T *v);
54 template<
class T>
inline bool read(NodeRef
const& C4_RESTRICT n, T *v);
55 template<
class T>
inline bool readkey(ConstNodeRef
const& C4_RESTRICT n, T *v);
56 template<
class T>
inline bool readkey(NodeRef
const& C4_RESTRICT n, T *v);
77 template<
class NodeRefType>
80 using value_type = NodeRefType;
81 using tree_type =
typename NodeRefType::tree_type;
83 tree_type * C4_RESTRICT m_tree;
86 child_iterator(tree_type * t,
id_type id) : m_tree(t), m_child_id(id) {}
88 child_iterator& operator++ () { _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; }
89 child_iterator& operator-- () { _RYML_ASSERT_VISIT_(m_tree->m_callbacks, m_child_id !=
NONE, m_tree,
NONE); m_child_id = m_tree->prev_sibling(m_child_id);
return *
this; }
91 NodeRefType operator* ()
const {
return NodeRefType(m_tree, m_child_id); }
92 NodeRefType operator-> ()
const {
return NodeRefType(m_tree, m_child_id); }
94 bool operator!= (child_iterator that)
const { _RYML_ASSERT_VISIT(m_tree == that.m_tree, m_tree,
NONE);
return m_child_id != that.m_child_id; }
95 bool operator== (child_iterator that)
const { _RYML_ASSERT_VISIT(m_tree == that.m_tree, m_tree,
NONE);
return m_child_id == that.m_child_id; }
98 template<
class NodeRefType>
101 using n_iterator = child_iterator<NodeRefType>;
105 children_view_(n_iterator
const& C4_RESTRICT b_,
106 n_iterator
const& C4_RESTRICT e_) : b(b_), e(e_) {}
108 n_iterator begin()
const {
return b; }
109 n_iterator end ()
const {
return e; }
112 template<
class NodeRefType,
class Visitor>
113 bool _visit(NodeRefType &node, Visitor fn,
id_type indentation_level,
bool skip_root=
false)
116 if( ! (node.is_root() && skip_root))
118 if(fn(node, indentation_level))
122 if(node.has_children())
124 for(
auto ch : node.children())
126 if(_visit(ch, fn, indentation_level + increment,
false))
135 template<
class NodeRefType,
class Visitor>
136 bool _visit_stacked(NodeRefType &node, Visitor fn,
id_type indentation_level,
bool skip_root=
false)
139 if( ! (node.is_root() && skip_root))
141 if(fn(node, indentation_level))
147 if(node.has_children())
149 fn.push(node, indentation_level);
150 for(
auto ch : node.children())
152 if(_visit_stacked(ch, fn, indentation_level + increment,
false))
154 fn.pop(node, indentation_level);
158 fn.pop(node, indentation_level);
163 template<
class Impl,
class ConstImpl>
164 struct RoNodeMethods;
175 template<
class Impl,
class ConstImpl>
178 C4_SUPPRESS_WARNING_GCC_CLANG_WITH_PUSH(
"-Wcast-align")
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
188 _RYML_ASSERT_BASIC(tree_ != nullptr); \
189 _RYML_ASSERT_VISIT_(tree_->m_callbacks, id_ != NONE, tree_, id_); \
190 _RYML_ASSERT_VISIT_(tree_->m_callbacks, (((Impl const* C4_RESTRICT)this)->readable()), tree_, id_)
193 #define _C4_IF_MUTABLE(ty) typename std::enable_if<!std::is_same<U, ConstImpl>::value, ty>::type
205 template<
class U=Impl>
206 C4_ALWAYS_INLINE
auto get()
RYML_NOEXCEPT -> _C4_IF_MUTABLE(
NodeData*) {
return ((Impl
const*)
this)->readable() ? tree__->get(id__) :
nullptr; }
258 RYML_DEPRECATED(
"use has_key_anchor()") bool
is_key_anchor() const noexcept {
_C4RR();
return tree_->has_key_anchor(id_); }
259 RYML_DEPRECATED(
"use has_val_anchor()") bool
is_val_hanchor() const noexcept {
_C4RR();
return tree_->has_val_anchor(id_); }
260 RYML_DEPRECATED(
"use has_anchor()") bool
is_anchor() const noexcept {
_C4RR();
return tree_->has_anchor(id_); }
261 RYML_DEPRECATED(
"use has_anchor() || is_ref()") bool
is_anchor_or_ref() const noexcept {
_C4RR();
return tree_->is_anchor_or_ref(id_); }
335 template<
class U=Impl>
336 C4_ALWAYS_INLINE
auto doc(
id_type i)
RYML_NOEXCEPT -> _C4_IF_MUTABLE(Impl) { _RYML_ASSERT_BASIC(tree_);
return {tree__, tree__->doc(i)}; }
339 template<
class U=Impl>
343 template<
class U=Impl>
347 template<
class U=Impl>
351 template<
class U=Impl>
355 template<
class U=Impl>
359 template<
class U=Impl>
363 template<
class U=Impl>
367 template<
class U=Impl>
371 template<
class U=Impl>
375 template<
class U=Impl>
379 template<
class U=Impl>
383 template<
class U=Impl>
390 C4_ALWAYS_INLINE
id_type child_pos(ConstImpl
const& n)
const RYML_NOEXCEPT {
_C4RR(); _RYML_ASSERT_VISIT_(tree_->m_callbacks, n.readable(), n.tree(), n.id());
return tree_->child_pos(id_, n.m_id); }
391 C4_ALWAYS_INLINE
id_type sibling_pos(ConstImpl
const& n)
const RYML_NOEXCEPT {
_C4RR(); _RYML_ASSERT_VISIT_(tree_->callbacks(), n.readable(), n.tree(), n.id());
return tree_->child_pos(tree_->parent(id_), n.m_id); }
422 template<
class U=Impl>
427 return ch !=
NONE ? Impl(tree__, ch) : Impl(tree__, id__,
key);
448 template<
class U=Impl>
452 id_type ch = tree__->child(id__, pos);
453 return ch !=
NONE ? Impl(tree__, ch) : Impl(tree__, id__, pos);
469 _RYML_ASSERT_VISIT_(tree_->m_callbacks, ch !=
NONE, tree_, id_);
485 id_type ch = tree_->child(id_, pos);
486 _RYML_ASSERT_VISIT_(tree_->m_callbacks, ch !=
NONE, tree_, id_);
529 template<
class U=Impl>
530 C4_ALWAYS_INLINE
auto at(csubstr
key) -> _C4_IF_MUTABLE(Impl)
532 _RYML_CHECK_BASIC(tree_ !=
nullptr);
533 _RYML_CHECK_VISIT_(tree_->m_callbacks, (id_ >= 0 && id_ < tree_->capacity()), tree_, id_);
534 _RYML_CHECK_VISIT_(tree_->m_callbacks, ((Impl
const*)
this)->readable(), tree_, id_);
535 _RYML_CHECK_VISIT_(tree_->m_callbacks, tree_->is_map(id_), tree_, id_);
537 return ch !=
NONE ? Impl(tree__, ch) : Impl(tree__, id__,
key);
565 template<
class U=Impl>
566 C4_ALWAYS_INLINE
auto at(
id_type pos) -> _C4_IF_MUTABLE(Impl)
568 _RYML_CHECK_BASIC(tree_ !=
nullptr);
569 const id_type cap = tree_->capacity();
570 _RYML_CHECK_VISIT_(tree_->m_callbacks, (id_ >= 0 && id_ < cap), tree_, id_);
571 _RYML_CHECK_VISIT_(tree_->m_callbacks, (pos >= 0 && pos < cap), tree_, id_);
572 _RYML_CHECK_VISIT_(tree_->m_callbacks, ((Impl
const*)
this)->readable(), tree_, id_);
573 _RYML_CHECK_VISIT_(tree_->m_callbacks, tree_->is_container(id_), tree_, id_);
574 id_type ch = tree__->child(id__, pos);
575 return ch !=
NONE ? Impl(tree__, ch) : Impl(tree__, id__, pos);
589 _RYML_CHECK_BASIC(tree_ !=
nullptr);
590 _RYML_CHECK_VISIT_(tree_->m_callbacks, (id_ >= 0 && id_ < tree_->capacity()), tree_, id_);
591 _RYML_CHECK_VISIT_(tree_->m_callbacks, ((Impl
const*)
this)->readable(), tree_, id_);
592 _RYML_CHECK_VISIT_(tree_->m_callbacks, tree_->is_map(id_), tree_, id_);
594 _RYML_CHECK_VISIT_(tree_->m_callbacks, ch !=
NONE, tree_, id_);
609 _RYML_CHECK_BASIC(tree_ !=
nullptr);
610 const id_type cap = tree_->capacity();
611 _RYML_CHECK_VISIT_(tree_->m_callbacks, (id_ >= 0 && id_ < cap), tree_, id_);
612 _RYML_CHECK_VISIT_(tree_->m_callbacks, (pos >= 0 && pos < cap), tree_, id_);
613 _RYML_CHECK_VISIT_(tree_->m_callbacks, ((Impl
const*)
this)->readable(), tree_, id_);
614 _RYML_CHECK_VISIT_(tree_->m_callbacks, tree_->is_container(id_), tree_, id_);
615 const id_type ch = tree_->child(id_, pos);
616 _RYML_CHECK_VISIT_(tree_->m_callbacks, ch !=
NONE, tree_, id_);
630 return tree_->location(parser, id_);
646 if( !
read((ConstImpl
const&)*
this, &v))
647 _RYML_ERR_VISIT_(tree_->m_callbacks, tree_, id_,
"could not deserialize value");
648 return *((ConstImpl
const*)
this);
658 if( !
readkey((ConstImpl
const&)*
this, &v.
k))
659 _RYML_ERR_VISIT_(tree_->m_callbacks, tree_, id_,
"could not deserialize key");
660 return *((ConstImpl
const*)
this);
680 bool get_if(csubstr name, T *var, T
const& fallback)
const
703 return *((ConstImpl
const*)
this);
710 return *((ConstImpl
const*)
this);
736 #if defined(__clang__)
737 # pragma clang diagnostic push
738 # pragma clang diagnostic ignored "-Wnull-dereference"
739 #elif defined(__GNUC__)
740 # pragma GCC diagnostic push
742 # pragma GCC diagnostic ignored "-Wnull-dereference"
754 template<
class U=Impl>
759 template<
class U=Impl>
766 template<
class U=Impl>
772 template<
class U=Impl>
776 NodeData const *nd = tree__->get(id__);
786 NodeData const *nd = tree_->get(id_);
796 template<
class Visitor>
800 return detail::_visit(*(ConstImpl
const*)
this, fn, indentation_level, skip_root);
803 template<
class Visitor,
class U=Impl>
805 -> _C4_IF_MUTABLE(
bool)
808 return detail::_visit(*(Impl*)
this, fn, indentation_level, skip_root);
812 template<
class Visitor>
816 return detail::_visit_stacked(*(ConstImpl
const*)
this, fn, indentation_level, skip_root);
819 template<
class Visitor,
class U=Impl>
821 -> _C4_IF_MUTABLE(
bool)
824 return detail::_visit_stacked(*(Impl*)
this, fn, indentation_level, skip_root);
829 #if defined(__clang__)
830 # pragma clang diagnostic pop
831 #elif defined(__GNUC__)
832 # pragma GCC diagnostic pop
835 #undef _C4_IF_MUTABLE
842 C4_SUPPRESS_WARNING_GCC_CLANG_POP
893 ConstNodeRef& operator= (std::nullptr_t) noexcept { m_tree =
nullptr; m_id =
NONE;
return *
this; }
910 C4_ALWAYS_INLINE
bool invalid() const noexcept {
return (!m_tree) || (m_id ==
NONE); }
913 C4_ALWAYS_INLINE
bool readable() const noexcept {
return m_tree !=
nullptr && m_id !=
NONE; }
916 constexpr
static C4_ALWAYS_INLINE
bool is_seed() noexcept {
return false; }
918 RYML_DEPRECATED(
"use one of readable(), is_seed() or !invalid()") bool valid() const noexcept {
return m_tree !=
nullptr && m_id !=
NONE; }
927 C4_ALWAYS_INLINE
Tree const*
tree() const noexcept {
return m_tree; }
928 C4_ALWAYS_INLINE
id_type id() const noexcept {
return m_id; }
941 RYML_DEPRECATED(
"use invalid()") bool operator== (std::nullptr_t) const noexcept {
return m_tree ==
nullptr || m_id ==
NONE; }
942 RYML_DEPRECATED(
"use !invalid()") bool operator!= (std::nullptr_t) const noexcept {
return !(m_tree ==
nullptr || m_id ==
NONE); }
944 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; }
945 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; }
1004 Tree *C4_RESTRICT m_tree;
1024 _RYML_ASSERT_BASIC(m_tree != nullptr); \
1025 _RYML_ASSERT_VISIT_(m_tree->m_callbacks, m_id != NONE && !is_seed(), m_tree, m_id)
1028 _RYML_ASSERT_BASIC(m_tree != nullptr); \
1029 _RYML_ASSERT_VISIT_(m_tree->m_callbacks, m_id != NONE, m_tree, m_id)
1036 NodeRef() noexcept : m_tree(
nullptr), m_id(
NONE), m_seed() { _clear_seed(); }
1037 NodeRef(
Tree &t) noexcept : m_tree(&t), m_id(t .root_id()), m_seed() { _clear_seed(); }
1038 NodeRef(
Tree *t) noexcept : m_tree(t ), m_id(t->root_id()), m_seed() { _clear_seed(); }
1040 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; }
1042 NodeRef(std::nullptr_t) noexcept : m_tree(
nullptr), m_id(
NONE), m_seed() {}
1067 bool invalid() const noexcept {
return m_tree ==
nullptr || m_id ==
NONE; }
1069 bool is_seed() const noexcept {
return (m_tree !=
nullptr && m_id !=
NONE) && (m_seed.str !=
nullptr || m_seed.len != (size_t)
NONE); }
1071 bool readable() const noexcept {
return (m_tree !=
nullptr && m_id !=
NONE) && (m_seed.str ==
nullptr && m_seed.len == (size_t)
NONE); }
1073 RYML_DEPRECATED(
"use one of readable(), is_seed() or !invalid()") inline
bool valid()
const {
return m_tree !=
nullptr && m_id !=
NONE; }
1084 if(m_tree == that.m_tree && m_id == that.m_id)
1086 bool seed = is_seed();
1091 return (m_seed.len == that.m_seed.len)
1092 && (m_seed.str == that.m_seed.str
1093 || m_seed == that.m_seed);
1106 RYML_DEPRECATED(
"use !readable()") bool operator== (std::nullptr_t)
const {
return m_tree ==
nullptr || m_id ==
NONE || is_seed(); }
1107 RYML_DEPRECATED(
"use readable()") bool operator!= (std::nullptr_t)
const {
return !(m_tree ==
nullptr || m_id ==
NONE || is_seed()); }
1109 RYML_DEPRECATED(
"use `this->val() == s`") bool operator== (csubstr s)
const {
_C4RR(); _RYML_ASSERT_VISIT_(m_tree->m_callbacks, has_val(), m_tree, m_id);
return m_tree->val(m_id) == s; }
1110 RYML_DEPRECATED(
"use `this->val() != s`") bool operator!= (csubstr s)
const {
_C4RR(); _RYML_ASSERT_VISIT_(m_tree->m_callbacks, has_val(), m_tree, m_id);
return m_tree->val(m_id) != s; }
1118 C4_ALWAYS_INLINE
Tree *
tree() noexcept {
return m_tree; }
1119 C4_ALWAYS_INLINE
Tree const*
tree() const noexcept {
return m_tree; }
1121 C4_ALWAYS_INLINE
id_type id() const noexcept {
return m_id; }
1136 void set_val(csubstr val) { _apply_seed(); m_tree->_set_val(m_id, val); }
1137 void set_key_tag(csubstr key_tag) { _apply_seed(); m_tree->set_key_tag(m_id, key_tag); }
1138 void set_val_tag(csubstr val_tag) { _apply_seed(); m_tree->set_val_tag(m_id, val_tag); }
1139 void set_key_anchor(csubstr key_anchor) { _apply_seed(); m_tree->set_key_anchor(m_id, key_anchor); }
1140 void set_val_anchor(csubstr val_anchor) { _apply_seed(); m_tree->set_val_anchor(m_id, val_anchor); }
1141 void set_key_ref(csubstr key_ref) { _apply_seed(); m_tree->set_key_ref(m_id, key_ref); }
1142 void set_val_ref(csubstr val_ref) { _apply_seed(); m_tree->set_val_ref(m_id, val_ref); }
1153 _C4RR(); m_tree->set_style_conditionally(m_id, type_mask, rem_style_flags, add_style_flags, recurse);
1162 m_tree->remove_children(m_id);
1163 m_tree->_clear(m_id);
1170 m_tree->_clear_key(m_id);
1177 m_tree->_clear_val(m_id);
1184 m_tree->remove_children(m_id);
1190 m_tree->_add_flags(m_id, t);
1196 m_tree->_add_flags(m_id, t);
1211 void operator= (std::nullptr_t)
1217 void operator= (csubstr v)
1224 void operator= (
const char (&v)[N])
1243 _RYML_ASSERT_BASIC(m_tree);
1244 return m_tree->to_arena(s);
1251 csubstr s = m_tree->to_arena(k);
1252 m_tree->_set_key(m_id, s);
1258 m_tree->_set_key(m_id, csubstr{});
1266 csubstr s = m_tree->to_arena(v);
1267 m_tree->_set_val(m_id, s);
1273 m_tree->_set_val(m_id, csubstr{});
1293 _RYML_ASSERT_VISIT_(m_tree->m_callbacks, val() == s, m_tree, m_id);
1310 set_key_serialized(v.
k);
1319 set_key_serialized(v.
k);
1325 set_key_serialized(w.
wrapper);
1331 set_val_serialized(w);
1344 m_id = m_tree->append_child(m_id);
1345 m_tree->_set_key(m_id, m_seed);
1346 m_seed.str =
nullptr;
1347 m_seed.len = (size_t)
NONE;
1349 else if(m_seed.len != (
size_t)
NONE)
1351 _RYML_ASSERT_VISIT_(m_tree->m_callbacks, (
size_t)m_tree->num_children(m_id) == m_seed.len, m_tree, m_id);
1352 m_id = m_tree->append_child(m_id);
1353 m_seed.str =
nullptr;
1354 m_seed.len = (size_t)
NONE;
1358 _RYML_ASSERT_VISIT_(m_tree->m_callbacks, readable(), m_tree, m_id);
1362 void _apply(csubstr v)
1364 m_tree->_set_val(m_id, v);
1367 void _apply(NodeScalar
const& v)
1369 m_tree->_set_val(m_id, v);
1372 void _apply(NodeInit
const& i)
1374 m_tree->_set(m_id, i);
1385 _RYML_ASSERT_VISIT_(m_tree->m_callbacks, after.m_tree == m_tree, m_tree, m_id);
1386 NodeRef r(m_tree, m_tree->insert_child(m_id, after.m_id));
1393 _RYML_ASSERT_VISIT_(m_tree->m_callbacks, after.m_tree == m_tree, m_tree, m_id);
1394 NodeRef r(m_tree, m_tree->insert_child(m_id, after.m_id));
1402 NodeRef r(m_tree, m_tree->insert_child(m_id,
NONE));
1409 NodeRef r(m_tree, m_tree->insert_child(m_id,
NONE));
1417 NodeRef r(m_tree, m_tree->append_child(m_id));
1424 NodeRef r(m_tree, m_tree->append_child(m_id));
1432 _RYML_ASSERT_VISIT_(m_tree->m_callbacks, after.
m_tree == m_tree, m_tree, m_id);
1433 NodeRef r(m_tree, m_tree->insert_sibling(m_id, after.
m_id));
1440 _RYML_ASSERT_VISIT_(m_tree->m_callbacks, after.
m_tree == m_tree, m_tree, m_id);
1441 NodeRef r(m_tree, m_tree->insert_sibling(m_id, after.
m_id));
1449 NodeRef r(m_tree, m_tree->prepend_sibling(m_id));
1456 NodeRef r(m_tree, m_tree->prepend_sibling(m_id));
1464 NodeRef r(m_tree, m_tree->append_sibling(m_id));
1471 NodeRef r(m_tree, m_tree->append_sibling(m_id));
1481 _RYML_ASSERT_VISIT_(m_tree->m_callbacks, has_child(child), m_tree, m_id);
1482 _RYML_ASSERT_VISIT_(m_tree->m_callbacks, child.
parent().id() ==
id(), m_tree, m_id);
1483 m_tree->remove(child.
id());
1491 _RYML_ASSERT_VISIT_(m_tree->m_callbacks, pos >= 0 && pos < num_children(), m_tree, m_id);
1492 id_type child = m_tree->child(m_id, pos);
1493 _RYML_ASSERT_VISIT_(m_tree->m_callbacks, child !=
NONE, m_tree, m_id);
1494 m_tree->remove(child);
1501 id_type child = m_tree->find_child(m_id,
key);
1502 _RYML_ASSERT_VISIT_(m_tree->m_callbacks, child !=
NONE, m_tree, m_id);
1503 m_tree->remove(child);
1515 m_tree->move(m_id, after.
m_id);
1525 if(parent.m_tree == m_tree)
1527 m_tree->move(m_id, parent.m_id, after.
m_id);
1531 parent.m_tree->
move(m_tree, m_id, parent.m_id, after.
m_id);
1532 m_tree = parent.m_tree;
1543 _RYML_ASSERT_VISIT_(m_tree->m_callbacks, m_tree == after.
m_tree || after.
m_id ==
NONE, m_tree, m_id);
1544 id_type dup = m_tree->duplicate(m_id, m_tree->parent(m_id), after.
m_id);
1557 _RYML_ASSERT_VISIT_(m_tree->m_callbacks, parent.m_tree == after.
m_tree || after.
m_id ==
NONE, m_tree, m_id);
1558 if(parent.m_tree == m_tree)
1560 id_type dup = m_tree->duplicate(m_id, parent.m_id, after.
m_id);
1567 NodeRef r(parent.m_tree, dup);
1575 _RYML_ASSERT_VISIT_(m_tree->m_callbacks, parent.m_tree == after.
m_tree, m_tree, m_id);
1576 if(parent.m_tree == m_tree)
1578 m_tree->duplicate_children(m_id, parent.m_id, after.
m_id);
1598 : m_tree(that.m_tree)
1599 , m_id(!that.is_seed() ? that.id() : (
id_type)
NONE)
1604 : m_tree(that.m_tree)
1605 , m_id(!that.is_seed() ? that.id() : (
id_type)
NONE)
1612 m_tree = (that.m_tree);
1613 m_id = (!that.is_seed() ? that.id() : (
id_type)
NONE);
1619 m_tree = (that.m_tree);
1620 m_id = (!that.is_seed() ? that.id() : (
id_type)
NONE);
1641 return read(n.m_tree, n.m_id, v);
1647 return read(n.tree(), n.id(), v);
1653 return readkey(n.m_tree, n.m_id, v);
1659 return readkey(n.tree(), n.id(), v);
1673 # pragma clang diagnostic pop
1674 #elif defined(__GNUC__)
1675 # pragma GCC diagnostic pop
1676 #elif defined(_MSC_VER)
1677 # pragma warning(pop)
encoding/decoding for base64.
Holds a pointer to an existing tree, and a node id.
Tree const * tree() const noexcept
ConstNodeRef(ConstNodeRef const &) noexcept=default
id_type id() const noexcept
ConstNodeRef(ConstNodeRef &&) noexcept=default
ConstNodeRef(Tree const *t) noexcept
ConstNodeRef(std::nullptr_t) noexcept
ConstNodeRef(Tree const *t, id_type id) noexcept
constexpr static bool is_seed() noexcept
because a ConstNodeRef cannot be used to write to the tree, it can never be a seed.
ConstNodeRef(Tree const &t) noexcept
ConstNodeRef & operator=(std::nullptr_t) noexcept
bool readable() const noexcept
because a ConstNodeRef cannot be used to write to the tree, readable() has the same meaning as !...
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)
void move(ConstNodeRef const &after)
change the node's position within its parent, placing it after after.
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)
NodeRef prepend_child(NodeInit const &i)
NodeRef insert_sibling(ConstNodeRef const &after)
NodeRef(Tree *t, id_type id, csubstr seed_key) noexcept
void set_val_tag(csubstr val_tag)
void clear_style(bool recurse=false)
NodeRef append_sibling(NodeInit const &i)
NodeRef insert_sibling(NodeInit const &i, ConstNodeRef const &after)
NodeRef(NodeRef &&) noexcept=default
NodeRef(Tree *t, id_type id, id_type seed_pos) noexcept
NodeRef prepend_sibling(NodeInit const &i)
csubstr to_arena(T const &s)
serialize a variable to the arena
void _clear_seed() noexcept
NodeRef insert_child(NodeRef after)
void set_val(csubstr val)
NodeRef prepend_sibling()
size_t set_key_serialized(T const &k)
void set_val_style(NodeType_e style)
NodeRef(Tree *t, id_type id) noexcept
NodeRef insert_child(NodeInit const &i, NodeRef after)
Tree const * tree() const noexcept
size_t set_val_serialized(std::nullptr_t)
id_type id() const noexcept
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)
NodeRef duplicate(ConstNodeRef const &after) const
duplicate the current node somewhere within its parent, and place it after the node after.
bool readable() const noexcept
true if the object is not invalid and not in seed state.
void duplicate_children(NodeRef const &parent, ConstNodeRef const &after) const
NodeRef(Tree *t) noexcept
size_t set_val_serialized(T const &v)
NodeRef duplicate(NodeRef const &parent, ConstNodeRef const &after) const
duplicate the current node somewhere into a different parent (possibly from a different tree),...
void set_type(NodeType t)
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)
NodeRef append_child(NodeInit const &i)
NodeRef(std::nullptr_t) noexcept
void set_key_ref(csubstr key_ref)
void remove_child(NodeRef &child)
void set_key_anchor(csubstr key_anchor)
void change_type(NodeType t)
NodeRef(Tree &t) noexcept
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)
void remove_child(id_type pos)
remove the nth child of this node
This is the main driver of parsing logic: it scans the YAML or JSON source for tokens,...
void move(id_type node, id_type after)
change the node's position in the parent
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_children(id_type node, id_type parent, id_type after)
recursively duplicate the node's children (but not the node)
#define RYML_NOEXCEPT
Conditionally expands to noexcept when RYML_USE_ASSERT is 0 and is empty otherwise.
base64_wrapper_< byte > base64_wrapper
a tag type to mark a payload to be encoded as base64
base64_wrapper_< cbyte > const_base64_wrapper
a tag type to mark a payload as base64-encoded
OStream & operator<<(OStream &s, Tree const &t)
emit YAML to an STL-like ostream
bool from_chars(csubstr buf, uint8_t *v) noexcept
NodeType_e & operator|=(NodeType_e &subject, NodeType_e bits) noexcept
NodeType_e
a bit mask for marking node types and styles
bool readkey(ConstNodeRef const &n, T *v)
void write(NodeRef *n, T const &v)
bool read(ConstNodeRef const &n, T *v)
bool operator!=(const char(&s)[N], basic_substring< C > const that) noexcept
bool operator==(const char(&s)[N], basic_substring< C > const that) noexcept
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...
@ npos
a null string position
(Undefined by default) Use shorter error message from checks/asserts: do not show the check condition...
fmt::base64_wrapper wrapper
fmt::const_base64_wrapper wrapper
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.
convenience class to initialize nodes
a node scalar is a csubstr, which may be tagged and anchored.
wraps a NodeType_e element with some syntactic sugar and predicates
auto at(csubstr key) -> Impl
Find child by key; complexity is O(num_children).
bool type_has_none(NodeType_e bits) const RYML_NOEXCEPT
Forward to Tree::type_has_none().
const_children_view cchildren() const RYML_NOEXCEPT
get an iterable view over children
bool is_key_anchor() const noexcept
auto first_child() RYML_NOEXCEPT -> Impl
Forward to Tree::first_child().
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().
auto children() RYML_NOEXCEPT -> children_view
get an iterable view over children.
bool is_flow_ml() const RYML_NOEXCEPT
Forward to Tree::is_flow_ml().
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
auto last_child() RYML_NOEXCEPT -> Impl
Forward to Tree::last_child().
auto visit_stacked(Visitor fn, id_type indentation_level=0, bool skip_root=true) RYML_NOEXCEPT -> bool
visit every child node calling fn(node, level)
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().
NodeScalar const & valsc() const RYML_NOEXCEPT
Forward to Tree::valsc().
auto parent() RYML_NOEXCEPT -> Impl
Forward to Tree::parent().
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).
const_children_view siblings() const RYML_NOEXCEPT
get an iterable view over all siblings (including the calling node)
bool is_key_literal() const RYML_NOEXCEPT
Forward to Tree::is_key_literal().
const_iterator cbegin() const RYML_NOEXCEPT
get an iterator to the first child
csubstr key_ref() const RYML_NOEXCEPT
Forward to Tree::key_ref().
ConstImpl sibling(id_type pos) const RYML_NOEXCEPT
Forward to Tree::sibling().
bool visit_stacked(Visitor fn, id_type indentation_level=0, bool skip_root=true) const RYML_NOEXCEPT
visit every child node calling fn(node, level)
bool has_child(ConstImpl const &n) const RYML_NOEXCEPT
Forward to Tree::has_child().
ConstImpl const & operator>>(T &v) const
deserialize the node's val to the given variable, forwarding to the user-overrideable read() function...
auto next_sibling() RYML_NOEXCEPT -> Impl
Forward to Tree::next_sibling().
bool visit(Visitor fn, id_type indentation_level=0, bool skip_root=true) const RYML_NOEXCEPT
visit every child node calling fn(node)
bool is_quoted() const RYML_NOEXCEPT
Forward to Tree::is_quoted().
bool parent_is_map() const RYML_NOEXCEPT
Forward to Tree::parent_is_map().
auto last_sibling() RYML_NOEXCEPT -> Impl
Forward to Tree::last_sibling().
bool has_child(csubstr name) const RYML_NOEXCEPT
Forward to Tree::has_child().
auto find_sibling(csubstr name) RYML_NOEXCEPT -> Impl
Forward to Tree::find_sibling().
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 type_has_any(NodeType_e bits) const RYML_NOEXCEPT
Forward to Tree::type_has_any().
ConstImpl last_sibling() const RYML_NOEXCEPT
Forward to Tree::last_sibling().
bool is_container() const RYML_NOEXCEPT
Forward to Tree::is_container().
id_type num_siblings() const RYML_NOEXCEPT
O(num_children).
ConstImpl last_child() const RYML_NOEXCEPT
Forward to Tree::last_child().
bool has_key() const RYML_NOEXCEPT
Forward to Tree::has_key().
csubstr key_tag() const RYML_NOEXCEPT
Forward to Tree::key_tag().
const_children_view csiblings() const RYML_NOEXCEPT
get an iterable view over all siblings (including the calling node)
auto find_child(csubstr name) RYML_NOEXCEPT -> Impl
Forward to Tree::find_child().
detail::child_iterator< Impl > iterator
csubstr val_ref() const RYML_NOEXCEPT
Forward to Tree::val_ref().
csubstr key() const RYML_NOEXCEPT
Forward to Tree::key().
ConstImpl child(id_type pos) const RYML_NOEXCEPT
Forward to Tree::child().
bool has_sibling(csubstr name) const RYML_NOEXCEPT
Forward to Tree::has_sibling().
NodeType key_style() const RYML_NOEXCEPT
Forward to Tree::key_style().
NodeScalar const & keysc() const RYML_NOEXCEPT
Forward to Tree::keysc().
size_t deserialize_val(fmt::base64_wrapper v) const
decode the base64-encoded key and assign the decoded blob to the given buffer/
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.
ConstImpl next_sibling() const RYML_NOEXCEPT
Forward to Tree::next_sibling().
ConstImpl find_sibling(csubstr name) const RYML_NOEXCEPT
Forward to Tree::find_sibling().
bool is_anchor_or_ref() const noexcept
const char * type_str() const RYML_NOEXCEPT
Forward to Tree::type_str().
csubstr val_anchor() const RYML_NOEXCEPT
Forward to Tree::val_anchor().
const_children_view children() const RYML_NOEXCEPT
get an iterable view over children
auto end() RYML_NOEXCEPT -> iterator
get an iterator to after the last child.
auto siblings() RYML_NOEXCEPT -> children_view
get an iterable view over all siblings (including the calling node)
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().
ConstImpl find_child(csubstr name) const RYML_NOEXCEPT
Forward to Tree::find_child().
NodeData const * get() const RYML_NOEXCEPT
returns the data or null when the id is NONE
ConstImpl at(csubstr key) const
Get a child by name, with error checking; complexity is O(num_children).
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().
ConstImpl ancestor_doc() const RYML_NOEXCEPT
Forward to Tree::ancestor_doc().
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().
auto begin() RYML_NOEXCEPT -> iterator
get a mutable iterator to the first child.
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().
detail::children_view_< ConstImpl > const_children_view
auto first_sibling() RYML_NOEXCEPT -> Impl
Forward to Tree::first_sibling().
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().
const_iterator end() const RYML_NOEXCEPT
get an iterator to after the last child
ConstImpl parent() const RYML_NOEXCEPT
Forward to Tree::parent().
bool key_is_null() const RYML_NOEXCEPT
Forward to Tree::key_is_null().
NodeType val_style() const RYML_NOEXCEPT
Forward to Tree::val_style().
auto get() RYML_NOEXCEPT -> NodeData *
returns the data or null when the id is NONE
detail::children_view_< Impl > children_view
bool parent_is_seq() const RYML_NOEXCEPT
Forward to Tree::parent_is_seq().
bool is_doc() const RYML_NOEXCEPT
Forward to Tree::is_doc().
auto doc(id_type i) RYML_NOEXCEPT -> Impl
Forward to Tree::doc().
auto visit(Visitor fn, id_type indentation_level=0, bool skip_root=true) RYML_NOEXCEPT -> bool
visit every child node calling fn(node)
bool is_key_dquo() const RYML_NOEXCEPT
Forward to Tree::is_key_dquo().
size_t deserialize_key(fmt::base64_wrapper v) const
decode the base64-encoded key and assign the decoded blob to the given buffer/
id_type num_children() const RYML_NOEXCEPT
O(num_children).
bool is_val_unfiltered() const noexcept
Forward to Tree::is_val_unfiltered().
ConstImpl first_sibling() const RYML_NOEXCEPT
Forward to Tree::first_sibling().
ConstImpl doc(id_type i) const RYML_NOEXCEPT
Forward to Tree::doc().
bool is_flow_sl() const RYML_NOEXCEPT
Forward to Tree::is_flow_sl().
auto at(id_type pos) -> Impl
Find child by position; complexity is O(pos).
bool is_flow() const RYML_NOEXCEPT
Forward to Tree::is_flow().
ConstImpl at(id_type pos) const
Get a child by position, with error checking; complexity is O(pos).
auto child(id_type pos) RYML_NOEXCEPT -> Impl
Forward to Tree::child().
bool is_block() const RYML_NOEXCEPT
Forward to Tree::is_block().
const_iterator cend() const RYML_NOEXCEPT
get an iterator to after the last child
bool is_key_folded() const RYML_NOEXCEPT
Forward to Tree::is_key_folded().
auto ancestor_doc() RYML_NOEXCEPT -> Impl
Forward to Tree::ancestor_doc().
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().
detail::child_iterator< ConstImpl > const_iterator
bool has_children() const RYML_NOEXCEPT
Forward to Tree::has_children().
bool is_val_quoted() const RYML_NOEXCEPT
Forward to Tree::is_val_quoted().
auto sibling(id_type pos) RYML_NOEXCEPT -> Impl
Forward to Tree::sibling().
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_val_hanchor() const noexcept
auto operator[](csubstr key) RYML_NOEXCEPT -> Impl
Find child by key; complexity is O(num_children).
bool has_val() const RYML_NOEXCEPT
Forward to Tree::has_val().
ConstImpl first_child() const RYML_NOEXCEPT
Forward to Tree::first_child().
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().
auto prev_sibling() RYML_NOEXCEPT -> Impl
Forward to Tree::prev_sibling().
ConstImpl prev_sibling() const RYML_NOEXCEPT
Forward to Tree::prev_sibling().
id_type num_other_siblings() const RYML_NOEXCEPT
O(num_siblings).
const_iterator begin() const RYML_NOEXCEPT
get an iterator to the first child
bool is_val_dquo() const RYML_NOEXCEPT
Forward to Tree::is_val_dquo().
bool is_ref() const RYML_NOEXCEPT
Forward to Tree::is_ref().