src/cx/tree.h

changeset 1108
c3bde8ff1c0b
parent 993
b642eca4b956
child 1109
89ec23988b88
equal deleted inserted replaced
1107:9d77c7a99441 1108:c3bde8ff1c0b
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
303 #define CX_TREE_SEARCH_INFINITE_DEPTH 0 303 #define CX_TREE_SEARCH_INFINITE_DEPTH 0
304 304
305 /** 305 /**
306 * Function pointer for a search function. 306 * Function pointer for a search function.
307 * 307 *
308 * 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
309 * 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
310 * the data. 310 * the data.
311 * 311 *
312 * 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
313 * 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 314 * Zero means exact match and a positive number is an implementation defined
333 333
334 334
335 /** 335 /**
336 * Function pointer for a search function. 336 * Function pointer for a search function.
337 * 337 *
338 * 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
339 * 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
340 * contain the data. 340 * contain the data.
341 * 341 *
342 * 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
343 * 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 344 * 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. 352 * that the search does not need to be continued in that branch.
353 * 353 *
354 * @param node the node that is currently investigated 354 * @param node the node that is currently investigated
355 * @param new_node a new node with the information which is searched 355 * @param new_node a new node with the information which is searched
356 * 356 *
357 * @return 0 if \p node contains the same data as \p new_node, 357 * @return 0 if @p node contains the same data as @p new_node,
358 * positive if one of the children might contain the data, 358 * positive if one of the children might contain the data,
359 * negative if neither the node, nor the children contains the data 359 * negative if neither the node, nor the children contains the data
360 */ 360 */
361 cx_attr_nonnull 361 cx_attr_nonnull
362 typedef int (*cx_tree_search_func)(const void *node, const void *new_node); 362 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 368 * closest result which might be a good starting point for adding a new node
369 * to the tree (see also #cx_tree_add()). 369 * to the tree (see also #cx_tree_add()).
370 * 370 *
371 * 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
372 * "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
373 * 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
374 * \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
375 * node matching the criteria is returned. 375 * node matching the criteria is returned.
376 * 376 *
377 * @param root the root node 377 * @param root the root node
378 * @param depth the maximum depth (zero=indefinite, one=just root) 378 * @param depth the maximum depth (zero=indefinite, one=just root)
379 * @param data the data to search for 379 * @param data the data to search for
404 * 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
405 * new node to the tree (see also #cx_tree_add()). 405 * new node to the tree (see also #cx_tree_add()).
406 * 406 *
407 * 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
408 * "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
409 * 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
410 * \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
411 * node matching the criteria is returned. 411 * node matching the criteria is returned.
412 * 412 *
413 * @param root the root node 413 * @param root the root node
414 * @param depth the maximum depth (zero=indefinite, one=just root) 414 * @param depth the maximum depth (zero=indefinite, one=just root)
415 * @param node the node to search for 415 * @param node the node to search for
489 /** 489 /**
490 * Describes a function that creates a tree node from the specified data. 490 * 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 491 * 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). 492 * 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 493 * Functions of this type shall either return a new pointer to a newly
494 * created node or \c NULL when allocation fails. 494 * created node or @c NULL when allocation fails.
495 * 495 *
496 * \note the function may leave the node pointers in the struct uninitialized. 496 * @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. 497 * The caller is responsible to set them according to the intended use case.
498 */ 498 */
499 cx_attr_nonnull_arg(1) 499 cx_attr_nonnull_arg(1)
500 typedef void *(*cx_tree_node_create_func)(const void *, void *); 500 typedef void *(*cx_tree_node_create_func)(const void *, void *);
501 501
511 * Adds multiple elements efficiently to a tree. 511 * Adds multiple elements efficiently to a tree.
512 * 512 *
513 * Once an element cannot be added to the tree, this function returns, leaving 513 * 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 514 * the iterator in a valid state pointing to the element that could not be
515 * added. 515 * added.
516 * Also, the pointer of the created node will be stored to \p failed. 516 * 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 517 * The integer returned by this function denotes the number of elements obtained
518 * from the \p iter that have been successfully processed. 518 * from the @p iter that have been successfully processed.
519 * When all elements could be processed, a \c NULL pointer will be written to 519 * When all elements could be processed, a @c NULL pointer will be written to
520 * \p failed. 520 * @p failed.
521 * 521 *
522 * The advantage of this function compared to multiple invocations of 522 * 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 523 * #cx_tree_add() is that the search for the insert locations is not always
524 * started from the root node. 524 * started from the root node.
525 * Instead, the function checks #cx_tree_add_look_around_depth many parent nodes 525 * Instead, the function checks #cx_tree_add_look_around_depth many parent nodes
564 564
565 /** 565 /**
566 * Adds multiple elements efficiently to a tree. 566 * Adds multiple elements efficiently to a tree.
567 * 567 *
568 * Once an element cannot be added to the tree, this function returns, storing 568 * Once an element cannot be added to the tree, this function returns, storing
569 * the pointer of the created node to \p failed. 569 * the pointer of the created node to @p failed.
570 * The integer returned by this function denotes the number of elements from 570 * The integer returned by this function denotes the number of elements from
571 * the \p src array that have been successfully processed. 571 * the @p src array that have been successfully processed.
572 * When all elements could be processed, a \c NULL pointer will be written to 572 * When all elements could be processed, a @c NULL pointer will be written to
573 * \p failed. 573 * @p failed.
574 * 574 *
575 * The advantage of this function compared to multiple invocations of 575 * 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 576 * #cx_tree_add() is that the search for the insert locations is not always
577 * started from the root node. 577 * started from the root node.
578 * Instead, the function checks #cx_tree_add_look_around_depth many parent nodes 578 * Instead, the function checks #cx_tree_add_look_around_depth many parent nodes
581 * again. 581 * again.
582 * 582 *
583 * Refer to the documentation of #cx_tree_add() for more details. 583 * Refer to the documentation of #cx_tree_add() for more details.
584 * 584 *
585 * @param src a pointer to the source data array 585 * @param src a pointer to the source data array
586 * @param num the number of elements in the \p src array 586 * @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 587 * @param elem_size the size of each element in the @p src array
588 * @param sfunc a search function 588 * @param sfunc a search function
589 * @param cfunc a node creation function 589 * @param cfunc a node creation function
590 * @param cdata optional additional data 590 * @param cdata optional additional data
591 * @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
592 * @param root the root node of the tree 592 * @param root the root node of the tree
619 619
620 /** 620 /**
621 * Adds data to a tree. 621 * Adds data to a tree.
622 * 622 *
623 * 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
624 * specified \p sfunc. 624 * specified @p sfunc.
625 * 625 *
626 * 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.
627 * 627 *
628 * 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.
629 * 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
630 * 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
631 * 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
632 * accordingly. 632 * accordingly.
633 * 633 *
634 * 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
635 * 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
636 * as a child. 636 * as a child.
637 * 637 *
638 * 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
639 * the tree and this function returns a non-zero value. 639 * 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 640 * The caller should check if @p cnode contains a node pointer and deal with the
641 * node that could not be added. 641 * node that could not be added.
642 * 642 *
643 * 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
644 * 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
645 * will be \c NULL. 645 * will be @c NULL.
646 * 646 *
647 * Multiple elements can be added more efficiently with 647 * Multiple elements can be added more efficiently with
648 * #cx_tree_add_array() or #cx_tree_add_iter(). 648 * #cx_tree_add_array() or #cx_tree_add_iter().
649 * 649 *
650 * @param src a pointer to the data 650 * @param src a pointer to the data
725 const CxAllocator *allocator; 725 const CxAllocator *allocator;
726 726
727 /** 727 /**
728 * A pointer to the root node. 728 * A pointer to the root node.
729 * 729 *
730 * Will be \c NULL when \c size is 0. 730 * Will be @c NULL when @c size is 0.
731 */ 731 */
732 void *root; 732 void *root;
733 733
734 /** 734 /**
735 * A function to create new nodes. 735 * A function to create new nodes.
799 }; 799 };
800 800
801 /** 801 /**
802 * 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
803 * 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
804 */ 808 */
805 #define CX_TREE_NODE_BASE(type) \ 809 #define CX_TREE_NODE_BASE(type) \
806 type *parent; \ 810 type *parent; \
807 type *children;\ 811 type *children;\
808 type *last_child;\ 812 type *last_child;\
809 type *prev;\ 813 type *prev;\
810 type *next 814 type *next
811 815
812 /** 816 /**
813 * 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.
814 */ 823 */
815 #define cx_tree_node_base_layout \ 824 #define cx_tree_node_base_layout \
816 offsetof(struct cx_tree_node_base_s, parent),\ 825 offsetof(struct cx_tree_node_base_s, parent),\
817 offsetof(struct cx_tree_node_base_s, children),\ 826 offsetof(struct cx_tree_node_base_s, children),\
818 offsetof(struct cx_tree_node_base_s, last_child),\ 827 offsetof(struct cx_tree_node_base_s, last_child),\
819 offsetof(struct cx_tree_node_base_s, prev), \ 828 offsetof(struct cx_tree_node_base_s, prev), \
820 offsetof(struct cx_tree_node_base_s, next) 829 offsetof(struct cx_tree_node_base_s, next)
821 830
822 /** 831 /**
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. 832 * The class definition for arbitrary trees.
834 */ 833 */
835 struct cx_tree_class_s { 834 struct cx_tree_class_s {
836 /** 835 /**
837 * Member function for inserting a single element. 836 * Member function for inserting a single element.
838 * 837 *
839 * Implementations SHALL NOT simply invoke \p insert_many as this comes 838 * Implementations SHALL NOT simply invoke @p insert_many as this comes
840 * with too much overhead. 839 * with too much overhead.
841 */ 840 */
842 cx_attr_nonnull
843 int (*insert_element)( 841 int (*insert_element)(
844 struct cx_tree_s *tree, 842 struct cx_tree_s *tree,
845 const void *data 843 const void *data
846 ); 844 );
847 845
849 * Member function for inserting multiple elements. 847 * Member function for inserting multiple elements.
850 * 848 *
851 * Implementations SHALL avoid to perform a full search in the tree for 849 * Implementations SHALL avoid to perform a full search in the tree for
852 * every element even though the source data MAY be unsorted. 850 * every element even though the source data MAY be unsorted.
853 */ 851 */
854 cx_attr_nonnull
855 size_t (*insert_many)( 852 size_t (*insert_many)(
856 struct cx_tree_s *tree, 853 struct cx_tree_s *tree,
857 struct cx_iterator_base_s *iter, 854 struct cx_iterator_base_s *iter,
858 size_t n 855 size_t n
859 ); 856 );
860 857
861 /** 858 /**
862 * Member function for finding a node. 859 * Member function for finding a node.
863 */ 860 */
864 cx_attr_nonnull
865 void *(*find)( 861 void *(*find)(
866 struct cx_tree_s *tree, 862 struct cx_tree_s *tree,
867 const void *subtree, 863 const void *subtree,
868 const void *data, 864 const void *data,
869 size_t depth 865 size_t depth
884 * 880 *
885 * When this function is invoked on the root node of the tree, it destroys the 881 * 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 882 * tree contents, but - in contrast to #cxTreeFree() - not the tree
887 * structure, leaving an empty tree behind. 883 * structure, leaving an empty tree behind.
888 * 884 *
889 * \note The destructor function, if any, will \em not be invoked. That means 885 * @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. 886 * you will need to free the removed subtree by yourself, eventually.
891 * 887 *
892 * \attention This function will not free the memory of the nodes with the 888 * @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 889 * tree's allocator, because that is usually done by the advanced destructor
894 * and would therefore result in a double-free. 890 * and would therefore result in a double-free.
895 * 891 *
896 * @param tree the tree 892 * @param tree the tree
897 * @param node the node to remove 893 * @param node the node to remove
908 * the advanced destructor, starting with the leaf nodes of the subtree. 904 * the advanced destructor, starting with the leaf nodes of the subtree.
909 * 905 *
910 * This is a convenience macro for invoking #cxTreeDestroySubtree() on the 906 * This is a convenience macro for invoking #cxTreeDestroySubtree() on the
911 * root node of the tree. 907 * root node of the tree.
912 * 908 *
913 * \attention Be careful when calling this function when no destructor function 909 * @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 910 * 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 911 * need a reference to the (former) root node of the tree somewhere or
916 * otherwise you will be leaking memory. 912 * otherwise you will be leaking memory.
917 * 913 *
918 * @param tree the tree 914 * @param tree the tree
926 * The destructor functions are invoked for each node, starting with the leaf 922 * The destructor functions are invoked for each node, starting with the leaf
927 * nodes. 923 * nodes.
928 * It is guaranteed that for each node the simple destructor is invoked before 924 * It is guaranteed that for each node the simple destructor is invoked before
929 * the advanced destructor. 925 * the advanced destructor.
930 * 926 *
931 * \attention This function will only invoke the destructor functions 927 * @attention This function will only invoke the destructor functions
932 * on the nodes. 928 * on the nodes.
933 * It will NOT additionally free the nodes with the tree's allocator, because 929 * 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 930 * that would cause a double-free in most scenarios where the advanced
935 * destructor is already freeing the memory. 931 * destructor is already freeing the memory.
936 * 932 *
945 } 941 }
946 942
947 /** 943 /**
948 * Creates a new tree structure based on the specified layout. 944 * Creates a new tree structure based on the specified layout.
949 * 945 *
950 * The specified \p allocator will be used for creating the tree struct 946 * 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. 947 * and SHALL be used by @p create_func to allocate memory for the nodes.
952 * 948 *
953 * \note This function will also register an advanced destructor which 949 * @note This function will also register an advanced destructor which
954 * will free the nodes with the allocator's free() method. 950 * will free the nodes with the allocator's free() method.
955 * 951 *
956 * @param allocator the allocator that shall be used 952 * @param allocator the allocator that shall be used
957 * (if \c NULL, a default stdlib allocator will be used) 953 * (if @c NULL, a default stdlib allocator will be used)
958 * @param create_func a function that creates new nodes 954 * @param create_func a function that creates new nodes
959 * @param search_func a function that compares two nodes 955 * @param search_func a function that compares two nodes
960 * @param search_data_func a function that compares a node with data 956 * @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 957 * @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 958 * @param loc_children offset in the node struct for the children linked list
985 ); 981 );
986 982
987 /** 983 /**
988 * Creates a new tree structure based on a default layout. 984 * Creates a new tree structure based on a default layout.
989 * 985 *
990 * Nodes created by \p create_func MUST contain #cx_tree_node_base_s as first 986 * 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 987 * member (or at least respect the default offsets specified in the tree
992 * struct) and they MUST be allocated with the specified allocator. 988 * struct) and they MUST be allocated with the specified allocator.
993 * 989 *
994 * \note This function will also register an advanced destructor which 990 * @note This function will also register an advanced destructor which
995 * will free the nodes with the allocator's free() method. 991 * will free the nodes with the allocator's free() method.
996 * 992 *
997 * @param allocator the allocator that shall be used 993 * @param allocator (@c CxAllocator*) the allocator that shall be used
998 * @param create_func a function that creates new nodes 994 * @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 995 * @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 996 * @param search_data_func (@c cx_tree_search_data_func) a function that compares a node with data
1001 * @return the new tree 997 * @return (@c CxTree*) the new tree
1002 * @see cxTreeCreate() 998 * @see cxTreeCreate()
1003 */ 999 */
1004 #define cxTreeCreateSimple(\ 1000 #define cxTreeCreateSimple(\
1005 allocator, create_func, search_func, search_data_func \ 1001 allocator, create_func, search_func, search_data_func \
1006 ) cxTreeCreate(allocator, create_func, search_func, search_data_func, \ 1002 ) cxTreeCreate(allocator, create_func, search_func, search_data_func, \
1007 cx_tree_node_base_layout) 1003 cx_tree_node_base_layout)
1008 1004
1009 /** 1005 /**
1010 * Creates a new tree structure based on an existing tree. 1006 * Creates a new tree structure based on an existing tree.
1011 * 1007 *
1012 * The specified \p allocator will be used for creating the tree struct. 1008 * The specified @p allocator will be used for creating the tree struct.
1013 * 1009 *
1014 * \attention This function will create an incompletely defined tree structure 1010 * @attention This function will create an incompletely defined tree structure
1015 * where neither the create function, the search function, nor a destructor 1011 * 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 1012 * will be set. If you wish to use any of this functionality for the wrapped
1017 * tree, you need to specify those functions afterwards. 1013 * tree, you need to specify those functions afterwards.
1018 * 1014 *
1019 * @param allocator the allocator that was used for nodes of the wrapped tree 1015 * @param allocator the allocator that was used for nodes of the wrapped tree
1020 * (if \c NULL, a default stdlib allocator is assumed) 1016 * (if @c NULL, a default stdlib allocator is assumed)
1021 * @param root the root node of the tree that shall be wrapped 1017 * @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 1018 * @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 1019 * @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 1020 * @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) 1021 * the last child in the linked list (negative if there is no such pointer)
1043 ); 1039 );
1044 1040
1045 /** 1041 /**
1046 * Inserts data into the tree. 1042 * Inserts data into the tree.
1047 * 1043 *
1048 * \remark For this function to work, the tree needs specified search and 1044 * @remark For this function to work, the tree needs specified search and
1049 * create functions, which might not be available for wrapped trees 1045 * create functions, which might not be available for wrapped trees
1050 * (see #cxTreeCreateWrapped()). 1046 * (see #cxTreeCreateWrapped()).
1051 * 1047 *
1052 * @param tree the tree 1048 * @param tree the tree
1053 * @param data the data to insert 1049 * @param data the data to insert
1054 * @return zero on success, non-zero on failure 1050 * @retval zero success
1051 * @retval non-zero failure
1055 */ 1052 */
1056 cx_attr_nonnull 1053 cx_attr_nonnull
1057 static inline int cxTreeInsert( 1054 static inline int cxTreeInsert(
1058 CxTree *tree, 1055 CxTree *tree,
1059 const void *data 1056 const void *data
1062 } 1059 }
1063 1060
1064 /** 1061 /**
1065 * Inserts elements provided by an iterator efficiently into the tree. 1062 * Inserts elements provided by an iterator efficiently into the tree.
1066 * 1063 *
1067 * \remark For this function to work, the tree needs specified search and 1064 * @remark For this function to work, the tree needs specified search and
1068 * create functions, which might not be available for wrapped trees 1065 * create functions, which might not be available for wrapped trees
1069 * (see #cxTreeCreateWrapped()). 1066 * (see #cxTreeCreateWrapped()).
1070 * 1067 *
1071 * @param tree the tree 1068 * @param tree the tree
1072 * @param iter the iterator providing the elements 1069 * @param iter the iterator providing the elements
1083 } 1080 }
1084 1081
1085 /** 1082 /**
1086 * Inserts an array of data efficiently into the tree. 1083 * Inserts an array of data efficiently into the tree.
1087 * 1084 *
1088 * \remark For this function to work, the tree needs specified search and 1085 * @remark For this function to work, the tree needs specified search and
1089 * create functions, which might not be available for wrapped trees 1086 * create functions, which might not be available for wrapped trees
1090 * (see #cxTreeCreateWrapped()). 1087 * (see #cxTreeCreateWrapped()).
1091 * 1088 *
1092 * @param tree the tree 1089 * @param tree the tree
1093 * @param data the array of data to insert 1090 * @param data the array of data to insert
1109 } 1106 }
1110 1107
1111 /** 1108 /**
1112 * Searches the data in the specified tree. 1109 * Searches the data in the specified tree.
1113 * 1110 *
1114 * \remark For this function to work, the tree needs a specified \c search_data 1111 * @remark For this function to work, the tree needs a specified @c search_data
1115 * function, which might not be available wrapped trees 1112 * function, which might not be available wrapped trees
1116 * (see #cxTreeCreateWrapped()). 1113 * (see #cxTreeCreateWrapped()).
1117 * 1114 *
1118 * @param tree the tree 1115 * @param tree the tree
1119 * @param data the data to search for 1116 * @param data the data to search for
1120 * @return the first matching node, or \c NULL when the data cannot be found 1117 * @return the first matching node, or @c NULL when the data cannot be found
1121 */ 1118 */
1122 cx_attr_nonnull 1119 cx_attr_nonnull
1123 cx_attr_nodiscard 1120 cx_attr_nodiscard
1124 static inline void *cxTreeFind( 1121 static inline void *cxTreeFind(
1125 CxTree *tree, 1122 CxTree *tree,
1129 } 1126 }
1130 1127
1131 /** 1128 /**
1132 * Searches the data in the specified subtree. 1129 * Searches the data in the specified subtree.
1133 * 1130 *
1134 * When \p max_depth is zero, the depth is not limited. 1131 * 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. 1132 * The @p subtree_root itself is on depth 1 and its children have depth 2.
1136 * 1133 *
1137 * \note When \p subtree_root is not part of the \p tree, the behavior is 1134 * @note When @p subtree_root is not part of the @p tree, the behavior is
1138 * undefined. 1135 * undefined.
1139 * 1136 *
1140 * \remark For this function to work, the tree needs a specified \c search_data 1137 * @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 1138 * function, which might not be the case for wrapped trees
1142 * (see #cxTreeCreateWrapped()). 1139 * (see #cxTreeCreateWrapped()).
1143 * 1140 *
1144 * @param tree the tree 1141 * @param tree the tree
1145 * @param data the data to search for 1142 * @param data the data to search for
1146 * @param subtree_root the node where to start 1143 * @param subtree_root the node where to start
1147 * @param max_depth the maximum search depth 1144 * @param max_depth the maximum search depth
1148 * @return the first matching node, or \c NULL when the data cannot be found 1145 * @return the first matching node, or @c NULL when the data cannot be found
1149 */ 1146 */
1150 cx_attr_nonnull 1147 cx_attr_nonnull
1151 cx_attr_nodiscard 1148 cx_attr_nodiscard
1152 static inline void *cxTreeFindInSubtree( 1149 static inline void *cxTreeFindInSubtree(
1153 CxTree *tree, 1150 CxTree *tree,
1172 /** 1169 /**
1173 * Determines the depth of the specified subtree. 1170 * Determines the depth of the specified subtree.
1174 * 1171 *
1175 * @param tree the tree 1172 * @param tree the tree
1176 * @param subtree_root the root node of the subtree 1173 * @param subtree_root the root node of the subtree
1177 * @return the tree depth including the \p subtree_root 1174 * @return the tree depth including the @p subtree_root
1178 */ 1175 */
1179 cx_attr_nonnull 1176 cx_attr_nonnull
1180 cx_attr_nodiscard 1177 cx_attr_nodiscard
1181 size_t cxTreeSubtreeDepth(CxTree *tree, void *subtree_root); 1178 size_t cxTreeSubtreeDepth(CxTree *tree, void *subtree_root);
1182 1179
1189 cx_attr_nonnull 1186 cx_attr_nonnull
1190 cx_attr_nodiscard 1187 cx_attr_nodiscard
1191 size_t cxTreeDepth(CxTree *tree); 1188 size_t cxTreeDepth(CxTree *tree);
1192 1189
1193 /** 1190 /**
1194 * Creates a depth-first iterator for the specified tree starting in \p node. 1191 * Creates a depth-first iterator for the specified tree starting in @p node.
1195 * 1192 *
1196 * If the node is not part of the tree, the behavior is undefined. 1193 * If the node is not part of the tree, the behavior is undefined.
1197 * 1194 *
1198 * @param tree the tree to iterate 1195 * @param tree the tree to iterate
1199 * @param node the node where to start 1196 * @param node the node where to start
1214 tree->loc_children, tree->loc_next 1211 tree->loc_children, tree->loc_next
1215 ); 1212 );
1216 } 1213 }
1217 1214
1218 /** 1215 /**
1219 * Creates a breadth-first iterator for the specified tree starting in \p node. 1216 * Creates a breadth-first iterator for the specified tree starting in @p node.
1220 * 1217 *
1221 * If the node is not part of the tree, the behavior is undefined. 1218 * If the node is not part of the tree, the behavior is undefined.
1222 * 1219 *
1223 * @param tree the tree to iterate 1220 * @param tree the tree to iterate
1224 * @param node the node where to start 1221 * @param node the node where to start
1265 } 1262 }
1266 1263
1267 /** 1264 /**
1268 * Sets the (new) parent of the specified child. 1265 * Sets the (new) parent of the specified child.
1269 * 1266 *
1270 * If the \p child is not already member of the tree, this function behaves 1267 * If the @p child is not already member of the tree, this function behaves
1271 * as #cxTreeAddChildNode(). 1268 * as #cxTreeAddChildNode().
1272 * 1269 *
1273 * @param tree the tree 1270 * @param tree the tree
1274 * @param parent the (new) parent of the child 1271 * @param parent the (new) parent of the child
1275 * @param child the node to add 1272 * @param child the node to add
1283 ); 1280 );
1284 1281
1285 /** 1282 /**
1286 * Adds a new node to the tree. 1283 * Adds a new node to the tree.
1287 * 1284 *
1288 * If the \p child is already member of the tree, the behavior is undefined. 1285 * 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. 1286 * Use #cxTreeSetParent() if you want to move a subtree to another location.
1290 * 1287 *
1291 * \attention The node may be externally created, but MUST obey the same rules 1288 * @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 1289 * as if it was created by the tree itself with #cxTreeAddChild() (e.g. use
1293 * the same allocator). 1290 * the same allocator).
1294 * 1291 *
1295 * @param tree the tree 1292 * @param tree the tree
1296 * @param parent the parent of the node to add 1293 * @param parent the parent of the node to add
1350 /** 1347 /**
1351 * Removes a node and re-links its children to its former parent. 1348 * Removes a node and re-links its children to its former parent.
1352 * 1349 *
1353 * If the node is not part of the tree, the behavior is undefined. 1350 * If the node is not part of the tree, the behavior is undefined.
1354 * 1351 *
1355 * \note The destructor function, if any, will \em not be invoked. That means 1352 * @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. 1353 * you will need to free the removed node by yourself, eventually.
1357 * 1354 *
1358 * @param tree the tree 1355 * @param tree the tree
1359 * @param node the node to remove (must not be the root node) 1356 * @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 1357 * @param relink_func optional callback to update the content of each re-linked
1361 * node 1358 * node
1362 * @return zero on success, non-zero if \p node is the root node of the tree 1359 * @return zero on success, non-zero if @p node is the root node of the tree
1363 */ 1360 */
1364 cx_attr_nonnull_arg(1, 2) 1361 cx_attr_nonnull_arg(1, 2)
1365 int cxTreeRemoveNode( 1362 int cxTreeRemoveNode(
1366 CxTree *tree, 1363 CxTree *tree,
1367 void *node, 1364 void *node,
1371 /** 1368 /**
1372 * Removes a node and it's subtree from the tree. 1369 * Removes a node and it's subtree from the tree.
1373 * 1370 *
1374 * If the node is not part of the tree, the behavior is undefined. 1371 * If the node is not part of the tree, the behavior is undefined.
1375 * 1372 *
1376 * \note The destructor function, if any, will \em not be invoked. That means 1373 * @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. 1374 * you will need to free the removed subtree by yourself, eventually.
1378 * 1375 *
1379 * @param tree the tree 1376 * @param tree the tree
1380 * @param node the node to remove 1377 * @param node the node to remove
1381 */ 1378 */
1388 * If the node is not part of the tree, the behavior is undefined. 1385 * If the node is not part of the tree, the behavior is undefined.
1389 * 1386 *
1390 * It is guaranteed that the simple destructor is invoked before 1387 * It is guaranteed that the simple destructor is invoked before
1391 * the advanced destructor. 1388 * the advanced destructor.
1392 * 1389 *
1393 * \attention This function will not free the memory of the node with the 1390 * @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 1391 * tree's allocator, because that is usually done by the advanced destructor
1395 * and would therefore result in a double-free. 1392 * and would therefore result in a double-free.
1396 * 1393 *
1397 * @param tree the tree 1394 * @param tree the tree
1398 * @param node the node to destroy (must not be the root node) 1395 * @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 1396 * @param relink_func optional callback to update the content of each re-linked
1400 * node 1397 * node
1401 * @return zero on success, non-zero if \p node is the root node of the tree 1398 * @return zero on success, non-zero if @p node is the root node of the tree
1402 */ 1399 */
1403 cx_attr_nonnull_arg(1, 2) 1400 cx_attr_nonnull_arg(1, 2)
1404 int cxTreeDestroyNode( 1401 int cxTreeDestroyNode(
1405 CxTree *tree, 1402 CxTree *tree,
1406 void *node, 1403 void *node,

mercurial