#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; }; 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) { 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 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) { 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; } 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) { struct b_tree_p *tree = priv; } static void tree_fini(b_object *obj, void *priv) { struct b_tree_p *tree = priv; } /*** ITERATOR FUNCTIONS *******************************************************/ static enum b_status iterator_move_next(const b_iterator *obj) { struct b_tree_iterator_p *it = b_object_get_private(obj, B_TYPE_TREE_ITERATOR); 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) ? B_SUCCESS : B_ERR_NO_DATA; } static enum b_status iterator_erase(b_iterator *obj) { struct b_tree_iterator_p *it = b_object_get_private(obj, B_TYPE_TREE_ITERATOR); 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; } static b_iterator_value iterator_get_value(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_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)