898 cxIteratorNext(visitor); |
898 cxIteratorNext(visitor); |
899 } |
899 } |
900 return visitor.depth; |
900 return visitor.depth; |
901 } |
901 } |
902 |
902 |
903 int cxTreeRemove(CxTree *tree, void *node) { |
903 int cxTreeRemove( |
|
904 CxTree *tree, |
|
905 void *node, |
|
906 cx_tree_relink_func relink_func |
|
907 ) { |
904 if (node == tree->root) return 1; |
908 if (node == tree->root) return 1; |
905 |
909 |
906 |
910 // determine the new parent |
|
911 ptrdiff_t loc_parent = tree->loc_parent; |
|
912 void *new_parent = tree_parent(node); |
|
913 |
|
914 // first, unlink from the parent |
|
915 cx_tree_unlink(node, cx_tree_node_layout(tree)); |
|
916 |
|
917 // then relink each child |
|
918 ptrdiff_t loc_children = tree->loc_children; |
|
919 ptrdiff_t loc_next = tree->loc_next; |
|
920 void *child = tree_children(node); |
|
921 while (child != NULL) { |
|
922 // forcibly set the parent to NULL - we do not use the unlink function |
|
923 // because that would unnecessarily modify the children linked list |
|
924 tree_parent(child) = NULL; |
|
925 |
|
926 // update contents, if required |
|
927 if (relink_func != NULL) { |
|
928 relink_func(child, node, new_parent); |
|
929 } |
|
930 |
|
931 // link to new parent |
|
932 cx_tree_link(new_parent, child, cx_tree_node_layout(tree)); |
|
933 |
|
934 // proceed to next child |
|
935 child = tree_next(child); |
|
936 } |
|
937 |
|
938 // clear the linked list of the removed node |
|
939 tree_children(node) = NULL; |
|
940 ptrdiff_t loc_last_child = tree->loc_last_child; |
|
941 if (loc_last_child >= 0) tree_last_child(node) = NULL; |
|
942 |
|
943 // the tree now has one member less |
|
944 tree->size--; |
907 |
945 |
908 return 0; |
946 return 0; |
909 } |
947 } |
910 |
948 |
911 void cxTreeRemoveSubtree(CxTree *tree, void *node) { |
949 void cxTreeRemoveSubtree(CxTree *tree, void *node) { |