1 #ifndef _UL_GAVLREPCUST_H
2 #define _UL_GAVLREPCUST_H
11 * GAVL_CUST_NODE_INT_REP_IMP - Implementation of new custom tree with internal node allowed item repeat
12 * @cust_prefix: defines prefix for builded function names
13 * @cust_root_t: user defined structure type of root of the tree
14 * @cust_item_t: user defined structure type of items stored in the tree
15 * @cust_key_t: type of the key used for sorting of the items
16 * @cust_root_node: the field of the root structure pointing to the tree root node
17 * @cust_item_node: the field of item structure used for chaining of items
18 * @cust_item_key: the key field of item structure defining order of items
19 * @cust_cmp_fnc: the keys compare function
21 * This version of custom tree implementation allows multiple items with same
22 * key value to be stored in tree.
23 * There are two macros designed for building custom AVL trees. The macro
24 * %GAVL_CUST_NODE_INT_DEC declares functions for custom tree manipulations
25 * and is intended for use in header files.
26 * The macro %GAVL_CUST_NODE_INT_REP_IMP builds implementations for non-inlined
27 * functions declared by %GAVL_CUST_NODE_INT_DEC. The @cust_cmp_fnc is used
28 * for comparison of item keys in the search and insert functions. The types
29 * of two input arguments of @cust_cmp_fnc functions must correspond
30 * with @cust_key_t type. Return value should be positive for case when
31 * the first pointed key value is greater then second, negative for reverse
32 * case and zero for equal pointed values.
34 #define GAVL_CUST_NODE_INT_REP_IMP(cust_prefix, cust_root_t, cust_item_t, cust_key_t,\
35 cust_root_node, cust_item_node, cust_item_key, cust_cmp_fnc) \
37 void cust_prefix##_init_root_field(cust_root_t *root)\
39 root->cust_root_node=NULL;\
42 int cust_prefix##_search_node4(const cust_root_t *root, cust_key_t *key, gavl_node_t **nodep, int mode)\
46 n=p=root->cust_root_node;\
48 cmp=cust_cmp_fnc(cust_prefix##_node2key(root,n),key);\
52 }else if((cmp<0)||(mode&GAVL_FAFTER)){\
58 if(!cmp && (mode&GAVL_FFIRST)){\
60 cmp=cust_cmp_fnc(cust_prefix##_node2key(root,n),key);\
65 cmp=cust_cmp_fnc(cust_prefix##_node2key(root,n),key);\
80 int cust_prefix##_search_node(const cust_root_t *root, cust_key_t *key, gavl_node_t **nodep)\
82 return cust_prefix##_search_node4(root, key, nodep, 0);\
85 cust_item_t *cust_prefix##_find(const cust_root_t *root, cust_key_t *key)\
88 if(cust_prefix##_search_node4(root, key, &node, 0))\
90 return cust_prefix##_node2item(root,node);\
93 cust_item_t *cust_prefix##_find_first(const cust_root_t *root, cust_key_t *key)\
96 if(cust_prefix##_search_node4(root, key, &n, GAVL_FFIRST))\
98 return cust_prefix##_node2item(root,n);\
101 cust_item_t *cust_prefix##_find_after(const cust_root_t *root, cust_key_t *key)\
104 if(cust_prefix##_search_node4(root, key, &node, GAVL_FAFTER)<=0){\
105 if(node) node=gavl_next_node(node);\
107 return node?cust_prefix##_node2item(root,node):NULL;\
110 int cust_prefix##_insert(cust_root_t *root, cust_item_t *item)\
113 gavl_node_t *where, *n2add;\
115 cmp=cust_prefix##_search_node4(root, &item->cust_item_key, &where, GAVL_FAFTER);\
116 n2add=&item->cust_item_node;\
117 return gavl_insert_primitive_at(&root->cust_root_node, n2add, where, cmp);\
120 int cust_prefix##_delete_node(cust_root_t *root, gavl_node_t *node)\
122 return gavl_delete_primitive(&root->cust_root_node, node);\
125 int cust_prefix##_delete(cust_root_t *root, cust_item_t *item)\
129 if(!item) return -1;\
130 n=&item->cust_item_node;\
131 /*check if node is inserted into tree*/\
132 for(p=n; p->parent; p=p->parent);\
133 if(p!=root->cust_root_node)\
135 ret=gavl_delete_primitive(&root->cust_root_node, n);\
139 gavl_node_t *cust_prefix##_first_node(const cust_root_t *root)\
141 gavl_node_t *n=root->cust_root_node;\
148 gavl_node_t *cust_prefix##_last_node(const cust_root_t *root)\
150 gavl_node_t *n=root->cust_root_node;\
162 #endif /* _UL_GAVLREPCUST_H */