665 loc_parent, loc_children, loc_last_child, |
665 loc_parent, loc_children, loc_last_child, |
666 loc_prev, loc_next); |
666 loc_prev, loc_next); |
667 } |
667 } |
668 |
668 |
669 static void cx_tree_default_destructor(CxTree *tree) { |
669 static void cx_tree_default_destructor(CxTree *tree) { |
670 // TODO: destroy the nodes |
670 if (tree->simple_destructor != NULL || tree->advanced_destructor != NULL) { |
|
671 CxTreeIterator iter = tree->cl->iterator(tree, true); |
|
672 cx_foreach(void *, node, iter) { |
|
673 if (iter.exiting) { |
|
674 if (tree->simple_destructor) { |
|
675 tree->simple_destructor(node); |
|
676 } |
|
677 if (tree->advanced_destructor) { |
|
678 tree->advanced_destructor(tree->destructor_data, node); |
|
679 } |
|
680 } |
|
681 } |
|
682 } |
671 cxFree(tree->allocator, tree); |
683 cxFree(tree->allocator, tree); |
672 } |
684 } |
673 |
685 |
674 static CxTreeIterator cx_tree_default_iterator( |
686 static CxTreeIterator cx_tree_default_iterator( |
675 CxTree *tree, |
687 CxTree *tree, |
683 |
695 |
684 static CxTreeVisitor cx_tree_default_visitor(CxTree *tree) { |
696 static CxTreeVisitor cx_tree_default_visitor(CxTree *tree) { |
685 return cx_tree_visitor(tree->root, tree->loc_children, tree->loc_next); |
697 return cx_tree_visitor(tree->root, tree->loc_children, tree->loc_next); |
686 } |
698 } |
687 |
699 |
|
700 static int cx_tree_default_insert_element( |
|
701 CxTree *tree, |
|
702 const void *data |
|
703 ) { |
|
704 void *node; |
|
705 if (tree->root == NULL) { |
|
706 node = tree->node_create(data, tree); |
|
707 if (node == NULL) return 1; |
|
708 cx_tree_zero_pointers(node, cx_tree_node_layout(tree)); |
|
709 tree->root = node; |
|
710 tree->size = 1; |
|
711 return 0; |
|
712 } |
|
713 int result = cx_tree_add(data, tree->search, tree->node_create, |
|
714 tree, &node, tree->root, cx_tree_node_layout(tree)); |
|
715 if (0 == result) { |
|
716 tree->size++; |
|
717 } else { |
|
718 cxFree(tree->allocator, node); |
|
719 } |
|
720 return result; |
|
721 } |
|
722 |
|
723 static size_t cx_tree_default_insert_many( |
|
724 CxTree *tree, |
|
725 struct cx_iterator_base_s *iter, |
|
726 size_t n |
|
727 ) { |
|
728 size_t ins = 0; |
|
729 if (!iter->valid(iter)) return 0; |
|
730 if (tree->root == NULL) { |
|
731 // use the first element from the iter to create the root node |
|
732 void **eptr = iter->current(iter); |
|
733 void *node = tree->node_create(*eptr, tree); |
|
734 if (node == NULL) return 0; |
|
735 cx_tree_zero_pointers(node, cx_tree_node_layout(tree)); |
|
736 tree->root = node; |
|
737 ins = 1; |
|
738 iter->next(iter); |
|
739 } |
|
740 void *failed; |
|
741 ins += cx_tree_add_iter(iter, n, tree->search, tree->node_create, |
|
742 tree, &failed, tree->root, cx_tree_node_layout(tree)); |
|
743 tree->size += ins; |
|
744 if (ins < n) { |
|
745 cxFree(tree->allocator, failed); |
|
746 } |
|
747 return ins; |
|
748 } |
|
749 |
688 static cx_tree_class cx_tree_default_class = { |
750 static cx_tree_class cx_tree_default_class = { |
689 cx_tree_default_destructor, |
751 cx_tree_default_destructor, |
690 NULL, |
752 cx_tree_default_insert_element, |
691 NULL, |
753 cx_tree_default_insert_many, |
692 NULL, |
754 NULL, |
693 cx_tree_default_iterator, |
755 cx_tree_default_iterator, |
694 cx_tree_default_visitor |
756 cx_tree_default_visitor |
695 }; |
757 }; |
696 |
758 |