#include #include #include #define ITERATOR_RECURSIVE 0x01u #define ITERATOR_IS_RECURSIVE(it) (((it)->_f01 & ITERATOR_RECURSIVE) != 0) #define ITERATOR_UNSET_RECURSIVE(it) ((it)->_f01 &= ~ITERATOR_RECURSIVE) #define ITERATOR_SET_RECURSIVE(it) ((it)->_f01 |= ITERATOR_RECURSIVE) #define NODE_PARENT(n) ((n)->__p01) #define NODE_FIRST_CHILD(n) ((n)->__p02) #define NODE_NEXT_SIBLING(n) ((n)->__p03) /*** PRIVATE DATA *************************************************************/ struct b_tree_p { struct b_tree_node *t_root; }; /*** PRIVATE FUNCTIONS ********************************************************/ static void tree_set_root(struct b_tree_p *tree, struct b_tree_node *node) { tree->t_root = node; } static const struct b_tree_node *next_node( const struct b_tree_node *node, bool recursive, int *depth_diff) { if (!node) { return NULL; } if (!recursive) { node = NODE_NEXT_SIBLING(node); return node; } int d = 0; struct b_tree_node *next = NODE_FIRST_CHILD(node); if (next) { d = 1; *depth_diff = d; return next; } const struct b_tree_node *n = node; next = NODE_NEXT_SIBLING(n); while (!next) { n = NODE_PARENT(n); if (!n) { break; } d--; next = NODE_NEXT_SIBLING(n); } *depth_diff = d; return next; } static void reparent_children( struct b_tree_node *old_parent, struct b_tree_node *new_parent) { struct b_tree_node *last = NODE_FIRST_CHILD(new_parent); while (last && NODE_NEXT_SIBLING(last)) { last = NODE_NEXT_SIBLING(last); } struct b_tree_node *cur = NODE_FIRST_CHILD(old_parent); while (cur) { struct b_tree_node *next = NODE_NEXT_SIBLING(cur); NODE_PARENT(cur) = new_parent; NODE_NEXT_SIBLING(cur) = NULL; if (last) { NODE_NEXT_SIBLING(last) = cur; } else { NODE_FIRST_CHILD(new_parent) = cur; } last = cur; cur = next; } } /*** PUBLIC FUNCTIONS *********************************************************/ void b_tree_set_root(b_tree *tree, struct b_tree_node *node) { B_CLASS_DISPATCH_STATIC(B_TYPE_TREE, tree_set_root, tree, node); } void b_tree_node_add_child(struct b_tree_node *parent, struct b_tree_node *child) { if (NODE_PARENT(child)) { return; } NODE_PARENT(child) = parent; if (!NODE_FIRST_CHILD(parent)) { NODE_FIRST_CHILD(parent) = child; return; } struct b_tree_node *cur = NODE_FIRST_CHILD(parent); while (NODE_NEXT_SIBLING(cur)) { cur = NODE_NEXT_SIBLING(cur); } NODE_NEXT_SIBLING(cur) = child; } void b_tree_node_add_sibling(struct b_tree_node *node, struct b_tree_node *to_add) { if (NODE_PARENT(to_add) || !NODE_PARENT(node)) { return; } b_tree_node_add_child(NODE_PARENT(node), to_add); } struct b_tree_node *b_tree_node_get_child(struct b_tree_node *node, size_t at) { size_t i = 0; struct b_tree_node *cur = NODE_FIRST_CHILD(node); while (i < at) { if (!cur) { return NULL; } cur = NODE_NEXT_SIBLING(cur); i++; } return cur; } /*** VIRTUAL FUNCTIONS ********************************************************/ static void tree_init(b_object *obj, void *priv) { struct b_tree_p *tree = priv; } 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_INIT(tree_init); B_TYPE_INSTANCE_INIT(tree_fini); B_TYPE_DEFINITION_END(b_tree) /*** ITERATOR FUNCTIONS *******************************************************/ static bool tree_iterator_next(struct b_iterator *it) { return b_tree_iterator_next((struct b_tree_iterator *)it); } 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); if (next) { it->depth += depth_diff; it->i++; } else { it->depth = 0; it->i = 0; } it->node = (struct b_tree_node *)next; return it->node != NULL; } 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; } b_status b_tree_iterator_erase(struct b_tree_iterator *it) { if (!it->node) { return B_ERR_OUT_OF_BOUNDS; } struct b_tree_node *parent = NODE_PARENT(it->node); if (!parent) { return B_ERR_NOT_SUPPORTED; } int d = 0; struct b_tree_node *n = it->node; struct b_tree_node *next = NODE_NEXT_SIBLING(n); if (!next) { next = NODE_FIRST_CHILD(n); } while (!next) { n = NODE_PARENT(n); if (!n) { break; } d--; next = NODE_NEXT_SIBLING(n); } remove_node(it->node); reparent_children(it->node, parent); return B_SUCCESS; } bool b_tree_iterator_is_valid(const struct b_tree_iterator *it) { return it->node != NULL; }