881 * |
881 * |
882 * It is guaranteed that the simple destructor is invoked before |
882 * It is guaranteed that the simple destructor is invoked before |
883 * the advanced destructor, starting with the leaf nodes of the subtree. |
883 * the advanced destructor, starting with the leaf nodes of the subtree. |
884 * |
884 * |
885 * When this function is invoked on the root node of the tree, it destroys the |
885 * When this function is invoked on the root node of the tree, it destroys the |
886 * tree contents, but - in contrast to #cxTreeDestroy() - not the tree |
886 * tree contents, but - in contrast to #cxTreeFree() - not the tree |
887 * structure, leaving an empty tree behind. |
887 * structure, leaving an empty tree behind. |
888 * |
888 * |
889 * \note The destructor function, if any, will \em not be invoked. That means |
889 * \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. |
890 * you will need to free the removed subtree by yourself, eventually. |
891 * |
891 * |
893 * tree's allocator, because that is usually done by the advanced destructor |
893 * tree's allocator, because that is usually done by the advanced destructor |
894 * and would therefore result in a double-free. |
894 * and would therefore result in a double-free. |
895 * |
895 * |
896 * @param tree the tree |
896 * @param tree the tree |
897 * @param node the node to remove |
897 * @param node the node to remove |
898 * @see cxTreeDestroy() |
898 * @see cxTreeFree() |
899 */ |
899 */ |
900 cx_attr_nonnull |
900 cx_attr_nonnull |
901 void cxTreeDestroySubtree(CxTree *tree, void *node); |
901 void cxTreeDestroySubtree(CxTree *tree, void *node); |
902 |
902 |
903 |
903 |
919 * @see cxTreeDestroySubtree() |
919 * @see cxTreeDestroySubtree() |
920 */ |
920 */ |
921 #define cxTreeClear(tree) cxTreeDestroySubtree(tree, tree->root) |
921 #define cxTreeClear(tree) cxTreeDestroySubtree(tree, tree->root) |
922 |
922 |
923 /** |
923 /** |
924 * Destroys the tree structure. |
924 * Deallocates the tree structure. |
925 * |
925 * |
926 * The destructor functions are invoked for each node, starting with the leaf |
926 * The destructor functions are invoked for each node, starting with the leaf |
927 * nodes. |
927 * nodes. |
928 * It is guaranteed that for each node the simple destructor is invoked before |
928 * It is guaranteed that for each node the simple destructor is invoked before |
929 * the advanced destructor. |
929 * the advanced destructor. |
932 * on the nodes. |
932 * on the nodes. |
933 * It will NOT additionally free the nodes with the tree's allocator, because |
933 * 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 |
934 * that would cause a double-free in most scenarios where the advanced |
935 * destructor is already freeing the memory. |
935 * destructor is already freeing the memory. |
936 * |
936 * |
937 * @param tree the tree to destroy |
937 * @param tree the tree to free |
938 */ |
938 */ |
939 static inline void cxTreeDestroy(CxTree *tree) { |
939 static inline void cxTreeFree(CxTree *tree) { |
940 if (tree == NULL) return; |
940 if (tree == NULL) return; |
941 if (tree->root != NULL) { |
941 if (tree->root != NULL) { |
942 cxTreeClear(tree); |
942 cxTreeClear(tree); |
943 } |
943 } |
944 cxFree(tree->allocator, tree); |
944 cxFree(tree->allocator, tree); |
969 * @see cxTreeCreateWrapped() |
969 * @see cxTreeCreateWrapped() |
970 */ |
970 */ |
971 cx_attr_nonnull_arg(2, 3, 4) |
971 cx_attr_nonnull_arg(2, 3, 4) |
972 cx_attr_nodiscard |
972 cx_attr_nodiscard |
973 cx_attr_malloc |
973 cx_attr_malloc |
974 cx_attr_dealloc(cxTreeDestroy, 1) |
974 cx_attr_dealloc(cxTreeFree, 1) |
975 CxTree *cxTreeCreate( |
975 CxTree *cxTreeCreate( |
976 const CxAllocator *allocator, |
976 const CxAllocator *allocator, |
977 cx_tree_node_create_func create_func, |
977 cx_tree_node_create_func create_func, |
978 cx_tree_search_func search_func, |
978 cx_tree_search_func search_func, |
979 cx_tree_search_data_func search_data_func, |
979 cx_tree_search_data_func search_data_func, |
1029 * @see cxTreeCreate() |
1029 * @see cxTreeCreate() |
1030 */ |
1030 */ |
1031 cx_attr_nonnull_arg(2) |
1031 cx_attr_nonnull_arg(2) |
1032 cx_attr_nodiscard |
1032 cx_attr_nodiscard |
1033 cx_attr_malloc |
1033 cx_attr_malloc |
1034 cx_attr_dealloc(cxTreeDestroy, 1) |
1034 cx_attr_dealloc(cxTreeFree, 1) |
1035 CxTree *cxTreeCreateWrapped( |
1035 CxTree *cxTreeCreateWrapped( |
1036 const CxAllocator *allocator, |
1036 const CxAllocator *allocator, |
1037 void *root, |
1037 void *root, |
1038 ptrdiff_t loc_parent, |
1038 ptrdiff_t loc_parent, |
1039 ptrdiff_t loc_children, |
1039 ptrdiff_t loc_children, |