diff --git a/ds/include/blue/ds/tree.h b/ds/include/blue/ds/tree.h index f2cc0a8..d01f2a0 100644 --- a/ds/include/blue/ds/tree.h +++ b/ds/include/blue/ds/tree.h @@ -1,18 +1,25 @@ -#ifndef BLUELIB_TREE_H_ -#define BLUELIB_TREE_H_ +#ifndef BLUE_DS_TREE_H_ +#define BLUE_DS_TREE_H_ +#include #include #include #include -#define B_TREE(p) ((b_tree *)(p)) -#define B_TREE_NODE_INIT ((b_tree_node){0}) +B_DECLS_BEGIN; + +#define B_TYPE_TREE (b_tree_get_type()) + +B_DECLARE_TYPE(b_tree); + +B_TYPE_CLASS_DECLARATION_BEGIN(b_tree) +B_TYPE_CLASS_DECLARATION_END(b_tree) + +#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)) -typedef struct b_tree b_tree; - #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)) @@ -29,8 +36,6 @@ typedef struct b_tree b_tree; typedef struct b_tree_node { struct b_tree_node *__p01, *__p02, *__p03; struct b_queue_entry __q01; - // struct b_tree_node *parent; - // struct b_tree_node *first_child, *next_sibling; } b_tree_node; typedef struct b_tree_iterator { @@ -41,16 +46,9 @@ typedef struct b_tree_iterator { unsigned char _f01; } b_tree_iterator; -BLUE_API b_tree *b_tree_create(void); +BLUE_API b_type b_tree_get_type(void); -static inline b_tree *b_tree_retain(b_tree *tree) -{ - return B_TREE(b_retain(B_DSREF(tree))); -} -static inline void b_tree_release(b_tree *tree) -{ - b_release(B_DSREF(tree)); -} +B_TYPE_DEFAULT_CONSTRUCTOR(b_tree, B_TYPE_TREE); BLUE_API void b_tree_set_root(b_tree *tree, struct b_tree_node *node); @@ -69,4 +67,6 @@ 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); +B_DECLS_END; + #endif diff --git a/ds/tree.c b/ds/tree.c index 24f2229..fa216a0 100644 --- a/ds/tree.c +++ b/ds/tree.c @@ -1,8 +1,4 @@ -#include "tree.h" - -#include #include -#include #include #include @@ -16,27 +12,85 @@ #define NODE_FIRST_CHILD(n) ((n)->__p02) #define NODE_NEXT_SIBLING(n) ((n)->__p03) -static struct b_dsref_type tree_type = { - .t_name = "corelib::tree", - .t_flags = B_DSREF_FUNDAMENTAL, - .t_id = B_DSREF_TYPE_TREE, - .t_instance_size = sizeof(struct b_tree), +/*** PRIVATE DATA *************************************************************/ + +struct b_tree_p { + struct b_tree_node *t_root; }; -struct b_tree *b_tree_create(void) +/*** PRIVATE FUNCTIONS ********************************************************/ + +static void tree_set_root(struct b_tree_p *tree, struct b_tree_node *node) { - struct b_tree *tree - = (struct b_tree *)b_dsref_type_instantiate(&tree_type); - if (!tree) { + 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; } - return tree; + 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; } -void b_tree_set_root(struct b_tree *tree, struct b_tree_node *node) +static void reparent_children( + struct b_tree_node *old_parent, struct b_tree_node *new_parent) { - tree->t_root = node; + 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) @@ -85,6 +139,35 @@ struct b_tree_node *b_tree_node_get_child(struct b_tree_node *node, size_t at) 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); @@ -105,9 +188,10 @@ struct b_tree_node *b_tree_node_get_parent(struct b_tree_node *node) return NODE_PARENT(node); } -int b_tree_iterator_begin(struct b_tree *tree, b_tree_iterator *it) +int b_tree_iterator_begin(b_tree *tree, b_tree_iterator *it) { - return b_tree_iterator_begin_at_node_recursive(tree->t_root, 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 = { @@ -143,42 +227,6 @@ int b_tree_iterator_begin_at_node_recursive( return 0; } -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; -} - bool b_tree_iterator_next(struct b_tree_iterator *it) { int depth_diff = 0; @@ -229,31 +277,6 @@ static void remove_node(struct b_tree_node *node) 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; - } -} - b_status b_tree_iterator_erase(struct b_tree_iterator *it) { if (!it->node) { @@ -293,8 +316,3 @@ bool b_tree_iterator_is_valid(const struct b_tree_iterator *it) { return it->node != NULL; } - -b_dsref_type_id b_tree_type_id(void) -{ - return (b_dsref_type_id)&tree_type; -} diff --git a/ds/tree.h b/ds/tree.h deleted file mode 100644 index 8db19b4..0000000 --- a/ds/tree.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef _B_TREE_H_ -#define _B_TREE_H_ - -#include "../object.h" - -#include -#include - -struct b_tree { - struct b_dsref t_base; - struct b_tree_node *t_root; -}; - -#endif