From 2d5da8605d6b23842c05620ce798cef206b0b64a Mon Sep 17 00:00:00 2001 From: Max Wash Date: Wed, 29 Oct 2025 14:35:46 +0000 Subject: [PATCH] ds: tree: update iterator interface --- ds/include/blue/ds/tree.h | 43 ++---- ds/tree.c | 281 +++++++++++++++++++++++--------------- 2 files changed, 185 insertions(+), 139 deletions(-) diff --git a/ds/include/blue/ds/tree.h b/ds/include/blue/ds/tree.h index d01f2a0..7d2a272 100644 --- a/ds/include/blue/ds/tree.h +++ b/ds/include/blue/ds/tree.h @@ -8,45 +8,30 @@ B_DECLS_BEGIN; -#define B_TYPE_TREE (b_tree_get_type()) +#define B_TYPE_TREE (b_tree_get_type()) +#define B_TYPE_TREE_ITERATOR (b_tree_iterator_get_type()) B_DECLARE_TYPE(b_tree); +B_DECLARE_TYPE(b_tree_iterator); B_TYPE_CLASS_DECLARATION_BEGIN(b_tree) B_TYPE_CLASS_DECLARATION_END(b_tree) +B_TYPE_CLASS_DECLARATION_BEGIN(b_tree_iterator) +B_TYPE_CLASS_DECLARATION_END(b_tree_iterator) + #define B_TREE_NODE_INIT ((b_tree_node) {0}) #define B_TREE_CONTAINER(t, m, v) \ ((void *)((v) ? (uintptr_t)(v) - (offsetof(t, m)) : 0)) -#define b_tree_node_foreach(it, node) \ - for (int z__b_unique_name() = b_tree_iterator_begin_at_node(node, it); \ - (it)->node != NULL; b_tree_iterator_next(it)) - -#define b_tree_node_foreach_recursive(it, node) \ - for (int z__b_unique_name() \ - = b_tree_iterator_begin_at_node_recursive(node, it); \ - (it)->node != NULL; b_tree_iterator_next(it)) - -#define b_tree_foreach(it, tree) \ - for (int z__b_unique_name() = b_tree_iterator_begin(tree, it); \ - (it)->node != NULL; b_tree_iterator_next(it)) - typedef struct b_tree_node { struct b_tree_node *__p01, *__p02, *__p03; struct b_queue_entry __q01; } b_tree_node; -typedef struct b_tree_iterator { - b_iterator _base; - size_t i, depth; - b_tree_node *node; - - unsigned char _f01; -} b_tree_iterator; - BLUE_API b_type b_tree_get_type(void); +BLUE_API b_type b_tree_iterator_get_type(void); B_TYPE_DEFAULT_CONSTRUCTOR(b_tree, B_TYPE_TREE); @@ -58,14 +43,14 @@ BLUE_API void b_tree_node_add_sibling(b_tree_node *node, b_tree_node *to_add); BLUE_API b_tree_node *b_tree_node_get_child(b_tree_node *node, size_t at); BLUE_API b_tree_node *b_tree_node_get_parent(b_tree_node *node); -BLUE_API int b_tree_iterator_begin(b_tree *tree, b_tree_iterator *it); -BLUE_API int b_tree_iterator_begin_at_node(b_tree_node *node, b_tree_iterator *it); -BLUE_API int b_tree_iterator_begin_at_node_recursive( - b_tree_node *node, b_tree_iterator *it); +BLUE_API b_iterator *b_tree_begin(b_tree *tree); +BLUE_API const b_iterator *b_tree_cbegin(const b_tree *tree); -BLUE_API bool b_tree_iterator_next(b_tree_iterator *it); -BLUE_API b_status b_tree_iterator_erase(b_tree_iterator *it); -BLUE_API bool b_tree_iterator_is_valid(const b_tree_iterator *it); +BLUE_API b_iterator *b_tree_node_begin(b_tree_node *node); +BLUE_API const b_iterator *b_tree_node_cbegin(const b_tree_node *node); + +BLUE_API b_iterator *b_tree_node_begin_recursive(b_tree_node *node); +BLUE_API const b_iterator *b_tree_node_cbegin_recursive(const b_tree_node *node); B_DECLS_END; diff --git a/ds/tree.c b/ds/tree.c index 1c5938d..e5e56ce 100644 --- a/ds/tree.c +++ b/ds/tree.c @@ -18,6 +18,13 @@ struct b_tree_p { struct b_tree_node *t_root; }; +struct b_tree_iterator_p { + size_t i, depth; + b_tree_node *node; + + unsigned char _f01; +}; + /*** PRIVATE FUNCTIONS ********************************************************/ static void tree_set_root(struct b_tree_p *tree, struct b_tree_node *node) @@ -61,6 +68,38 @@ static const struct b_tree_node *next_node( return next; } +static void remove_node(struct b_tree_node *node) +{ + struct b_tree_node *parent = NODE_PARENT(node); + if (!parent) { + return; + } + + struct b_tree_node *n0 = NULL, *n1 = NULL; + n0 = NODE_FIRST_CHILD(parent); + + while (n0) { + if (n0 == node) { + break; + } + + n1 = n0; + n0 = NODE_NEXT_SIBLING(n0); + } + + if (!n0) { + return; + } + + if (n1) { + NODE_NEXT_SIBLING(n1) = NODE_NEXT_SIBLING(n0); + } else { + NODE_FIRST_CHILD(parent) = NODE_NEXT_SIBLING(n0); + } + + NODE_PARENT(n0) = NODE_NEXT_SIBLING(n0) = NULL; +} + static void reparent_children( struct b_tree_node *old_parent, struct b_tree_node *new_parent) { @@ -139,6 +178,66 @@ struct b_tree_node *b_tree_node_get_child(struct b_tree_node *node, size_t at) return cur; } +b_iterator *b_tree_begin(b_tree *tree) +{ + struct b_tree_p *p = b_object_get_private(tree, B_TYPE_TREE); + return b_tree_node_begin(p->t_root); +} + +const b_iterator *b_tree_cbegin(const b_tree *tree) +{ + struct b_tree_p *p = b_object_get_private(tree, B_TYPE_TREE); + return b_tree_node_begin(p->t_root); +} + +b_iterator *b_tree_node_begin(struct b_tree_node *node) +{ + b_tree_iterator *it_obj = b_object_create(B_TYPE_TREE_ITERATOR); + struct b_tree_iterator_p *it + = b_object_get_private(it_obj, B_TYPE_TREE_ITERATOR); + + it->node = NODE_FIRST_CHILD(node); + it->i = 0; + it->depth = 0; + + ITERATOR_UNSET_RECURSIVE(it); + + if (!it->node) { + b_iterator_set_status(it_obj, B_ERR_NO_DATA); + } + + return it_obj; +} + +const b_iterator *b_tree_node_cbegin(const struct b_tree_node *node) +{ + return b_tree_node_begin((struct b_tree_node *)node); +} + +b_iterator *b_tree_node_begin_recursive(struct b_tree_node *node) +{ + b_tree_iterator *it_obj = b_object_create(B_TYPE_TREE_ITERATOR); + struct b_tree_iterator_p *it + = b_object_get_private(it_obj, B_TYPE_TREE_ITERATOR); + + it->node = node; + it->i = 0; + it->depth = 0; + + ITERATOR_SET_RECURSIVE(it); + + if (!it->node) { + b_iterator_set_status(it_obj, B_ERR_NO_DATA); + } + + return it_obj; +} + +const b_iterator *b_tree_node_cbegin_recursive(const struct b_tree_node *node) +{ + return b_tree_node_begin_recursive((struct b_tree_node *)node); +} + /*** VIRTUAL FUNCTIONS ********************************************************/ static void tree_init(b_object *obj, void *priv) @@ -151,85 +250,13 @@ static void tree_fini(b_object *obj, void *priv) struct b_tree_p *tree = priv; } -/*** CLASS DEFINITION *********************************************************/ - -B_TYPE_CLASS_DEFINITION_BEGIN(b_tree) - B_TYPE_CLASS_INTERFACE_BEGIN(b_object, B_TYPE_OBJECT) - B_INTERFACE_ENTRY(to_string) = NULL; - B_TYPE_CLASS_INTERFACE_END(b_object, B_TYPE_OBJECT) -B_TYPE_CLASS_DEFINITION_END(b_tree) - -B_TYPE_DEFINITION_BEGIN(b_tree) - B_TYPE_ID(0x8d8fa36b, 0xc515, 0x4803, 0x8124, 0xfd704f01b8ae); - B_TYPE_CLASS(b_tree_class); - B_TYPE_INSTANCE_PRIVATE(struct b_tree_p); - B_TYPE_INSTANCE_INIT(tree_init); - B_TYPE_INSTANCE_FINI(tree_fini); -B_TYPE_DEFINITION_END(b_tree) - /*** ITERATOR FUNCTIONS *******************************************************/ -static bool tree_iterator_next(struct b_iterator *it) +static enum b_status iterator_move_next(const b_iterator *obj) { - return b_tree_iterator_next((struct b_tree_iterator *)it); -} + struct b_tree_iterator_p *it + = b_object_get_private(obj, B_TYPE_TREE_ITERATOR); -static b_status tree_iterator_erase(struct b_iterator *it) -{ - return b_tree_iterator_erase((struct b_tree_iterator *)it); -} - -static bool tree_iterator_is_valid(const struct b_iterator *it) -{ - return b_tree_iterator_is_valid((const struct b_tree_iterator *)it); -} - -struct b_tree_node *b_tree_node_get_parent(struct b_tree_node *node) -{ - return NODE_PARENT(node); -} - -int b_tree_iterator_begin(b_tree *tree, b_tree_iterator *it) -{ - struct b_tree_p *p = b_object_get_private(tree, B_TYPE_TREE); - return b_tree_iterator_begin_at_node_recursive(p->t_root, it); -} - -static b_iterator_ops it_ops = { - .it_next = tree_iterator_next, - .it_erase = tree_iterator_erase, - .it_close = NULL, - .it_is_valid = tree_iterator_is_valid, -}; - -int b_tree_iterator_begin_at_node(struct b_tree_node *node, b_tree_iterator *it) -{ - it->node = NODE_FIRST_CHILD(node); - it->i = 0; - it->depth = 0; - - it->_base.it_ops = &it_ops; - - ITERATOR_UNSET_RECURSIVE(it); - - return 0; -} - -int b_tree_iterator_begin_at_node_recursive( - struct b_tree_node *node, b_tree_iterator *it) -{ - it->node = node; - it->i = 0; - it->depth = 0; - it->_base.it_ops = &it_ops; - - ITERATOR_SET_RECURSIVE(it); - - return 0; -} - -bool b_tree_iterator_next(struct b_tree_iterator *it) -{ int depth_diff = 0; const struct b_tree_node *next = next_node(it->node, ITERATOR_IS_RECURSIVE(it), &depth_diff); @@ -243,43 +270,14 @@ bool b_tree_iterator_next(struct b_tree_iterator *it) } it->node = (struct b_tree_node *)next; - return it->node != NULL; + return (it->node != NULL) ? B_SUCCESS : B_ERR_NO_DATA; } -static void remove_node(struct b_tree_node *node) +static enum b_status iterator_erase(b_iterator *obj) { - struct b_tree_node *parent = NODE_PARENT(node); - if (!parent) { - return; - } + struct b_tree_iterator_p *it + = b_object_get_private(obj, B_TYPE_TREE_ITERATOR); - struct b_tree_node *n0 = NULL, *n1 = NULL; - n0 = NODE_FIRST_CHILD(parent); - - while (n0) { - if (n0 == node) { - break; - } - - n1 = n0; - n0 = NODE_NEXT_SIBLING(n0); - } - - if (!n0) { - return; - } - - if (n1) { - NODE_NEXT_SIBLING(n1) = NODE_NEXT_SIBLING(n0); - } else { - NODE_FIRST_CHILD(parent) = NODE_NEXT_SIBLING(n0); - } - - NODE_PARENT(n0) = NODE_NEXT_SIBLING(n0) = NULL; -} - -b_status b_tree_iterator_erase(struct b_tree_iterator *it) -{ if (!it->node) { return B_ERR_OUT_OF_BOUNDS; } @@ -313,7 +311,70 @@ b_status b_tree_iterator_erase(struct b_tree_iterator *it) return B_SUCCESS; } -bool b_tree_iterator_is_valid(const struct b_tree_iterator *it) +static b_iterator_value iterator_get_value(b_iterator *obj) { - return it->node != NULL; + struct b_tree_iterator_p *it + = b_object_get_private(obj, B_TYPE_TREE_ITERATOR); + + if (!it->node) { + return B_ITERATOR_VALUE_NULL; + } + + return B_ITERATOR_VALUE_PTR(it->node); } + +static const b_iterator_value iterator_get_cvalue(const b_iterator *obj) +{ + struct b_tree_iterator_p *it + = b_object_get_private(obj, B_TYPE_TREE_ITERATOR); + + if (!it->node) { + return B_ITERATOR_VALUE_NULL; + } + + return B_ITERATOR_VALUE_CPTR(it->node); +} + +/*** CLASS DEFINITION *********************************************************/ + +// ---- b_tree DEFINITION +B_TYPE_CLASS_DEFINITION_BEGIN(b_tree) + B_TYPE_CLASS_INTERFACE_BEGIN(b_object, B_TYPE_OBJECT) + B_INTERFACE_ENTRY(to_string) = NULL; + B_TYPE_CLASS_INTERFACE_END(b_object, B_TYPE_OBJECT) + + B_TYPE_CLASS_INTERFACE_BEGIN(b_iterable, B_TYPE_ITERABLE) + B_INTERFACE_ENTRY(it_begin) = b_tree_begin; + B_INTERFACE_ENTRY(it_cbegin) = b_tree_cbegin; + B_TYPE_CLASS_INTERFACE_END(b_iterable, B_TYPE_ITERABLE) +B_TYPE_CLASS_DEFINITION_END(b_tree) + +B_TYPE_DEFINITION_BEGIN(b_tree) + B_TYPE_ID(0x8d8fa36b, 0xc515, 0x4803, 0x8124, 0xfd704f01b8ae); + B_TYPE_CLASS(b_tree_class); + B_TYPE_IMPLEMENTS(B_TYPE_ITERABLE); + B_TYPE_INSTANCE_PRIVATE(struct b_tree_p); + B_TYPE_INSTANCE_INIT(tree_init); + B_TYPE_INSTANCE_FINI(tree_fini); +B_TYPE_DEFINITION_END(b_tree) + +// ---- b_tree_iterator DEFINITION +B_TYPE_CLASS_DEFINITION_BEGIN(b_tree_iterator) + B_TYPE_CLASS_INTERFACE_BEGIN(b_object, B_TYPE_OBJECT) + B_INTERFACE_ENTRY(to_string) = NULL; + B_TYPE_CLASS_INTERFACE_END(b_object, B_TYPE_OBJECT) + + B_TYPE_CLASS_INTERFACE_BEGIN(b_iterator, B_TYPE_ITERATOR) + B_INTERFACE_ENTRY(it_move_next) = iterator_move_next; + B_INTERFACE_ENTRY(it_erase) = iterator_erase; + B_INTERFACE_ENTRY(it_get_value) = iterator_get_value; + B_INTERFACE_ENTRY(it_get_cvalue) = iterator_get_cvalue; + B_TYPE_CLASS_INTERFACE_END(b_iterator, B_TYPE_ITERATOR) +B_TYPE_CLASS_DEFINITION_END(b_tree_iterator) + +B_TYPE_DEFINITION_BEGIN(b_tree_iterator) + B_TYPE_ID(0xb896e671, 0x84b2, 0x4892, 0xaf09, 0x407f305f4bf8); + B_TYPE_EXTENDS(B_TYPE_ITERATOR); + B_TYPE_CLASS(b_tree_iterator_class); + B_TYPE_INSTANCE_PRIVATE(struct b_tree_iterator_p); +B_TYPE_DEFINITION_END(b_tree_iterator)