mirror of
https://github.com/biojppm/rapidyaml.git
synced 2026-01-18 13:31:19 +01:00
soa hierarchy wip
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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))
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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())
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user