From 453a920af8e3e362f0a8a15d65c2f0c0a206ad6b Mon Sep 17 00:00:00 2001 From: Patrick Pelissier Date: Sat, 4 Jun 2022 14:54:51 +0200 Subject: [PATCH] Add methods to scan in post-order a sub-tree --- m-tree.h | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/m-tree.h b/m-tree.h index 1f93854f..77d6a203 100644 --- a/m-tree.h +++ b/m-tree.h @@ -269,7 +269,7 @@ typedef int32_t m_tr33_index_t; ptr[i].parent = M_TR33_NO_NODE; \ ptr[i].left = M_TR33_NO_NODE; \ ptr[i].right = M_TR33_NO_NODE; \ - ptr[i].child = i+1; \ + ptr[i].child = i+1; \ } \ /* The last node has no child in the free node list */ \ ptr[alloc-1].child = M_TR33_NO_NODE; \ @@ -771,6 +771,38 @@ typedef int32_t m_tr33_index_t; M_TR33_IT_CONTRACT(*it, false); \ } \ \ + /* Scan all nodes, first the children then the parent */ \ + static inline it_t \ + M_C(name, _it_subpost)(it_t it) { \ + M_TR33_IT_CONTRACT(it, true); \ + /* Evaluate child first, so go down to the lowest child */ \ + while (M_C(name, _it_down)(&it)) {} \ + M_TR33_IT_CONTRACT(it, false); \ + return it; \ + } \ + \ + /* Scan all nodes, first the children then the parent (uses with _it_subpost) */ \ + static inline void \ + M_C(name, _next_subpost)(it_t *it, it_t ref) { \ + M_TR33_IT_CONTRACT(*it, true); \ + M_TR33_IT_CONTRACT(ref, true); \ + M_ASSERT(it->tree == ref.tree); \ + if (it->index == ref.index) { \ + /* Reach end of tree */ \ + it->index = M_TR33_NO_NODE; \ + return; \ + } \ + /* First go right */ \ + if (M_C(name, _it_right)(it)) { \ + /* then go down */ \ + while (M_C(name, _it_down)(it)) {} \ + return; \ + } \ + /* If impossible to go right, move up */ \ + bool b = M_C(name, _it_up)(it); \ + assert(b); \ + } \ + \ static inline void \ M_C(name, _prune)(it_t it) { \ M_TR33_IT_CONTRACT(it, true); \