Wed, 31 Dec 2025 16:40:12 +0100
update ucx to version 4.0
|
253
087cc9216f28
initial newapi GTK port
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
1 | /* |
|
087cc9216f28
initial newapi GTK port
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
2 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. |
|
087cc9216f28
initial newapi GTK port
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
3 | * |
|
087cc9216f28
initial newapi GTK port
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
4 | * Copyright 2024 Mike Becker, Olaf Wintermann All rights reserved. |
|
087cc9216f28
initial newapi GTK port
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
5 | * |
|
087cc9216f28
initial newapi GTK port
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
6 | * Redistribution and use in source and binary forms, with or without |
|
087cc9216f28
initial newapi GTK port
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
7 | * modification, are permitted provided that the following conditions are met: |
|
087cc9216f28
initial newapi GTK port
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
8 | * |
|
087cc9216f28
initial newapi GTK port
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
9 | * 1. Redistributions of source code must retain the above copyright |
|
087cc9216f28
initial newapi GTK port
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
10 | * notice, this list of conditions and the following disclaimer. |
|
087cc9216f28
initial newapi GTK port
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
11 | * |
|
087cc9216f28
initial newapi GTK port
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
12 | * 2. Redistributions in binary form must reproduce the above copyright |
|
087cc9216f28
initial newapi GTK port
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
13 | * notice, this list of conditions and the following disclaimer in the |
|
087cc9216f28
initial newapi GTK port
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
14 | * documentation and/or other materials provided with the distribution. |
|
087cc9216f28
initial newapi GTK port
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
15 | * |
|
087cc9216f28
initial newapi GTK port
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
|
087cc9216f28
initial newapi GTK port
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
17 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
|
087cc9216f28
initial newapi GTK port
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
18 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
|
087cc9216f28
initial newapi GTK port
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
19 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE |
|
087cc9216f28
initial newapi GTK port
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
20 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
|
087cc9216f28
initial newapi GTK port
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
21 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
|
087cc9216f28
initial newapi GTK port
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
22 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
|
087cc9216f28
initial newapi GTK port
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
23 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
|
087cc9216f28
initial newapi GTK port
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
24 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
|
087cc9216f28
initial newapi GTK port
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
25 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
|
087cc9216f28
initial newapi GTK port
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
26 | * POSSIBILITY OF SUCH DAMAGE. |
|
087cc9216f28
initial newapi GTK port
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
27 | */ |
|
087cc9216f28
initial newapi GTK port
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
28 | /** |
| 440 | 29 | * @file tree.h |
| 30 | * @brief Interface for tree implementations. | |
| 31 | * @author Mike Becker | |
| 32 | * @author Olaf Wintermann | |
| 33 | * @copyright 2-Clause BSD License | |
|
253
087cc9216f28
initial newapi GTK port
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
34 | */ |
|
087cc9216f28
initial newapi GTK port
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
35 | |
|
087cc9216f28
initial newapi GTK port
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
36 | #ifndef UCX_TREE_H |
|
087cc9216f28
initial newapi GTK port
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
37 | #define UCX_TREE_H |
|
087cc9216f28
initial newapi GTK port
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
38 | |
|
087cc9216f28
initial newapi GTK port
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
39 | #include "common.h" |
|
087cc9216f28
initial newapi GTK port
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
40 | |
| 324 | 41 | #include "collection.h" |
| 42 | ||
| 43 | /** | |
| 44 | * An element in a visitor queue. | |
| 45 | */ | |
| 46 | struct cx_tree_visitor_queue_s { | |
| 47 | /** | |
| 48 | * The tree node to visit. | |
| 49 | */ | |
| 50 | void *node; | |
| 51 | /** | |
| 52 | * The depth of the node. | |
|
629
0385a450c2a6
add list initializer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
471
diff
changeset
|
53 | * The first visited node has depth 1. |
| 324 | 54 | */ |
| 55 | size_t depth; | |
| 56 | /** | |
| 440 | 57 | * The next element in the queue or @c NULL. |
| 324 | 58 | */ |
| 59 | struct cx_tree_visitor_queue_s *next; | |
| 60 | }; | |
| 61 | ||
| 62 | /** | |
|
1040
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
63 | * An iterator (DFS) or visitor (BFS) for a tree. |
| 324 | 64 | */ |
|
1040
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
65 | typedef struct cx_tree_combined_iterator_s { |
| 324 | 66 | /** |
| 67 | * Base members. | |
| 68 | */ | |
| 69 | CX_ITERATOR_BASE; | |
| 70 | /** | |
| 71 | * Offset in the node struct for the children linked list. | |
| 72 | */ | |
| 73 | ptrdiff_t loc_children; | |
| 74 | /** | |
| 75 | * Offset in the node struct for the next pointer. | |
| 76 | */ | |
| 77 | ptrdiff_t loc_next; | |
| 78 | /** | |
| 79 | * The total number of distinct nodes that have been passed so far. | |
|
943
9b5948aa5b90
update ucx to version 3.2
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
870
diff
changeset
|
80 | * This includes the currently visited node. |
| 324 | 81 | */ |
| 82 | size_t counter; | |
| 83 | /** | |
|
1040
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
84 | * The current depth in the tree. |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
85 | */ |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
86 | size_t depth; |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
87 | /** |
| 324 | 88 | * The currently observed node. |
| 89 | * | |
| 90 | * This is the same what cxIteratorCurrent() would return. | |
| 91 | */ | |
| 92 | void *node; | |
| 93 | /** | |
|
1040
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
94 | * Memory for BFS or DFS-specific data. |
| 324 | 95 | */ |
|
1040
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
96 | union { |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
97 | struct { |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
98 | /** |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
99 | * Stores a copy of the pointer to the successor of the visited node. |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
100 | * Allows freeing a node on exit without corrupting the iteration. |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
101 | */ |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
102 | void *node_next; |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
103 | /** |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
104 | * Internal stack. |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
105 | * Will be automatically freed once the iterator becomes invalid. |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
106 | * |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
107 | * If you want to discard the iterator before, you need to manually |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
108 | * call cxTreeIteratorDispose(). |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
109 | */ |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
110 | void **stack; |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
111 | /** |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
112 | * Internal capacity of the stack. |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
113 | */ |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
114 | size_t stack_capacity; |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
115 | }; |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
116 | struct { |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
117 | /** |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
118 | * The next element in the visitor queue. |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
119 | */ |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
120 | struct cx_tree_visitor_queue_s *queue_next; |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
121 | /** |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
122 | * The last element in the visitor queue. |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
123 | */ |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
124 | struct cx_tree_visitor_queue_s *queue_last; |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
125 | }; |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
126 | }; |
| 324 | 127 | /** |
|
1040
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
128 | * Indicates whether the subtree below the current node shall be skipped. |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
129 | */ |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
130 | bool skip; |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
131 | /** |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
132 | * Set to true, when the iterator shall visit a node again |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
133 | * when all its children have been processed. |
| 324 | 134 | */ |
|
1040
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
135 | bool visit_on_exit; |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
136 | /** |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
137 | * True, if this iterator is currently leaving the node. |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
138 | */ |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
139 | bool exiting; |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
140 | /** |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
141 | * Indicates whether the @c iterator (true) or the @c visitor (false) aspect is active. |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
142 | */ |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
143 | bool use_dfs; |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
144 | } CxTreeIterator; |
| 324 | 145 | |
| 146 | /** | |
| 147 | * Releases internal memory of the given tree iterator. | |
| 148 | * @param iter the iterator | |
| 149 | */ | |
|
1040
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
150 | CX_EXTERN CX_NONNULL |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
151 | void cxTreeIteratorDispose(CxTreeIterator *iter); |
| 324 | 152 | |
| 153 | /** | |
| 154 | * Advises the iterator to skip the subtree below the current node and | |
| 155 | * also continues the current loop. | |
| 156 | * | |
| 440 | 157 | * @param iterator (@c CxTreeIterator) the iterator |
| 324 | 158 | */ |
| 159 | #define cxTreeIteratorContinue(iterator) (iterator).skip = true; continue | |
| 160 | ||
| 161 | /** | |
| 162 | * Links a node to a (new) parent. | |
| 163 | * | |
| 845 | 164 | * If the node already has a parent, it is unlinked, first. |
| 440 | 165 | * If the parent has children already, the node is @em appended to the list |
| 324 | 166 | * of all currently existing children. |
| 167 | * | |
| 168 | * @param parent the parent node | |
| 169 | * @param node the node that shall be linked | |
| 170 | * @param loc_parent offset in the node struct for the parent pointer | |
| 171 | * @param loc_children offset in the node struct for the children linked list | |
| 172 | * @param loc_last_child optional offset in the node struct for the pointer to | |
| 173 | * the last child in the linked list (negative if there is no such pointer) | |
| 440 | 174 | * @param loc_prev optional offset in the node struct for the prev pointer |
| 324 | 175 | * @param loc_next offset in the node struct for the next pointer |
|
1040
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
176 | * @see cx_tree_remove() |
| 324 | 177 | */ |
|
1040
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
178 | CX_EXTERN CX_NONNULL |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
179 | void cx_tree_add(void *parent, void *node, |
| 870 | 180 | ptrdiff_t loc_parent, ptrdiff_t loc_children, ptrdiff_t loc_last_child, |
| 181 | ptrdiff_t loc_prev, ptrdiff_t loc_next); | |
|
253
087cc9216f28
initial newapi GTK port
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
182 | |
| 324 | 183 | /** |
| 184 | * Unlinks a node from its parent. | |
| 185 | * | |
| 186 | * If the node has no parent, this function does nothing. | |
| 187 | * | |
| 188 | * @param node the node that shall be unlinked from its parent | |
| 189 | * @param loc_parent offset in the node struct for the parent pointer | |
| 190 | * @param loc_children offset in the node struct for the children linked list | |
| 191 | * @param loc_last_child optional offset in the node struct for the pointer to | |
| 192 | * the last child in the linked list (negative if there is no such pointer) | |
| 440 | 193 | * @param loc_prev optional offset in the node struct for the prev pointer |
| 324 | 194 | * @param loc_next offset in the node struct for the next pointer |
|
1040
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
195 | * @see cx_tree_add() |
| 324 | 196 | */ |
|
1040
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
197 | CX_EXTERN CX_NONNULL |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
198 | void cx_tree_remove(void *node, |
| 870 | 199 | ptrdiff_t loc_parent, ptrdiff_t loc_children, ptrdiff_t loc_last_child, |
| 200 | ptrdiff_t loc_prev, ptrdiff_t loc_next); | |
| 324 | 201 | |
| 202 | /** | |
| 440 | 203 | * Macro that can be used instead of the magic value for infinite search depth. |
| 204 | */ | |
| 205 | #define CX_TREE_SEARCH_INFINITE_DEPTH 0 | |
| 206 | ||
| 207 | /** | |
| 324 | 208 | * Function pointer for a search function. |
| 209 | * | |
| 440 | 210 | * A function of this kind shall check if the specified @p node |
| 211 | * contains the given @p data or if one of the children might contain | |
| 324 | 212 | * the data. |
| 213 | * | |
| 214 | * The function should use the returned integer to indicate how close the | |
| 215 | * match is, where a negative number means that it does not match at all. | |
| 440 | 216 | * Zero means exact match and a positive number is an implementation defined |
| 217 | * measure for the distance to an exact match. | |
| 324 | 218 | * |
| 845 | 219 | * For example, consider a tree that stores file path information. |
| 220 | * A node which is describing a parent directory of a searched file shall | |
| 324 | 221 | * return a positive number to indicate that a child node might contain the |
| 222 | * searched item. On the other hand, if the node denotes a path that is not a | |
| 223 | * prefix of the searched filename, the function would return -1 to indicate | |
| 224 | * that the search does not need to be continued in that branch. | |
| 225 | * | |
| 226 | * @param node the node that is currently investigated | |
| 227 | * @param data the data that is searched for | |
| 228 | * | |
| 229 | * @return 0 if the node contains the data, | |
| 230 | * positive if one of the children might contain the data, | |
| 845 | 231 | * negative if neither the node nor the children contains the data |
| 324 | 232 | */ |
|
1040
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
233 | typedef int (*cx_tree_search_func)(const void *node, const void *data); |
| 324 | 234 | |
| 235 | /** | |
| 236 | * Searches for data in a tree. | |
| 237 | * | |
| 845 | 238 | * When the data cannot be found exactly, the search function might return the |
| 239 | * closest result, which might be a good starting point for adding a new node | |
|
1040
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
240 | * to the tree. |
| 324 | 241 | * |
| 845 | 242 | * Depending on the tree structure, it is not necessarily guaranteed that the |
| 324 | 243 | * "closest" match is uniquely defined. This function will search for a node |
| 440 | 244 | * with the best match according to the @p sfunc (meaning: the return value of |
| 245 | * @p sfunc which is closest to zero). If that is also ambiguous, an arbitrary | |
| 324 | 246 | * node matching the criteria is returned. |
| 247 | * | |
| 248 | * @param root the root node | |
|
1040
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
249 | * @param max_depth the maximum depth (zero=indefinite, one=just root) |
| 324 | 250 | * @param data the data to search for |
| 251 | * @param sfunc the search function | |
| 252 | * @param result where the result shall be stored | |
| 253 | * @param loc_children offset in the node struct for the children linked list | |
| 254 | * @param loc_next offset in the node struct for the next pointer | |
| 255 | * @return zero if the node was found exactly, positive if a node was found that | |
| 256 | * could contain the node (but doesn't right now), negative if the tree does not | |
| 257 | * contain any node that might be related to the searched data | |
| 258 | */ | |
|
1040
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
259 | CX_EXTERN CX_NONNULL_ARG(4, 5) CX_ACCESS_W(5) |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
260 | int cx_tree_search(const void *root, size_t max_depth, |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
261 | const void *data, cx_tree_search_func sfunc, void **result, |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
262 | ptrdiff_t loc_children, ptrdiff_t loc_next); |
| 324 | 263 | |
| 264 | /** | |
| 265 | * Creates a depth-first iterator for a tree with the specified root node. | |
| 266 | * | |
| 267 | * @note A tree iterator needs to maintain a stack of visited nodes, which is | |
|
629
0385a450c2a6
add list initializer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
471
diff
changeset
|
268 | * allocated using the cxDefaultAllocator. |
| 324 | 269 | * When the iterator becomes invalid, this memory is automatically released. |
| 270 | * However, if you wish to cancel the iteration before the iterator becomes | |
| 271 | * invalid by itself, you MUST call cxTreeIteratorDispose() manually to release | |
| 272 | * the memory. | |
| 273 | * | |
| 274 | * @remark The returned iterator does not support cxIteratorFlagRemoval(). | |
| 275 | * | |
| 276 | * @param root the root node | |
| 277 | * @param visit_on_exit set to true, when the iterator shall visit a node again | |
| 278 | * after processing all children | |
| 279 | * @param loc_children offset in the node struct for the children linked list | |
| 280 | * @param loc_next offset in the node struct for the next pointer | |
| 281 | * @return the new tree iterator | |
| 282 | * @see cxTreeIteratorDispose() | |
| 283 | */ | |
|
1040
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
284 | CX_EXTERN CX_NODISCARD |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
285 | CxTreeIterator cx_tree_iterator(void *root, bool visit_on_exit, |
| 870 | 286 | ptrdiff_t loc_children, ptrdiff_t loc_next); |
| 324 | 287 | |
| 288 | /** | |
| 289 | * Creates a breadth-first iterator for a tree with the specified root node. | |
| 290 | * | |
|
629
0385a450c2a6
add list initializer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
471
diff
changeset
|
291 | * @note A tree visitor needs to maintain a queue of to-be visited nodes, which |
|
0385a450c2a6
add list initializer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
471
diff
changeset
|
292 | * is allocated using the cxDefaultAllocator. |
| 324 | 293 | * When the visitor becomes invalid, this memory is automatically released. |
| 294 | * However, if you wish to cancel the iteration before the visitor becomes | |
|
1040
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
295 | * invalid by itself, you MUST call cxTreeIteratorDispose() manually to release |
| 324 | 296 | * the memory. |
| 297 | * | |
| 298 | * @remark The returned iterator does not support cxIteratorFlagRemoval(). | |
| 299 | * | |
| 300 | * @param root the root node | |
| 301 | * @param loc_children offset in the node struct for the children linked list | |
| 302 | * @param loc_next offset in the node struct for the next pointer | |
| 303 | * @return the new tree visitor | |
|
1040
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
304 | * @see cxTreeIteratorDispose() |
| 324 | 305 | */ |
|
1040
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
306 | CX_EXTERN CX_NODISCARD |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
307 | CxTreeIterator cx_tree_visitor(void *root, |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
308 | ptrdiff_t loc_children, ptrdiff_t loc_next); |
| 324 | 309 | |
| 310 | /** | |
| 311 | * Base structure that can be used for tree nodes in a #CxTree. | |
| 312 | */ | |
| 313 | struct cx_tree_node_base_s { | |
| 314 | /** | |
| 315 | * Pointer to the parent. | |
| 316 | */ | |
| 317 | struct cx_tree_node_base_s *parent; | |
| 318 | /** | |
| 319 | * Pointer to the first child. | |
| 320 | */ | |
| 321 | struct cx_tree_node_base_s *children; | |
| 322 | /** | |
| 323 | * Pointer to the last child. | |
| 324 | */ | |
| 325 | struct cx_tree_node_base_s *last_child; | |
| 326 | /** | |
| 327 | * Pointer to the previous sibling. | |
| 328 | */ | |
| 329 | struct cx_tree_node_base_s *prev; | |
| 330 | /** | |
| 331 | * Pointer to the next sibling. | |
| 332 | */ | |
| 333 | struct cx_tree_node_base_s *next; | |
| 334 | }; | |
| 335 | ||
| 336 | /** | |
| 337 | * Structure for holding the base data of a tree. | |
| 338 | */ | |
|
1040
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
339 | typedef struct cx_tree_s { |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
340 | /** Base attributes. */ |
|
992
f421aef8f865
remove old UCX2 properties
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
943
diff
changeset
|
341 | CX_COLLECTION_BASE; |
| 324 | 342 | /** |
| 343 | * A pointer to the root node. | |
| 344 | * | |
| 440 | 345 | * Will be @c NULL when @c size is 0. |
| 324 | 346 | */ |
| 347 | void *root; | |
| 348 | ||
| 349 | /** | |
|
1040
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
350 | * The size of the node structure. |
| 324 | 351 | */ |
|
1040
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
352 | size_t node_size; |
| 324 | 353 | |
| 354 | /** | |
| 355 | * Offset in the node struct for the parent pointer. | |
| 356 | */ | |
| 357 | ptrdiff_t loc_parent; | |
| 358 | ||
| 359 | /** | |
| 360 | * Offset in the node struct for the children linked list. | |
| 361 | */ | |
| 362 | ptrdiff_t loc_children; | |
| 363 | ||
| 364 | /** | |
| 365 | * Optional offset in the node struct for the pointer to the last child | |
| 366 | * in the linked list (negative if there is no such pointer). | |
| 367 | */ | |
| 368 | ptrdiff_t loc_last_child; | |
| 369 | ||
| 370 | /** | |
| 371 | * Offset in the node struct for the previous sibling pointer. | |
| 372 | */ | |
| 373 | ptrdiff_t loc_prev; | |
| 374 | ||
| 375 | /** | |
| 376 | * Offset in the node struct for the next sibling pointer. | |
| 377 | */ | |
| 378 | ptrdiff_t loc_next; | |
|
1040
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
379 | |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
380 | /** |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
381 | * Offset in the node struct where the payload is located. |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
382 | */ |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
383 | ptrdiff_t loc_data; |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
384 | } CxTree; |
| 324 | 385 | |
| 386 | /** | |
| 387 | * Macro to roll out the #cx_tree_node_base_s structure with a custom | |
| 388 | * node type. | |
| 440 | 389 | * |
| 845 | 390 | * Must be used as the first member in your custom tree struct. |
| 440 | 391 | * |
| 392 | * @param type the data type for the nodes | |
| 324 | 393 | */ |
|
1040
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
394 | #define CX_TREE_NODE(type) \ |
| 324 | 395 | type *parent; \ |
| 396 | type *children;\ | |
| 397 | type *last_child;\ | |
| 398 | type *prev;\ | |
| 399 | type *next | |
| 400 | ||
| 401 | /** | |
|
1040
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
402 | * Macro for specifying the layout of a tree node. |
| 440 | 403 | * |
|
1040
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
404 | * When your tree uses #CX_TREE_NODE, you can use this |
| 440 | 405 | * macro in all tree functions that expect the layout parameters |
| 406 | * @c loc_parent, @c loc_children, @c loc_last_child, @c loc_prev, | |
| 407 | * and @c loc_next. | |
|
1040
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
408 | * @param struct_name the name of the node structure |
| 324 | 409 | */ |
|
1040
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
410 | #define cx_tree_node_layout(struct_name) \ |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
411 | offsetof(struct_name, parent),\ |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
412 | offsetof(struct_name, children),\ |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
413 | offsetof(struct_name, last_child),\ |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
414 | offsetof(struct_name, prev), \ |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
415 | offsetof(struct_name, next) |
| 440 | 416 | |
| 417 | /** | |
| 845 | 418 | * Destroys a node and its subtree. |
| 440 | 419 | * |
| 420 | * It is guaranteed that the simple destructor is invoked before | |
| 421 | * the advanced destructor, starting with the leaf nodes of the subtree. | |
| 422 | * | |
| 423 | * When this function is invoked on the root node of the tree, it destroys the | |
| 424 | * tree contents, but - in contrast to #cxTreeFree() - not the tree | |
| 425 | * structure, leaving an empty tree behind. | |
| 426 | * | |
| 427 | * @note The destructor function, if any, will @em not be invoked. That means | |
| 428 | * you will need to free the removed subtree by yourself, eventually. | |
| 429 | * | |
| 430 | * @attention This function will not free the memory of the nodes with the | |
| 431 | * tree's allocator, because that is usually done by the advanced destructor | |
| 432 | * and would therefore result in a double-free. | |
| 433 | * | |
| 434 | * @param tree the tree | |
|
1040
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
435 | * @param node the node being the root of the subtree to remove |
| 440 | 436 | * @see cxTreeFree() |
| 437 | */ | |
|
1040
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
438 | CX_EXTERN CX_NONNULL |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
439 | void cxTreeDestroySubtree(CxTree *tree, void *node); |
| 440 | 440 | |
| 441 | ||
| 442 | /** | |
| 443 | * Destroys the tree contents. | |
| 444 | * | |
| 445 | * It is guaranteed that the simple destructor is invoked before | |
| 446 | * the advanced destructor, starting with the leaf nodes of the subtree. | |
| 447 | * | |
| 448 | * This is a convenience macro for invoking #cxTreeDestroySubtree() on the | |
| 449 | * root node of the tree. | |
| 450 | * | |
| 451 | * @attention Be careful when calling this function when no destructor function | |
| 452 | * is registered that actually frees the memory of nodes. In that case you will | |
| 845 | 453 | * need a reference to the (former) root node of the tree somewhere, or |
| 440 | 454 | * otherwise you will be leaking memory. |
| 455 | * | |
| 456 | * @param tree the tree | |
| 457 | * @see cxTreeDestroySubtree() | |
| 458 | */ | |
|
1040
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
459 | CX_INLINE |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
460 | void cxTreeClear(CxTree *tree) { |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
461 | if (tree->root != NULL) { |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
462 | cxTreeDestroySubtree(tree, tree->root); |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
463 | } |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
464 | } |
| 440 | 465 | |
| 466 | /** | |
| 467 | * Deallocates the tree structure. | |
| 468 | * | |
| 469 | * The destructor functions are invoked for each node, starting with the leaf | |
| 470 | * nodes. | |
| 471 | * It is guaranteed that for each node the simple destructor is invoked before | |
| 472 | * the advanced destructor. | |
| 473 | * | |
| 474 | * @attention This function will only invoke the destructor functions | |
| 475 | * on the nodes. | |
| 476 | * It will NOT additionally free the nodes with the tree's allocator, because | |
| 477 | * that would cause a double-free in most scenarios where the advanced | |
| 478 | * destructor is already freeing the memory. | |
| 479 | * | |
| 480 | * @param tree the tree to free | |
| 481 | */ | |
|
1040
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
482 | CX_EXTERN |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
483 | void cxTreeFree(CxTree *tree); |
| 324 | 484 | |
| 485 | /** | |
|
1040
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
486 | * Creates a new tree. |
| 324 | 487 | * |
|
1040
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
488 | * The specified @p allocator will be used for creating the tree struct |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
489 | * @em and the nodes. |
| 324 | 490 | * |
|
1040
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
491 | * When you do not specify an existing @p root, the tree will be created |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
492 | * empty. Additionally, cxFree() is registered as the advanced destructor for |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
493 | * the tree so that all nodes that you will add to the tree are automatically |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
494 | * freed together with the tree. |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
495 | * When @p root is not @c NULL, no destructors are registered automatically. |
| 324 | 496 | * |
|
1040
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
497 | * @param allocator the allocator to use |
|
629
0385a450c2a6
add list initializer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
471
diff
changeset
|
498 | * (if @c NULL, the cxDefaultAllocator is assumed) |
|
1040
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
499 | * @param node_size the complete size of one node |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
500 | * @param elem_size the size of the payload stored in the node |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
501 | * (@c CX_STORE_POINTERS is also supported) |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
502 | * @param root an optional already existing root node |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
503 | * @param loc_data optional offset in the node struct for the payload |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
504 | * (when negative, cxTreeAddData() is not supported) |
| 324 | 505 | * @param loc_parent offset in the node struct for the parent pointer |
| 506 | * @param loc_children offset in the node struct for the children linked list | |
| 507 | * @param loc_last_child optional offset in the node struct for the pointer to | |
| 508 | * the last child in the linked list (negative if there is no such pointer) | |
| 440 | 509 | * @param loc_prev optional offset in the node struct for the prev pointer |
| 324 | 510 | * @param loc_next offset in the node struct for the next pointer |
| 511 | * @return the new tree | |
| 512 | * @see cxTreeCreate() | |
| 513 | */ | |
|
1040
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
514 | CX_EXTERN CX_NODISCARD CX_MALLOC CX_DEALLOC(cxTreeFree, 1) |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
515 | CxTree *cxTreeCreate(const CxAllocator *allocator, |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
516 | size_t node_size, size_t elem_size, void *root, ptrdiff_t loc_data, |
| 870 | 517 | ptrdiff_t loc_parent, ptrdiff_t loc_children, ptrdiff_t loc_last_child, |
| 518 | ptrdiff_t loc_prev, ptrdiff_t loc_next); | |
| 324 | 519 | |
| 520 | /** | |
| 521 | * Searches the data in the specified subtree. | |
| 522 | * | |
| 440 | 523 | * When @p max_depth is zero, the depth is not limited. |
| 524 | * The @p subtree_root itself is on depth 1 and its children have depth 2. | |
| 525 | * | |
|
1040
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
526 | * @note When @p subtree_root is not @c NULL and not part of the @p tree, |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
527 | * the behavior is undefined. |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
528 | * |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
529 | * @attention When @p loc_data is not available, this function immediately returns |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
530 | * @c NULL. |
| 324 | 531 | * |
|
1040
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
532 | * @param tree the tree |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
533 | * @param data the data to search for |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
534 | * @param subtree_root the node where to start (@c NULL to start from root) |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
535 | * @param max_depth the maximum search depth |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
536 | * @param use_dfs @c true when depth-first search should be used; |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
537 | * @c false when breadth-first search should be used |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
538 | * @return the first matching node, or @c NULL when the data cannot be found |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
539 | * @see cxTreeFind() |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
540 | */ |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
541 | CX_EXTERN CX_NONNULL_ARG(1, 2) CX_NODISCARD |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
542 | void *cxTreeFindInSubtree(CxTree *tree, const void *data, void *subtree_root, |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
543 | size_t max_depth, bool use_dfs); |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
544 | |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
545 | /** |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
546 | * Searches the data in the specified tree. |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
547 | * |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
548 | * @attention When @p loc_data is not available, this function immediately returns |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
549 | * @c NULL. |
| 324 | 550 | * |
| 551 | * @param tree the tree | |
| 552 | * @param data the data to search for | |
|
1040
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
553 | * @param use_dfs @c true when depth-first search should be used; |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
554 | * @c false when breadth-first search should be used |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
555 | * @return the first matching node, or @c NULL when the data cannot be found |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
556 | * @see cxTreeFindInSubtree() |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
557 | * @see cxTreeFindFast() |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
558 | */ |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
559 | CX_INLINE CX_NONNULL CX_NODISCARD |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
560 | void *cxTreeFind(CxTree *tree, const void *data, bool use_dfs) { |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
561 | if (tree->root == NULL) return NULL; |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
562 | return cxTreeFindInSubtree(tree, data, tree->root, 0, use_dfs); |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
563 | } |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
564 | |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
565 | /** |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
566 | * Performs an efficient depth-first search in a branch of the specified tree. |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
567 | * |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
568 | * When @p max_depth is zero, the depth is not limited. |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
569 | * The @p subtree_root itself is on depth 1 and its children have depth 2. |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
570 | * |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
571 | * @note When @p subtree_root is not @c NULL and not part of the @p tree, |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
572 | * the behavior is undefined. |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
573 | * |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
574 | * @param tree the tree |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
575 | * @param data the data to search for |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
576 | * @param sfunc the search function |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
577 | * @param subtree_root the node where to start (@c NULL to start from root) |
| 440 | 578 | * @param max_depth the maximum search depth |
| 579 | * @return the first matching node, or @c NULL when the data cannot be found | |
|
1040
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
580 | * @see cxTreeFindInSubtree() |
| 324 | 581 | */ |
|
1040
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
582 | CX_EXTERN CX_NONNULL CX_NODISCARD |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
583 | void *cxTreeFindFastInSubtree(CxTree *tree, const void *data, |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
584 | cx_tree_search_func sfunc, void *subtree_root, size_t max_depth); |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
585 | |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
586 | /** |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
587 | * Performs an efficient depth-first search in the tree. |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
588 | * |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
589 | * @param tree the tree |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
590 | * @param data the data to search for |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
591 | * @param sfunc the search function |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
592 | * @return the first matching node, or @c NULL when the data cannot be found |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
593 | * @see cxTreeFind() |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
594 | */ |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
595 | CX_INLINE CX_NONNULL CX_NODISCARD |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
596 | void *cxTreeFindFast(CxTree *tree, const void *data, cx_tree_search_func sfunc) { |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
597 | return cxTreeFindFastInSubtree(tree, data, sfunc, tree->root, 0); |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
598 | } |
| 324 | 599 | |
| 600 | /** | |
| 601 | * Determines the size of the specified subtree. | |
| 602 | * | |
| 603 | * @param tree the tree | |
| 604 | * @param subtree_root the root node of the subtree | |
| 605 | * @return the number of nodes in the specified subtree | |
| 606 | */ | |
|
1040
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
607 | CX_EXTERN CX_NONNULL CX_NODISCARD |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
608 | size_t cxTreeSubtreeSize(CxTree *tree, void *subtree_root); |
| 324 | 609 | |
| 610 | /** | |
| 611 | * Determines the depth of the specified subtree. | |
| 612 | * | |
| 613 | * @param tree the tree | |
| 614 | * @param subtree_root the root node of the subtree | |
| 440 | 615 | * @return the tree depth including the @p subtree_root |
| 324 | 616 | */ |
|
1040
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
617 | CX_EXTERN CX_NONNULL CX_NODISCARD |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
618 | size_t cxTreeSubtreeDepth(CxTree *tree, void *subtree_root); |
| 324 | 619 | |
| 620 | /** | |
|
629
0385a450c2a6
add list initializer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
471
diff
changeset
|
621 | * Determines the size of the entire tree. |
|
0385a450c2a6
add list initializer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
471
diff
changeset
|
622 | * |
|
0385a450c2a6
add list initializer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
471
diff
changeset
|
623 | * @param tree the tree |
|
0385a450c2a6
add list initializer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
471
diff
changeset
|
624 | * @return the tree size, counting the root as one |
|
0385a450c2a6
add list initializer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
471
diff
changeset
|
625 | */ |
|
1040
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
626 | CX_EXTERN CX_NONNULL CX_NODISCARD |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
627 | size_t cxTreeSize(CxTree *tree); |
|
629
0385a450c2a6
add list initializer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
471
diff
changeset
|
628 | |
|
0385a450c2a6
add list initializer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
471
diff
changeset
|
629 | /** |
| 324 | 630 | * Determines the depth of the entire tree. |
| 631 | * | |
| 632 | * @param tree the tree | |
| 633 | * @return the tree depth, counting the root as one | |
| 634 | */ | |
|
1040
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
635 | CX_EXTERN CX_NONNULL CX_NODISCARD |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
636 | size_t cxTreeDepth(CxTree *tree); |
| 324 | 637 | |
| 638 | /** | |
| 440 | 639 | * Creates a depth-first iterator for the specified tree starting in @p node. |
| 640 | * | |
| 641 | * If the node is not part of the tree, the behavior is undefined. | |
| 642 | * | |
| 643 | * @param tree the tree to iterate | |
| 644 | * @param node the node where to start | |
| 645 | * @param visit_on_exit true, if the iterator shall visit a node again when | |
| 646 | * leaving the subtree | |
| 647 | * @return a tree iterator (depth-first) | |
| 648 | * @see cxTreeVisit() | |
| 649 | */ | |
|
1040
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
650 | CX_EXTERN CX_NONNULL CX_NODISCARD |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
651 | CxTreeIterator cxTreeIterateSubtree(CxTree *tree, void *node, bool visit_on_exit); |
| 440 | 652 | |
| 653 | /** | |
| 654 | * Creates a breadth-first iterator for the specified tree starting in @p node. | |
| 655 | * | |
| 656 | * If the node is not part of the tree, the behavior is undefined. | |
| 657 | * | |
| 658 | * @param tree the tree to iterate | |
| 659 | * @param node the node where to start | |
| 660 | * @return a tree visitor (a.k.a. breadth-first iterator) | |
| 661 | * @see cxTreeIterate() | |
| 662 | */ | |
|
1040
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
663 | CX_EXTERN CX_NONNULL CX_NODISCARD |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
664 | CxTreeIterator cxTreeVisitSubtree(CxTree *tree, void *node); |
| 440 | 665 | |
| 666 | /** | |
| 324 | 667 | * Creates a depth-first iterator for the specified tree. |
| 668 | * | |
| 669 | * @param tree the tree to iterate | |
| 670 | * @param visit_on_exit true, if the iterator shall visit a node again when | |
| 440 | 671 | * leaving the subtree |
| 324 | 672 | * @return a tree iterator (depth-first) |
| 440 | 673 | * @see cxTreeVisit() |
| 324 | 674 | */ |
|
1040
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
675 | CX_EXTERN CX_NONNULL CX_NODISCARD |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
676 | CxTreeIterator cxTreeIterate(CxTree *tree, bool visit_on_exit); |
| 324 | 677 | |
| 678 | /** | |
| 679 | * Creates a breadth-first iterator for the specified tree. | |
| 680 | * | |
| 681 | * @param tree the tree to iterate | |
| 682 | * @return a tree visitor (a.k.a. breadth-first iterator) | |
| 440 | 683 | * @see cxTreeIterate() |
| 324 | 684 | */ |
|
1040
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
685 | CX_EXTERN CX_NONNULL CX_NODISCARD |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
686 | CxTreeIterator cxTreeVisit(CxTree *tree); |
| 324 | 687 | |
| 688 | /** | |
| 440 | 689 | * Sets the (new) parent of the specified child. |
| 690 | * | |
| 845 | 691 | * If the @p child is not already a member of the tree, this function behaves |
|
1040
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
692 | * as #cxTreeAddNode(). |
| 440 | 693 | * |
| 694 | * @param tree the tree | |
| 695 | * @param parent the (new) parent of the child | |
| 696 | * @param child the node to add | |
|
1040
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
697 | * @see cxTreeAddNode() |
| 440 | 698 | */ |
|
1040
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
699 | CX_EXTERN CX_NONNULL |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
700 | void cxTreeSetParent(CxTree *tree, void *parent, void *child); |
| 440 | 701 | |
| 702 | /** | |
| 324 | 703 | * Adds a new node to the tree. |
| 704 | * | |
| 845 | 705 | * If the @p child is already a member of the tree, the behavior is undefined. |
| 440 | 706 | * Use #cxTreeSetParent() if you want to move a subtree to another location. |
| 707 | * | |
| 708 | * @attention The node may be externally created, but MUST obey the same rules | |
|
1040
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
709 | * as if it was created by the tree itself with #cxTreeAddData() (e.g., use |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
710 | * the tree's allocator). |
| 324 | 711 | * |
| 712 | * @param tree the tree | |
| 713 | * @param parent the parent of the node to add | |
| 714 | * @param child the node to add | |
| 440 | 715 | * @see cxTreeSetParent() |
|
1040
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
716 | * @see cxTreeAddData() |
| 324 | 717 | */ |
|
1040
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
718 | CX_EXTERN CX_NONNULL |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
719 | void cxTreeAddNode(CxTree *tree, void *parent, void *child); |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
720 | |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
721 | /** |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
722 | * Creates a new node and adds it to the tree. |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
723 | * |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
724 | * @param tree the tree |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
725 | * @param parent the parent node of the new node |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
726 | * @param data the data that will be submitted to the create function |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
727 | * @return the added node or @c NULL when the allocation failed |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
728 | * @see cxTreeAdd() |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
729 | */ |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
730 | CX_EXTERN CX_NONNULL |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
731 | void *cxTreeAddData(CxTree *tree, void *parent, const void *data); |
| 324 | 732 | |
| 733 | /** | |
| 734 | * Creates a new node and adds it to the tree. | |
| 735 | * | |
|
1040
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
736 | * @param tree the tree |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
737 | * @param parent the parent node of the new node |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
738 | * @return the added node or @c NULL when the allocation failed |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
739 | */ |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
740 | CX_EXTERN CX_NODISCARD CX_NONNULL |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
741 | void *cxTreeCreateNode(CxTree *tree, void *parent); |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
742 | |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
743 | /** |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
744 | * Creates a new root node or returns the existing root node. |
| 324 | 745 | * |
|
1040
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
746 | * @param tree the tree |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
747 | * @return the new root node, the existing root node, or @c NULL when the allocation failed |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
748 | * @see cxTreeCreateRootData() |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
749 | */ |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
750 | CX_EXTERN CX_NODISCARD CX_NONNULL |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
751 | void *cxTreeCreateRoot(CxTree *tree); |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
752 | |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
753 | /** |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
754 | * Creates a new root node or uses the existing root node and writes the specified data to that node. |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
755 | * |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
756 | * @note This function immediately returns @c NULL when @c loc_data was not initialized with a positive value. |
| 324 | 757 | * |
| 758 | * @param tree the tree | |
|
1040
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
759 | * @param data the data for the root node |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
760 | * @return the new root node, the existing root node, |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
761 | * or @c NULL when the allocation failed or the data location is not known |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
762 | * @see cxTreeCreateRoot() |
| 324 | 763 | */ |
|
1040
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
764 | CX_EXTERN CX_NODISCARD CX_NONNULL |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
765 | void *cxTreeCreateRootData(CxTree *tree, const void *data); |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
766 | |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
767 | /** |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
768 | * Exchanges the root of the tree. |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
769 | * |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
770 | * @attention The old tree nodes might need to be deallocated by the caller. |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
771 | * On the other hand, when the tree has destructors registered, keep in mind |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
772 | * that they will be applied to the new tree. |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
773 | * In particular, using cxTreeCreate() with a @c NULL root and setting the |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
774 | * root with this function is @em not equivalent to creating the tree with |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
775 | * a reference to an existing root because trees created without a root will |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
776 | * have destructors registered. |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
777 | * |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
778 | * @param tree the tree |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
779 | * @param new_root the new root node |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
780 | * @return the old root node (or @c NULL when the tree was empty) |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
781 | */ |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
782 | CX_EXTERN CX_NONNULL_ARG(1) CX_NODISCARD |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
783 | void *cxTreeSetRoot(CxTree *tree, void *new_root); |
| 324 | 784 | |
| 785 | /** | |
| 786 | * A function that is invoked when a node needs to be re-linked to a new parent. | |
| 787 | * | |
| 788 | * When a node is re-linked, sometimes the contents need to be updated. | |
| 440 | 789 | * This callback is invoked by #cxTreeRemoveNode() and #cxTreeDestroyNode() |
| 790 | * so that those updates can be applied when re-linking the children of the | |
| 791 | * removed node. | |
| 324 | 792 | * |
| 793 | * @param node the affected node | |
| 794 | * @param old_parent the old parent of the node | |
| 795 | * @param new_parent the new parent of the node | |
| 796 | */ | |
| 797 | typedef void (*cx_tree_relink_func)( | |
| 798 | void *node, | |
| 799 | const void *old_parent, | |
| 800 | const void *new_parent | |
| 801 | ); | |
| 802 | ||
| 803 | /** | |
| 804 | * Removes a node and re-links its children to its former parent. | |
| 805 | * | |
| 806 | * If the node is not part of the tree, the behavior is undefined. | |
| 807 | * | |
| 440 | 808 | * @note The destructor function, if any, will @em not be invoked. That means |
| 324 | 809 | * you will need to free the removed node by yourself, eventually. |
| 810 | * | |
| 811 | * @param tree the tree | |
| 812 | * @param node the node to remove (must not be the root node) | |
| 813 | * @param relink_func optional callback to update the content of each re-linked | |
| 814 | * node | |
| 440 | 815 | * @return zero on success, non-zero if @p node is the root node of the tree |
| 324 | 816 | */ |
|
1040
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
817 | CX_EXTERN CX_NONNULL_ARG(1, 2) |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
818 | int cxTreeRemoveNode(CxTree *tree, void *node, cx_tree_relink_func relink_func); |
| 324 | 819 | |
| 820 | /** | |
| 845 | 821 | * Removes a node and its subtree from the tree. |
| 324 | 822 | * |
| 823 | * If the node is not part of the tree, the behavior is undefined. | |
| 824 | * | |
| 440 | 825 | * @note The destructor function, if any, will @em not be invoked. That means |
| 324 | 826 | * you will need to free the removed subtree by yourself, eventually. |
| 827 | * | |
| 828 | * @param tree the tree | |
| 829 | * @param node the node to remove | |
| 830 | */ | |
|
1040
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
831 | CX_EXTERN CX_NONNULL |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
832 | void cxTreeRemoveSubtree(CxTree *tree, void *node); |
| 324 | 833 | |
| 440 | 834 | /** |
| 835 | * Destroys a node and re-links its children to its former parent. | |
| 836 | * | |
| 837 | * If the node is not part of the tree, the behavior is undefined. | |
| 838 | * | |
| 839 | * It is guaranteed that the simple destructor is invoked before | |
| 840 | * the advanced destructor. | |
| 841 | * | |
| 842 | * @attention This function will not free the memory of the node with the | |
| 843 | * tree's allocator, because that is usually done by the advanced destructor | |
| 844 | * and would therefore result in a double-free. | |
| 845 | * | |
| 846 | * @param tree the tree | |
| 847 | * @param node the node to destroy (must not be the root node) | |
| 848 | * @param relink_func optional callback to update the content of each re-linked | |
| 849 | * node | |
| 850 | * @return zero on success, non-zero if @p node is the root node of the tree | |
| 851 | */ | |
|
1040
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
852 | CX_EXTERN CX_NONNULL_ARG(1, 2) |
|
473d8cb58a6c
update ucx to version 4.0
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
992
diff
changeset
|
853 | int cxTreeDestroyNode(CxTree *tree, void *node, cx_tree_relink_func relink_func); |
|
253
087cc9216f28
initial newapi GTK port
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
854 | |
|
087cc9216f28
initial newapi GTK port
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
855 | #endif //UCX_TREE_H |