src/tree.c

changeset 902
5ed7f634f046
parent 901
109567325fe7
child 903
a018f5916d3b
equal deleted inserted replaced
901:109567325fe7 902:5ed7f634f046
664 cfunc, cdata, failed, root, 664 cfunc, cdata, failed, root,
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) {
670 // TODO: destroy the nodes
671 cxFree(tree->allocator, tree);
672 }
673
674 static CxTreeIterator cx_tree_default_iterator(
675 CxTree *tree,
676 bool visit_on_exit
677 ) {
678 return cx_tree_iterator(
679 tree->root, visit_on_exit,
680 tree->loc_children, tree->loc_next
681 );
682 }
683
684 static CxTreeVisitor cx_tree_default_visitor(CxTree *tree) {
685 return cx_tree_visitor(tree->root, tree->loc_children, tree->loc_next);
686 }
687
688 static cx_tree_class cx_tree_default_class = {
689 cx_tree_default_destructor,
690 NULL,
691 NULL,
692 NULL,
693 cx_tree_default_iterator,
694 cx_tree_default_visitor
695 };
696
697 CxTree *cxTreeCreate(
698 const CxAllocator *allocator,
699 cx_tree_node_create_func create_func,
700 cx_tree_search_func search_func,
701 ptrdiff_t loc_parent,
702 ptrdiff_t loc_children,
703 ptrdiff_t loc_last_child,
704 ptrdiff_t loc_prev,
705 ptrdiff_t loc_next
706 ) {
707 CxTree *tree = cxMalloc(allocator, sizeof(CxTree));
708 if (tree == NULL) return NULL;
709
710 tree->cl = &cx_tree_default_class;
711 tree->allocator = allocator;
712 tree->node_create = create_func;
713 tree->search = search_func;
714 tree->advanced_destructor = (cx_destructor_func2) cxFree;
715 tree->destructor_data = (void *) allocator;
716 tree->loc_parent = loc_parent;
717 tree->loc_children = loc_children;
718 tree->loc_last_child = loc_last_child;
719 tree->loc_prev = loc_prev;
720 tree->loc_next = loc_next;
721 tree->root = NULL;
722 tree->size = 0;
723
724 return tree;
725 }
726
727 CxTree *cxTreeCreateWrapped(
728 void *root,
729 ptrdiff_t loc_parent,
730 ptrdiff_t loc_children,
731 ptrdiff_t loc_last_child,
732 ptrdiff_t loc_prev,
733 ptrdiff_t loc_next
734 ) {
735 CxTree *tree = malloc(sizeof(CxTree));
736 if (tree == NULL) return NULL;
737
738 tree->cl = &cx_tree_default_class;
739 // set the allocator anyway, just in case...
740 tree->allocator = cxDefaultAllocator;
741 tree->node_create = NULL;
742 tree->search = NULL;
743 tree->advanced_destructor = NULL;
744 tree->destructor_data = NULL;
745 tree->loc_parent = loc_parent;
746 tree->loc_children = loc_children;
747 tree->loc_last_child = loc_last_child;
748 tree->loc_prev = loc_prev;
749 tree->loc_next = loc_next;
750 tree->root = root;
751 tree->size = cxTreeSubtreeSize(tree, root);
752 return tree;
753 }
669 754
670 int cxTreeAddChild( 755 int cxTreeAddChild(
671 CxTree *tree, 756 CxTree *tree,
672 void *parent, 757 void *parent,
673 const void *data) { 758 const void *data) {
676 cx_tree_zero_pointers(node, cx_tree_node_layout(tree)); 761 cx_tree_zero_pointers(node, cx_tree_node_layout(tree));
677 cx_tree_link(parent, node, cx_tree_node_layout(tree)); 762 cx_tree_link(parent, node, cx_tree_node_layout(tree));
678 tree->size++; 763 tree->size++;
679 return 0; 764 return 0;
680 } 765 }
766
767 size_t cxTreeSubtreeSize(CxTree *tree, void *subtree_root) {
768 CxTreeVisitor visitor = cx_tree_visitor(
769 subtree_root,
770 tree->loc_children,
771 tree->loc_next
772 );
773 while (cxIteratorValid(visitor)) {
774 cxIteratorNext(visitor);
775 }
776 return visitor.counter;
777 }

mercurial