src/tree.c

changeset 909
f4e00bb3f3b2
parent 908
f49f8a7060aa
child 910
5c2af036103f
equal deleted inserted replaced
908:f49f8a7060aa 909:f4e00bb3f3b2
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) {

mercurial