231 |
231 |
232 /** |
232 /** |
233 * Advises the iterator to skip the subtree below the current node and |
233 * Advises the iterator to skip the subtree below the current node and |
234 * also continues the current loop. |
234 * also continues the current loop. |
235 * |
235 * |
236 * @param iterator the iterator |
236 * @param iterator (@c CxTreeIterator) the iterator |
237 */ |
237 */ |
238 #define cxTreeIteratorContinue(iterator) (iterator).skip = true; continue |
238 #define cxTreeIteratorContinue(iterator) (iterator).skip = true; continue |
239 |
239 |
240 /** |
240 /** |
241 * Advises the visitor to skip the subtree below the current node and |
241 * Advises the visitor to skip the subtree below the current node and |
242 * also continues the current loop. |
242 * also continues the current loop. |
243 * |
243 * |
244 * @param visitor the visitor |
244 * @param visitor (@c CxTreeVisitor) the visitor |
245 */ |
245 */ |
246 #define cxTreeVisitorContinue(visitor) cxTreeIteratorContinue(visitor) |
246 #define cxTreeVisitorContinue(visitor) cxTreeIteratorContinue(visitor) |
247 |
247 |
248 /** |
248 /** |
249 * Links a node to a (new) parent. |
249 * Links a node to a (new) parent. |
250 * |
250 * |
251 * If the node has already a parent, it is unlinked, first. |
251 * If the node has already a parent, it is unlinked, first. |
252 * If the parent has children already, the node is \em appended to the list |
252 * If the parent has children already, the node is @em appended to the list |
253 * of all currently existing children. |
253 * of all currently existing children. |
254 * |
254 * |
255 * @param parent the parent node |
255 * @param parent the parent node |
256 * @param node the node that shall be linked |
256 * @param node the node that shall be linked |
257 * @param loc_parent offset in the node struct for the parent pointer |
257 * @param loc_parent offset in the node struct for the parent pointer |
258 * @param loc_children offset in the node struct for the children linked list |
258 * @param loc_children offset in the node struct for the children linked list |
259 * @param loc_last_child optional offset in the node struct for the pointer to |
259 * @param loc_last_child optional offset in the node struct for the pointer to |
260 * the last child in the linked list (negative if there is no such pointer) |
260 * the last child in the linked list (negative if there is no such pointer) |
261 * @param loc_prev offset in the node struct for the prev pointer |
261 * @param loc_prev optional offset in the node struct for the prev pointer |
262 * @param loc_next offset in the node struct for the next pointer |
262 * @param loc_next offset in the node struct for the next pointer |
263 * @see cx_tree_unlink() |
263 * @see cx_tree_unlink() |
264 */ |
264 */ |
265 __attribute__((__nonnull__)) |
265 cx_attr_nonnull |
266 void cx_tree_link( |
266 void cx_tree_link( |
267 void *restrict parent, |
267 void *parent, |
268 void *restrict node, |
268 void *node, |
269 ptrdiff_t loc_parent, |
269 ptrdiff_t loc_parent, |
270 ptrdiff_t loc_children, |
270 ptrdiff_t loc_children, |
271 ptrdiff_t loc_last_child, |
271 ptrdiff_t loc_last_child, |
272 ptrdiff_t loc_prev, |
272 ptrdiff_t loc_prev, |
273 ptrdiff_t loc_next |
273 ptrdiff_t loc_next |
281 * @param node the node that shall be unlinked from its parent |
281 * @param node the node that shall be unlinked from its parent |
282 * @param loc_parent offset in the node struct for the parent pointer |
282 * @param loc_parent offset in the node struct for the parent pointer |
283 * @param loc_children offset in the node struct for the children linked list |
283 * @param loc_children offset in the node struct for the children linked list |
284 * @param loc_last_child optional offset in the node struct for the pointer to |
284 * @param loc_last_child optional offset in the node struct for the pointer to |
285 * the last child in the linked list (negative if there is no such pointer) |
285 * the last child in the linked list (negative if there is no such pointer) |
286 * @param loc_prev offset in the node struct for the prev pointer |
286 * @param loc_prev optional offset in the node struct for the prev pointer |
287 * @param loc_next offset in the node struct for the next pointer |
287 * @param loc_next offset in the node struct for the next pointer |
288 * @see cx_tree_link() |
288 * @see cx_tree_link() |
289 */ |
289 */ |
290 __attribute__((__nonnull__)) |
290 cx_attr_nonnull |
291 void cx_tree_unlink( |
291 void cx_tree_unlink( |
292 void *node, |
292 void *node, |
293 ptrdiff_t loc_parent, |
293 ptrdiff_t loc_parent, |
294 ptrdiff_t loc_children, |
294 ptrdiff_t loc_children, |
295 ptrdiff_t loc_last_child, |
295 ptrdiff_t loc_last_child, |
296 ptrdiff_t loc_prev, |
296 ptrdiff_t loc_prev, |
297 ptrdiff_t loc_next |
297 ptrdiff_t loc_next |
298 ); |
298 ); |
299 |
299 |
300 /** |
300 /** |
|
301 * Macro that can be used instead of the magic value for infinite search depth. |
|
302 */ |
|
303 #define CX_TREE_SEARCH_INFINITE_DEPTH 0 |
|
304 |
|
305 /** |
301 * Function pointer for a search function. |
306 * Function pointer for a search function. |
302 * |
307 * |
303 * A function of this kind shall check if the specified \p node |
308 * A function of this kind shall check if the specified @p node |
304 * contains the given \p data or if one of the children might contain |
309 * contains the given @p data or if one of the children might contain |
305 * the data. |
310 * the data. |
306 * |
311 * |
307 * The function should use the returned integer to indicate how close the |
312 * The function should use the returned integer to indicate how close the |
308 * match is, where a negative number means that it does not match at all. |
313 * match is, where a negative number means that it does not match at all. |
|
314 * Zero means exact match and a positive number is an implementation defined |
|
315 * measure for the distance to an exact match. |
309 * |
316 * |
310 * For example if a tree stores file path information, a node that is |
317 * For example if a tree stores file path information, a node that is |
311 * describing a parent directory of a filename that is searched, shall |
318 * describing a parent directory of a filename that is searched, shall |
312 * return a positive number to indicate that a child node might contain the |
319 * return a positive number to indicate that a child node might contain the |
313 * searched item. On the other hand, if the node denotes a path that is not a |
320 * searched item. On the other hand, if the node denotes a path that is not a |
319 * |
326 * |
320 * @return 0 if the node contains the data, |
327 * @return 0 if the node contains the data, |
321 * positive if one of the children might contain the data, |
328 * positive if one of the children might contain the data, |
322 * negative if neither the node, nor the children contains the data |
329 * negative if neither the node, nor the children contains the data |
323 */ |
330 */ |
|
331 cx_attr_nonnull |
324 typedef int (*cx_tree_search_data_func)(const void *node, const void *data); |
332 typedef int (*cx_tree_search_data_func)(const void *node, const void *data); |
325 |
333 |
326 |
334 |
327 /** |
335 /** |
328 * Function pointer for a search function. |
336 * Function pointer for a search function. |
329 * |
337 * |
330 * A function of this kind shall check if the specified \p node |
338 * A function of this kind shall check if the specified @p node |
331 * contains the same \p data as \p new_node or if one of the children might |
339 * contains the same @p data as @p new_node or if one of the children might |
332 * contain the data. |
340 * contain the data. |
333 * |
341 * |
334 * The function should use the returned integer to indicate how close the |
342 * The function should use the returned integer to indicate how close the |
335 * match is, where a negative number means that it does not match at all. |
343 * match is, where a negative number means that it does not match at all. |
|
344 * Zero means exact match and a positive number is an implementation defined |
|
345 * measure for the distance to an exact match. |
336 * |
346 * |
337 * For example if a tree stores file path information, a node that is |
347 * For example if a tree stores file path information, a node that is |
338 * describing a parent directory of a filename that is searched, shall |
348 * describing a parent directory of a filename that is searched, shall |
339 * return a positive number to indicate that a child node might contain the |
349 * return a positive number to indicate that a child node might contain the |
340 * searched item. On the other hand, if the node denotes a path that is not a |
350 * searched item. On the other hand, if the node denotes a path that is not a |
357 * closest result which might be a good starting point for adding a new node |
368 * closest result which might be a good starting point for adding a new node |
358 * to the tree (see also #cx_tree_add()). |
369 * to the tree (see also #cx_tree_add()). |
359 * |
370 * |
360 * Depending on the tree structure it is not necessarily guaranteed that the |
371 * Depending on the tree structure it is not necessarily guaranteed that the |
361 * "closest" match is uniquely defined. This function will search for a node |
372 * "closest" match is uniquely defined. This function will search for a node |
362 * with the best match according to the \p sfunc (meaning: the return value of |
373 * with the best match according to the @p sfunc (meaning: the return value of |
363 * \p sfunc which is closest to zero). If that is also ambiguous, an arbitrary |
374 * @p sfunc which is closest to zero). If that is also ambiguous, an arbitrary |
364 * node matching the criteria is returned. |
375 * node matching the criteria is returned. |
365 * |
376 * |
366 * @param root the root node |
377 * @param root the root node |
|
378 * @param depth the maximum depth (zero=indefinite, one=just root) |
367 * @param data the data to search for |
379 * @param data the data to search for |
368 * @param sfunc the search function |
380 * @param sfunc the search function |
369 * @param result where the result shall be stored |
381 * @param result where the result shall be stored |
370 * @param loc_children offset in the node struct for the children linked list |
382 * @param loc_children offset in the node struct for the children linked list |
371 * @param loc_next offset in the node struct for the next pointer |
383 * @param loc_next offset in the node struct for the next pointer |
372 * @return zero if the node was found exactly, positive if a node was found that |
384 * @return zero if the node was found exactly, positive if a node was found that |
373 * could contain the node (but doesn't right now), negative if the tree does not |
385 * could contain the node (but doesn't right now), negative if the tree does not |
374 * contain any node that might be related to the searched data |
386 * contain any node that might be related to the searched data |
375 */ |
387 */ |
376 __attribute__((__nonnull__)) |
388 cx_attr_nonnull |
|
389 cx_attr_access_w(5) |
377 int cx_tree_search_data( |
390 int cx_tree_search_data( |
378 const void *root, |
391 const void *root, |
|
392 size_t depth, |
379 const void *data, |
393 const void *data, |
380 cx_tree_search_data_func sfunc, |
394 cx_tree_search_data_func sfunc, |
381 void **result, |
395 void **result, |
382 ptrdiff_t loc_children, |
396 ptrdiff_t loc_children, |
383 ptrdiff_t loc_next |
397 ptrdiff_t loc_next |
390 * return a closest result which might be a good starting point for adding the |
404 * return a closest result which might be a good starting point for adding the |
391 * new node to the tree (see also #cx_tree_add()). |
405 * new node to the tree (see also #cx_tree_add()). |
392 * |
406 * |
393 * Depending on the tree structure it is not necessarily guaranteed that the |
407 * Depending on the tree structure it is not necessarily guaranteed that the |
394 * "closest" match is uniquely defined. This function will search for a node |
408 * "closest" match is uniquely defined. This function will search for a node |
395 * with the best match according to the \p sfunc (meaning: the return value of |
409 * with the best match according to the @p sfunc (meaning: the return value of |
396 * \p sfunc which is closest to zero). If that is also ambiguous, an arbitrary |
410 * @p sfunc which is closest to zero). If that is also ambiguous, an arbitrary |
397 * node matching the criteria is returned. |
411 * node matching the criteria is returned. |
398 * |
412 * |
399 * @param root the root node |
413 * @param root the root node |
|
414 * @param depth the maximum depth (zero=indefinite, one=just root) |
400 * @param node the node to search for |
415 * @param node the node to search for |
401 * @param sfunc the search function |
416 * @param sfunc the search function |
402 * @param result where the result shall be stored |
417 * @param result where the result shall be stored |
403 * @param loc_children offset in the node struct for the children linked list |
418 * @param loc_children offset in the node struct for the children linked list |
404 * @param loc_next offset in the node struct for the next pointer |
419 * @param loc_next offset in the node struct for the next pointer |
405 * @return zero if the node was found exactly, positive if a node was found that |
420 * @return zero if the node was found exactly, positive if a node was found that |
406 * could contain the node (but doesn't right now), negative if the tree does not |
421 * could contain the node (but doesn't right now), negative if the tree does not |
407 * contain any node that might be related to the searched data |
422 * contain any node that might be related to the searched data |
408 */ |
423 */ |
409 __attribute__((__nonnull__)) |
424 cx_attr_nonnull |
|
425 cx_attr_access_w(5) |
410 int cx_tree_search( |
426 int cx_tree_search( |
411 const void *root, |
427 const void *root, |
|
428 size_t depth, |
412 const void *node, |
429 const void *node, |
413 cx_tree_search_func sfunc, |
430 cx_tree_search_func sfunc, |
414 void **result, |
431 void **result, |
415 ptrdiff_t loc_children, |
432 ptrdiff_t loc_children, |
416 ptrdiff_t loc_next |
433 ptrdiff_t loc_next |
560 * again. |
581 * again. |
561 * |
582 * |
562 * Refer to the documentation of #cx_tree_add() for more details. |
583 * Refer to the documentation of #cx_tree_add() for more details. |
563 * |
584 * |
564 * @param src a pointer to the source data array |
585 * @param src a pointer to the source data array |
565 * @param num the number of elements in the \p src array |
586 * @param num the number of elements in the @p src array |
566 * @param elem_size the size of each element in the \p src array |
587 * @param elem_size the size of each element in the @p src array |
567 * @param sfunc a search function |
588 * @param sfunc a search function |
568 * @param cfunc a node creation function |
589 * @param cfunc a node creation function |
569 * @param cdata optional additional data |
590 * @param cdata optional additional data |
570 * @param failed location where the pointer to a failed node shall be stored |
591 * @param failed location where the pointer to a failed node shall be stored |
571 * @param root the root node of the tree |
592 * @param root the root node of the tree |
572 * @param loc_parent offset in the node struct for the parent pointer |
593 * @param loc_parent offset in the node struct for the parent pointer |
573 * @param loc_children offset in the node struct for the children linked list |
594 * @param loc_children offset in the node struct for the children linked list |
574 * @param loc_last_child optional offset in the node struct for the pointer to |
595 * @param loc_last_child optional offset in the node struct for the pointer to |
575 * the last child in the linked list (negative if there is no such pointer) |
596 * the last child in the linked list (negative if there is no such pointer) |
576 * @param loc_prev offset in the node struct for the prev pointer |
597 * @param loc_prev optional offset in the node struct for the prev pointer |
577 * @param loc_next offset in the node struct for the next pointer |
598 * @param loc_next offset in the node struct for the next pointer |
578 * @return the number of array elements successfully processed |
599 * @return the number of array elements successfully processed |
579 * @see cx_tree_add() |
600 * @see cx_tree_add() |
580 */ |
601 */ |
581 __attribute__((__nonnull__(1, 4, 5, 7, 8))) |
602 cx_attr_nonnull_arg(1, 4, 5, 7, 8) |
|
603 cx_attr_access_w(7) |
582 size_t cx_tree_add_array( |
604 size_t cx_tree_add_array( |
583 const void *src, |
605 const void *src, |
584 size_t num, |
606 size_t num, |
585 size_t elem_size, |
607 size_t elem_size, |
586 cx_tree_search_func sfunc, |
608 cx_tree_search_func sfunc, |
597 |
619 |
598 /** |
620 /** |
599 * Adds data to a tree. |
621 * Adds data to a tree. |
600 * |
622 * |
601 * An adequate location where to add the new tree node is searched with the |
623 * An adequate location where to add the new tree node is searched with the |
602 * specified \p sfunc. |
624 * specified @p sfunc. |
603 * |
625 * |
604 * When a location is found, the \p cfunc will be invoked with \p cdata. |
626 * When a location is found, the @p cfunc will be invoked with @p cdata. |
605 * |
627 * |
606 * The node returned by \p cfunc will be linked into the tree. |
628 * The node returned by @p cfunc will be linked into the tree. |
607 * When \p sfunc returned a positive integer, the new node will be linked as a |
629 * When @p sfunc returned a positive integer, the new node will be linked as a |
608 * child. The other children (now siblings of the new node) are then checked |
630 * child. The other children (now siblings of the new node) are then checked |
609 * with \p sfunc, whether they could be children of the new node and re-linked |
631 * with @p sfunc, whether they could be children of the new node and re-linked |
610 * accordingly. |
632 * accordingly. |
611 * |
633 * |
612 * When \p sfunc returned zero and the found node has a parent, the new |
634 * When @p sfunc returned zero and the found node has a parent, the new |
613 * node will be added as sibling - otherwise, the new node will be added |
635 * node will be added as sibling - otherwise, the new node will be added |
614 * as a child. |
636 * as a child. |
615 * |
637 * |
616 * When \p sfunc returned a negative value, the new node will not be added to |
638 * When @p sfunc returned a negative value, the new node will not be added to |
617 * the tree and this function returns a non-zero value. |
639 * the tree and this function returns a non-zero value. |
618 * The caller should check if \p cnode contains a node pointer and deal with the |
640 * The caller should check if @p cnode contains a node pointer and deal with the |
619 * node that could not be added. |
641 * node that could not be added. |
620 * |
642 * |
621 * This function also returns a non-zero value when \p cfunc tries to allocate |
643 * This function also returns a non-zero value when @p cfunc tries to allocate |
622 * a new node but fails to do so. In that case, the pointer stored to \p cnode |
644 * a new node but fails to do so. In that case, the pointer stored to @p cnode |
623 * will be \c NULL. |
645 * will be @c NULL. |
624 * |
646 * |
625 * Multiple elements can be added more efficiently with |
647 * Multiple elements can be added more efficiently with |
626 * #cx_tree_add_array() or #cx_tree_add_iter(). |
648 * #cx_tree_add_array() or #cx_tree_add_iter(). |
627 * |
649 * |
628 * @param src a pointer to the data |
650 * @param src a pointer to the data |
776 }; |
799 }; |
777 |
800 |
778 /** |
801 /** |
779 * Macro to roll out the #cx_tree_node_base_s structure with a custom |
802 * Macro to roll out the #cx_tree_node_base_s structure with a custom |
780 * node type. |
803 * node type. |
|
804 * |
|
805 * Must be used as first member in your custom tree struct. |
|
806 * |
|
807 * @param type the data type for the nodes |
781 */ |
808 */ |
782 #define CX_TREE_NODE_BASE(type) \ |
809 #define CX_TREE_NODE_BASE(type) \ |
783 type *parent; \ |
810 type *parent; \ |
784 type *children;\ |
811 type *children;\ |
785 type *last_child;\ |
812 type *last_child;\ |
786 type *prev;\ |
813 type *prev;\ |
787 type *next |
814 type *next |
788 |
815 |
789 /** |
816 /** |
790 * Macro for specifying the layout of a base node tree. |
817 * Macro for specifying the layout of a base node tree. |
|
818 * |
|
819 * When your tree uses #CX_TREE_NODE_BASE, you can use this |
|
820 * macro in all tree functions that expect the layout parameters |
|
821 * @c loc_parent, @c loc_children, @c loc_last_child, @c loc_prev, |
|
822 * and @c loc_next. |
791 */ |
823 */ |
792 #define cx_tree_node_base_layout \ |
824 #define cx_tree_node_base_layout \ |
793 offsetof(struct cx_tree_node_base_s, parent),\ |
825 offsetof(struct cx_tree_node_base_s, parent),\ |
794 offsetof(struct cx_tree_node_base_s, children),\ |
826 offsetof(struct cx_tree_node_base_s, children),\ |
795 offsetof(struct cx_tree_node_base_s, last_child),\ |
827 offsetof(struct cx_tree_node_base_s, last_child),\ |
796 offsetof(struct cx_tree_node_base_s, prev), \ |
828 offsetof(struct cx_tree_node_base_s, prev), \ |
797 offsetof(struct cx_tree_node_base_s, next) |
829 offsetof(struct cx_tree_node_base_s, next) |
798 |
830 |
799 /** |
831 /** |
800 * Macro for obtaining the node pointer layout for a specific tree. |
|
801 */ |
|
802 #define cx_tree_node_layout(tree) \ |
|
803 (tree)->loc_parent,\ |
|
804 (tree)->loc_children,\ |
|
805 (tree)->loc_last_child,\ |
|
806 (tree)->loc_prev, \ |
|
807 (tree)->loc_next |
|
808 |
|
809 /** |
|
810 * The class definition for arbitrary trees. |
832 * The class definition for arbitrary trees. |
811 */ |
833 */ |
812 struct cx_tree_class_s { |
834 struct cx_tree_class_s { |
813 /** |
|
814 * Destructor function. |
|
815 * |
|
816 * Implementations SHALL invoke the node destructor functions if provided |
|
817 * and SHALL deallocate the tree memory. |
|
818 */ |
|
819 void (*destructor)(struct cx_tree_s *); |
|
820 |
|
821 /** |
835 /** |
822 * Member function for inserting a single element. |
836 * Member function for inserting a single element. |
823 * |
837 * |
824 * Implementations SHALL NOT simply invoke \p insert_many as this comes |
838 * Implementations SHALL NOT simply invoke @p insert_many as this comes |
825 * with too much overhead. |
839 * with too much overhead. |
826 */ |
840 */ |
827 int (*insert_element)( |
841 int (*insert_element)( |
828 struct cx_tree_s *tree, |
842 struct cx_tree_s *tree, |
829 const void *data |
843 const void *data |
845 * Member function for finding a node. |
859 * Member function for finding a node. |
846 */ |
860 */ |
847 void *(*find)( |
861 void *(*find)( |
848 struct cx_tree_s *tree, |
862 struct cx_tree_s *tree, |
849 const void *subtree, |
863 const void *subtree, |
850 const void *data |
864 const void *data, |
|
865 size_t depth |
851 ); |
866 ); |
852 |
|
853 /** |
|
854 * Member function for creating an iterator for the tree. |
|
855 */ |
|
856 CxTreeIterator (*iterator)( |
|
857 struct cx_tree_s *tree, |
|
858 bool visit_on_exit |
|
859 ); |
|
860 |
|
861 /** |
|
862 * Member function for creating a visitor for the tree. |
|
863 */ |
|
864 CxTreeVisitor (*visitor)(struct cx_tree_s *tree); |
|
865 }; |
867 }; |
866 |
868 |
867 /** |
869 /** |
868 * Common type for all tree implementations. |
870 * Common type for all tree implementations. |
869 */ |
871 */ |
870 typedef struct cx_tree_s CxTree; |
872 typedef struct cx_tree_s CxTree; |
871 |
873 |
|
874 |
|
875 /** |
|
876 * Destroys a node and it's subtree. |
|
877 * |
|
878 * It is guaranteed that the simple destructor is invoked before |
|
879 * the advanced destructor, starting with the leaf nodes of the subtree. |
|
880 * |
|
881 * When this function is invoked on the root node of the tree, it destroys the |
|
882 * tree contents, but - in contrast to #cxTreeFree() - not the tree |
|
883 * structure, leaving an empty tree behind. |
|
884 * |
|
885 * @note The destructor function, if any, will @em not be invoked. That means |
|
886 * you will need to free the removed subtree by yourself, eventually. |
|
887 * |
|
888 * @attention This function will not free the memory of the nodes with the |
|
889 * tree's allocator, because that is usually done by the advanced destructor |
|
890 * and would therefore result in a double-free. |
|
891 * |
|
892 * @param tree the tree |
|
893 * @param node the node to remove |
|
894 * @see cxTreeFree() |
|
895 */ |
|
896 cx_attr_nonnull |
|
897 void cxTreeDestroySubtree(CxTree *tree, void *node); |
|
898 |
|
899 |
|
900 /** |
|
901 * Destroys the tree contents. |
|
902 * |
|
903 * It is guaranteed that the simple destructor is invoked before |
|
904 * the advanced destructor, starting with the leaf nodes of the subtree. |
|
905 * |
|
906 * This is a convenience macro for invoking #cxTreeDestroySubtree() on the |
|
907 * root node of the tree. |
|
908 * |
|
909 * @attention Be careful when calling this function when no destructor function |
|
910 * is registered that actually frees the memory of nodes. In that case you will |
|
911 * need a reference to the (former) root node of the tree somewhere or |
|
912 * otherwise you will be leaking memory. |
|
913 * |
|
914 * @param tree the tree |
|
915 * @see cxTreeDestroySubtree() |
|
916 */ |
|
917 #define cxTreeClear(tree) cxTreeDestroySubtree(tree, tree->root) |
|
918 |
|
919 /** |
|
920 * Deallocates the tree structure. |
|
921 * |
|
922 * The destructor functions are invoked for each node, starting with the leaf |
|
923 * nodes. |
|
924 * It is guaranteed that for each node the simple destructor is invoked before |
|
925 * the advanced destructor. |
|
926 * |
|
927 * @attention This function will only invoke the destructor functions |
|
928 * on the nodes. |
|
929 * It will NOT additionally free the nodes with the tree's allocator, because |
|
930 * that would cause a double-free in most scenarios where the advanced |
|
931 * destructor is already freeing the memory. |
|
932 * |
|
933 * @param tree the tree to free |
|
934 */ |
|
935 void cxTreeFree(CxTree *tree); |
|
936 |
872 /** |
937 /** |
873 * Creates a new tree structure based on the specified layout. |
938 * Creates a new tree structure based on the specified layout. |
874 * |
939 * |
875 * The specified \p allocator will be used for creating the tree struct |
940 * The specified @p allocator will be used for creating the tree struct |
876 * and SHALL be used by \p create_func to allocate memory for the nodes. |
941 * and SHALL be used by @p create_func to allocate memory for the nodes. |
877 * |
942 * |
878 * \note This function will also register an advanced destructor which |
943 * @note This function will also register an advanced destructor which |
879 * will free the nodes with the allocator's free() method. |
944 * will free the nodes with the allocator's free() method. |
880 * |
945 * |
881 * @param allocator the allocator that shall be used |
946 * @param allocator the allocator that shall be used |
|
947 * (if @c NULL, a default stdlib allocator will be used) |
882 * @param create_func a function that creates new nodes |
948 * @param create_func a function that creates new nodes |
883 * @param search_func a function that compares two nodes |
949 * @param search_func a function that compares two nodes |
884 * @param search_data_func a function that compares a node with data |
950 * @param search_data_func a function that compares a node with data |
885 * @param loc_parent offset in the node struct for the parent pointer |
951 * @param loc_parent offset in the node struct for the parent pointer |
886 * @param loc_children offset in the node struct for the children linked list |
952 * @param loc_children offset in the node struct for the children linked list |
887 * @param loc_last_child optional offset in the node struct for the pointer to |
953 * @param loc_last_child optional offset in the node struct for the pointer to |
888 * the last child in the linked list (negative if there is no such pointer) |
954 * the last child in the linked list (negative if there is no such pointer) |
889 * @param loc_prev offset in the node struct for the prev pointer |
955 * @param loc_prev optional offset in the node struct for the prev pointer |
890 * @param loc_next offset in the node struct for the next pointer |
956 * @param loc_next offset in the node struct for the next pointer |
891 * @return the new tree |
957 * @return the new tree |
892 * @see cxTreeCreateSimple() |
958 * @see cxTreeCreateSimple() |
893 * @see cxTreeCreateWrapped() |
959 * @see cxTreeCreateWrapped() |
894 */ |
960 */ |
895 __attribute__((__nonnull__, __warn_unused_result__)) |
961 cx_attr_nonnull_arg(2, 3, 4) |
|
962 cx_attr_nodiscard |
|
963 cx_attr_malloc |
|
964 cx_attr_dealloc(cxTreeFree, 1) |
896 CxTree *cxTreeCreate( |
965 CxTree *cxTreeCreate( |
897 const CxAllocator *allocator, |
966 const CxAllocator *allocator, |
898 cx_tree_node_create_func create_func, |
967 cx_tree_node_create_func create_func, |
899 cx_tree_search_func search_func, |
968 cx_tree_search_func search_func, |
900 cx_tree_search_data_func search_data_func, |
969 cx_tree_search_data_func search_data_func, |
906 ); |
975 ); |
907 |
976 |
908 /** |
977 /** |
909 * Creates a new tree structure based on a default layout. |
978 * Creates a new tree structure based on a default layout. |
910 * |
979 * |
911 * Nodes created by \p create_func MUST contain #cx_tree_node_base_s as first |
980 * Nodes created by @p create_func MUST contain #cx_tree_node_base_s as first |
912 * member (or at least respect the default offsets specified in the tree |
981 * member (or at least respect the default offsets specified in the tree |
913 * struct) and they MUST be allocated with the specified allocator. |
982 * struct) and they MUST be allocated with the specified allocator. |
914 * |
983 * |
915 * \note This function will also register an advanced destructor which |
984 * @note This function will also register an advanced destructor which |
916 * will free the nodes with the allocator's free() method. |
985 * will free the nodes with the allocator's free() method. |
917 * |
986 * |
918 * @param allocator the allocator that shall be used |
987 * @param allocator (@c CxAllocator*) the allocator that shall be used |
919 * @param create_func a function that creates new nodes |
988 * @param create_func (@c cx_tree_node_create_func) a function that creates new nodes |
920 * @param search_func a function that compares two nodes |
989 * @param search_func (@c cx_tree_search_func) a function that compares two nodes |
921 * @param search_data_func a function that compares a node with data |
990 * @param search_data_func (@c cx_tree_search_data_func) a function that compares a node with data |
922 * @return the new tree |
991 * @return (@c CxTree*) the new tree |
923 * @see cxTreeCreate() |
992 * @see cxTreeCreate() |
924 */ |
993 */ |
925 __attribute__((__nonnull__, __warn_unused_result__)) |
994 #define cxTreeCreateSimple(\ |
926 static inline CxTree *cxTreeCreateSimple( |
995 allocator, create_func, search_func, search_data_func \ |
927 const CxAllocator *allocator, |
996 ) cxTreeCreate(allocator, create_func, search_func, search_data_func, \ |
928 cx_tree_node_create_func create_func, |
997 cx_tree_node_base_layout) |
929 cx_tree_search_func search_func, |
|
930 cx_tree_search_data_func search_data_func |
|
931 ) { |
|
932 return cxTreeCreate( |
|
933 allocator, |
|
934 create_func, |
|
935 search_func, |
|
936 search_data_func, |
|
937 cx_tree_node_base_layout |
|
938 ); |
|
939 } |
|
940 |
998 |
941 /** |
999 /** |
942 * Creates a new tree structure based on an existing tree. |
1000 * Creates a new tree structure based on an existing tree. |
943 * |
1001 * |
944 * The specified \p allocator will be used for creating the tree struct. |
1002 * The specified @p allocator will be used for creating the tree struct. |
945 * |
1003 * |
946 * \attention This function will create an incompletely defined tree structure |
1004 * @attention This function will create an incompletely defined tree structure |
947 * where neither the create function, the search function, nor a destructor |
1005 * where neither the create function, the search function, nor a destructor |
948 * will be set. If you wish to use any of this functionality for the wrapped |
1006 * will be set. If you wish to use any of this functionality for the wrapped |
949 * tree, you need to specify those functions afterwards. |
1007 * tree, you need to specify those functions afterwards. |
950 * |
1008 * |
|
1009 * @param allocator the allocator that was used for nodes of the wrapped tree |
|
1010 * (if @c NULL, a default stdlib allocator is assumed) |
951 * @param root the root node of the tree that shall be wrapped |
1011 * @param root the root node of the tree that shall be wrapped |
952 * @param loc_parent offset in the node struct for the parent pointer |
1012 * @param loc_parent offset in the node struct for the parent pointer |
953 * @param loc_children offset in the node struct for the children linked list |
1013 * @param loc_children offset in the node struct for the children linked list |
954 * @param loc_last_child optional offset in the node struct for the pointer to |
1014 * @param loc_last_child optional offset in the node struct for the pointer to |
955 * the last child in the linked list (negative if there is no such pointer) |
1015 * the last child in the linked list (negative if there is no such pointer) |
956 * @param loc_prev offset in the node struct for the prev pointer |
1016 * @param loc_prev optional offset in the node struct for the prev pointer |
957 * @param loc_next offset in the node struct for the next pointer |
1017 * @param loc_next offset in the node struct for the next pointer |
958 * @return the new tree |
1018 * @return the new tree |
959 * @see cxTreeCreate() |
1019 * @see cxTreeCreate() |
960 */ |
1020 */ |
961 __attribute__((__nonnull__, __warn_unused_result__)) |
1021 cx_attr_nonnull_arg(2) |
|
1022 cx_attr_nodiscard |
|
1023 cx_attr_malloc |
|
1024 cx_attr_dealloc(cxTreeFree, 1) |
962 CxTree *cxTreeCreateWrapped( |
1025 CxTree *cxTreeCreateWrapped( |
963 const CxAllocator *allocator, |
1026 const CxAllocator *allocator, |
964 void *root, |
1027 void *root, |
965 ptrdiff_t loc_parent, |
1028 ptrdiff_t loc_parent, |
966 ptrdiff_t loc_children, |
1029 ptrdiff_t loc_children, |
968 ptrdiff_t loc_prev, |
1031 ptrdiff_t loc_prev, |
969 ptrdiff_t loc_next |
1032 ptrdiff_t loc_next |
970 ); |
1033 ); |
971 |
1034 |
972 /** |
1035 /** |
973 * Destroys the tree structure. |
|
974 * |
|
975 * \attention This function will only invoke the destructor functions |
|
976 * on the nodes, if specified. |
|
977 * It will NOT additionally free the nodes with the tree's allocator, because |
|
978 * that would cause a double-free in most scenarios. |
|
979 * |
|
980 * @param tree the tree to destroy |
|
981 */ |
|
982 __attribute__((__nonnull__)) |
|
983 static inline void cxTreeDestroy(CxTree *tree) { |
|
984 tree->cl->destructor(tree); |
|
985 } |
|
986 |
|
987 /** |
|
988 * Inserts data into the tree. |
1036 * Inserts data into the tree. |
989 * |
1037 * |
990 * \remark For this function to work, the tree needs specified search and |
1038 * @remark For this function to work, the tree needs specified search and |
991 * create functions, which might not be available for wrapped trees |
1039 * create functions, which might not be available for wrapped trees |
992 * (see #cxTreeCreateWrapped()). |
1040 * (see #cxTreeCreateWrapped()). |
993 * |
1041 * |
994 * @param tree the tree |
1042 * @param tree the tree |
995 * @param data the data to insert |
1043 * @param data the data to insert |
996 * @return zero on success, non-zero on failure |
1044 * @retval zero success |
997 */ |
1045 * @retval non-zero failure |
998 __attribute__((__nonnull__)) |
1046 */ |
|
1047 cx_attr_nonnull |
999 static inline int cxTreeInsert( |
1048 static inline int cxTreeInsert( |
1000 CxTree *tree, |
1049 CxTree *tree, |
1001 const void *data |
1050 const void *data |
1002 ) { |
1051 ) { |
1003 return tree->cl->insert_element(tree, data); |
1052 return tree->cl->insert_element(tree, data); |
1004 } |
1053 } |
1005 |
1054 |
1006 /** |
1055 /** |
1007 * Inserts elements provided by an iterator efficiently into the tree. |
1056 * Inserts elements provided by an iterator efficiently into the tree. |
1008 * |
1057 * |
1009 * \remark For this function to work, the tree needs specified search and |
1058 * @remark For this function to work, the tree needs specified search and |
1010 * create functions, which might not be available for wrapped trees |
1059 * create functions, which might not be available for wrapped trees |
1011 * (see #cxTreeCreateWrapped()). |
1060 * (see #cxTreeCreateWrapped()). |
1012 * |
1061 * |
1013 * @param tree the tree |
1062 * @param tree the tree |
1014 * @param iter the iterator providing the elements |
1063 * @param iter the iterator providing the elements |
1015 * @param n the maximum number of elements to insert |
1064 * @param n the maximum number of elements to insert |
1016 * @return the number of elements that could be successfully inserted |
1065 * @return the number of elements that could be successfully inserted |
1017 */ |
1066 */ |
1018 __attribute__((__nonnull__)) |
1067 cx_attr_nonnull |
1019 static inline size_t cxTreeInsertIter( |
1068 static inline size_t cxTreeInsertIter( |
1020 CxTree *tree, |
1069 CxTree *tree, |
1021 struct cx_iterator_base_s *iter, |
1070 struct cx_iterator_base_s *iter, |
1022 size_t n |
1071 size_t n |
1023 ) { |
1072 ) { |
1051 } |
1100 } |
1052 |
1101 |
1053 /** |
1102 /** |
1054 * Searches the data in the specified tree. |
1103 * Searches the data in the specified tree. |
1055 * |
1104 * |
1056 * \remark For this function to work, the tree needs a specified \c search_data |
1105 * @remark For this function to work, the tree needs a specified @c search_data |
1057 * function, which might not be available wrapped trees |
1106 * function, which might not be available wrapped trees |
1058 * (see #cxTreeCreateWrapped()). |
1107 * (see #cxTreeCreateWrapped()). |
1059 * |
1108 * |
1060 * @param tree the tree |
1109 * @param tree the tree |
1061 * @param data the data to search for |
1110 * @param data the data to search for |
1062 * @return the first matching node, or \c NULL when the data cannot be found |
1111 * @return the first matching node, or @c NULL when the data cannot be found |
1063 */ |
1112 */ |
1064 __attribute__((__nonnull__)) |
1113 cx_attr_nonnull |
|
1114 cx_attr_nodiscard |
1065 static inline void *cxTreeFind( |
1115 static inline void *cxTreeFind( |
1066 CxTree *tree, |
1116 CxTree *tree, |
1067 const void *data |
1117 const void *data |
1068 ) { |
1118 ) { |
1069 return tree->cl->find(tree, tree->root, data); |
1119 return tree->cl->find(tree, tree->root, data, 0); |
1070 } |
1120 } |
1071 |
1121 |
1072 /** |
1122 /** |
1073 * Searches the data in the specified subtree. |
1123 * Searches the data in the specified subtree. |
1074 * |
1124 * |
1075 * \note When \p subtree_root is not part of the \p tree, the behavior is |
1125 * When @p max_depth is zero, the depth is not limited. |
|
1126 * The @p subtree_root itself is on depth 1 and its children have depth 2. |
|
1127 * |
|
1128 * @note When @p subtree_root is not part of the @p tree, the behavior is |
1076 * undefined. |
1129 * undefined. |
1077 * |
1130 * |
1078 * \remark For this function to work, the tree needs a specified \c search_data |
1131 * @remark For this function to work, the tree needs a specified @c search_data |
1079 * function, which might not be the case for wrapped trees |
1132 * function, which might not be the case for wrapped trees |
1080 * (see #cxTreeCreateWrapped()). |
1133 * (see #cxTreeCreateWrapped()). |
1081 * |
1134 * |
1082 * @param tree the tree |
1135 * @param tree the tree |
1083 * @param data the data to search for |
1136 * @param data the data to search for |
1084 * @param subtree_root the node where to start |
1137 * @param subtree_root the node where to start |
1085 * @return the first matching node, or \c NULL when the data cannot be found |
1138 * @param max_depth the maximum search depth |
1086 */ |
1139 * @return the first matching node, or @c NULL when the data cannot be found |
1087 __attribute__((__nonnull__)) |
1140 */ |
|
1141 cx_attr_nonnull |
|
1142 cx_attr_nodiscard |
1088 static inline void *cxTreeFindInSubtree( |
1143 static inline void *cxTreeFindInSubtree( |
1089 CxTree *tree, |
1144 CxTree *tree, |
1090 const void *data, |
1145 const void *data, |
1091 void *subtree_root |
1146 void *subtree_root, |
|
1147 size_t max_depth |
1092 ) { |
1148 ) { |
1093 return tree->cl->find(tree, subtree_root, data); |
1149 return tree->cl->find(tree, subtree_root, data, max_depth); |
1094 } |
1150 } |
1095 |
1151 |
1096 /** |
1152 /** |
1097 * Determines the size of the specified subtree. |
1153 * Determines the size of the specified subtree. |
1098 * |
1154 * |
1099 * @param tree the tree |
1155 * @param tree the tree |
1100 * @param subtree_root the root node of the subtree |
1156 * @param subtree_root the root node of the subtree |
1101 * @return the number of nodes in the specified subtree |
1157 * @return the number of nodes in the specified subtree |
1102 */ |
1158 */ |
1103 __attribute__((__nonnull__)) |
1159 cx_attr_nonnull |
|
1160 cx_attr_nodiscard |
1104 size_t cxTreeSubtreeSize(CxTree *tree, void *subtree_root); |
1161 size_t cxTreeSubtreeSize(CxTree *tree, void *subtree_root); |
1105 |
1162 |
1106 /** |
1163 /** |
1107 * Determines the depth of the specified subtree. |
1164 * Determines the depth of the specified subtree. |
1108 * |
1165 * |
1109 * @param tree the tree |
1166 * @param tree the tree |
1110 * @param subtree_root the root node of the subtree |
1167 * @param subtree_root the root node of the subtree |
1111 * @return the tree depth including the \p subtree_root |
1168 * @return the tree depth including the @p subtree_root |
1112 */ |
1169 */ |
1113 __attribute__((__nonnull__)) |
1170 cx_attr_nonnull |
|
1171 cx_attr_nodiscard |
1114 size_t cxTreeSubtreeDepth(CxTree *tree, void *subtree_root); |
1172 size_t cxTreeSubtreeDepth(CxTree *tree, void *subtree_root); |
1115 |
1173 |
1116 /** |
1174 /** |
1117 * Determines the depth of the entire tree. |
1175 * Determines the depth of the entire tree. |
1118 * |
1176 * |
1119 * @param tree the tree |
1177 * @param tree the tree |
1120 * @return the tree depth, counting the root as one |
1178 * @return the tree depth, counting the root as one |
1121 */ |
1179 */ |
1122 __attribute__((__nonnull__)) |
1180 cx_attr_nonnull |
|
1181 cx_attr_nodiscard |
1123 size_t cxTreeDepth(CxTree *tree); |
1182 size_t cxTreeDepth(CxTree *tree); |
|
1183 |
|
1184 /** |
|
1185 * Creates a depth-first iterator for the specified tree starting in @p node. |
|
1186 * |
|
1187 * If the node is not part of the tree, the behavior is undefined. |
|
1188 * |
|
1189 * @param tree the tree to iterate |
|
1190 * @param node the node where to start |
|
1191 * @param visit_on_exit true, if the iterator shall visit a node again when |
|
1192 * leaving the subtree |
|
1193 * @return a tree iterator (depth-first) |
|
1194 * @see cxTreeVisit() |
|
1195 */ |
|
1196 cx_attr_nonnull |
|
1197 cx_attr_nodiscard |
|
1198 static inline CxTreeIterator cxTreeIterateSubtree( |
|
1199 CxTree *tree, |
|
1200 void *node, |
|
1201 bool visit_on_exit |
|
1202 ) { |
|
1203 return cx_tree_iterator( |
|
1204 node, visit_on_exit, |
|
1205 tree->loc_children, tree->loc_next |
|
1206 ); |
|
1207 } |
|
1208 |
|
1209 /** |
|
1210 * Creates a breadth-first iterator for the specified tree starting in @p node. |
|
1211 * |
|
1212 * If the node is not part of the tree, the behavior is undefined. |
|
1213 * |
|
1214 * @param tree the tree to iterate |
|
1215 * @param node the node where to start |
|
1216 * @return a tree visitor (a.k.a. breadth-first iterator) |
|
1217 * @see cxTreeIterate() |
|
1218 */ |
|
1219 cx_attr_nonnull |
|
1220 cx_attr_nodiscard |
|
1221 static inline CxTreeVisitor cxTreeVisitSubtree(CxTree *tree, void *node) { |
|
1222 return cx_tree_visitor( |
|
1223 node, tree->loc_children, tree->loc_next |
|
1224 ); |
|
1225 } |
1124 |
1226 |
1125 /** |
1227 /** |
1126 * Creates a depth-first iterator for the specified tree. |
1228 * Creates a depth-first iterator for the specified tree. |
1127 * |
1229 * |
1128 * @param tree the tree to iterate |
1230 * @param tree the tree to iterate |
1129 * @param visit_on_exit true, if the iterator shall visit a node again when |
1231 * @param visit_on_exit true, if the iterator shall visit a node again when |
1130 * leaving the sub-tree |
1232 * leaving the subtree |
1131 * @return a tree iterator (depth-first) |
1233 * @return a tree iterator (depth-first) |
1132 * @see cxTreeVisitor() |
1234 * @see cxTreeVisit() |
1133 */ |
1235 */ |
1134 __attribute__((__nonnull__, __warn_unused_result__)) |
1236 cx_attr_nonnull |
1135 static inline CxTreeIterator cxTreeIterator( |
1237 cx_attr_nodiscard |
|
1238 static inline CxTreeIterator cxTreeIterate( |
1136 CxTree *tree, |
1239 CxTree *tree, |
1137 bool visit_on_exit |
1240 bool visit_on_exit |
1138 ) { |
1241 ) { |
1139 return tree->cl->iterator(tree, visit_on_exit); |
1242 return cxTreeIterateSubtree(tree, tree->root, visit_on_exit); |
1140 } |
1243 } |
1141 |
1244 |
1142 /** |
1245 /** |
1143 * Creates a breadth-first iterator for the specified tree. |
1246 * Creates a breadth-first iterator for the specified tree. |
1144 * |
1247 * |
1145 * @param tree the tree to iterate |
1248 * @param tree the tree to iterate |
1146 * @return a tree visitor (a.k.a. breadth-first iterator) |
1249 * @return a tree visitor (a.k.a. breadth-first iterator) |
1147 * @see cxTreeIterator() |
1250 * @see cxTreeIterate() |
1148 */ |
1251 */ |
1149 __attribute__((__nonnull__, __warn_unused_result__)) |
1252 cx_attr_nonnull |
1150 static inline CxTreeVisitor cxTreeVisitor(CxTree *tree) { |
1253 cx_attr_nodiscard |
1151 return tree->cl->visitor(tree); |
1254 static inline CxTreeVisitor cxTreeVisit(CxTree *tree) { |
|
1255 return cxTreeVisitSubtree(tree, tree->root); |
1152 } |
1256 } |
1153 |
1257 |
1154 /** |
1258 /** |
|
1259 * Sets the (new) parent of the specified child. |
|
1260 * |
|
1261 * If the @p child is not already member of the tree, this function behaves |
|
1262 * as #cxTreeAddChildNode(). |
|
1263 * |
|
1264 * @param tree the tree |
|
1265 * @param parent the (new) parent of the child |
|
1266 * @param child the node to add |
|
1267 * @see cxTreeAddChildNode() |
|
1268 */ |
|
1269 cx_attr_nonnull |
|
1270 void cxTreeSetParent( |
|
1271 CxTree *tree, |
|
1272 void *parent, |
|
1273 void *child |
|
1274 ); |
|
1275 |
|
1276 /** |
1155 * Adds a new node to the tree. |
1277 * Adds a new node to the tree. |
1156 * |
1278 * |
1157 * \attention The node may be externally created, but MUST obey the same rules |
1279 * If the @p child is already member of the tree, the behavior is undefined. |
|
1280 * Use #cxTreeSetParent() if you want to move a subtree to another location. |
|
1281 * |
|
1282 * @attention The node may be externally created, but MUST obey the same rules |
1158 * as if it was created by the tree itself with #cxTreeAddChild() (e.g. use |
1283 * as if it was created by the tree itself with #cxTreeAddChild() (e.g. use |
1159 * the same allocator). |
1284 * the same allocator). |
1160 * |
1285 * |
1161 * @param tree the tree |
1286 * @param tree the tree |
1162 * @param parent the parent of the node to add |
1287 * @param parent the parent of the node to add |
1163 * @param child the node to add |
1288 * @param child the node to add |
1164 */ |
1289 * @see cxTreeSetParent() |
1165 __attribute__((__nonnull__)) |
1290 */ |
1166 static inline void cxTreeAddChildNode( |
1291 cx_attr_nonnull |
|
1292 void cxTreeAddChildNode( |
1167 CxTree *tree, |
1293 CxTree *tree, |
1168 void *parent, |
1294 void *parent, |
1169 void *child) { |
1295 void *child |
1170 cx_tree_link(parent, child, cx_tree_node_layout(tree)); |
1296 ); |
1171 tree->size++; |
|
1172 } |
|
1173 |
1297 |
1174 /** |
1298 /** |
1175 * Creates a new node and adds it to the tree. |
1299 * Creates a new node and adds it to the tree. |
1176 * |
1300 * |
1177 * With this function you can decide where exactly the new node shall be added. |
1301 * With this function you can decide where exactly the new node shall be added. |
1215 /** |
1341 /** |
1216 * Removes a node and re-links its children to its former parent. |
1342 * Removes a node and re-links its children to its former parent. |
1217 * |
1343 * |
1218 * If the node is not part of the tree, the behavior is undefined. |
1344 * If the node is not part of the tree, the behavior is undefined. |
1219 * |
1345 * |
1220 * \note The destructor function, if any, will \em not be invoked. That means |
1346 * @note The destructor function, if any, will @em not be invoked. That means |
1221 * you will need to free the removed node by yourself, eventually. |
1347 * you will need to free the removed node by yourself, eventually. |
1222 * |
1348 * |
1223 * @param tree the tree |
1349 * @param tree the tree |
1224 * @param node the node to remove (must not be the root node) |
1350 * @param node the node to remove (must not be the root node) |
1225 * @param relink_func optional callback to update the content of each re-linked |
1351 * @param relink_func optional callback to update the content of each re-linked |
1226 * node |
1352 * node |
1227 * @return zero on success, non-zero if \p node is the root node of the tree |
1353 * @return zero on success, non-zero if @p node is the root node of the tree |
1228 */ |
1354 */ |
1229 __attribute__((__nonnull__(1,2))) |
1355 cx_attr_nonnull_arg(1, 2) |
1230 int cxTreeRemove( |
1356 int cxTreeRemoveNode( |
1231 CxTree *tree, |
1357 CxTree *tree, |
1232 void *node, |
1358 void *node, |
1233 cx_tree_relink_func relink_func |
1359 cx_tree_relink_func relink_func |
1234 ); |
1360 ); |
1235 |
1361 |
1236 /** |
1362 /** |
1237 * Removes a node and it's subtree from the tree. |
1363 * Removes a node and it's subtree from the tree. |
1238 * |
1364 * |
1239 * If the node is not part of the tree, the behavior is undefined. |
1365 * If the node is not part of the tree, the behavior is undefined. |
1240 * |
1366 * |
1241 * \note The destructor function, if any, will \em not be invoked. That means |
1367 * @note The destructor function, if any, will @em not be invoked. That means |
1242 * you will need to free the removed subtree by yourself, eventually. |
1368 * you will need to free the removed subtree by yourself, eventually. |
1243 * |
1369 * |
1244 * @param tree the tree |
1370 * @param tree the tree |
1245 * @param node the node to remove |
1371 * @param node the node to remove |
1246 */ |
1372 */ |
1247 __attribute__((__nonnull__)) |
1373 cx_attr_nonnull |
1248 void cxTreeRemoveSubtree(CxTree *tree, void *node); |
1374 void cxTreeRemoveSubtree(CxTree *tree, void *node); |
|
1375 |
|
1376 /** |
|
1377 * Destroys a node and re-links its children to its former parent. |
|
1378 * |
|
1379 * If the node is not part of the tree, the behavior is undefined. |
|
1380 * |
|
1381 * It is guaranteed that the simple destructor is invoked before |
|
1382 * the advanced destructor. |
|
1383 * |
|
1384 * @attention This function will not free the memory of the node with the |
|
1385 * tree's allocator, because that is usually done by the advanced destructor |
|
1386 * and would therefore result in a double-free. |
|
1387 * |
|
1388 * @param tree the tree |
|
1389 * @param node the node to destroy (must not be the root node) |
|
1390 * @param relink_func optional callback to update the content of each re-linked |
|
1391 * node |
|
1392 * @return zero on success, non-zero if @p node is the root node of the tree |
|
1393 */ |
|
1394 cx_attr_nonnull_arg(1, 2) |
|
1395 int cxTreeDestroyNode( |
|
1396 CxTree *tree, |
|
1397 void *node, |
|
1398 cx_tree_relink_func relink_func |
|
1399 ); |
1249 |
1400 |
1250 #ifdef __cplusplus |
1401 #ifdef __cplusplus |
1251 } // extern "C" |
1402 } // extern "C" |
1252 #endif |
1403 #endif |
1253 |
1404 |