ucx/cx/tree.h

changeset 16
04c9f8d8f03b
parent 11
0aa8cbd7912e
child 21
5ea41679e15d
equal deleted inserted replaced
15:862ab606ee06 16:04c9f8d8f03b
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE. 26 * POSSIBILITY OF SUCH DAMAGE.
27 */ 27 */
28 /** 28 /**
29 * \file tree.h 29 * @file tree.h
30 * \brief Interface for tree implementations. 30 * @brief Interface for tree implementations.
31 * \author Mike Becker 31 * @author Mike Becker
32 * \author Olaf Wintermann 32 * @author Olaf Wintermann
33 * \copyright 2-Clause BSD License 33 * @copyright 2-Clause BSD License
34 */ 34 */
35 35
36 #ifndef UCX_TREE_H 36 #ifndef UCX_TREE_H
37 #define UCX_TREE_H 37 #define UCX_TREE_H
38 38
136 /** 136 /**
137 * The depth of the node. 137 * The depth of the node.
138 */ 138 */
139 size_t depth; 139 size_t depth;
140 /** 140 /**
141 * The next element in the queue or \c NULL. 141 * The next element in the queue or @c NULL.
142 */ 142 */
143 struct cx_tree_visitor_queue_s *next; 143 struct cx_tree_visitor_queue_s *next;
144 }; 144 };
145 145
146 /** 146 /**
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
261 * @param loc_prev optional 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 cx_attr_nonnull 265 cx_attr_nonnull
266 cx_attr_export
266 void cx_tree_link( 267 void cx_tree_link(
267 void *parent, 268 void *parent,
268 void *node, 269 void *node,
269 ptrdiff_t loc_parent, 270 ptrdiff_t loc_parent,
270 ptrdiff_t loc_children, 271 ptrdiff_t loc_children,
286 * @param loc_prev optional offset in the node struct for the prev pointer 287 * @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 288 * @param loc_next offset in the node struct for the next pointer
288 * @see cx_tree_link() 289 * @see cx_tree_link()
289 */ 290 */
290 cx_attr_nonnull 291 cx_attr_nonnull
292 cx_attr_export
291 void cx_tree_unlink( 293 void cx_tree_unlink(
292 void *node, 294 void *node,
293 ptrdiff_t loc_parent, 295 ptrdiff_t loc_parent,
294 ptrdiff_t loc_children, 296 ptrdiff_t loc_children,
295 ptrdiff_t loc_last_child, 297 ptrdiff_t loc_last_child,
303 #define CX_TREE_SEARCH_INFINITE_DEPTH 0 305 #define CX_TREE_SEARCH_INFINITE_DEPTH 0
304 306
305 /** 307 /**
306 * Function pointer for a search function. 308 * Function pointer for a search function.
307 * 309 *
308 * A function of this kind shall check if the specified \p node 310 * A function of this kind shall check if the specified @p node
309 * contains the given \p data or if one of the children might contain 311 * contains the given @p data or if one of the children might contain
310 * the data. 312 * the data.
311 * 313 *
312 * The function should use the returned integer to indicate how close the 314 * The function should use the returned integer to indicate how close the
313 * match is, where a negative number means that it does not match at all. 315 * 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 316 * Zero means exact match and a positive number is an implementation defined
333 335
334 336
335 /** 337 /**
336 * Function pointer for a search function. 338 * Function pointer for a search function.
337 * 339 *
338 * A function of this kind shall check if the specified \p node 340 * A function of this kind shall check if the specified @p node
339 * contains the same \p data as \p new_node or if one of the children might 341 * contains the same @p data as @p new_node or if one of the children might
340 * contain the data. 342 * contain the data.
341 * 343 *
342 * The function should use the returned integer to indicate how close the 344 * The function should use the returned integer to indicate how close the
343 * match is, where a negative number means that it does not match at all. 345 * 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 346 * Zero means exact match and a positive number is an implementation defined
352 * that the search does not need to be continued in that branch. 354 * that the search does not need to be continued in that branch.
353 * 355 *
354 * @param node the node that is currently investigated 356 * @param node the node that is currently investigated
355 * @param new_node a new node with the information which is searched 357 * @param new_node a new node with the information which is searched
356 * 358 *
357 * @return 0 if \p node contains the same data as \p new_node, 359 * @return 0 if @p node contains the same data as @p new_node,
358 * positive if one of the children might contain the data, 360 * positive if one of the children might contain the data,
359 * negative if neither the node, nor the children contains the data 361 * negative if neither the node, nor the children contains the data
360 */ 362 */
361 cx_attr_nonnull 363 cx_attr_nonnull
362 typedef int (*cx_tree_search_func)(const void *node, const void *new_node); 364 typedef int (*cx_tree_search_func)(const void *node, const void *new_node);
368 * closest result which might be a good starting point for adding a new node 370 * closest result which might be a good starting point for adding a new node
369 * to the tree (see also #cx_tree_add()). 371 * to the tree (see also #cx_tree_add()).
370 * 372 *
371 * Depending on the tree structure it is not necessarily guaranteed that the 373 * Depending on the tree structure it is not necessarily guaranteed that the
372 * "closest" match is uniquely defined. This function will search for a node 374 * "closest" match is uniquely defined. This function will search for a node
373 * with the best match according to the \p sfunc (meaning: the return value of 375 * with the best match according to the @p sfunc (meaning: the return value of
374 * \p sfunc which is closest to zero). If that is also ambiguous, an arbitrary 376 * @p sfunc which is closest to zero). If that is also ambiguous, an arbitrary
375 * node matching the criteria is returned. 377 * node matching the criteria is returned.
376 * 378 *
377 * @param root the root node 379 * @param root the root node
378 * @param depth the maximum depth (zero=indefinite, one=just root) 380 * @param depth the maximum depth (zero=indefinite, one=just root)
379 * @param data the data to search for 381 * @param data the data to search for
385 * could contain the node (but doesn't right now), negative if the tree does not 387 * could contain the node (but doesn't right now), negative if the tree does not
386 * contain any node that might be related to the searched data 388 * contain any node that might be related to the searched data
387 */ 389 */
388 cx_attr_nonnull 390 cx_attr_nonnull
389 cx_attr_access_w(5) 391 cx_attr_access_w(5)
392 cx_attr_export
390 int cx_tree_search_data( 393 int cx_tree_search_data(
391 const void *root, 394 const void *root,
392 size_t depth, 395 size_t depth,
393 const void *data, 396 const void *data,
394 cx_tree_search_data_func sfunc, 397 cx_tree_search_data_func sfunc,
404 * return a closest result which might be a good starting point for adding the 407 * return a closest result which might be a good starting point for adding the
405 * new node to the tree (see also #cx_tree_add()). 408 * new node to the tree (see also #cx_tree_add()).
406 * 409 *
407 * Depending on the tree structure it is not necessarily guaranteed that the 410 * Depending on the tree structure it is not necessarily guaranteed that the
408 * "closest" match is uniquely defined. This function will search for a node 411 * "closest" match is uniquely defined. This function will search for a node
409 * with the best match according to the \p sfunc (meaning: the return value of 412 * with the best match according to the @p sfunc (meaning: the return value of
410 * \p sfunc which is closest to zero). If that is also ambiguous, an arbitrary 413 * @p sfunc which is closest to zero). If that is also ambiguous, an arbitrary
411 * node matching the criteria is returned. 414 * node matching the criteria is returned.
412 * 415 *
413 * @param root the root node 416 * @param root the root node
414 * @param depth the maximum depth (zero=indefinite, one=just root) 417 * @param depth the maximum depth (zero=indefinite, one=just root)
415 * @param node the node to search for 418 * @param node the node to search for
421 * could contain the node (but doesn't right now), negative if the tree does not 424 * could contain the node (but doesn't right now), negative if the tree does not
422 * contain any node that might be related to the searched data 425 * contain any node that might be related to the searched data
423 */ 426 */
424 cx_attr_nonnull 427 cx_attr_nonnull
425 cx_attr_access_w(5) 428 cx_attr_access_w(5)
429 cx_attr_export
426 int cx_tree_search( 430 int cx_tree_search(
427 const void *root, 431 const void *root,
428 size_t depth, 432 size_t depth,
429 const void *node, 433 const void *node,
430 cx_tree_search_func sfunc, 434 cx_tree_search_func sfunc,
452 * @param loc_next offset in the node struct for the next pointer 456 * @param loc_next offset in the node struct for the next pointer
453 * @return the new tree iterator 457 * @return the new tree iterator
454 * @see cxTreeIteratorDispose() 458 * @see cxTreeIteratorDispose()
455 */ 459 */
456 cx_attr_nodiscard 460 cx_attr_nodiscard
461 cx_attr_export
457 CxTreeIterator cx_tree_iterator( 462 CxTreeIterator cx_tree_iterator(
458 void *root, 463 void *root,
459 bool visit_on_exit, 464 bool visit_on_exit,
460 ptrdiff_t loc_children, 465 ptrdiff_t loc_children,
461 ptrdiff_t loc_next 466 ptrdiff_t loc_next
478 * @param loc_next offset in the node struct for the next pointer 483 * @param loc_next offset in the node struct for the next pointer
479 * @return the new tree visitor 484 * @return the new tree visitor
480 * @see cxTreeVisitorDispose() 485 * @see cxTreeVisitorDispose()
481 */ 486 */
482 cx_attr_nodiscard 487 cx_attr_nodiscard
488 cx_attr_export
483 CxTreeVisitor cx_tree_visitor( 489 CxTreeVisitor cx_tree_visitor(
484 void *root, 490 void *root,
485 ptrdiff_t loc_children, 491 ptrdiff_t loc_children,
486 ptrdiff_t loc_next 492 ptrdiff_t loc_next
487 ); 493 );
489 /** 495 /**
490 * Describes a function that creates a tree node from the specified data. 496 * Describes a function that creates a tree node from the specified data.
491 * The first argument points to the data the node shall contain and 497 * The first argument points to the data the node shall contain and
492 * the second argument may be used for additional data (e.g. an allocator). 498 * the second argument may be used for additional data (e.g. an allocator).
493 * Functions of this type shall either return a new pointer to a newly 499 * Functions of this type shall either return a new pointer to a newly
494 * created node or \c NULL when allocation fails. 500 * created node or @c NULL when allocation fails.
495 * 501 *
496 * \note the function may leave the node pointers in the struct uninitialized. 502 * @note the function may leave the node pointers in the struct uninitialized.
497 * The caller is responsible to set them according to the intended use case. 503 * The caller is responsible to set them according to the intended use case.
498 */ 504 */
499 cx_attr_nonnull_arg(1) 505 cx_attr_nonnull_arg(1)
500 typedef void *(*cx_tree_node_create_func)(const void *, void *); 506 typedef void *(*cx_tree_node_create_func)(const void *, void *);
501 507
503 * The local search depth for a new subtree when adding multiple elements. 509 * The local search depth for a new subtree when adding multiple elements.
504 * The default value is 3. 510 * The default value is 3.
505 * This variable is used by #cx_tree_add_array() and #cx_tree_add_iter() to 511 * This variable is used by #cx_tree_add_array() and #cx_tree_add_iter() to
506 * implement optimized insertion of multiple elements into a tree. 512 * implement optimized insertion of multiple elements into a tree.
507 */ 513 */
514 cx_attr_export
508 extern unsigned int cx_tree_add_look_around_depth; 515 extern unsigned int cx_tree_add_look_around_depth;
509 516
510 /** 517 /**
511 * Adds multiple elements efficiently to a tree. 518 * Adds multiple elements efficiently to a tree.
512 * 519 *
513 * Once an element cannot be added to the tree, this function returns, leaving 520 * Once an element cannot be added to the tree, this function returns, leaving
514 * the iterator in a valid state pointing to the element that could not be 521 * the iterator in a valid state pointing to the element that could not be
515 * added. 522 * added.
516 * Also, the pointer of the created node will be stored to \p failed. 523 * Also, the pointer of the created node will be stored to @p failed.
517 * The integer returned by this function denotes the number of elements obtained 524 * The integer returned by this function denotes the number of elements obtained
518 * from the \p iter that have been successfully processed. 525 * from the @p iter that have been successfully processed.
519 * When all elements could be processed, a \c NULL pointer will be written to 526 * When all elements could be processed, a @c NULL pointer will be written to
520 * \p failed. 527 * @p failed.
521 * 528 *
522 * The advantage of this function compared to multiple invocations of 529 * The advantage of this function compared to multiple invocations of
523 * #cx_tree_add() is that the search for the insert locations is not always 530 * #cx_tree_add() is that the search for the insert locations is not always
524 * started from the root node. 531 * started from the root node.
525 * Instead, the function checks #cx_tree_add_look_around_depth many parent nodes 532 * Instead, the function checks #cx_tree_add_look_around_depth many parent nodes
545 * @return the number of nodes created and added 552 * @return the number of nodes created and added
546 * @see cx_tree_add() 553 * @see cx_tree_add()
547 */ 554 */
548 cx_attr_nonnull_arg(1, 3, 4, 6, 7) 555 cx_attr_nonnull_arg(1, 3, 4, 6, 7)
549 cx_attr_access_w(6) 556 cx_attr_access_w(6)
557 cx_attr_export
550 size_t cx_tree_add_iter( 558 size_t cx_tree_add_iter(
551 struct cx_iterator_base_s *iter, 559 struct cx_iterator_base_s *iter,
552 size_t num, 560 size_t num,
553 cx_tree_search_func sfunc, 561 cx_tree_search_func sfunc,
554 cx_tree_node_create_func cfunc, 562 cx_tree_node_create_func cfunc,
564 572
565 /** 573 /**
566 * Adds multiple elements efficiently to a tree. 574 * Adds multiple elements efficiently to a tree.
567 * 575 *
568 * Once an element cannot be added to the tree, this function returns, storing 576 * Once an element cannot be added to the tree, this function returns, storing
569 * the pointer of the created node to \p failed. 577 * the pointer of the created node to @p failed.
570 * The integer returned by this function denotes the number of elements from 578 * The integer returned by this function denotes the number of elements from
571 * the \p src array that have been successfully processed. 579 * the @p src array that have been successfully processed.
572 * When all elements could be processed, a \c NULL pointer will be written to 580 * When all elements could be processed, a @c NULL pointer will be written to
573 * \p failed. 581 * @p failed.
574 * 582 *
575 * The advantage of this function compared to multiple invocations of 583 * The advantage of this function compared to multiple invocations of
576 * #cx_tree_add() is that the search for the insert locations is not always 584 * #cx_tree_add() is that the search for the insert locations is not always
577 * started from the root node. 585 * started from the root node.
578 * Instead, the function checks #cx_tree_add_look_around_depth many parent nodes 586 * Instead, the function checks #cx_tree_add_look_around_depth many parent nodes
581 * again. 589 * again.
582 * 590 *
583 * Refer to the documentation of #cx_tree_add() for more details. 591 * Refer to the documentation of #cx_tree_add() for more details.
584 * 592 *
585 * @param src a pointer to the source data array 593 * @param src a pointer to the source data array
586 * @param num the number of elements in the \p src array 594 * @param num the number of elements in the @p src array
587 * @param elem_size the size of each element in the \p src array 595 * @param elem_size the size of each element in the @p src array
588 * @param sfunc a search function 596 * @param sfunc a search function
589 * @param cfunc a node creation function 597 * @param cfunc a node creation function
590 * @param cdata optional additional data 598 * @param cdata optional additional data
591 * @param failed location where the pointer to a failed node shall be stored 599 * @param failed location where the pointer to a failed node shall be stored
592 * @param root the root node of the tree 600 * @param root the root node of the tree
599 * @return the number of array elements successfully processed 607 * @return the number of array elements successfully processed
600 * @see cx_tree_add() 608 * @see cx_tree_add()
601 */ 609 */
602 cx_attr_nonnull_arg(1, 4, 5, 7, 8) 610 cx_attr_nonnull_arg(1, 4, 5, 7, 8)
603 cx_attr_access_w(7) 611 cx_attr_access_w(7)
612 cx_attr_export
604 size_t cx_tree_add_array( 613 size_t cx_tree_add_array(
605 const void *src, 614 const void *src,
606 size_t num, 615 size_t num,
607 size_t elem_size, 616 size_t elem_size,
608 cx_tree_search_func sfunc, 617 cx_tree_search_func sfunc,
619 628
620 /** 629 /**
621 * Adds data to a tree. 630 * Adds data to a tree.
622 * 631 *
623 * An adequate location where to add the new tree node is searched with the 632 * An adequate location where to add the new tree node is searched with the
624 * specified \p sfunc. 633 * specified @p sfunc.
625 * 634 *
626 * When a location is found, the \p cfunc will be invoked with \p cdata. 635 * When a location is found, the @p cfunc will be invoked with @p cdata.
627 * 636 *
628 * The node returned by \p cfunc will be linked into the tree. 637 * The node returned by @p cfunc will be linked into the tree.
629 * When \p sfunc returned a positive integer, the new node will be linked as a 638 * When @p sfunc returned a positive integer, the new node will be linked as a
630 * child. The other children (now siblings of the new node) are then checked 639 * child. The other children (now siblings of the new node) are then checked
631 * with \p sfunc, whether they could be children of the new node and re-linked 640 * with @p sfunc, whether they could be children of the new node and re-linked
632 * accordingly. 641 * accordingly.
633 * 642 *
634 * When \p sfunc returned zero and the found node has a parent, the new 643 * When @p sfunc returned zero and the found node has a parent, the new
635 * node will be added as sibling - otherwise, the new node will be added 644 * node will be added as sibling - otherwise, the new node will be added
636 * as a child. 645 * as a child.
637 * 646 *
638 * When \p sfunc returned a negative value, the new node will not be added to 647 * When @p sfunc returned a negative value, the new node will not be added to
639 * the tree and this function returns a non-zero value. 648 * the tree and this function returns a non-zero value.
640 * The caller should check if \p cnode contains a node pointer and deal with the 649 * The caller should check if @p cnode contains a node pointer and deal with the
641 * node that could not be added. 650 * node that could not be added.
642 * 651 *
643 * This function also returns a non-zero value when \p cfunc tries to allocate 652 * This function also returns a non-zero value when @p cfunc tries to allocate
644 * a new node but fails to do so. In that case, the pointer stored to \p cnode 653 * a new node but fails to do so. In that case, the pointer stored to @p cnode
645 * will be \c NULL. 654 * will be @c NULL.
646 * 655 *
647 * Multiple elements can be added more efficiently with 656 * Multiple elements can be added more efficiently with
648 * #cx_tree_add_array() or #cx_tree_add_iter(). 657 * #cx_tree_add_array() or #cx_tree_add_iter().
649 * 658 *
650 * @param src a pointer to the data 659 * @param src a pointer to the data
662 * @return zero when a new node was created and added to the tree, 671 * @return zero when a new node was created and added to the tree,
663 * non-zero otherwise 672 * non-zero otherwise
664 */ 673 */
665 cx_attr_nonnull_arg(1, 2, 3, 5, 6) 674 cx_attr_nonnull_arg(1, 2, 3, 5, 6)
666 cx_attr_access_w(5) 675 cx_attr_access_w(5)
676 cx_attr_export
667 int cx_tree_add( 677 int cx_tree_add(
668 const void *src, 678 const void *src,
669 cx_tree_search_func sfunc, 679 cx_tree_search_func sfunc,
670 cx_tree_node_create_func cfunc, 680 cx_tree_node_create_func cfunc,
671 void *cdata, 681 void *cdata,
725 const CxAllocator *allocator; 735 const CxAllocator *allocator;
726 736
727 /** 737 /**
728 * A pointer to the root node. 738 * A pointer to the root node.
729 * 739 *
730 * Will be \c NULL when \c size is 0. 740 * Will be @c NULL when @c size is 0.
731 */ 741 */
732 void *root; 742 void *root;
733 743
734 /** 744 /**
735 * A function to create new nodes. 745 * A function to create new nodes.
799 }; 809 };
800 810
801 /** 811 /**
802 * Macro to roll out the #cx_tree_node_base_s structure with a custom 812 * Macro to roll out the #cx_tree_node_base_s structure with a custom
803 * node type. 813 * node type.
814 *
815 * Must be used as first member in your custom tree struct.
816 *
817 * @param type the data type for the nodes
804 */ 818 */
805 #define CX_TREE_NODE_BASE(type) \ 819 #define CX_TREE_NODE_BASE(type) \
806 type *parent; \ 820 type *parent; \
807 type *children;\ 821 type *children;\
808 type *last_child;\ 822 type *last_child;\
809 type *prev;\ 823 type *prev;\
810 type *next 824 type *next
811 825
812 /** 826 /**
813 * Macro for specifying the layout of a base node tree. 827 * Macro for specifying the layout of a base node tree.
828 *
829 * When your tree uses #CX_TREE_NODE_BASE, you can use this
830 * macro in all tree functions that expect the layout parameters
831 * @c loc_parent, @c loc_children, @c loc_last_child, @c loc_prev,
832 * and @c loc_next.
814 */ 833 */
815 #define cx_tree_node_base_layout \ 834 #define cx_tree_node_base_layout \
816 offsetof(struct cx_tree_node_base_s, parent),\ 835 offsetof(struct cx_tree_node_base_s, parent),\
817 offsetof(struct cx_tree_node_base_s, children),\ 836 offsetof(struct cx_tree_node_base_s, children),\
818 offsetof(struct cx_tree_node_base_s, last_child),\ 837 offsetof(struct cx_tree_node_base_s, last_child),\
819 offsetof(struct cx_tree_node_base_s, prev), \ 838 offsetof(struct cx_tree_node_base_s, prev), \
820 offsetof(struct cx_tree_node_base_s, next) 839 offsetof(struct cx_tree_node_base_s, next)
821 840
822 /** 841 /**
823 * Macro for obtaining the node pointer layout for a specific tree.
824 */
825 #define cx_tree_node_layout(tree) \
826 (tree)->loc_parent,\
827 (tree)->loc_children,\
828 (tree)->loc_last_child,\
829 (tree)->loc_prev, \
830 (tree)->loc_next
831
832 /**
833 * The class definition for arbitrary trees. 842 * The class definition for arbitrary trees.
834 */ 843 */
835 struct cx_tree_class_s { 844 struct cx_tree_class_s {
836 /** 845 /**
837 * Member function for inserting a single element. 846 * Member function for inserting a single element.
838 * 847 *
839 * Implementations SHALL NOT simply invoke \p insert_many as this comes 848 * Implementations SHALL NOT simply invoke @p insert_many as this comes
840 * with too much overhead. 849 * with too much overhead.
841 */ 850 */
842 cx_attr_nonnull
843 int (*insert_element)( 851 int (*insert_element)(
844 struct cx_tree_s *tree, 852 struct cx_tree_s *tree,
845 const void *data 853 const void *data
846 ); 854 );
847 855
849 * Member function for inserting multiple elements. 857 * Member function for inserting multiple elements.
850 * 858 *
851 * Implementations SHALL avoid to perform a full search in the tree for 859 * Implementations SHALL avoid to perform a full search in the tree for
852 * every element even though the source data MAY be unsorted. 860 * every element even though the source data MAY be unsorted.
853 */ 861 */
854 cx_attr_nonnull
855 size_t (*insert_many)( 862 size_t (*insert_many)(
856 struct cx_tree_s *tree, 863 struct cx_tree_s *tree,
857 struct cx_iterator_base_s *iter, 864 struct cx_iterator_base_s *iter,
858 size_t n 865 size_t n
859 ); 866 );
860 867
861 /** 868 /**
862 * Member function for finding a node. 869 * Member function for finding a node.
863 */ 870 */
864 cx_attr_nonnull
865 void *(*find)( 871 void *(*find)(
866 struct cx_tree_s *tree, 872 struct cx_tree_s *tree,
867 const void *subtree, 873 const void *subtree,
868 const void *data, 874 const void *data,
869 size_t depth 875 size_t depth
884 * 890 *
885 * When this function is invoked on the root node of the tree, it destroys the 891 * When this function is invoked on the root node of the tree, it destroys the
886 * tree contents, but - in contrast to #cxTreeFree() - not the tree 892 * tree contents, but - in contrast to #cxTreeFree() - not the tree
887 * structure, leaving an empty tree behind. 893 * structure, leaving an empty tree behind.
888 * 894 *
889 * \note The destructor function, if any, will \em not be invoked. That means 895 * @note The destructor function, if any, will @em not be invoked. That means
890 * you will need to free the removed subtree by yourself, eventually. 896 * you will need to free the removed subtree by yourself, eventually.
891 * 897 *
892 * \attention This function will not free the memory of the nodes with the 898 * @attention This function will not free the memory of the nodes with the
893 * tree's allocator, because that is usually done by the advanced destructor 899 * tree's allocator, because that is usually done by the advanced destructor
894 * and would therefore result in a double-free. 900 * and would therefore result in a double-free.
895 * 901 *
896 * @param tree the tree 902 * @param tree the tree
897 * @param node the node to remove 903 * @param node the node to remove
898 * @see cxTreeFree() 904 * @see cxTreeFree()
899 */ 905 */
900 cx_attr_nonnull 906 cx_attr_nonnull
907 cx_attr_export
901 void cxTreeDestroySubtree(CxTree *tree, void *node); 908 void cxTreeDestroySubtree(CxTree *tree, void *node);
902 909
903 910
904 /** 911 /**
905 * Destroys the tree contents. 912 * Destroys the tree contents.
908 * the advanced destructor, starting with the leaf nodes of the subtree. 915 * the advanced destructor, starting with the leaf nodes of the subtree.
909 * 916 *
910 * This is a convenience macro for invoking #cxTreeDestroySubtree() on the 917 * This is a convenience macro for invoking #cxTreeDestroySubtree() on the
911 * root node of the tree. 918 * root node of the tree.
912 * 919 *
913 * \attention Be careful when calling this function when no destructor function 920 * @attention Be careful when calling this function when no destructor function
914 * is registered that actually frees the memory of nodes. In that case you will 921 * is registered that actually frees the memory of nodes. In that case you will
915 * need a reference to the (former) root node of the tree somewhere or 922 * need a reference to the (former) root node of the tree somewhere or
916 * otherwise you will be leaking memory. 923 * otherwise you will be leaking memory.
917 * 924 *
918 * @param tree the tree 925 * @param tree the tree
926 * The destructor functions are invoked for each node, starting with the leaf 933 * The destructor functions are invoked for each node, starting with the leaf
927 * nodes. 934 * nodes.
928 * It is guaranteed that for each node the simple destructor is invoked before 935 * It is guaranteed that for each node the simple destructor is invoked before
929 * the advanced destructor. 936 * the advanced destructor.
930 * 937 *
931 * \attention This function will only invoke the destructor functions 938 * @attention This function will only invoke the destructor functions
932 * on the nodes. 939 * on the nodes.
933 * It will NOT additionally free the nodes with the tree's allocator, because 940 * It will NOT additionally free the nodes with the tree's allocator, because
934 * that would cause a double-free in most scenarios where the advanced 941 * that would cause a double-free in most scenarios where the advanced
935 * destructor is already freeing the memory. 942 * destructor is already freeing the memory.
936 * 943 *
937 * @param tree the tree to free 944 * @param tree the tree to free
938 */ 945 */
939 static inline void cxTreeFree(CxTree *tree) { 946 cx_attr_export
940 if (tree == NULL) return; 947 void cxTreeFree(CxTree *tree);
941 if (tree->root != NULL) {
942 cxTreeClear(tree);
943 }
944 cxFree(tree->allocator, tree);
945 }
946 948
947 /** 949 /**
948 * Creates a new tree structure based on the specified layout. 950 * Creates a new tree structure based on the specified layout.
949 * 951 *
950 * The specified \p allocator will be used for creating the tree struct 952 * The specified @p allocator will be used for creating the tree struct
951 * and SHALL be used by \p create_func to allocate memory for the nodes. 953 * and SHALL be used by @p create_func to allocate memory for the nodes.
952 * 954 *
953 * \note This function will also register an advanced destructor which 955 * @note This function will also register an advanced destructor which
954 * will free the nodes with the allocator's free() method. 956 * will free the nodes with the allocator's free() method.
955 * 957 *
956 * @param allocator the allocator that shall be used 958 * @param allocator the allocator that shall be used
957 * (if \c NULL, a default stdlib allocator will be used) 959 * (if @c NULL, a default stdlib allocator will be used)
958 * @param create_func a function that creates new nodes 960 * @param create_func a function that creates new nodes
959 * @param search_func a function that compares two nodes 961 * @param search_func a function that compares two nodes
960 * @param search_data_func a function that compares a node with data 962 * @param search_data_func a function that compares a node with data
961 * @param loc_parent offset in the node struct for the parent pointer 963 * @param loc_parent offset in the node struct for the parent pointer
962 * @param loc_children offset in the node struct for the children linked list 964 * @param loc_children offset in the node struct for the children linked list
970 */ 972 */
971 cx_attr_nonnull_arg(2, 3, 4) 973 cx_attr_nonnull_arg(2, 3, 4)
972 cx_attr_nodiscard 974 cx_attr_nodiscard
973 cx_attr_malloc 975 cx_attr_malloc
974 cx_attr_dealloc(cxTreeFree, 1) 976 cx_attr_dealloc(cxTreeFree, 1)
977 cx_attr_export
975 CxTree *cxTreeCreate( 978 CxTree *cxTreeCreate(
976 const CxAllocator *allocator, 979 const CxAllocator *allocator,
977 cx_tree_node_create_func create_func, 980 cx_tree_node_create_func create_func,
978 cx_tree_search_func search_func, 981 cx_tree_search_func search_func,
979 cx_tree_search_data_func search_data_func, 982 cx_tree_search_data_func search_data_func,
985 ); 988 );
986 989
987 /** 990 /**
988 * Creates a new tree structure based on a default layout. 991 * Creates a new tree structure based on a default layout.
989 * 992 *
990 * Nodes created by \p create_func MUST contain #cx_tree_node_base_s as first 993 * Nodes created by @p create_func MUST contain #cx_tree_node_base_s as first
991 * member (or at least respect the default offsets specified in the tree 994 * member (or at least respect the default offsets specified in the tree
992 * struct) and they MUST be allocated with the specified allocator. 995 * struct) and they MUST be allocated with the specified allocator.
993 * 996 *
994 * \note This function will also register an advanced destructor which 997 * @note This function will also register an advanced destructor which
995 * will free the nodes with the allocator's free() method. 998 * will free the nodes with the allocator's free() method.
996 * 999 *
997 * @param allocator the allocator that shall be used 1000 * @param allocator (@c CxAllocator*) the allocator that shall be used
998 * @param create_func a function that creates new nodes 1001 * @param create_func (@c cx_tree_node_create_func) a function that creates new nodes
999 * @param search_func a function that compares two nodes 1002 * @param search_func (@c cx_tree_search_func) a function that compares two nodes
1000 * @param search_data_func a function that compares a node with data 1003 * @param search_data_func (@c cx_tree_search_data_func) a function that compares a node with data
1001 * @return the new tree 1004 * @return (@c CxTree*) the new tree
1002 * @see cxTreeCreate() 1005 * @see cxTreeCreate()
1003 */ 1006 */
1004 #define cxTreeCreateSimple(\ 1007 #define cxTreeCreateSimple(\
1005 allocator, create_func, search_func, search_data_func \ 1008 allocator, create_func, search_func, search_data_func \
1006 ) cxTreeCreate(allocator, create_func, search_func, search_data_func, \ 1009 ) cxTreeCreate(allocator, create_func, search_func, search_data_func, \
1007 cx_tree_node_base_layout) 1010 cx_tree_node_base_layout)
1008 1011
1009 /** 1012 /**
1010 * Creates a new tree structure based on an existing tree. 1013 * Creates a new tree structure based on an existing tree.
1011 * 1014 *
1012 * The specified \p allocator will be used for creating the tree struct. 1015 * The specified @p allocator will be used for creating the tree struct.
1013 * 1016 *
1014 * \attention This function will create an incompletely defined tree structure 1017 * @attention This function will create an incompletely defined tree structure
1015 * where neither the create function, the search function, nor a destructor 1018 * where neither the create function, the search function, nor a destructor
1016 * will be set. If you wish to use any of this functionality for the wrapped 1019 * will be set. If you wish to use any of this functionality for the wrapped
1017 * tree, you need to specify those functions afterwards. 1020 * tree, you need to specify those functions afterwards.
1018 * 1021 *
1019 * @param allocator the allocator that was used for nodes of the wrapped tree 1022 * @param allocator the allocator that was used for nodes of the wrapped tree
1020 * (if \c NULL, a default stdlib allocator is assumed) 1023 * (if @c NULL, a default stdlib allocator is assumed)
1021 * @param root the root node of the tree that shall be wrapped 1024 * @param root the root node of the tree that shall be wrapped
1022 * @param loc_parent offset in the node struct for the parent pointer 1025 * @param loc_parent offset in the node struct for the parent pointer
1023 * @param loc_children offset in the node struct for the children linked list 1026 * @param loc_children offset in the node struct for the children linked list
1024 * @param loc_last_child optional offset in the node struct for the pointer to 1027 * @param loc_last_child optional offset in the node struct for the pointer to
1025 * the last child in the linked list (negative if there is no such pointer) 1028 * the last child in the linked list (negative if there is no such pointer)
1030 */ 1033 */
1031 cx_attr_nonnull_arg(2) 1034 cx_attr_nonnull_arg(2)
1032 cx_attr_nodiscard 1035 cx_attr_nodiscard
1033 cx_attr_malloc 1036 cx_attr_malloc
1034 cx_attr_dealloc(cxTreeFree, 1) 1037 cx_attr_dealloc(cxTreeFree, 1)
1038 cx_attr_export
1035 CxTree *cxTreeCreateWrapped( 1039 CxTree *cxTreeCreateWrapped(
1036 const CxAllocator *allocator, 1040 const CxAllocator *allocator,
1037 void *root, 1041 void *root,
1038 ptrdiff_t loc_parent, 1042 ptrdiff_t loc_parent,
1039 ptrdiff_t loc_children, 1043 ptrdiff_t loc_children,
1043 ); 1047 );
1044 1048
1045 /** 1049 /**
1046 * Inserts data into the tree. 1050 * Inserts data into the tree.
1047 * 1051 *
1048 * \remark For this function to work, the tree needs specified search and 1052 * @remark For this function to work, the tree needs specified search and
1049 * create functions, which might not be available for wrapped trees 1053 * create functions, which might not be available for wrapped trees
1050 * (see #cxTreeCreateWrapped()). 1054 * (see #cxTreeCreateWrapped()).
1051 * 1055 *
1052 * @param tree the tree 1056 * @param tree the tree
1053 * @param data the data to insert 1057 * @param data the data to insert
1054 * @return zero on success, non-zero on failure 1058 * @retval zero success
1059 * @retval non-zero failure
1055 */ 1060 */
1056 cx_attr_nonnull 1061 cx_attr_nonnull
1057 static inline int cxTreeInsert( 1062 static inline int cxTreeInsert(
1058 CxTree *tree, 1063 CxTree *tree,
1059 const void *data 1064 const void *data
1062 } 1067 }
1063 1068
1064 /** 1069 /**
1065 * Inserts elements provided by an iterator efficiently into the tree. 1070 * Inserts elements provided by an iterator efficiently into the tree.
1066 * 1071 *
1067 * \remark For this function to work, the tree needs specified search and 1072 * @remark For this function to work, the tree needs specified search and
1068 * create functions, which might not be available for wrapped trees 1073 * create functions, which might not be available for wrapped trees
1069 * (see #cxTreeCreateWrapped()). 1074 * (see #cxTreeCreateWrapped()).
1070 * 1075 *
1071 * @param tree the tree 1076 * @param tree the tree
1072 * @param iter the iterator providing the elements 1077 * @param iter the iterator providing the elements
1074 * @return the number of elements that could be successfully inserted 1079 * @return the number of elements that could be successfully inserted
1075 */ 1080 */
1076 cx_attr_nonnull 1081 cx_attr_nonnull
1077 static inline size_t cxTreeInsertIter( 1082 static inline size_t cxTreeInsertIter(
1078 CxTree *tree, 1083 CxTree *tree,
1079 struct cx_iterator_base_s *iter, 1084 CxIteratorBase *iter,
1080 size_t n 1085 size_t n
1081 ) { 1086 ) {
1082 return tree->cl->insert_many(tree, iter, n); 1087 return tree->cl->insert_many(tree, iter, n);
1083 } 1088 }
1084 1089
1085 /** 1090 /**
1086 * Inserts an array of data efficiently into the tree. 1091 * Inserts an array of data efficiently into the tree.
1087 * 1092 *
1088 * \remark For this function to work, the tree needs specified search and 1093 * @remark For this function to work, the tree needs specified search and
1089 * create functions, which might not be available for wrapped trees 1094 * create functions, which might not be available for wrapped trees
1090 * (see #cxTreeCreateWrapped()). 1095 * (see #cxTreeCreateWrapped()).
1091 * 1096 *
1092 * @param tree the tree 1097 * @param tree the tree
1093 * @param data the array of data to insert 1098 * @param data the array of data to insert
1109 } 1114 }
1110 1115
1111 /** 1116 /**
1112 * Searches the data in the specified tree. 1117 * Searches the data in the specified tree.
1113 * 1118 *
1114 * \remark For this function to work, the tree needs a specified \c search_data 1119 * @remark For this function to work, the tree needs a specified @c search_data
1115 * function, which might not be available wrapped trees 1120 * function, which might not be available wrapped trees
1116 * (see #cxTreeCreateWrapped()). 1121 * (see #cxTreeCreateWrapped()).
1117 * 1122 *
1118 * @param tree the tree 1123 * @param tree the tree
1119 * @param data the data to search for 1124 * @param data the data to search for
1120 * @return the first matching node, or \c NULL when the data cannot be found 1125 * @return the first matching node, or @c NULL when the data cannot be found
1121 */ 1126 */
1122 cx_attr_nonnull 1127 cx_attr_nonnull
1123 cx_attr_nodiscard 1128 cx_attr_nodiscard
1124 static inline void *cxTreeFind( 1129 static inline void *cxTreeFind(
1125 CxTree *tree, 1130 CxTree *tree,
1129 } 1134 }
1130 1135
1131 /** 1136 /**
1132 * Searches the data in the specified subtree. 1137 * Searches the data in the specified subtree.
1133 * 1138 *
1134 * When \p max_depth is zero, the depth is not limited. 1139 * When @p max_depth is zero, the depth is not limited.
1135 * The \p subtree_root itself is on depth 1 and its children have depth 2. 1140 * The @p subtree_root itself is on depth 1 and its children have depth 2.
1136 * 1141 *
1137 * \note When \p subtree_root is not part of the \p tree, the behavior is 1142 * @note When @p subtree_root is not part of the @p tree, the behavior is
1138 * undefined. 1143 * undefined.
1139 * 1144 *
1140 * \remark For this function to work, the tree needs a specified \c search_data 1145 * @remark For this function to work, the tree needs a specified @c search_data
1141 * function, which might not be the case for wrapped trees 1146 * function, which might not be the case for wrapped trees
1142 * (see #cxTreeCreateWrapped()). 1147 * (see #cxTreeCreateWrapped()).
1143 * 1148 *
1144 * @param tree the tree 1149 * @param tree the tree
1145 * @param data the data to search for 1150 * @param data the data to search for
1146 * @param subtree_root the node where to start 1151 * @param subtree_root the node where to start
1147 * @param max_depth the maximum search depth 1152 * @param max_depth the maximum search depth
1148 * @return the first matching node, or \c NULL when the data cannot be found 1153 * @return the first matching node, or @c NULL when the data cannot be found
1149 */ 1154 */
1150 cx_attr_nonnull 1155 cx_attr_nonnull
1151 cx_attr_nodiscard 1156 cx_attr_nodiscard
1152 static inline void *cxTreeFindInSubtree( 1157 static inline void *cxTreeFindInSubtree(
1153 CxTree *tree, 1158 CxTree *tree,
1165 * @param subtree_root the root node of the subtree 1170 * @param subtree_root the root node of the subtree
1166 * @return the number of nodes in the specified subtree 1171 * @return the number of nodes in the specified subtree
1167 */ 1172 */
1168 cx_attr_nonnull 1173 cx_attr_nonnull
1169 cx_attr_nodiscard 1174 cx_attr_nodiscard
1175 cx_attr_export
1170 size_t cxTreeSubtreeSize(CxTree *tree, void *subtree_root); 1176 size_t cxTreeSubtreeSize(CxTree *tree, void *subtree_root);
1171 1177
1172 /** 1178 /**
1173 * Determines the depth of the specified subtree. 1179 * Determines the depth of the specified subtree.
1174 * 1180 *
1175 * @param tree the tree 1181 * @param tree the tree
1176 * @param subtree_root the root node of the subtree 1182 * @param subtree_root the root node of the subtree
1177 * @return the tree depth including the \p subtree_root 1183 * @return the tree depth including the @p subtree_root
1178 */ 1184 */
1179 cx_attr_nonnull 1185 cx_attr_nonnull
1180 cx_attr_nodiscard 1186 cx_attr_nodiscard
1187 cx_attr_export
1181 size_t cxTreeSubtreeDepth(CxTree *tree, void *subtree_root); 1188 size_t cxTreeSubtreeDepth(CxTree *tree, void *subtree_root);
1182 1189
1183 /** 1190 /**
1184 * Determines the depth of the entire tree. 1191 * Determines the depth of the entire tree.
1185 * 1192 *
1186 * @param tree the tree 1193 * @param tree the tree
1187 * @return the tree depth, counting the root as one 1194 * @return the tree depth, counting the root as one
1188 */ 1195 */
1189 cx_attr_nonnull 1196 cx_attr_nonnull
1190 cx_attr_nodiscard 1197 cx_attr_nodiscard
1198 cx_attr_export
1191 size_t cxTreeDepth(CxTree *tree); 1199 size_t cxTreeDepth(CxTree *tree);
1192 1200
1193 /** 1201 /**
1194 * Creates a depth-first iterator for the specified tree starting in \p node. 1202 * Creates a depth-first iterator for the specified tree starting in @p node.
1195 * 1203 *
1196 * If the node is not part of the tree, the behavior is undefined. 1204 * If the node is not part of the tree, the behavior is undefined.
1197 * 1205 *
1198 * @param tree the tree to iterate 1206 * @param tree the tree to iterate
1199 * @param node the node where to start 1207 * @param node the node where to start
1214 tree->loc_children, tree->loc_next 1222 tree->loc_children, tree->loc_next
1215 ); 1223 );
1216 } 1224 }
1217 1225
1218 /** 1226 /**
1219 * Creates a breadth-first iterator for the specified tree starting in \p node. 1227 * Creates a breadth-first iterator for the specified tree starting in @p node.
1220 * 1228 *
1221 * If the node is not part of the tree, the behavior is undefined. 1229 * If the node is not part of the tree, the behavior is undefined.
1222 * 1230 *
1223 * @param tree the tree to iterate 1231 * @param tree the tree to iterate
1224 * @param node the node where to start 1232 * @param node the node where to start
1265 } 1273 }
1266 1274
1267 /** 1275 /**
1268 * Sets the (new) parent of the specified child. 1276 * Sets the (new) parent of the specified child.
1269 * 1277 *
1270 * If the \p child is not already member of the tree, this function behaves 1278 * If the @p child is not already member of the tree, this function behaves
1271 * as #cxTreeAddChildNode(). 1279 * as #cxTreeAddChildNode().
1272 * 1280 *
1273 * @param tree the tree 1281 * @param tree the tree
1274 * @param parent the (new) parent of the child 1282 * @param parent the (new) parent of the child
1275 * @param child the node to add 1283 * @param child the node to add
1276 * @see cxTreeAddChildNode() 1284 * @see cxTreeAddChildNode()
1277 */ 1285 */
1278 cx_attr_nonnull 1286 cx_attr_nonnull
1287 cx_attr_export
1279 void cxTreeSetParent( 1288 void cxTreeSetParent(
1280 CxTree *tree, 1289 CxTree *tree,
1281 void *parent, 1290 void *parent,
1282 void *child 1291 void *child
1283 ); 1292 );
1284 1293
1285 /** 1294 /**
1286 * Adds a new node to the tree. 1295 * Adds a new node to the tree.
1287 * 1296 *
1288 * If the \p child is already member of the tree, the behavior is undefined. 1297 * If the @p child is already member of the tree, the behavior is undefined.
1289 * Use #cxTreeSetParent() if you want to move a subtree to another location. 1298 * Use #cxTreeSetParent() if you want to move a subtree to another location.
1290 * 1299 *
1291 * \attention The node may be externally created, but MUST obey the same rules 1300 * @attention The node may be externally created, but MUST obey the same rules
1292 * as if it was created by the tree itself with #cxTreeAddChild() (e.g. use 1301 * as if it was created by the tree itself with #cxTreeAddChild() (e.g. use
1293 * the same allocator). 1302 * the same allocator).
1294 * 1303 *
1295 * @param tree the tree 1304 * @param tree the tree
1296 * @param parent the parent of the node to add 1305 * @param parent the parent of the node to add
1297 * @param child the node to add 1306 * @param child the node to add
1298 * @see cxTreeSetParent() 1307 * @see cxTreeSetParent()
1299 */ 1308 */
1300 cx_attr_nonnull 1309 cx_attr_nonnull
1310 cx_attr_export
1301 void cxTreeAddChildNode( 1311 void cxTreeAddChildNode(
1302 CxTree *tree, 1312 CxTree *tree,
1303 void *parent, 1313 void *parent,
1304 void *child 1314 void *child
1305 ); 1315 );
1320 * @param data the data that will be submitted to the create function 1330 * @param data the data that will be submitted to the create function
1321 * @return zero when the new node was created, non-zero on allocation failure 1331 * @return zero when the new node was created, non-zero on allocation failure
1322 * @see cxTreeInsert() 1332 * @see cxTreeInsert()
1323 */ 1333 */
1324 cx_attr_nonnull 1334 cx_attr_nonnull
1335 cx_attr_export
1325 int cxTreeAddChild( 1336 int cxTreeAddChild(
1326 CxTree *tree, 1337 CxTree *tree,
1327 void *parent, 1338 void *parent,
1328 const void *data 1339 const void *data
1329 ); 1340 );
1350 /** 1361 /**
1351 * Removes a node and re-links its children to its former parent. 1362 * Removes a node and re-links its children to its former parent.
1352 * 1363 *
1353 * If the node is not part of the tree, the behavior is undefined. 1364 * If the node is not part of the tree, the behavior is undefined.
1354 * 1365 *
1355 * \note The destructor function, if any, will \em not be invoked. That means 1366 * @note The destructor function, if any, will @em not be invoked. That means
1356 * you will need to free the removed node by yourself, eventually. 1367 * you will need to free the removed node by yourself, eventually.
1357 * 1368 *
1358 * @param tree the tree 1369 * @param tree the tree
1359 * @param node the node to remove (must not be the root node) 1370 * @param node the node to remove (must not be the root node)
1360 * @param relink_func optional callback to update the content of each re-linked 1371 * @param relink_func optional callback to update the content of each re-linked
1361 * node 1372 * node
1362 * @return zero on success, non-zero if \p node is the root node of the tree 1373 * @return zero on success, non-zero if @p node is the root node of the tree
1363 */ 1374 */
1364 cx_attr_nonnull_arg(1, 2) 1375 cx_attr_nonnull_arg(1, 2)
1376 cx_attr_export
1365 int cxTreeRemoveNode( 1377 int cxTreeRemoveNode(
1366 CxTree *tree, 1378 CxTree *tree,
1367 void *node, 1379 void *node,
1368 cx_tree_relink_func relink_func 1380 cx_tree_relink_func relink_func
1369 ); 1381 );
1371 /** 1383 /**
1372 * Removes a node and it's subtree from the tree. 1384 * Removes a node and it's subtree from the tree.
1373 * 1385 *
1374 * If the node is not part of the tree, the behavior is undefined. 1386 * If the node is not part of the tree, the behavior is undefined.
1375 * 1387 *
1376 * \note The destructor function, if any, will \em not be invoked. That means 1388 * @note The destructor function, if any, will @em not be invoked. That means
1377 * you will need to free the removed subtree by yourself, eventually. 1389 * you will need to free the removed subtree by yourself, eventually.
1378 * 1390 *
1379 * @param tree the tree 1391 * @param tree the tree
1380 * @param node the node to remove 1392 * @param node the node to remove
1381 */ 1393 */
1382 cx_attr_nonnull 1394 cx_attr_nonnull
1395 cx_attr_export
1383 void cxTreeRemoveSubtree(CxTree *tree, void *node); 1396 void cxTreeRemoveSubtree(CxTree *tree, void *node);
1384 1397
1385 /** 1398 /**
1386 * Destroys a node and re-links its children to its former parent. 1399 * Destroys a node and re-links its children to its former parent.
1387 * 1400 *
1388 * If the node is not part of the tree, the behavior is undefined. 1401 * If the node is not part of the tree, the behavior is undefined.
1389 * 1402 *
1390 * It is guaranteed that the simple destructor is invoked before 1403 * It is guaranteed that the simple destructor is invoked before
1391 * the advanced destructor. 1404 * the advanced destructor.
1392 * 1405 *
1393 * \attention This function will not free the memory of the node with the 1406 * @attention This function will not free the memory of the node with the
1394 * tree's allocator, because that is usually done by the advanced destructor 1407 * tree's allocator, because that is usually done by the advanced destructor
1395 * and would therefore result in a double-free. 1408 * and would therefore result in a double-free.
1396 * 1409 *
1397 * @param tree the tree 1410 * @param tree the tree
1398 * @param node the node to destroy (must not be the root node) 1411 * @param node the node to destroy (must not be the root node)
1399 * @param relink_func optional callback to update the content of each re-linked 1412 * @param relink_func optional callback to update the content of each re-linked
1400 * node 1413 * node
1401 * @return zero on success, non-zero if \p node is the root node of the tree 1414 * @return zero on success, non-zero if @p node is the root node of the tree
1402 */ 1415 */
1403 cx_attr_nonnull_arg(1, 2) 1416 cx_attr_nonnull_arg(1, 2)
1417 cx_attr_export
1404 int cxTreeDestroyNode( 1418 int cxTreeDestroyNode(
1405 CxTree *tree, 1419 CxTree *tree,
1406 void *node, 1420 void *node,
1407 cx_tree_relink_func relink_func 1421 cx_tree_relink_func relink_func
1408 ); 1422 );

mercurial