ucx
UAP Common Extensions
Loading...
Searching...
No Matches
tree.h
Go to the documentation of this file.
1/*
2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3 *
4 * Copyright 2024 Mike Becker, Olaf Wintermann All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE.
27 */
35
36#ifndef UCX_TREE_H
37#define UCX_TREE_H
38
39#include "common.h"
40
41#include "collection.h"
42
43#ifdef __cplusplus
44extern "C" {
45#endif
46
63typedef struct cx_tree_iterator_s {
71 bool skip;
80 bool exiting;
84 ptrdiff_t loc_children;
88 ptrdiff_t loc_next;
93 size_t counter;
99 void *node;
112 void **stack;
117 union {
126 size_t depth;
127 };
129
148
211
218
225
232#define cxTreeIteratorContinue(iterator) (iterator).skip = true; continue
233
240#define cxTreeVisitorContinue(visitor) cxTreeIteratorContinue(visitor)
241
260CX_EXPORT void cx_tree_link(void *parent, void *node,
261 ptrdiff_t loc_parent, ptrdiff_t loc_children, ptrdiff_t loc_last_child,
262 ptrdiff_t loc_prev, ptrdiff_t loc_next);
263
280 ptrdiff_t loc_parent, ptrdiff_t loc_children, ptrdiff_t loc_last_child,
281 ptrdiff_t loc_prev, ptrdiff_t loc_next);
282
286#define CX_TREE_SEARCH_INFINITE_DEPTH 0
287
314typedef int (*cx_tree_search_data_func)(const void *node, const void *data);
315
316
343typedef int (*cx_tree_search_func)(const void *node, const void *new_node);
344
370CX_EXPORT int cx_tree_search_data(const void *root, size_t depth,
371 const void *data, cx_tree_search_data_func sfunc,
372 void **result, ptrdiff_t loc_children, ptrdiff_t loc_next);
373
399CX_EXPORT int cx_tree_search(const void *root, size_t depth,
400 const void *node, cx_tree_search_func sfunc,
401 void **result, ptrdiff_t loc_children, ptrdiff_t loc_next);
402
424CX_EXPORT CxTreeIterator cx_tree_iterator(void *root, bool visit_on_exit,
425 ptrdiff_t loc_children, ptrdiff_t loc_next);
426
447 ptrdiff_t loc_children, ptrdiff_t loc_next);
448
459typedef void *(*cx_tree_node_create_func)(const void *, void *);
460
467CX_EXPORT extern unsigned int cx_tree_add_look_around_depth;
468
508CX_EXPORT size_t cx_tree_add_iter(struct cx_iterator_base_s *iter, size_t num,
510 void *cdata, void **failed, void *root,
511 ptrdiff_t loc_parent, ptrdiff_t loc_children, ptrdiff_t loc_last_child,
512 ptrdiff_t loc_prev, ptrdiff_t loc_next);
513
552CX_EXPORT size_t cx_tree_add_array(const void *src, size_t num, size_t elem_size,
554 void *cdata, void **failed, void *root,
555 ptrdiff_t loc_parent, ptrdiff_t loc_children, ptrdiff_t loc_last_child,
556 ptrdiff_t loc_prev, ptrdiff_t loc_next);
557
604CX_EXPORT int cx_tree_add(const void *src,
606 void *cdata, void **cnode, void *root,
607 ptrdiff_t loc_parent, ptrdiff_t loc_children, ptrdiff_t loc_last_child,
608 ptrdiff_t loc_prev, ptrdiff_t loc_next);
609
610
615
641
729
738#define CX_TREE_NODE_BASE(type) \
739 type *parent; \
740 type *children;\
741 type *last_child;\
742 type *prev;\
743 type *next
744
753#define cx_tree_node_base_layout \
754 offsetof(struct cx_tree_node_base_s, parent),\
755 offsetof(struct cx_tree_node_base_s, children),\
756 offsetof(struct cx_tree_node_base_s, last_child),\
757 offsetof(struct cx_tree_node_base_s, prev), \
758 offsetof(struct cx_tree_node_base_s, next)
759
770 int (*insert_element)(struct cx_tree_s *tree, const void *data);
771
778 size_t (*insert_many)(struct cx_tree_s *tree, struct cx_iterator_base_s *iter, size_t n);
779
783 void *(*find)(struct cx_tree_s *tree, const void *subtree, const void *data, size_t depth);
784};
785
789typedef struct cx_tree_s CxTree;
790
791
814CX_EXPORT void cxTreeDestroySubtree(CxTree *tree, void *node);
815
816
834#define cxTreeClear(tree) cxTreeDestroySubtree(tree, tree->root)
835
853
880 cx_tree_search_func search_func, cx_tree_search_data_func search_data_func,
881 ptrdiff_t loc_parent, ptrdiff_t loc_children, ptrdiff_t loc_last_child,
882 ptrdiff_t loc_prev, ptrdiff_t loc_next);
883
901#define cxTreeCreateSimple(allocator, create_func, search_func, search_data_func) \
902 cxTreeCreate(allocator, create_func, search_func, search_data_func, cx_tree_node_base_layout)
903
928 ptrdiff_t loc_parent, ptrdiff_t loc_children, ptrdiff_t loc_last_child,
929 ptrdiff_t loc_prev, ptrdiff_t loc_next);
930
944CX_EXPORT int cxTreeInsert(CxTree *tree, const void *data);
945
959CX_EXPORT size_t cxTreeInsertIter(CxTree *tree, CxIteratorBase *iter, size_t n);
960
975CX_EXPORT size_t cxTreeInsertArray(CxTree *tree, const void *data, size_t elem_size, size_t n);
976
989CX_EXPORT void *cxTreeFind(CxTree *tree, const void *data);
990
1011CX_EXPORT void *cxTreeFindInSubtree(CxTree *tree, const void *data, void *subtree_root, size_t max_depth);
1012
1021CX_EXPORT size_t cxTreeSubtreeSize(CxTree *tree, void *subtree_root);
1022
1031CX_EXPORT size_t cxTreeSubtreeDepth(CxTree *tree, void *subtree_root);
1032
1041
1050
1064CX_EXPORT CxTreeIterator cxTreeIterateSubtree(CxTree *tree, void *node, bool visit_on_exit);
1065
1078
1090
1100
1113CX_EXPORT void cxTreeSetParent(CxTree *tree, void *parent, void *child);
1114
1131CX_EXPORT void cxTreeAddChildNode(CxTree *tree, void *parent, void *child);
1132
1151CX_EXPORT int cxTreeAddChild(CxTree *tree, void *parent, const void *data);
1152
1165typedef void (*cx_tree_relink_func)(
1166 void *node,
1167 const void *old_parent,
1168 const void *new_parent
1169);
1170
1186CX_EXPORT int cxTreeRemoveNode(CxTree *tree, void *node, cx_tree_relink_func relink_func);
1187
1200CX_EXPORT void cxTreeRemoveSubtree(CxTree *tree, void *node);
1201
1221CX_EXPORT int cxTreeDestroyNode(CxTree *tree, void *node, cx_tree_relink_func relink_func);
1222
1223#ifdef __cplusplus
1224} // extern "C"
1225#endif
1226
1227#endif //UCX_TREE_H
void(* cx_destructor_func2)(void *data, void *memory)
Function pointer type for destructor functions.
Definition allocator.h:120
struct cx_allocator_s CxAllocator
High-Level type alias for the allocator type.
Definition allocator.h:84
void(* cx_destructor_func)(void *memory)
Function pointer type for destructor functions.
Definition allocator.h:107
Common definitions for various collection implementations.
Common definitions and feature checks.
#define cx_attr_nonnull
All pointer arguments must be non-NULL.
Definition common.h:141
#define CX_EXPORT
Only used for building Windows DLLs.
Definition common.h:278
#define cx_attr_nodiscard
Warn about discarded return value.
Definition common.h:256
#define cx_attr_malloc
The attributed function always returns freshly allocated memory.
Definition common.h:156
#define cx_attr_access_w(...)
Specifies that the function will only write through the given pointer.
Definition common.h:246
#define cx_attr_nonnull_arg(...)
The specified pointer arguments must be non-NULL.
Definition common.h:146
#define cx_attr_dealloc(...)
Not supported in clang.
Definition common.h:172
#define CX_ITERATOR_BASE
Declares base attributes for an iterator.
Definition iterator.h:98
struct cx_iterator_base_s CxIteratorBase
Convenience type definition for the base structure of an iterator.
Definition iterator.h:92
Common data for all iterators.
Definition iterator.h:48
The class definition for arbitrary trees.
Definition tree.h:763
size_t(* insert_many)(struct cx_tree_s *tree, struct cx_iterator_base_s *iter, size_t n)
Member function for inserting multiple elements.
Definition tree.h:778
int(* insert_element)(struct cx_tree_s *tree, const void *data)
Member function for inserting a single element.
Definition tree.h:770
A depth-first tree iterator.
Definition tree.h:63
bool skip
Indicates whether the subtree below the current node shall be skipped.
Definition tree.h:71
void ** stack
Internal stack.
Definition tree.h:112
bool visit_on_exit
Set to true, when the iterator shall visit a node again when all its children have been processed.
Definition tree.h:76
ptrdiff_t loc_next
Offset in the node struct for the next pointer.
Definition tree.h:88
size_t depth
The current depth in the tree.
Definition tree.h:126
void * node_next
Stores a copy of the pointer to the successor of the visited node.
Definition tree.h:104
void * node
The currently observed node.
Definition tree.h:99
size_t stack_size
Internal stack size.
Definition tree.h:121
size_t counter
The total number of distinct nodes that have been passed so far.
Definition tree.h:93
ptrdiff_t loc_children
Offset in the node struct for the children linked list.
Definition tree.h:84
bool exiting
True, if this iterator is currently leaving the node.
Definition tree.h:80
size_t stack_capacity
Internal capacity of the stack.
Definition tree.h:116
Base structure that can be used for tree nodes in a CxTree.
Definition tree.h:619
struct cx_tree_node_base_s * children
Pointer to the first child.
Definition tree.h:627
struct cx_tree_node_base_s * prev
Pointer to the previous sibling.
Definition tree.h:635
struct cx_tree_node_base_s * last_child
Pointer to the last child.
Definition tree.h:631
struct cx_tree_node_base_s * parent
Pointer to the parent.
Definition tree.h:623
struct cx_tree_node_base_s * next
Pointer to the next sibling.
Definition tree.h:639
Structure for holding the base data of a tree.
Definition tree.h:645
ptrdiff_t loc_parent
Offset in the node struct for the parent pointer.
Definition tree.h:706
ptrdiff_t loc_children
Offset in the node struct for the children linked list.
Definition tree.h:711
ptrdiff_t loc_next
Offset in the node struct for the next sibling pointer.
Definition tree.h:727
cx_tree_search_data_func search_data
A function to compare a node with data.
Definition tree.h:696
cx_destructor_func2 advanced_destructor
An optional advanced destructor for the tree nodes.
Definition tree.h:681
cx_tree_node_create_func node_create
A function to create new nodes.
Definition tree.h:671
size_t size
The number of currently stored elements.
Definition tree.h:701
const CxAllocator * allocator
Allocator to allocate new nodes.
Definition tree.h:654
cx_tree_search_func search
A function to compare two nodes.
Definition tree.h:691
ptrdiff_t loc_last_child
Optional offset in the node struct for the pointer to the last child in the linked list (negative if ...
Definition tree.h:717
ptrdiff_t loc_prev
Offset in the node struct for the previous sibling pointer.
Definition tree.h:722
void * destructor_data
The pointer to additional data that is passed to the advanced destructor.
Definition tree.h:686
const cx_tree_class * cl
The tree class definition.
Definition tree.h:649
void * root
A pointer to the root node.
Definition tree.h:661
cx_destructor_func simple_destructor
An optional simple destructor for the tree nodes.
Definition tree.h:676
An element in a visitor queue.
Definition tree.h:133
size_t depth
The depth of the node.
Definition tree.h:142
void * node
The tree node to visit.
Definition tree.h:137
struct cx_tree_visitor_queue_s * next
The next element in the queue or NULL.
Definition tree.h:146
A breadth-first tree iterator.
Definition tree.h:170
ptrdiff_t loc_next
Offset in the node struct for the next pointer.
Definition tree.h:186
struct cx_tree_visitor_queue_s * queue_last
The last element in the visitor queue.
Definition tree.h:209
size_t counter
The total number of distinct nodes that have been passed so far.
Definition tree.h:191
size_t depth
The current depth in the tree.
Definition tree.h:201
bool skip
Indicates whether the subtree below the current node shall be skipped.
Definition tree.h:178
void * node
The currently observed node.
Definition tree.h:197
ptrdiff_t loc_children
Offset in the node struct for the children linked list.
Definition tree.h:182
struct cx_tree_visitor_queue_s * queue_next
The next element in the visitor queue.
Definition tree.h:205
void cxTreeSetParent(CxTree *tree, void *parent, void *child)
Sets the (new) parent of the specified child.
void cx_tree_link(void *parent, void *node, ptrdiff_t loc_parent, ptrdiff_t loc_children, ptrdiff_t loc_last_child, ptrdiff_t loc_prev, ptrdiff_t loc_next)
Links a node to a (new) parent.
CxTreeIterator cx_tree_iterator(void *root, bool visit_on_exit, ptrdiff_t loc_children, ptrdiff_t loc_next)
Creates a depth-first iterator for a tree with the specified root node.
void cxTreeAddChildNode(CxTree *tree, void *parent, void *child)
Adds a new node to the tree.
CxTreeVisitor cxTreeVisitSubtree(CxTree *tree, void *node)
Creates a breadth-first iterator for the specified tree starting in node.
int(* cx_tree_search_func)(const void *node, const void *new_node)
Function pointer for a search function.
Definition tree.h:343
CxTreeIterator cxTreeIterateSubtree(CxTree *tree, void *node, bool visit_on_exit)
Creates a depth-first iterator for the specified tree starting in node.
void * cxTreeFindInSubtree(CxTree *tree, const void *data, void *subtree_root, size_t max_depth)
Searches the data in the specified subtree.
unsigned int cx_tree_add_look_around_depth
The local search depth for a new subtree when adding multiple elements.
int cxTreeDestroyNode(CxTree *tree, void *node, cx_tree_relink_func relink_func)
Destroys a node and re-links its children to its former parent.
size_t cx_tree_add_array(const void *src, size_t num, size_t elem_size, cx_tree_search_func sfunc, cx_tree_node_create_func cfunc, void *cdata, void **failed, void *root, ptrdiff_t loc_parent, ptrdiff_t loc_children, ptrdiff_t loc_last_child, ptrdiff_t loc_prev, ptrdiff_t loc_next)
Adds multiple elements efficiently to a tree.
CxTreeVisitor cxTreeVisit(CxTree *tree)
Creates a breadth-first iterator for the specified tree.
int cx_tree_search(const void *root, size_t depth, const void *node, cx_tree_search_func sfunc, void **result, ptrdiff_t loc_children, ptrdiff_t loc_next)
Searches for a node in a tree.
size_t cxTreeSubtreeDepth(CxTree *tree, void *subtree_root)
Determines the depth of the specified subtree.
void cxTreeDestroySubtree(CxTree *tree, void *node)
Destroys a node and its subtree.
void(* cx_tree_relink_func)(void *node, const void *old_parent, const void *new_parent)
A function that is invoked when a node needs to be re-linked to a new parent.
Definition tree.h:1165
int(* cx_tree_search_data_func)(const void *node, const void *data)
Function pointer for a search function.
Definition tree.h:314
size_t cxTreeDepth(CxTree *tree)
Determines the depth of the entire tree.
size_t cxTreeInsertIter(CxTree *tree, CxIteratorBase *iter, size_t n)
Inserts elements provided by an iterator efficiently into the tree.
int cxTreeRemoveNode(CxTree *tree, void *node, cx_tree_relink_func relink_func)
Removes a node and re-links its children to its former parent.
int cxTreeInsert(CxTree *tree, const void *data)
Inserts data into the tree.
struct cx_tree_visitor_s CxTreeVisitor
A breadth-first tree iterator.
CxTree * cxTreeCreateWrapped(const CxAllocator *allocator, void *root, ptrdiff_t loc_parent, ptrdiff_t loc_children, ptrdiff_t loc_last_child, ptrdiff_t loc_prev, ptrdiff_t loc_next)
Creates a new tree structure based on an existing tree.
void cxTreeFree(CxTree *tree)
Deallocates the tree structure.
size_t cxTreeSubtreeSize(CxTree *tree, void *subtree_root)
Determines the size of the specified subtree.
struct cx_tree_s CxTree
Common type for all tree implementations.
Definition tree.h:789
void cxTreeIteratorDispose(CxTreeIterator *iter)
Releases internal memory of the given tree iterator.
int cxTreeAddChild(CxTree *tree, void *parent, const void *data)
Creates a new node and adds it to the tree.
void cx_tree_unlink(void *node, ptrdiff_t loc_parent, ptrdiff_t loc_children, ptrdiff_t loc_last_child, ptrdiff_t loc_prev, ptrdiff_t loc_next)
Unlinks a node from its parent.
void *(* cx_tree_node_create_func)(const void *, void *)
Describes a function that creates a tree node from the specified data.
Definition tree.h:459
size_t cx_tree_add_iter(struct cx_iterator_base_s *iter, size_t num, cx_tree_search_func sfunc, cx_tree_node_create_func cfunc, void *cdata, void **failed, void *root, ptrdiff_t loc_parent, ptrdiff_t loc_children, ptrdiff_t loc_last_child, ptrdiff_t loc_prev, ptrdiff_t loc_next)
Adds multiple elements efficiently to a tree.
struct cx_tree_class_s cx_tree_class
Tree class type.
Definition tree.h:614
size_t cxTreeInsertArray(CxTree *tree, const void *data, size_t elem_size, size_t n)
Inserts an array of data efficiently into the tree.
struct cx_tree_iterator_s CxTreeIterator
A depth-first tree iterator.
int cx_tree_search_data(const void *root, size_t depth, const void *data, cx_tree_search_data_func sfunc, void **result, ptrdiff_t loc_children, ptrdiff_t loc_next)
Searches for data in a tree.
CxTreeIterator cxTreeIterate(CxTree *tree, bool visit_on_exit)
Creates a depth-first iterator for the specified tree.
CxTreeVisitor cx_tree_visitor(void *root, ptrdiff_t loc_children, ptrdiff_t loc_next)
Creates a breadth-first iterator for a tree with the specified root node.
int cx_tree_add(const void *src, cx_tree_search_func sfunc, cx_tree_node_create_func cfunc, void *cdata, void **cnode, void *root, ptrdiff_t loc_parent, ptrdiff_t loc_children, ptrdiff_t loc_last_child, ptrdiff_t loc_prev, ptrdiff_t loc_next)
Adds data to a tree.
size_t cxTreeSize(CxTree *tree)
Determines the size of the entire tree.
void cxTreeVisitorDispose(CxTreeVisitor *visitor)
Releases internal memory of the given tree visitor.
void cxTreeRemoveSubtree(CxTree *tree, void *node)
Removes a node and its subtree from the tree.
CxTree * cxTreeCreate(const CxAllocator *allocator, cx_tree_node_create_func create_func, cx_tree_search_func search_func, cx_tree_search_data_func search_data_func, ptrdiff_t loc_parent, ptrdiff_t loc_children, ptrdiff_t loc_last_child, ptrdiff_t loc_prev, ptrdiff_t loc_next)
Creates a new tree structure based on the specified layout.
void * cxTreeFind(CxTree *tree, const void *data)
Searches the data in the specified tree.