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
61
73 ptrdiff_t loc_children;
77 ptrdiff_t loc_next;
82 size_t counter;
86 size_t depth;
92 void *node;
96 union {
97 struct {
110 void **stack;
115 };
116 struct {
125 };
126 };
130 bool skip;
145
152
159#define cxTreeIteratorContinue(iterator) (iterator).skip = true; continue
160
179void cx_tree_add(void *parent, void *node,
180 ptrdiff_t loc_parent, ptrdiff_t loc_children, ptrdiff_t loc_last_child,
181 ptrdiff_t loc_prev, ptrdiff_t loc_next);
182
199 ptrdiff_t loc_parent, ptrdiff_t loc_children, ptrdiff_t loc_last_child,
200 ptrdiff_t loc_prev, ptrdiff_t loc_next);
201
205#define CX_TREE_SEARCH_INFINITE_DEPTH 0
206
233typedef int (*cx_tree_search_func)(const void *node, const void *data);
234
260int cx_tree_search(const void *root, size_t max_depth,
261 const void *data, cx_tree_search_func sfunc, void **result,
262 ptrdiff_t loc_children, ptrdiff_t loc_next);
263
285CxTreeIterator cx_tree_iterator(void *root, bool visit_on_exit,
286 ptrdiff_t loc_children, ptrdiff_t loc_next);
287
308 ptrdiff_t loc_children, ptrdiff_t loc_next);
309
335
339typedef struct cx_tree_s {
347 void *root;
348
352 size_t node_size;
353
357 ptrdiff_t loc_parent;
358
362 ptrdiff_t loc_children;
363
368 ptrdiff_t loc_last_child;
369
373 ptrdiff_t loc_prev;
374
378 ptrdiff_t loc_next;
379
383 ptrdiff_t loc_data;
385
394#define CX_TREE_NODE(type) \
395 type *parent; \
396 type *children;\
397 type *last_child;\
398 type *prev;\
399 type *next
400
410#define cx_tree_node_layout(struct_name) \
411 offsetof(struct_name, parent),\
412 offsetof(struct_name, children),\
413 offsetof(struct_name, last_child),\
414 offsetof(struct_name, prev), \
415 offsetof(struct_name, next)
416
439void cxTreeDestroySubtree(CxTree *tree, void *node);
440
441
460void cxTreeClear(CxTree *tree) {
461 if (tree->root != NULL) {
462 cxTreeDestroySubtree(tree, tree->root);
463 }
464}
465
483void cxTreeFree(CxTree *tree);
484
516 size_t node_size, size_t elem_size, void *root, ptrdiff_t loc_data,
517 ptrdiff_t loc_parent, ptrdiff_t loc_children, ptrdiff_t loc_last_child,
518 ptrdiff_t loc_prev, ptrdiff_t loc_next);
519
542void *cxTreeFindInSubtree(CxTree *tree, const void *data, void *subtree_root,
543 size_t max_depth, bool use_dfs);
544
560void *cxTreeFind(CxTree *tree, const void *data, bool use_dfs) {
561 if (tree->root == NULL) return NULL;
562 return cxTreeFindInSubtree(tree, data, tree->root, 0, use_dfs);
563}
564
583void *cxTreeFindFastInSubtree(CxTree *tree, const void *data,
584 cx_tree_search_func sfunc, void *subtree_root, size_t max_depth);
585
596void *cxTreeFindFast(CxTree *tree, const void *data, cx_tree_search_func sfunc) {
597 return cxTreeFindFastInSubtree(tree, data, sfunc, tree->root, 0);
598}
599
608size_t cxTreeSubtreeSize(CxTree *tree, void *subtree_root);
609
618size_t cxTreeSubtreeDepth(CxTree *tree, void *subtree_root);
619
627size_t cxTreeSize(CxTree *tree);
628
636size_t cxTreeDepth(CxTree *tree);
637
651CxTreeIterator cxTreeIterateSubtree(CxTree *tree, void *node, bool visit_on_exit);
652
665
676CxTreeIterator cxTreeIterate(CxTree *tree, bool visit_on_exit);
677
687
700void cxTreeSetParent(CxTree *tree, void *parent, void *child);
701
719void cxTreeAddNode(CxTree *tree, void *parent, void *child);
720
731void *cxTreeAddData(CxTree *tree, void *parent, const void *data);
732
741void *cxTreeCreateNode(CxTree *tree, void *parent);
742
752
765void *cxTreeCreateRootData(CxTree *tree, const void *data);
766
783void *cxTreeSetRoot(CxTree *tree, void *new_root);
784
797typedef void (*cx_tree_relink_func)(
798 void *node,
799 const void *old_parent,
800 const void *new_parent
801);
802
818int cxTreeRemoveNode(CxTree *tree, void *node, cx_tree_relink_func relink_func);
819
832void cxTreeRemoveSubtree(CxTree *tree, void *node);
833
853int cxTreeDestroyNode(CxTree *tree, void *node, cx_tree_relink_func relink_func);
854
855#endif //UCX_TREE_H
struct cx_allocator_s CxAllocator
High-Level type alias for the allocator type.
Definition allocator.h:80
Common definitions for various collection implementations.
#define CX_COLLECTION_BASE
Use this macro to declare common members for a collection structure.
Definition collection.h:118
Common definitions and feature checks.
#define CX_MALLOC
The attributed function always returns freshly allocated memory.
Definition common.h:156
#define CX_DEALLOC(...)
Not supported in clang.
Definition common.h:172
#define CX_INLINE
Declares a function to be inlined.
Definition common.h:311
#define CX_NONNULL
All pointer arguments must be non-NULL.
Definition common.h:141
#define CX_NODISCARD
Warn about discarded return value.
Definition common.h:256
#define CX_NONNULL_ARG(...)
The specified pointer arguments must be non-NULL.
Definition common.h:146
#define CX_EXTERN
Declares a function with external linkage.
Definition common.h:297
#define CX_ACCESS_W(...)
Specifies that the function will only write through the given pointer.
Definition common.h:246
#define CX_ITERATOR_BASE
Declares base attributes for an iterator.
Definition iterator.h:94
An iterator (DFS) or visitor (BFS) for a tree.
Definition tree.h:65
size_t stack_capacity
Internal capacity of the stack.
Definition tree.h:114
ptrdiff_t loc_children
Offset in the node struct for the children linked list.
Definition tree.h:73
size_t depth
The current depth in the tree.
Definition tree.h:86
struct cx_tree_visitor_queue_s * queue_last
The last element in the visitor queue.
Definition tree.h:124
void * node
The currently observed node.
Definition tree.h:92
bool exiting
True, if this iterator is currently leaving the node.
Definition tree.h:139
bool use_dfs
Indicates whether the iterator (true) or the visitor (false) aspect is active.
Definition tree.h:143
struct cx_tree_visitor_queue_s * queue_next
The next element in the visitor queue.
Definition tree.h:120
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:135
void ** stack
Internal stack.
Definition tree.h:110
ptrdiff_t loc_next
Offset in the node struct for the next pointer.
Definition tree.h:77
size_t counter
The total number of distinct nodes that have been passed so far.
Definition tree.h:82
bool skip
Indicates whether the subtree below the current node shall be skipped.
Definition tree.h:130
void * node_next
Stores a copy of the pointer to the successor of the visited node.
Definition tree.h:102
Base structure that can be used for tree nodes in a CxTree.
Definition tree.h:313
struct cx_tree_node_base_s * children
Pointer to the first child.
Definition tree.h:321
struct cx_tree_node_base_s * prev
Pointer to the previous sibling.
Definition tree.h:329
struct cx_tree_node_base_s * last_child
Pointer to the last child.
Definition tree.h:325
struct cx_tree_node_base_s * parent
Pointer to the parent.
Definition tree.h:317
struct cx_tree_node_base_s * next
Pointer to the next sibling.
Definition tree.h:333
Structure for holding the base data of a tree.
Definition tree.h:339
ptrdiff_t loc_parent
Offset in the node struct for the parent pointer.
Definition tree.h:357
ptrdiff_t loc_children
Offset in the node struct for the children linked list.
Definition tree.h:362
ptrdiff_t loc_next
Offset in the node struct for the next sibling pointer.
Definition tree.h:378
ptrdiff_t loc_data
Offset in the node struct where the payload is located.
Definition tree.h:383
size_t node_size
The size of the node structure.
Definition tree.h:352
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:368
ptrdiff_t loc_prev
Offset in the node struct for the previous sibling pointer.
Definition tree.h:373
void * root
A pointer to the root node.
Definition tree.h:347
An element in a visitor queue.
Definition tree.h:46
size_t depth
The depth of the node.
Definition tree.h:55
void * node
The tree node to visit.
Definition tree.h:50
struct cx_tree_visitor_queue_s * next
The next element in the queue or NULL.
Definition tree.h:59
void cxTreeSetParent(CxTree *tree, void *parent, void *child)
Sets the (new) parent of the specified child.
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.
CxTreeIterator cxTreeIterateSubtree(CxTree *tree, void *node, bool visit_on_exit)
Creates a depth-first iterator for the specified tree starting in node.
int cxTreeDestroyNode(CxTree *tree, void *node, cx_tree_relink_func relink_func)
Destroys a node and re-links its children to its former parent.
void * cxTreeCreateRoot(CxTree *tree)
Creates a new root node or returns the existing root node.
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.
static void cxTreeClear(CxTree *tree)
Destroys the tree contents.
Definition tree.h:460
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:797
static void * cxTreeFind(CxTree *tree, const void *data, bool use_dfs)
Searches the data in the specified tree.
Definition tree.h:560
void cxTreeAddNode(CxTree *tree, void *parent, void *child)
Adds a new node to the tree.
size_t cxTreeDepth(CxTree *tree)
Determines the depth of the entire 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.
void * cxTreeCreateRootData(CxTree *tree, const void *data)
Creates a new root node or uses the existing root node and writes the specified data to that node.
void * cxTreeFindInSubtree(CxTree *tree, const void *data, void *subtree_root, size_t max_depth, bool use_dfs)
Searches the data in the specified subtree.
void cx_tree_remove(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.
struct cx_tree_combined_iterator_s CxTreeIterator
An iterator (DFS) or visitor (BFS) for a tree.
CxTreeIterator cxTreeVisit(CxTree *tree)
Creates a breadth-first iterator for the specified tree.
void cxTreeFree(CxTree *tree)
Deallocates the tree structure.
size_t cxTreeSubtreeSize(CxTree *tree, void *subtree_root)
Determines the size of the specified subtree.
static void * cxTreeFindFast(CxTree *tree, const void *data, cx_tree_search_func sfunc)
Performs an efficient depth-first search in the tree.
Definition tree.h:596
struct cx_tree_s CxTree
Structure for holding the base data of a tree.
CxTreeIterator 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.
void cxTreeIteratorDispose(CxTreeIterator *iter)
Releases internal memory of the given tree iterator.
void cx_tree_add(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.
CxTree * cxTreeCreate(const CxAllocator *allocator, size_t node_size, size_t elem_size, void *root, ptrdiff_t loc_data, 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.
CxTreeIterator 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 *data)
Function pointer for a search function.
Definition tree.h:233
void * cxTreeSetRoot(CxTree *tree, void *new_root)
Exchanges the root of the tree.
int cx_tree_search(const void *root, size_t max_depth, const void *data, cx_tree_search_func sfunc, void **result, ptrdiff_t loc_children, ptrdiff_t loc_next)
Searches for data in a tree.
void * cxTreeCreateNode(CxTree *tree, void *parent)
Creates a new node and adds it to the tree.
CxTreeIterator cxTreeIterate(CxTree *tree, bool visit_on_exit)
Creates a depth-first iterator for the specified tree.
size_t cxTreeSize(CxTree *tree)
Determines the size of the entire tree.
void * cxTreeFindFastInSubtree(CxTree *tree, const void *data, cx_tree_search_func sfunc, void *subtree_root, size_t max_depth)
Performs an efficient depth-first search in a branch of the specified tree.
void cxTreeRemoveSubtree(CxTree *tree, void *node)
Removes a node and its subtree from the tree.
void * cxTreeAddData(CxTree *tree, void *parent, const void *data)
Creates a new node and adds it to the tree.