soa hierarchy wip

This commit is contained in:
Joao Paulo Magalhaes
2024-05-12 14:35:10 +01:00
parent 5d0763056c
commit 9d16212401
5 changed files with 347 additions and 310 deletions

View File

@@ -34,11 +34,10 @@ inline void check_invariants(Tree const& t, id_type node)
node = t.root_id();
}
NodeRelation const& n = t.m_relation[node];
#if defined(RYML_DBG) && 0
if(n.m_first_child != NONE || n.m_last_child != NONE)
if(t.m_first_child[node] != NONE || t.m_last_child[node] != NONE)
{
printf("check(%zu): fc=%zu lc=%zu\n", node, n.m_first_child, n.m_last_child);
printf("check(%zu): fc=%zu lc=%zu\n", node, t.m_first_child[node], t.m_last_child[node]);
}
else
{
@@ -46,78 +45,77 @@ inline void check_invariants(Tree const& t, id_type node)
}
#endif
C4_CHECK(n.m_parent != node);
if(n.m_parent == NONE)
C4_CHECK(t.m_parent[node] != node);
if(t.m_parent[node] == NONE)
{
C4_CHECK(t.is_root(node));
}
else //if(n.m_parent != NONE)
else //if(t.m_parent[node] != NONE)
{
C4_CHECK(t.has_child(n.m_parent, node));
C4_CHECK(t.has_child(t.m_parent[node], node));
NodeRelation const& p = t.m_relation[n.m_parent];
if(n.m_prev_sibling == NONE)
id_type p = t.m_parent[node];
if(t.m_prev_sibling[node] == NONE)
{
C4_CHECK(p.m_first_child == node);
C4_CHECK(t.m_first_child[p] == node);
C4_CHECK(t.first_sibling(node) == node);
}
else
{
C4_CHECK(p.m_first_child != node);
C4_CHECK(t.m_first_child[p] != node);
C4_CHECK(t.first_sibling(node) != node);
}
if(n.m_next_sibling == NONE)
if(t.m_next_sibling[node] == NONE)
{
C4_CHECK(p.m_last_child == node);
C4_CHECK(t.m_last_child[p] == node);
C4_CHECK(t.last_sibling(node) == node);
}
else
{
C4_CHECK(p.m_last_child != node);
C4_CHECK(t.m_last_child[p] != node);
C4_CHECK(t.last_sibling(node) != node);
}
}
C4_CHECK(n.m_first_child != node);
C4_CHECK(n.m_last_child != node);
if(n.m_first_child != NONE || n.m_last_child != NONE)
C4_CHECK(t.m_first_child[node] != node);
C4_CHECK(t.m_last_child[node] != node);
if(t.m_first_child[node] != NONE || t.m_last_child[node] != NONE)
{
C4_CHECK(n.m_first_child != NONE);
C4_CHECK(n.m_last_child != NONE);
C4_CHECK(t.m_first_child[node] != NONE);
C4_CHECK(t.m_last_child[node] != NONE);
}
C4_CHECK(n.m_prev_sibling != node);
C4_CHECK(n.m_next_sibling != node);
if(n.m_prev_sibling != NONE)
C4_CHECK(t.m_prev_sibling[node] != node);
C4_CHECK(t.m_next_sibling[node] != node);
if(t.m_prev_sibling[node] != NONE)
{
C4_CHECK(t.m_relation[n.m_prev_sibling].m_next_sibling == node);
C4_CHECK(t.m_relation[n.m_prev_sibling].m_prev_sibling != node);
C4_CHECK(t.m_next_sibling[t.m_prev_sibling[node]] == node);
C4_CHECK(t.m_prev_sibling[t.m_prev_sibling[node]] != node);
}
if(n.m_next_sibling != NONE)
if(t.m_next_sibling[node] != NONE)
{
C4_CHECK(t.m_relation[n.m_next_sibling].m_prev_sibling == node);
C4_CHECK(t.m_relation[n.m_next_sibling].m_next_sibling != node);
C4_CHECK(t.m_prev_sibling[t.m_next_sibling[node]] == node);
C4_CHECK(t.m_next_sibling[t.m_next_sibling[node]] != node);
}
id_type count = 0;
for(id_type i = n.m_first_child; i != NONE; i = t.next_sibling(i))
for(id_type i = t.m_first_child[node]; i != NONE; i = t.next_sibling(i))
{
#if defined(RYML_DBG) && 0
printf("check(%zu): descend to child[%zu]=%zu\n", node, count, i);
#endif
NodeRelation const& ch = t.m_relation[i];
C4_CHECK(ch.m_parent == node);
C4_CHECK(ch.m_next_sibling != i);
C4_CHECK(t.m_parent[i] == node);
C4_CHECK(t.m_next_sibling[i] != i);
++count;
}
C4_CHECK(count == t.num_children(node));
if(n.m_prev_sibling == NONE && n.m_next_sibling == NONE)
if(t.m_prev_sibling[node] == NONE && t.m_next_sibling[node] == NONE)
{
if(n.m_parent != NONE)
if(t.m_parent[node] != NONE)
{
C4_CHECK(t.num_children(n.m_parent) == 1);
C4_CHECK(t.num_children(t.m_parent[node]) == 1);
C4_CHECK(t.num_siblings(node) == 1);
}
}
@@ -153,19 +151,18 @@ inline void check_free_list(Tree const& t)
C4_CHECK(t.m_free_head >= 0 && t.m_free_head < t.m_cap);
C4_CHECK(t.m_free_tail >= 0 && t.m_free_tail < t.m_cap);
NodeRelation const& head = t.m_relation[t.m_free_head];
//NodeRelation const& tail = t.m_relation[t.m_free_tail];
id_type head = t.m_free_head;
//id_type tail = t.m_free_tail;
//C4_CHECK(head.m_prev_sibling == NONE);
//C4_CHECK(tail.m_next_sibling == NONE);
//C4_CHECK(m_prev_sibling[head] == NONE);
//C4_CHECK(m_next_sibling[tail] == NONE);
id_type count = 0;
for(id_type i = t.m_free_head, prev = NONE; i != NONE; i = t.m_relation[i].m_next_sibling)
for(id_type i = t.m_free_head, prev = NONE; i != NONE; i = t.m_next_sibling[i])
{
NodeRelation const& elm = t.m_relation[i];
if(&elm != &head)
if(i != head)
{
C4_CHECK(elm.m_prev_sibling == prev);
C4_CHECK(t.m_prev_sibling[i] == prev);
}
prev = i;
++count;

View File

@@ -13,6 +13,7 @@ namespace c4 {
namespace yml {
#define _ryml_num_val_arrays (size_t(6u))
#define _ryml_num_hcy_arrays (size_t(5u))
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
@@ -82,8 +83,8 @@ ConstNodeRef Tree::cdocref(id_type i) const
//-----------------------------------------------------------------------------
// the tree's node data arrays are allocated all into a single buffer.
// these utilities help doing that.
// the tree's node data and hierarchy arrays are allocated all into a
// single buffer. these utilities help doing that.
namespace {
template<class T>
bool _is_aligned(T const* ptr)
@@ -108,9 +109,9 @@ struct node_buf_data
size_for_val_align = _get_padding(size_for_type, alignof(csubstr));
val_start = size_for_type + size_for_val_align;
size_for_val = _ryml_num_val_arrays * new_cap * sizeof(csubstr);
size_for_rel_align = _get_padding(val_start + size_for_val, alignof(NodeRelation));
size_for_rel_align = _get_padding(val_start + size_for_val, alignof(id_type));
rel_start = val_start + size_for_val + size_for_rel_align;
size_for_rel = new_cap * sizeof(NodeRelation);
size_for_rel = _ryml_num_val_arrays * new_cap * sizeof(id_type);
total_size = rel_start + size_for_rel;
}
size_t size_for_type;
@@ -132,20 +133,28 @@ C4_NO_INLINE void _resize_node_data(Callbacks const& cb,
csubstr *C4_RESTRICT * m_key,
csubstr *C4_RESTRICT * m_key_tag,
csubstr *C4_RESTRICT * m_key_anchor,
NodeRelation *C4_RESTRICT * m_relation)
id_type *C4_RESTRICT * m_parent,
id_type *C4_RESTRICT * m_first_child,
id_type *C4_RESTRICT * m_last_child,
id_type *C4_RESTRICT * m_prev_sibling,
id_type *C4_RESTRICT * m_next_sibling)
{
_RYML_CB_ASSERT(cb, new_cap > 0);
const node_buf_data newsz(new_cap);
uint8_t *buf = _RYML_CB_ALLOC_HINT(cb, uint8_t, (size_t)newsz.total_size, *m_type);
_RYML_CB_CHECK(cb, buf != nullptr);
NodeType *type = reinterpret_cast<NodeType*>(buf);
csubstr *val = reinterpret_cast<csubstr*>(buf + newsz.val_start);
csubstr *val_tag = reinterpret_cast<csubstr*>(buf + newsz.val_start + 1 * new_cap * sizeof(csubstr));
csubstr *val_anchor = reinterpret_cast<csubstr*>(buf + newsz.val_start + 2 * new_cap * sizeof(csubstr));
csubstr *key = reinterpret_cast<csubstr*>(buf + newsz.val_start + 3 * new_cap * sizeof(csubstr));
csubstr *key_tag = reinterpret_cast<csubstr*>(buf + newsz.val_start + 4 * new_cap * sizeof(csubstr));
csubstr *key_anchor = reinterpret_cast<csubstr*>(buf + newsz.val_start + 5 * new_cap * sizeof(csubstr));
NodeRelation *rel = reinterpret_cast<NodeRelation*>(buf + newsz.rel_start);
NodeType *type = reinterpret_cast<NodeType*>(buf);
csubstr *val = reinterpret_cast<csubstr*>(buf + newsz.val_start);
csubstr *val_tag = reinterpret_cast<csubstr*>(buf + newsz.val_start + 1 * new_cap * sizeof(csubstr));
csubstr *val_anchor = reinterpret_cast<csubstr*>(buf + newsz.val_start + 2 * new_cap * sizeof(csubstr));
csubstr *key = reinterpret_cast<csubstr*>(buf + newsz.val_start + 3 * new_cap * sizeof(csubstr));
csubstr *key_tag = reinterpret_cast<csubstr*>(buf + newsz.val_start + 4 * new_cap * sizeof(csubstr));
csubstr *key_anchor = reinterpret_cast<csubstr*>(buf + newsz.val_start + 5 * new_cap * sizeof(csubstr));
id_type *parent = reinterpret_cast<id_type*>(buf + newsz.rel_start + 0 * new_cap * sizeof(id_type));
id_type *first_child = reinterpret_cast<id_type*>(buf + newsz.rel_start + 1 * new_cap * sizeof(id_type));
id_type *last_child = reinterpret_cast<id_type*>(buf + newsz.rel_start + 2 * new_cap * sizeof(id_type));
id_type *prev_sibling = reinterpret_cast<id_type*>(buf + newsz.rel_start + 3 * new_cap * sizeof(id_type));
id_type *next_sibling = reinterpret_cast<id_type*>(buf + newsz.rel_start + 4 * new_cap * sizeof(id_type));
_RYML_CB_ASSERT(cb, _is_aligned(type));
_RYML_CB_ASSERT(cb, _is_aligned(val));
_RYML_CB_ASSERT(cb, _is_aligned(val_tag));
@@ -153,7 +162,11 @@ C4_NO_INLINE void _resize_node_data(Callbacks const& cb,
_RYML_CB_ASSERT(cb, _is_aligned(key));
_RYML_CB_ASSERT(cb, _is_aligned(key_tag));
_RYML_CB_ASSERT(cb, _is_aligned(key_anchor));
_RYML_CB_ASSERT(cb, _is_aligned(rel));
_RYML_CB_ASSERT(cb, _is_aligned(parent));
_RYML_CB_ASSERT(cb, _is_aligned(first_child));
_RYML_CB_ASSERT(cb, _is_aligned(last_child));
_RYML_CB_ASSERT(cb, _is_aligned(prev_sibling));
_RYML_CB_ASSERT(cb, _is_aligned(next_sibling));
if(old_cap)
{
memcpy(type, *m_type, old_cap * sizeof(NodeType));
@@ -163,7 +176,11 @@ C4_NO_INLINE void _resize_node_data(Callbacks const& cb,
memcpy(key, *m_key, old_cap * sizeof(csubstr));
memcpy(key_tag, *m_key_tag, old_cap * sizeof(csubstr));
memcpy(key_anchor, *m_key_anchor, old_cap * sizeof(csubstr));
memcpy(rel, *m_relation, old_cap * sizeof(NodeRelation));
memcpy(parent, *m_parent, old_cap * sizeof(id_type));
memcpy(first_child, *m_first_child, old_cap * sizeof(id_type));
memcpy(last_child, *m_last_child, old_cap * sizeof(id_type));
memcpy(prev_sibling, *m_prev_sibling, old_cap * sizeof(id_type));
memcpy(next_sibling, *m_next_sibling, old_cap * sizeof(id_type));
const node_buf_data oldsz(old_cap);
_RYML_CB_FREE(cb, *m_type, uint8_t, oldsz.total_size);
}
@@ -174,7 +191,11 @@ C4_NO_INLINE void _resize_node_data(Callbacks const& cb,
*m_key = key;
*m_key_tag = key_tag;
*m_key_anchor = key_anchor;
*m_relation = rel;
*m_parent = parent;
*m_first_child = first_child;
*m_last_child = last_child;
*m_prev_sibling = prev_sibling;
*m_next_sibling = next_sibling;
}
} // namespace
@@ -188,7 +209,11 @@ Tree::Tree(Callbacks const& cb)
, m_key(nullptr)
, m_key_tag(nullptr)
, m_key_anchor(nullptr)
, m_relation(nullptr)
, m_parent(nullptr)
, m_first_child(nullptr)
, m_last_child(nullptr)
, m_prev_sibling(nullptr)
, m_next_sibling(nullptr)
, m_cap(0)
, m_size(0)
, m_free_head(NONE)
@@ -244,7 +269,7 @@ void Tree::_free()
if(m_type) // allocated for everything
{
_RYML_CB_ASSERT(m_callbacks, m_cap > 0);
const node_buf_data oldsz(m_cap);
const node_buf_data oldsz((size_t)m_cap);
_RYML_CB_FREE(m_callbacks, m_type, uint8_t, oldsz.total_size);
}
if(m_arena.str)
@@ -264,7 +289,11 @@ void Tree::_clear()
m_key = nullptr;
m_key_tag = nullptr;
m_key_anchor = nullptr;
m_relation = nullptr;
m_parent = nullptr;
m_first_child = nullptr;
m_last_child = nullptr;
m_prev_sibling = nullptr;
m_next_sibling = nullptr;
m_cap = 0;
m_size = 0;
m_free_head = 0;
@@ -284,14 +313,18 @@ void Tree::_copy(Tree const& that)
_RYML_CB_ASSERT(m_callbacks, m_key == nullptr);
_RYML_CB_ASSERT(m_callbacks, m_key_tag == nullptr);
_RYML_CB_ASSERT(m_callbacks, m_key_anchor == nullptr);
_RYML_CB_ASSERT(m_callbacks, m_relation == nullptr);
_RYML_CB_ASSERT(m_callbacks, m_parent == nullptr);
_RYML_CB_ASSERT(m_callbacks, m_first_child == nullptr);
_RYML_CB_ASSERT(m_callbacks, m_last_child == nullptr);
_RYML_CB_ASSERT(m_callbacks, m_prev_sibling == nullptr);
_RYML_CB_ASSERT(m_callbacks, m_next_sibling == nullptr);
_RYML_CB_ASSERT(m_callbacks, m_arena.str == nullptr);
_RYML_CB_ASSERT(m_callbacks, m_arena.len == 0);
if(that.m_cap)
{
_resize_node_data(m_callbacks,
0,
that.m_cap,
(size_t)0,
(size_t)that.m_cap,
&m_type,
&m_val,
&m_val_tag,
@@ -299,10 +332,14 @@ void Tree::_copy(Tree const& that)
&m_key,
&m_key_tag,
&m_key_anchor,
&m_relation);
&m_parent,
&m_first_child,
&m_last_child,
&m_prev_sibling,
&m_next_sibling);
memcpy(m_type, that.m_type, (size_t)that.m_cap * sizeof(NodeType));
memcpy(m_val, that.m_val, (size_t)that.m_cap * _ryml_num_val_arrays * sizeof(csubstr));
memcpy(m_relation, that.m_relation, (size_t)that.m_cap * sizeof(NodeRelation));
memcpy(m_val, that.m_val, _ryml_num_val_arrays * (size_t)that.m_cap * sizeof(csubstr));
memcpy(m_parent, that.m_parent, _ryml_num_hcy_arrays * (size_t)that.m_cap * sizeof(id_type));
m_cap = that.m_cap;
m_size = that.m_size;
m_free_head = that.m_free_head;
@@ -332,7 +369,11 @@ void Tree::_move(Tree & that) noexcept
_RYML_CB_ASSERT(m_callbacks, m_key == nullptr);
_RYML_CB_ASSERT(m_callbacks, m_key_tag == nullptr);
_RYML_CB_ASSERT(m_callbacks, m_key_anchor == nullptr);
_RYML_CB_ASSERT(m_callbacks, m_relation == nullptr);
_RYML_CB_ASSERT(m_callbacks, m_parent == nullptr);
_RYML_CB_ASSERT(m_callbacks, m_first_child == nullptr);
_RYML_CB_ASSERT(m_callbacks, m_last_child == nullptr);
_RYML_CB_ASSERT(m_callbacks, m_prev_sibling == nullptr);
_RYML_CB_ASSERT(m_callbacks, m_next_sibling == nullptr);
_RYML_CB_ASSERT(m_callbacks, m_arena.str == nullptr);
_RYML_CB_ASSERT(m_callbacks, m_arena.len == 0);
m_type = that.m_type;
@@ -342,7 +383,11 @@ void Tree::_move(Tree & that) noexcept
m_key = that.m_key;
m_key_tag = that.m_key_tag;
m_key_anchor = that.m_key_anchor;
m_relation = that.m_relation;
m_parent = that.m_parent;
m_first_child = that.m_first_child;
m_last_child = that.m_last_child;
m_prev_sibling = that.m_prev_sibling;
m_next_sibling = that.m_next_sibling;
m_cap = that.m_cap;
m_size = that.m_size;
m_free_head = that.m_free_head;
@@ -407,7 +452,11 @@ void Tree::reserve(id_type cap)
&m_key,
&m_key_tag,
&m_key_anchor,
&m_relation);
&m_parent,
&m_first_child,
&m_last_child,
&m_prev_sibling,
&m_next_sibling);
id_type first = m_cap;
id_type del = cap - m_cap;
m_cap = cap;
@@ -416,8 +465,8 @@ void Tree::reserve(id_type cap)
{
_RYML_CB_ASSERT(m_callbacks, m_val != nullptr);
_RYML_CB_ASSERT(m_callbacks, m_free_tail != NONE);
m_relation[m_free_tail].m_next_sibling = first;
m_relation[first].m_prev_sibling = m_free_tail;
m_next_sibling[m_free_tail] = first;
m_prev_sibling[first] = m_free_tail;
m_free_tail = cap-1;
}
else
@@ -472,10 +521,10 @@ void Tree::_clear_range(id_type first, id_type num)
for(id_type i = first, e = first + num; i < e; ++i)
{
_clear(i);
m_relation[i].m_prev_sibling = i - 1;
m_relation[i].m_next_sibling = i + 1;
m_prev_sibling[i] = i - 1;
m_next_sibling[i] = i + 1;
}
m_relation[first + num - 1].m_next_sibling = NONE;
m_next_sibling[first + num - 1] = NONE;
// we don't need to clear the node data
}
@@ -495,12 +544,11 @@ void Tree::_release(id_type i)
void Tree::_free_list_add(id_type i)
{
_RYML_CB_ASSERT(m_callbacks, i >= 0 && i < m_cap);
NodeRelation &C4_RESTRICT w = m_relation[i];
w.m_parent = NONE;
w.m_next_sibling = m_free_head;
w.m_prev_sibling = NONE;
m_parent[i] = NONE;
m_next_sibling[i] = m_free_head;
m_prev_sibling[i] = NONE;
if(m_free_head != NONE)
m_relation[m_free_head].m_prev_sibling = i;
m_prev_sibling[m_free_head] = i;
m_free_head = i;
if(m_free_tail == NONE)
m_free_tail = m_free_head;
@@ -510,7 +558,7 @@ void Tree::_free_list_rem(id_type i)
{
_RYML_CB_ASSERT(m_callbacks, i >= 0 && i < m_cap);
if(m_free_head == i)
m_free_head = m_relation[i].m_next_sibling;
m_free_head = m_next_sibling[i];
_rem_hierarchy(i);
}
@@ -528,7 +576,7 @@ id_type Tree::_claim()
_RYML_CB_ASSERT(m_callbacks, m_free_head >= 0 && m_free_head < m_cap);
const id_type ichild = m_free_head;
++m_size;
m_free_head = m_relation[ichild].m_next_sibling;
m_free_head = m_next_sibling[ichild];
if(m_free_head == NONE)
{
m_free_tail = NONE;
@@ -553,52 +601,47 @@ C4_SUPPRESS_WARNING_GCC("-Wanalyzer-fd-leak")
#endif
#endif
void Tree::_set_hierarchy(id_type ichild, id_type iparent, id_type iprev_sibling)
void Tree::_set_hierarchy(id_type child, id_type parent, id_type iprev_sibling)
{
_RYML_CB_ASSERT(m_callbacks, m_relation != nullptr);
_RYML_CB_ASSERT(m_callbacks, ichild >= 0 && ichild < m_cap);
_RYML_CB_ASSERT(m_callbacks, iparent == NONE || (iparent >= 0 && iparent < m_cap));
_RYML_CB_ASSERT(m_callbacks, m_cap > 0);
_RYML_CB_ASSERT(m_callbacks, m_parent != nullptr);
_RYML_CB_ASSERT(m_callbacks, child >= 0 && child < m_cap);
_RYML_CB_ASSERT(m_callbacks, parent == NONE || (parent >= 0 && parent < m_cap));
_RYML_CB_ASSERT(m_callbacks, iprev_sibling == NONE || (iprev_sibling >= 0 && iprev_sibling < m_cap));
NodeRelation *C4_RESTRICT child = &m_relation[ichild];
child->m_parent = iparent;
child->m_prev_sibling = NONE;
child->m_next_sibling = NONE;
_RYML_CB_ASSERT(m_callbacks, iparent != NONE || ichild == 0);
_RYML_CB_ASSERT(m_callbacks, iparent != NONE || iprev_sibling == NONE);
if(iparent == NONE)
m_parent[child] = parent;
m_prev_sibling[child] = NONE;
m_next_sibling[child] = NONE;
_RYML_CB_ASSERT(m_callbacks, parent != NONE || child == 0);
_RYML_CB_ASSERT(m_callbacks, parent != NONE || iprev_sibling == NONE);
if(parent == NONE)
return;
id_type inext_sibling = iprev_sibling != NONE ? next_sibling(iprev_sibling) : first_child(iparent);
NodeRelation *C4_RESTRICT psib = nullptr;
NodeRelation *C4_RESTRICT nsib = nullptr;
id_type inext_sibling = iprev_sibling != NONE ? next_sibling(iprev_sibling) : first_child(parent);
if(iprev_sibling != NONE)
{
psib = &m_relation[iprev_sibling];
_RYML_CB_ASSERT(m_callbacks, next_sibling(iprev_sibling) == inext_sibling);
child->m_prev_sibling = iprev_sibling;
psib->m_next_sibling = ichild;
_RYML_CB_ASSERT(m_callbacks, psib->m_prev_sibling != psib->m_next_sibling || psib->m_prev_sibling == NONE);
m_prev_sibling[child] = iprev_sibling;
m_next_sibling[iprev_sibling] = child;
_RYML_CB_ASSERT(m_callbacks, m_prev_sibling[iprev_sibling] != m_next_sibling[iprev_sibling] || m_prev_sibling[iprev_sibling] == NONE);
}
if(inext_sibling != NONE)
{
nsib = &m_relation[inext_sibling];
_RYML_CB_ASSERT(m_callbacks, prev_sibling(inext_sibling) == iprev_sibling);
child->m_next_sibling = inext_sibling;
nsib->m_prev_sibling = ichild;
_RYML_CB_ASSERT(m_callbacks, nsib->m_prev_sibling != nsib->m_next_sibling || nsib->m_prev_sibling == NONE);
m_next_sibling[child] = inext_sibling;
m_prev_sibling[inext_sibling] = child;
_RYML_CB_ASSERT(m_callbacks, m_prev_sibling[inext_sibling] != m_next_sibling[inext_sibling] || m_prev_sibling[inext_sibling]);
}
NodeRelation *C4_RESTRICT parent = &m_relation[iparent];
if(parent->m_first_child != NONE)
if(m_first_child[parent] != NONE)
{
if(child->m_next_sibling == parent->m_first_child)
parent->m_first_child = ichild;
if(child->m_prev_sibling == parent->m_last_child)
parent->m_last_child = ichild;
if(m_next_sibling[child] == m_first_child[parent])
m_first_child[parent] = child;
if(m_prev_sibling[child] == m_last_child[parent])
m_last_child[parent] = child;
}
else
{
_RYML_CB_ASSERT(m_callbacks, parent->m_last_child == NONE);
parent->m_first_child = ichild;
parent->m_last_child = ichild;
_RYML_CB_ASSERT(m_callbacks, m_last_child[parent] == NONE);
m_first_child[parent] = child;
m_last_child[parent] = child;
}
}
@@ -610,32 +653,20 @@ C4_SUPPRESS_WARNING_CLANG_POP
void Tree::_rem_hierarchy(id_type i)
{
_RYML_CB_ASSERT(m_callbacks, i >= 0 && i < m_cap);
NodeRelation &C4_RESTRICT w = m_relation[i];
// remove from the parent
if(w.m_parent != NONE)
const id_type parent = m_parent[i];
if(parent != NONE)
{
NodeRelation &C4_RESTRICT p = m_relation[w.m_parent];
if(p.m_first_child == i)
{
p.m_first_child = w.m_next_sibling;
}
if(p.m_last_child == i)
{
p.m_last_child = w.m_prev_sibling;
}
if(m_first_child[parent] == i)
m_first_child[parent] = m_next_sibling[i];
if(m_last_child[parent] == i)
m_last_child[parent] = m_prev_sibling[i];
}
// remove from the used list
if(w.m_prev_sibling != NONE)
{
NodeRelation *C4_RESTRICT prev = &m_relation[w.m_prev_sibling];
prev->m_next_sibling = w.m_next_sibling;
}
if(w.m_next_sibling != NONE)
{
NodeRelation *C4_RESTRICT next = &m_relation[w.m_next_sibling];
next->m_prev_sibling = w.m_prev_sibling;
}
if(m_prev_sibling[i] != NONE)
m_next_sibling[m_prev_sibling[i]] = m_next_sibling[i];
if(m_next_sibling[i] != NONE)
m_prev_sibling[m_next_sibling[i]] = m_prev_sibling[i];
}
//-----------------------------------------------------------------------------
@@ -701,153 +732,151 @@ void Tree::_swap(id_type n_, id_type m_)
}
//-----------------------------------------------------------------------------
void Tree::_swap_hierarchy(id_type ia, id_type ib)
void Tree::_swap_hierarchy(id_type a, id_type b)
{
if(ia == ib) return;
if(a == b) return;
for(id_type i = first_child(ia); i != NONE; i = next_sibling(i))
for(id_type i = first_child(a); i != NONE; i = next_sibling(i))
{
if(i == ib || i == ia)
if(i == b || i == a)
continue;
m_relation[i].m_parent = ib;
m_parent[i] = b;
}
for(id_type i = first_child(ib); i != NONE; i = next_sibling(i))
for(id_type i = first_child(b); i != NONE; i = next_sibling(i))
{
if(i == ib || i == ia)
if(i == b || i == a)
continue;
m_relation[i].m_parent = ia;
m_parent[i] = a;
}
auto & C4_RESTRICT a = m_relation[ia];
auto & C4_RESTRICT b = m_relation[ib];
auto & C4_RESTRICT pa = m_relation[a.m_parent];
auto & C4_RESTRICT pb = m_relation[b.m_parent];
auto & C4_RESTRICT pa = m_parent[a];
auto & C4_RESTRICT pb = m_parent[b];
if(&pa == &pb)
if(pa == pb)
{
if((pa.m_first_child == ib && pa.m_last_child == ia)
if((m_first_child[pa] == b && m_last_child[pa] == a)
||
(pa.m_first_child == ia && pa.m_last_child == ib))
(m_first_child[a] == a && m_last_child[pa] == b))
{
std::swap(pa.m_first_child, pa.m_last_child);
std::swap(m_first_child[pa], m_last_child[pa]);
}
else
{
bool changed = false;
if(pa.m_first_child == ia)
if(m_first_child[pa] == a)
{
pa.m_first_child = ib;
m_first_child[pa] = b;
changed = true;
}
if(pa.m_last_child == ia)
if(m_last_child[pa] == a)
{
pa.m_last_child = ib;
m_last_child[pa] = b;
changed = true;
}
if(pb.m_first_child == ib && !changed)
if(m_first_child[pb] == b && !changed)
{
pb.m_first_child = ia;
m_first_child[pb] = a;
}
if(pb.m_last_child == ib && !changed)
if(m_last_child[pb] == b && !changed)
{
pb.m_last_child = ia;
m_last_child[pb] = a;
}
}
}
else
{
if(pa.m_first_child == ia)
pa.m_first_child = ib;
if(pa.m_last_child == ia)
pa.m_last_child = ib;
if(pb.m_first_child == ib)
pb.m_first_child = ia;
if(pb.m_last_child == ib)
pb.m_last_child = ia;
if(m_first_child[pa] == a)
m_first_child[pa] = b;
if(m_last_child[pa] == a)
m_last_child[pa] = b;
if(m_first_child[pb] == b)
m_first_child[pb] = a;
if(m_last_child[pb] == b)
m_last_child[pb] = a;
}
std::swap(a.m_first_child , b.m_first_child);
std::swap(a.m_last_child , b.m_last_child);
std::swap(m_first_child[a] , m_first_child[b]);
std::swap(m_last_child[a] , m_last_child[b]);
if(a.m_prev_sibling != ib && b.m_prev_sibling != ia &&
a.m_next_sibling != ib && b.m_next_sibling != ia)
if(m_prev_sibling[a] != b && m_prev_sibling[b] != a &&
m_next_sibling[a] != b && m_next_sibling[b] != a)
{
if(a.m_prev_sibling != NONE && a.m_prev_sibling != ib)
m_relation[a.m_prev_sibling].m_next_sibling = ib;
if(a.m_next_sibling != NONE && a.m_next_sibling != ib)
m_relation[a.m_next_sibling].m_prev_sibling = ib;
if(b.m_prev_sibling != NONE && b.m_prev_sibling != ia)
m_relation[b.m_prev_sibling].m_next_sibling = ia;
if(b.m_next_sibling != NONE && b.m_next_sibling != ia)
m_relation[b.m_next_sibling].m_prev_sibling = ia;
std::swap(a.m_prev_sibling, b.m_prev_sibling);
std::swap(a.m_next_sibling, b.m_next_sibling);
if(m_prev_sibling[a] != NONE && m_prev_sibling[a] != b)
m_next_sibling[m_prev_sibling[a]] = b;
if(m_next_sibling[a] != NONE && m_next_sibling[a] != b)
m_prev_sibling[m_next_sibling[a]] = b;
if(m_prev_sibling[b] != NONE && m_prev_sibling[b] != a)
m_next_sibling[m_prev_sibling[b]] = a;
if(m_next_sibling[b] != NONE && m_next_sibling[b] != a)
m_prev_sibling[m_next_sibling[b]] = a;
std::swap(m_prev_sibling[a], m_prev_sibling[b]);
std::swap(m_next_sibling[a], m_next_sibling[b]);
}
else
{
if(a.m_next_sibling == ib) // n will go after m
if(m_next_sibling[a] == b) // n will go after m
{
_RYML_CB_ASSERT(m_callbacks, b.m_prev_sibling == ia);
if(a.m_prev_sibling != NONE)
_RYML_CB_ASSERT(m_callbacks, m_prev_sibling[b] == a);
if(m_prev_sibling[a] != NONE)
{
_RYML_CB_ASSERT(m_callbacks, a.m_prev_sibling != ib);
m_relation[a.m_prev_sibling].m_next_sibling = ib;
_RYML_CB_ASSERT(m_callbacks, m_prev_sibling[a] != b);
m_next_sibling[m_prev_sibling[a]] = b;
}
if(b.m_next_sibling != NONE)
if(m_next_sibling[b] != NONE)
{
_RYML_CB_ASSERT(m_callbacks, b.m_next_sibling != ia);
m_relation[b.m_next_sibling].m_prev_sibling = ia;
_RYML_CB_ASSERT(m_callbacks, m_next_sibling[b] != a);
m_prev_sibling[m_next_sibling[b]] = a;
}
id_type ns = b.m_next_sibling;
b.m_prev_sibling = a.m_prev_sibling;
b.m_next_sibling = ia;
a.m_prev_sibling = ib;
a.m_next_sibling = ns;
id_type ns = m_next_sibling[b];
m_prev_sibling[b] = m_prev_sibling[a];
m_next_sibling[b] = a;
m_prev_sibling[a] = b;
m_next_sibling[a] = ns;
}
else if(a.m_prev_sibling == ib) // m will go after n
else if(m_prev_sibling[a] == b) // m will go after n
{
_RYML_CB_ASSERT(m_callbacks, b.m_next_sibling == ia);
if(b.m_prev_sibling != NONE)
_RYML_CB_ASSERT(m_callbacks, m_next_sibling[b] == a);
if(m_prev_sibling[b] != NONE)
{
_RYML_CB_ASSERT(m_callbacks, b.m_prev_sibling != ia);
m_relation[b.m_prev_sibling].m_next_sibling = ia;
_RYML_CB_ASSERT(m_callbacks, m_prev_sibling[b] != a);
m_next_sibling[m_prev_sibling[b]] = a;
}
if(a.m_next_sibling != NONE)
if(m_next_sibling[a] != NONE)
{
_RYML_CB_ASSERT(m_callbacks, a.m_next_sibling != ib);
m_relation[a.m_next_sibling].m_prev_sibling = ib;
_RYML_CB_ASSERT(m_callbacks, m_next_sibling[a] != b);
m_prev_sibling[m_next_sibling[a]] = b;
}
id_type ns = b.m_prev_sibling;
a.m_prev_sibling = b.m_prev_sibling;
a.m_next_sibling = ib;
b.m_prev_sibling = ia;
b.m_next_sibling = ns;
id_type ns = m_prev_sibling[b];
m_prev_sibling[a] = m_prev_sibling[b];
m_next_sibling[a] = b;
m_prev_sibling[b] = a;
m_next_sibling[b] = ns;
}
else
{
C4_NEVER_REACH();
}
}
_RYML_CB_ASSERT(m_callbacks, a.m_next_sibling != ia);
_RYML_CB_ASSERT(m_callbacks, a.m_prev_sibling != ia);
_RYML_CB_ASSERT(m_callbacks, b.m_next_sibling != ib);
_RYML_CB_ASSERT(m_callbacks, b.m_prev_sibling != ib);
_RYML_CB_ASSERT(m_callbacks, m_next_sibling[a] != a);
_RYML_CB_ASSERT(m_callbacks, m_prev_sibling[a] != a);
_RYML_CB_ASSERT(m_callbacks, m_next_sibling[b] != b);
_RYML_CB_ASSERT(m_callbacks, m_prev_sibling[b] != b);
if(a.m_parent != ib && b.m_parent != ia)
if(m_parent[a] != b && m_parent[b] != a)
{
std::swap(a.m_parent, b.m_parent);
std::swap(m_parent[a], m_parent[b]);
}
else
{
if(a.m_parent == ib && b.m_parent != ia)
if(m_parent[a] == b && m_parent[b] != a)
{
a.m_parent = b.m_parent;
b.m_parent = ia;
m_parent[a] = m_parent[b];
m_parent[b] = a;
}
else if(a.m_parent != ib && b.m_parent == ia)
else if(m_parent[a] != b && m_parent[b] == a)
{
b.m_parent = a.m_parent;
a.m_parent = ib;
m_parent[b] = m_parent[a];
m_parent[a] = b;
}
else
{
@@ -859,34 +888,32 @@ void Tree::_swap_hierarchy(id_type ia, id_type ib)
//-----------------------------------------------------------------------------
void Tree::_copy_hierarchy(id_type dst_, id_type src_)
{
auto const& C4_RESTRICT src = m_relation[src_];
auto & C4_RESTRICT dst = m_relation[dst_];
auto & C4_RESTRICT prt = m_relation[src.m_parent];
for(id_type i = src.m_first_child; i != NONE; i = next_sibling(i))
const id_type prt = m_parent[src_];
for(id_type i = m_first_child[src_]; i != NONE; i = next_sibling(i))
{
m_relation[i].m_parent = dst_;
m_parent[i] = dst_;
}
if(src.m_prev_sibling != NONE)
if(m_prev_sibling[src_] != NONE)
{
m_relation[src.m_prev_sibling].m_next_sibling = dst_;
m_next_sibling[m_prev_sibling[src_]] = dst_;
}
if(src.m_next_sibling != NONE)
if(m_next_sibling[src_] != NONE)
{
m_relation[src.m_next_sibling].m_prev_sibling = dst_;
m_prev_sibling[m_next_sibling[src_]] = dst_;
}
if(prt.m_first_child == src_)
if(m_first_child[prt] == src_)
{
prt.m_first_child = dst_;
m_first_child[prt] = dst_;
}
if(prt.m_last_child == src_)
if(m_last_child[prt] == src_)
{
prt.m_last_child = dst_;
m_last_child[prt] = dst_;
}
dst.m_parent = src.m_parent;
dst.m_first_child = src.m_first_child;
dst.m_last_child = src.m_last_child;
dst.m_prev_sibling = src.m_prev_sibling;
dst.m_next_sibling = src.m_next_sibling;
m_parent[dst_] = m_parent[src_];
m_first_child[dst_] = m_first_child[src_];
m_last_child[dst_] = m_last_child[src_];
m_prev_sibling[dst_] = m_prev_sibling[src_];
m_next_sibling[dst_] = m_next_sibling[src_];
}
//-----------------------------------------------------------------------------
@@ -981,14 +1008,14 @@ void Tree::set_root_as_stream()
void Tree::remove_children(id_type node)
{
_ryml_chkid(node);
id_type ich = m_relation[node].m_first_child;
id_type ich = m_first_child[node];
while(ich != NONE)
{
remove_children(ich);
_ryml_chkid(ich);
const id_type next = m_relation[ich].m_next_sibling;
const id_type next = m_next_sibling[ich];
_release(ich);
if(ich == m_relation[node].m_last_child)
if(ich == m_last_child[node])
break;
ich = next;
}
@@ -1301,14 +1328,14 @@ id_type Tree::find_child(id_type node, csubstr const& name) const
_ryml_chkid(node);
_RYML_CB_ASSERT(m_callbacks, node != NONE);
_RYML_CB_ASSERT(m_callbacks, is_map(node));
if(m_relation[node].m_first_child == NONE)
if(m_first_child[node] == NONE)
{
_RYML_CB_ASSERT(m_callbacks, m_relation[node].m_last_child == NONE);
_RYML_CB_ASSERT(m_callbacks, m_last_child[node] == NONE);
return NONE;
}
else
{
_RYML_CB_ASSERT(m_callbacks, m_relation[node].m_last_child != NONE);
_RYML_CB_ASSERT(m_callbacks, m_last_child[node] != NONE);
}
for(id_type i = first_child(node); i != NONE; i = next_sibling(i))
{

View File

@@ -200,22 +200,6 @@ public:
};
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
struct RYML_EXPORT NodeRelation
{
id_type m_parent;
id_type m_first_child;
id_type m_last_child;
id_type m_next_sibling;
id_type m_prev_sibling;
};
C4_MUST_BE_TRIVIAL_COPY(NodeRelation);
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
@@ -367,8 +351,8 @@ public:
C4_ALWAYS_INLINE bool is_val_ref(id_type node) const { _ryml_chkid(node); return m_type[node].is_val_ref(); }
C4_ALWAYS_INLINE bool is_ref(id_type node) const { _ryml_chkid(node); return m_type[node].is_ref(); }
C4_ALWAYS_INLINE bool parent_is_seq(id_type node) const { _ryml_chkid(node); _RYML_CB_ASSERT(m_callbacks, has_parent(node)); return is_seq(m_relation[node].m_parent); }
C4_ALWAYS_INLINE bool parent_is_map(id_type node) const { _ryml_chkid(node); _RYML_CB_ASSERT(m_callbacks, has_parent(node)); return is_map(m_relation[node].m_parent); }
C4_ALWAYS_INLINE bool parent_is_seq(id_type node) const { _ryml_chkid(node); _RYML_CB_ASSERT(m_callbacks, has_parent(node)); return is_seq(m_parent[node]); }
C4_ALWAYS_INLINE bool parent_is_map(id_type node) const { _ryml_chkid(node); _RYML_CB_ASSERT(m_callbacks, has_parent(node)); return is_map(m_parent[node]); }
/** true when the node has an anchor named a */
C4_ALWAYS_INLINE bool has_anchor(id_type node, csubstr a) const { _ryml_chkid(node); return ((m_type[node] & KEYANCH) && m_key_anchor[node] == a) || ((m_type[node] & VALANCH) && m_val_anchor[node] == a); }
@@ -401,9 +385,9 @@ public:
/** @name hierarchy predicates */
/** @{ */
bool is_root(id_type node) const { _ryml_chkid(node); _RYML_CB_ASSERT(m_callbacks, m_relation[node].m_parent != NONE || node == 0); return m_relation[node].m_parent == NONE; }
bool is_root(id_type node) const { _ryml_chkid(node); _RYML_CB_ASSERT(m_callbacks, m_parent[node] != NONE || node == 0); return m_parent[node] == NONE; }
bool has_parent(id_type node) const { _ryml_chkid(node); return m_relation[node].m_parent != NONE; }
bool has_parent(id_type node) const { _ryml_chkid(node); return m_parent[node] != NONE; }
/** true when key and val are empty, and has no children */
bool empty(id_type node) const
@@ -414,26 +398,23 @@ public:
}
/** true if @p node has a child with id @p ch */
bool has_child(id_type node, id_type ch) const { _ryml_chkid(node); return m_relation[ch].m_parent == node; }
bool has_child(id_type node, id_type ch) const { _ryml_chkid(node); return m_parent[ch] == node; }
/** true if @p node has a child with key @p key */
bool has_child(id_type node, csubstr key) const { _ryml_chkid(node); return find_child(node, key) != NONE; }
/** true if @p node has any children key */
bool has_children(id_type node) const { _ryml_chkid(node); return m_relation[node].m_first_child != NONE; }
bool has_children(id_type node) const { _ryml_chkid(node); return m_first_child[node] != NONE; }
/** true if @p node has a sibling with id @p sib */
bool has_sibling(id_type node, id_type sib) const { _ryml_chkid(node); return m_relation[node].m_parent == m_relation[sib].m_parent; }
bool has_sibling(id_type node, id_type sib) const { _ryml_chkid(node); return m_parent[node] == m_parent[sib]; }
/** true if one of the node's siblings has the given key */
bool has_sibling(id_type node, csubstr key) const { _ryml_chkid(node); return find_sibling(node, key) != NONE; }
/** true if node is not a single child */
bool has_other_siblings(id_type node) const
{
_ryml_chkid(node);
NodeRelation const *C4_RESTRICT n = &m_relation[node];
if(C4_LIKELY(n->m_parent != NONE))
{
n = &m_relation[n->m_parent];
return n->m_first_child != n->m_last_child;
}
const id_type parent = m_parent[node];
if(C4_LIKELY(parent != NONE))
return m_first_child[parent] != m_last_child[parent];
return false;
}
@@ -446,29 +427,29 @@ public:
/** @name hierarchy getters */
/** @{ */
id_type parent(id_type node) const { _ryml_chkid(node); return m_relation[node].m_parent; }
id_type parent(id_type node) const { _ryml_chkid(node); return m_parent[node]; }
id_type prev_sibling(id_type node) const { _ryml_chkid(node); return m_relation[node].m_prev_sibling; }
id_type next_sibling(id_type node) const { _ryml_chkid(node); return m_relation[node].m_next_sibling; }
id_type prev_sibling(id_type node) const { _ryml_chkid(node); return m_prev_sibling[node]; }
id_type next_sibling(id_type node) const { _ryml_chkid(node); return m_next_sibling[node]; }
/** O(#num_children) */
id_type num_children(id_type node) const;
id_type child_pos(id_type node, id_type ch) const;
id_type first_child(id_type node) const { _ryml_chkid(node); return m_relation[node].m_first_child; }
id_type last_child(id_type node) const { _ryml_chkid(node); return m_relation[node].m_last_child; }
id_type first_child(id_type node) const { _ryml_chkid(node); return m_first_child[node]; }
id_type last_child(id_type node) const { _ryml_chkid(node); return m_last_child[node]; }
id_type child(id_type node, id_type pos) const;
id_type find_child(id_type node, csubstr const& key) const;
/** O(#num_siblings) */
/** counts with this */
id_type num_siblings(id_type node) const { _ryml_chkid(node); return is_root(node) ? 1 : num_children(m_relation[node].m_parent); }
id_type num_siblings(id_type node) const { _ryml_chkid(node); return is_root(node) ? 1 : num_children(m_parent[node]); }
/** does not count with this */
id_type num_other_siblings(id_type node) const { _ryml_chkid(node); id_type ns = num_siblings(node); _RYML_CB_ASSERT(m_callbacks, ns > 0); return ns-1; }
id_type sibling_pos(id_type node, id_type sib) const { _ryml_chkid(node); _ryml_chkid(sib); _RYML_CB_ASSERT(m_callbacks, ! is_root(node) || node == root_id()); return child_pos(m_relation[node].m_parent, sib); }
id_type first_sibling(id_type node) const { _ryml_chkid(node); return is_root(node) ? node : m_relation[m_relation[node].m_parent].m_first_child; }
id_type last_sibling(id_type node) const { _ryml_chkid(node); return is_root(node) ? node : m_relation[m_relation[node].m_parent].m_last_child; }
id_type sibling(id_type node, id_type pos) const { _ryml_chkid(node); return child(m_relation[node].m_parent, pos); }
id_type find_sibling(id_type node, csubstr const& key) const { _ryml_chkid(node); return find_child(m_relation[node].m_parent, key); }
id_type sibling_pos(id_type node, id_type sib) const { _ryml_chkid(node); _ryml_chkid(sib); _RYML_CB_ASSERT(m_callbacks, ! is_root(node) || node == root_id()); return child_pos(m_parent[node], sib); }
id_type first_sibling(id_type node) const { _ryml_chkid(node); return is_root(node) ? node : m_first_child[m_parent[node]]; }
id_type last_sibling(id_type node) const { _ryml_chkid(node); return is_root(node) ? node : m_last_child[m_parent[node]]; }
id_type sibling(id_type node, id_type pos) const { _ryml_chkid(node); return child(m_parent[node], pos); }
id_type find_sibling(id_type node, csubstr const& key) const { _ryml_chkid(node); return find_child(m_parent[node], key); }
id_type doc(id_type i) const { id_type rid = root_id(); _RYML_CB_ASSERT(m_callbacks, is_stream(rid)); return child(rid, i); } //!< gets the @p i document node index. requires that the root node is a stream.
@@ -646,7 +627,7 @@ public:
{
_RYML_CB_ASSERT(m_callbacks, parent != NONE);
_RYML_CB_ASSERT(m_callbacks, is_container(parent) || is_root(parent));
_RYML_CB_ASSERT(m_callbacks, after == NONE || (m_relation[after].m_parent == parent));
_RYML_CB_ASSERT(m_callbacks, after == NONE || (m_parent[after] == parent));
id_type child = _claim();
_set_hierarchy(child, parent, after);
return child;
@@ -654,11 +635,11 @@ public:
/** create and insert a node as the first child of @p parent */
C4_ALWAYS_INLINE id_type prepend_child(id_type parent) { return insert_child(parent, NONE); }
/** create and insert a node as the last child of @p parent */
C4_ALWAYS_INLINE id_type append_child(id_type parent) { return insert_child(parent, m_relation[parent].m_last_child); }
C4_ALWAYS_INLINE id_type append_child(id_type parent) { return insert_child(parent, m_last_child[parent]); }
C4_ALWAYS_INLINE id_type _append_child__unprotected(id_type parent)
{
id_type child = _claim();
_set_hierarchy(child, parent, m_relation[parent].m_last_child);
_set_hierarchy(child, parent, m_last_child[parent]);
return child;
}
@@ -667,11 +648,11 @@ public:
//! create and insert a new sibling of n. insert after "after"
C4_ALWAYS_INLINE id_type insert_sibling(id_type node, id_type after)
{
return insert_child(m_relation[node].m_parent, after);
return insert_child(m_parent[node], after);
}
/** create and insert a node as the first node of @p parent */
C4_ALWAYS_INLINE id_type prepend_sibling(id_type node) { return prepend_child(m_relation[node].m_parent); }
C4_ALWAYS_INLINE id_type append_sibling(id_type node) { return append_child(m_relation[node].m_parent); }
C4_ALWAYS_INLINE id_type prepend_sibling(id_type node) { return prepend_child(m_parent[node]); }
C4_ALWAYS_INLINE id_type append_sibling(id_type node) { return append_child(m_parent[node]); }
public:
@@ -1076,12 +1057,6 @@ public:
/** @cond dev*/
id_type _id(NodeRelation const* C4_RESTRICT nr) const
{
_RYML_CB_ASSERT(m_callbacks, nr == nullptr || (nr >= m_relation && nr < m_relation + m_cap));
return nr ? (id_type)(nr - m_relation) : NONE;
}
#if ! RYML_USE_ASSERT
C4_ALWAYS_INLINE void _check_next_flags(id_type, type_bits) {}
#else
@@ -1176,7 +1151,7 @@ public:
void _set_parent_as_container_if_needed(id_type node)
{
id_type parent = m_relation[node].m_parent;
id_type parent = m_parent[node];
if(parent != NONE)
{
if( ! (is_seq(parent) || is_map(parent)))
@@ -1279,9 +1254,9 @@ public:
//m_val[node].clear();
//m_val_tag[node].clear();
//m_val_anchor[node].clear();
m_relation[node].m_parent = NONE;
m_relation[node].m_first_child = NONE;
m_relation[node].m_last_child = NONE;
m_parent[node] = NONE;
m_first_child[node] = NONE;
m_last_child[node] = NONE;
}
inline void _clear_key(id_type node)
@@ -1324,13 +1299,19 @@ public:
// formerly NodeData
NodeType *C4_RESTRICT m_type;
csubstr *C4_RESTRICT m_val;
csubstr *C4_RESTRICT m_val_tag;
csubstr *C4_RESTRICT m_val_anchor;
csubstr *C4_RESTRICT m_key;
csubstr *C4_RESTRICT m_key_tag;
csubstr *C4_RESTRICT m_key_anchor;
NodeRelation *C4_RESTRICT m_relation;
id_type *C4_RESTRICT m_parent;
id_type *C4_RESTRICT m_first_child;
id_type *C4_RESTRICT m_last_child;
id_type *C4_RESTRICT m_prev_sibling;
id_type *C4_RESTRICT m_next_sibling;
id_type m_cap;
id_type m_size;

View File

@@ -562,7 +562,7 @@ size_t test_tree_invariants(ConstNodeRef const& n)
ConstNodeRef parent = n.parent();
Tree const& t = *n.tree();
id_type id = n.id();
if(t.m_relation[id].m_prev_sibling == NONE)
if(t.m_prev_sibling[id] == NONE)
{
if(parent.readable())
{
@@ -570,7 +570,7 @@ size_t test_tree_invariants(ConstNodeRef const& n)
}
}
if(t.m_relation[id].m_next_sibling == NONE)
if(t.m_next_sibling[id] == NONE)
{
if(parent.readable())
{

View File

@@ -867,7 +867,11 @@ TEST(Tree, reserve)
csubstr const* m_key = t.m_key;
csubstr const* m_key_tag = t.m_key_tag;
csubstr const* m_key_anchor = t.m_key_anchor;
NodeRelation const* m_relation = t.m_relation;
id_type const* m_parent = t.m_parent;
id_type const* m_first_child = t.m_first_child;
id_type const* m_last_child = t.m_last_child;
id_type const* m_prev_sibling = t.m_prev_sibling;
id_type const* m_next_sibling = t.m_next_sibling;
t.reserve(16);
t.reserve_arena(64);
EXPECT_EQ(t.m_type, m_type);
@@ -877,7 +881,11 @@ TEST(Tree, reserve)
EXPECT_EQ(t.m_key, m_key);
EXPECT_EQ(t.m_key_tag, m_key_tag);
EXPECT_EQ(t.m_key_anchor, m_key_anchor);
EXPECT_EQ(t.m_relation, m_relation);
EXPECT_EQ(t.m_parent, m_parent);
EXPECT_EQ(t.m_first_child, m_first_child);
EXPECT_EQ(t.m_last_child, m_last_child);
EXPECT_EQ(t.m_prev_sibling, m_prev_sibling);
EXPECT_EQ(t.m_next_sibling, m_next_sibling);
EXPECT_EQ(t.capacity(), 16);
EXPECT_EQ(t.slack(), 15);
EXPECT_EQ(t.size(), 1);
@@ -903,7 +911,11 @@ TEST(Tree, reserve)
m_key = t.m_key;
m_key_tag = t.m_key_tag;
m_key_anchor = t.m_key_anchor;
m_relation = t.m_relation;
m_parent = t.m_parent;
m_first_child = t.m_first_child;
m_last_child = t.m_last_child;
m_prev_sibling = t.m_prev_sibling;
m_next_sibling = t.m_next_sibling;
parse_in_arena("[a, b, c, d, e, f]", &t);
EXPECT_EQ(t.m_type, m_type);
EXPECT_EQ(t.m_val, m_val);
@@ -912,7 +924,11 @@ TEST(Tree, reserve)
EXPECT_EQ(t.m_key, m_key);
EXPECT_EQ(t.m_key_tag, m_key_tag);
EXPECT_EQ(t.m_key_anchor, m_key_anchor);
EXPECT_EQ(t.m_relation, m_relation);
EXPECT_EQ(t.m_parent, m_parent);
EXPECT_EQ(t.m_first_child, m_first_child);
EXPECT_EQ(t.m_last_child, m_last_child);
EXPECT_EQ(t.m_prev_sibling, m_prev_sibling);
EXPECT_EQ(t.m_next_sibling, m_next_sibling);
EXPECT_EQ(t.capacity(), 32);
EXPECT_EQ(t.slack(), 25);
EXPECT_EQ(t.size(), 7);
@@ -986,7 +1002,11 @@ TEST(Tree, clear)
csubstr const* m_key = t.m_key;
csubstr const* m_key_tag = t.m_key_tag;
csubstr const* m_key_anchor = t.m_key_anchor;
NodeRelation const* m_relation = t.m_relation;
id_type const* m_parent = t.m_parent;
id_type const* m_first_child = t.m_first_child;
id_type const* m_last_child = t.m_last_child;
id_type const* m_prev_sibling = t.m_prev_sibling;
id_type const* m_next_sibling = t.m_next_sibling;
t.reserve(16);
t.reserve_arena(64);
EXPECT_EQ(t.m_type, m_type);
@@ -996,7 +1016,11 @@ TEST(Tree, clear)
EXPECT_EQ(t.m_key, m_key);
EXPECT_EQ(t.m_key_tag, m_key_tag);
EXPECT_EQ(t.m_key_anchor, m_key_anchor);
EXPECT_EQ(t.m_relation, m_relation);
EXPECT_EQ(t.m_parent, m_parent);
EXPECT_EQ(t.m_first_child, m_first_child);
EXPECT_EQ(t.m_last_child, m_last_child);
EXPECT_EQ(t.m_prev_sibling, m_prev_sibling);
EXPECT_EQ(t.m_next_sibling, m_next_sibling);
EXPECT_EQ(t.capacity(), 16);
EXPECT_EQ(t.slack(), 15);
EXPECT_EQ(t.size(), 1);
@@ -1022,7 +1046,11 @@ TEST(Tree, clear)
m_key = t.m_key;
m_key_tag = t.m_key_tag;
m_key_anchor = t.m_key_anchor;
m_relation = t.m_relation;
m_parent = t.m_parent;
m_first_child = t.m_first_child;
m_last_child = t.m_last_child;
m_prev_sibling = t.m_prev_sibling;
m_next_sibling = t.m_next_sibling;
parse_in_arena("[a, b, c, d, e, f]", &t);
EXPECT_EQ(t.m_type, m_type);
EXPECT_EQ(t.m_val, m_val);
@@ -1031,7 +1059,11 @@ TEST(Tree, clear)
EXPECT_EQ(t.m_key, m_key);
EXPECT_EQ(t.m_key_tag, m_key_tag);
EXPECT_EQ(t.m_key_anchor, m_key_anchor);
EXPECT_EQ(t.m_relation, m_relation);
EXPECT_EQ(t.m_parent, m_parent);
EXPECT_EQ(t.m_first_child, m_first_child);
EXPECT_EQ(t.m_last_child, m_last_child);
EXPECT_EQ(t.m_prev_sibling, m_prev_sibling);
EXPECT_EQ(t.m_next_sibling, m_next_sibling);
EXPECT_EQ(t.capacity(), 32);
EXPECT_EQ(t.slack(), 25);
EXPECT_EQ(t.size(), 7);