679 cfunc, cdata, failed, root, |
679 cfunc, cdata, failed, root, |
680 loc_parent, loc_children, loc_last_child, |
680 loc_parent, loc_children, loc_last_child, |
681 loc_prev, loc_next); |
681 loc_prev, loc_next); |
682 } |
682 } |
683 |
683 |
684 static void cx_tree_default_destructor(CxTree *tree) { |
|
685 if (tree->simple_destructor != NULL || tree->advanced_destructor != NULL) { |
|
686 CxTreeIterator iter = tree->cl->iterator(tree, true); |
|
687 cx_foreach(void *, node, iter) { |
|
688 if (iter.exiting) { |
|
689 if (tree->simple_destructor) { |
|
690 tree->simple_destructor(node); |
|
691 } |
|
692 if (tree->advanced_destructor) { |
|
693 tree->advanced_destructor(tree->destructor_data, node); |
|
694 } |
|
695 } |
|
696 } |
|
697 } |
|
698 cxFree(tree->allocator, tree); |
|
699 } |
|
700 |
|
701 static CxTreeIterator cx_tree_default_iterator( |
684 static CxTreeIterator cx_tree_default_iterator( |
702 CxTree *tree, |
685 CxTree *tree, |
703 bool visit_on_exit |
686 bool visit_on_exit |
704 ) { |
687 ) { |
705 return cx_tree_iterator( |
688 return cx_tree_iterator( |
783 return NULL; |
766 return NULL; |
784 } |
767 } |
785 } |
768 } |
786 |
769 |
787 static cx_tree_class cx_tree_default_class = { |
770 static cx_tree_class cx_tree_default_class = { |
788 cx_tree_default_destructor, |
|
789 cx_tree_default_insert_element, |
771 cx_tree_default_insert_element, |
790 cx_tree_default_insert_many, |
772 cx_tree_default_insert_many, |
791 cx_tree_default_find, |
773 cx_tree_default_find, |
792 cx_tree_default_iterator, |
774 cx_tree_default_iterator, |
793 cx_tree_default_visitor |
775 cx_tree_default_visitor |
955 } |
937 } |
956 size_t subtree_size = cxTreeSubtreeSize(tree, node); |
938 size_t subtree_size = cxTreeSubtreeSize(tree, node); |
957 cx_tree_unlink(node, cx_tree_node_layout(tree)); |
939 cx_tree_unlink(node, cx_tree_node_layout(tree)); |
958 tree->size -= subtree_size; |
940 tree->size -= subtree_size; |
959 } |
941 } |
|
942 |
|
943 int cxTreeDestroyNode( |
|
944 CxTree *tree, |
|
945 void *node, |
|
946 cx_tree_relink_func relink_func |
|
947 ) { |
|
948 int result = cxTreeRemoveNode(tree, node, relink_func); |
|
949 if (result == 0) { |
|
950 if (tree->simple_destructor) { |
|
951 tree->simple_destructor(node); |
|
952 } |
|
953 if (tree->advanced_destructor) { |
|
954 tree->advanced_destructor(tree->destructor_data, node); |
|
955 } |
|
956 return 0; |
|
957 } else { |
|
958 return result; |
|
959 } |
|
960 } |
|
961 |
|
962 void cxTreeDestroySubtree(CxTree *tree, void *node) { |
|
963 cx_tree_unlink(node, cx_tree_node_layout(tree)); |
|
964 CxTreeIterator iter = cx_tree_iterator( |
|
965 node, true, |
|
966 tree->loc_children, tree->loc_next |
|
967 ); |
|
968 cx_foreach(void *, child, iter) { |
|
969 if (iter.exiting) { |
|
970 if (tree->simple_destructor) { |
|
971 tree->simple_destructor(child); |
|
972 } |
|
973 if (tree->advanced_destructor) { |
|
974 tree->advanced_destructor(tree->destructor_data, child); |
|
975 } |
|
976 } |
|
977 } |
|
978 tree->size -= iter.counter; |
|
979 if (node == tree->root) { |
|
980 tree->root = NULL; |
|
981 } |
|
982 } |