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 |
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 |
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 |
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 |
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, |
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, |