73static void** vt_sp_tree_search(
void* obj,
const void* key) {
return sp_tree_search(obj, key); }
74static void** vt_sp_tree_search_le(
void* obj,
const void* key) {
return sp_tree_search_le(obj, key); }
75static void** vt_sp_tree_search_lt(
void* obj,
const void* key) {
return sp_tree_search_lt(obj, key); }
76static void** vt_sp_tree_search_ge(
void* obj,
const void* key) {
return sp_tree_search_ge(obj, key); }
77static void** vt_sp_tree_search_gt(
void* obj,
const void* key) {
return sp_tree_search_gt(obj, key); }
79static bool vt_sp_tree_verify(
const void* obj) {
return sp_tree_verify(obj); }
80static bool vt_sp_itor_search(
void* itor,
const void* key) {
return sp_itor_search(itor, key); }
81static bool vt_sp_itor_remove(
void* itor) {
return sp_itor_remove(itor); }
122static sp_node* node_new(
void* key);
149 dct->
_vtable = &sp_tree_vtable;
160 unsigned rotations = 0;
189 if (pp->
llink == p) {
194 if ((pp->
llink = pr) != NULL)
200 if ((p->
llink = nr) != NULL)
207 if ((p->
llink = nr) != NULL)
213 if ((pp->
rlink = nl) != NULL)
217 if (pp->
rlink == p) {
222 if ((pp->
rlink = pl) != NULL)
228 if ((p->
rlink = nl) != NULL)
235 if ((p->
rlink = nl) != NULL)
241 if ((pp->
llink = nr) != NULL)
247 if (ppp->
llink == pp)
268 parent = node; node = node->
llink;
269 }
else if (cmp > 0) {
270 parent = node; node = node->
rlink;
280 if (!(node = node_new(key)))
283 if (!(node->
parent = parent)) {
290 parent->
llink = node;
292 parent->
rlink = node;
402 remove_node(
tree, node);
457 itor->
_vtable = &sp_tree_itor_vtable;
491 remove_node(itor->
tree, itor->
node);
int(* dict_compare_func)(const void *, const void *)
A pointer to a function that compares two keys.
void(* dict_delete_func)(void *, void *)
A pointer to a function that is called when a key-value pair gets removed from a dictionary.
bool(* dict_visit_func)(const void *, void *, void *)
A pointer to a function used for iterating over dictionary contents.
bool sp_itor_last(sp_itor *itor)
Position |itor| on the last element in key order and return true, or unposition it and return false i...
dict * sp_dict_new(dict_compare_func cmp_func)
Like sp_tree_new(), but wrapped in a generic dict for use with the dict_* macros.
dict_remove_result sp_tree_remove(sp_tree *tree, const void *key)
Remove the element with key |key|.
void ** sp_itor_datum(sp_itor *itor)
Return the address of the datum |itor| is positioned on, through which it can be read or replaced,...
bool sp_itor_nextn(sp_itor *itor, size_t count)
Move |itor| |count| elements forward and return whether it is still positioned.
bool sp_itor_search_ge(sp_itor *itor, const void *key)
Position |itor| on the least key greater than or equal to |key| and return true, or unposition it and...
bool sp_itor_prev(sp_itor *itor)
Move |itor| to the previous element in key order and return true, or unposition it and return false i...
dict_insert_result sp_tree_insert(sp_tree *tree, void *key)
Insert |key| unless an equal key is present.
size_t sp_tree_clear(sp_tree *tree, dict_delete_func delete_func)
Remove every element, calling |delete_func|(key, datum) for each unless |delete_func| is NULL.
void sp_itor_free(sp_itor *itor)
Free an iterator.
bool sp_tree_select(sp_tree *tree, size_t n, const void **key, void **datum)
Store the key and datum of the |n|th element in key order (0-based) through |key| and |datum| and ret...
size_t sp_tree_min_path_length(const sp_tree *tree)
Return the shallowest depth at which a child link is absent, the root being at depth 1,...
sp_itor * sp_itor_new(sp_tree *tree)
Create an iterator over |tree| that is not positioned on any element yet.
bool sp_itor_next(sp_itor *itor)
Move |itor| to the next element in key order and return true, or unposition it and return false if th...
int sp_itor_compare(const sp_itor *i1, const sp_itor *i2)
Compare the positions of two iterators over the same tree: return a negative value,...
bool sp_itor_remove(sp_itor *itor)
Remove the element |itor| is positioned on and unposition |itor|; return false if it was not position...
bool sp_itor_prevn(sp_itor *itor, size_t count)
Move |itor| |count| elements back and return whether it is still positioned.
size_t sp_tree_max_path_length(const sp_tree *tree)
Return the greatest depth of any node, the root being at depth 1, or 0 for an empty tree: the height ...
void ** sp_tree_search_lt(sp_tree *tree, const void *key)
Return the address of the datum of the greatest key less than |key|, or NULL if there is none.
dict_itor * sp_dict_itor_new(sp_tree *tree)
Like sp_itor_new(), but wrapped in a generic dict_itor for use with the dict_itor_* macros.
size_t sp_tree_free(sp_tree *tree, dict_delete_func delete_func)
Remove every element, calling |delete_func|(key, datum) for each unless |delete_func| is NULL,...
size_t sp_tree_traverse(sp_tree *tree, dict_visit_func visit, void *user_data)
Call |visit|(key, datum, |user_data|) for each element in key order, stopping early if |visit| return...
void sp_itor_invalidate(sp_itor *itor)
Unposition |itor|, so that it is not positioned on any element.
size_t sp_tree_count(const sp_tree *tree)
Return the number of elements.
void ** sp_tree_search_gt(sp_tree *tree, const void *key)
Return the address of the datum of the least key greater than |key|, or NULL if there is none.
void ** sp_tree_search_le(sp_tree *tree, const void *key)
Return the address of the datum of the greatest key less than or equal to |key|, or NULL if there is ...
bool sp_itor_valid(const sp_itor *itor)
Return whether |itor| is positioned on an element.
bool sp_itor_search_le(sp_itor *itor, const void *key)
Position |itor| on the greatest key less than or equal to |key| and return true, or unposition it and...
bool sp_tree_verify(const sp_tree *tree)
Check the internal invariants of the tree and return true if they hold, or print the first failed che...
bool sp_itor_first(sp_itor *itor)
Position |itor| on the first element in key order and return true, or unposition it and return false ...
size_t sp_tree_total_path_length(const sp_tree *tree)
Return the sum of the depths of all nodes, the root being at depth 1, or 0 for an empty tree.
bool sp_itor_search_lt(sp_itor *itor, const void *key)
Position |itor| on the greatest key less than |key| and return true, or unposition it and return fals...
const void * sp_itor_key(const sp_itor *itor)
Return the key |itor| is positioned on, or NULL if it is not positioned.
bool sp_itor_search_gt(sp_itor *itor, const void *key)
Position |itor| on the least key greater than |key| and return true, or unposition it and return fals...
sp_tree * sp_tree_new(dict_compare_func cmp_func)
Create an empty tree that orders keys with |cmp_func| (must not be NULL).
void ** sp_tree_search_ge(sp_tree *tree, const void *key)
Return the address of the datum of the least key greater than or equal to |key|, or NULL if there is ...
void ** sp_tree_search(sp_tree *tree, const void *key)
Return the address of the datum stored for |key|, or NULL if |key| is not present.
bool sp_itor_search(sp_itor *itor, const void *key)
Position |itor| on |key| and return true, or unposition it and return false if |key| is not present.
const itor_vtable * _vtable
The operations of one container type.
const dict_vtable * _vtable
dict_compare_func cmp_func
bool tree_iterator_last(void *Iterator)
size_t tree_free(void *Tree, dict_delete_func delete_func)
void * tree_search_gt_node(void *Tree, const void *key)
void ** tree_iterator_datum(void *Iterator)
bool tree_iterator_next(void *Iterator)
void * tree_search_le_node(void *Tree, const void *key)
void tree_iterator_invalidate(void *Iterator)
int tree_iterator_compare(const void *Iterator1, const void *Iterator2)
void * tree_search_node(void *Tree, const void *key)
bool tree_verify_common(const void *Tree)
bool tree_iterator_search_le(void *Iterator, const void *key)
void * tree_search_lt_node(void *Tree, const void *key)
bool tree_iterator_valid(const void *Iterator)
size_t tree_count(const void *Tree)
size_t tree_clear(void *Tree, dict_delete_func delete_func)
const void * tree_iterator_key(const void *Iterator)
size_t tree_min_path_length(const void *Tree)
void * tree_node_min(void *Node)
bool tree_iterator_nextn(void *Iterator, size_t count)
size_t tree_traverse(void *Tree, dict_visit_func visit, void *user_data)
size_t tree_total_path_length(const void *Tree)
bool tree_iterator_first(void *Iterator)
bool tree_select(void *Tree, size_t n, const void **key, void **datum)
void tree_iterator_free(void *Iterator)
bool tree_iterator_prevn(void *Iterator, size_t count)
bool tree_iterator_search_lt(void *Iterator, const void *key)
bool tree_iterator_search_ge(void *Iterator, const void *key)
size_t tree_max_path_length(const void *Tree)
void * tree_iterator_key_vt(void *Iterator)
int tree_iterator_compare_vt(void *Iterator1, void *Iterator2)
bool tree_iterator_search_gt(void *Iterator, const void *key)
void * tree_search_ge_node(void *Tree, const void *key)
bool tree_iterator_search(void *Iterator, const void *key)
bool tree_iterator_prev(void *Iterator)
#define TREE_NODE_FIELDS(node_type)
#define TREE_ITERATOR_FIELDS(tree_type, node_type)
#define TREE_FIELDS(node_type)