731 int prepend |
731 int prepend |
732 ) { |
732 ) { |
733 return cx_ll_insert_iter(iter, &elem, prepend); |
733 return cx_ll_insert_iter(iter, &elem, prepend); |
734 } |
734 } |
735 |
735 |
|
736 static void cx_ll_destructor(CxList *list) { |
|
737 cx_linked_list *ll = (cx_linked_list *) list; |
|
738 |
|
739 cx_linked_list_node *node = ll->begin; |
|
740 while (node) { |
|
741 void *next = node->next; |
|
742 cxFree(list->allocator, node); |
|
743 node = next; |
|
744 } |
|
745 // do not free the list pointer, this is just a destructor! |
|
746 } |
|
747 |
736 static cx_list_class cx_linked_list_class = { |
748 static cx_list_class cx_linked_list_class = { |
|
749 cx_ll_destructor, |
737 cx_ll_add, |
750 cx_ll_add, |
738 cx_ll_insert, |
751 cx_ll_insert, |
739 cx_ll_insert_iter, |
752 cx_ll_insert_iter, |
740 cx_ll_remove, |
753 cx_ll_remove, |
741 cx_ll_at, |
754 cx_ll_at, |
757 cx_pll_compare, |
771 cx_pll_compare, |
758 cx_ll_reverse, |
772 cx_ll_reverse, |
759 cx_pll_iterator, |
773 cx_pll_iterator, |
760 }; |
774 }; |
761 |
775 |
762 static CxList *cx_ll_default_destructor(CxList *list) { |
|
763 cx_linked_list *ll = (cx_linked_list *) list; |
|
764 |
|
765 cx_linked_list_node *node = ll->begin; |
|
766 while (node) { |
|
767 void *next = node->next; |
|
768 cxFree(list->allocator, node); |
|
769 node = next; |
|
770 } |
|
771 |
|
772 cxFree(list->allocator, list); |
|
773 return NULL; |
|
774 } |
|
775 |
|
776 CxList *cxLinkedListCreate( |
776 CxList *cxLinkedListCreate( |
777 CxAllocator const *allocator, |
777 CxAllocator const *allocator, |
778 CxListComparator comparator, |
778 CxListComparator comparator, |
779 size_t item_size |
779 size_t item_size |
780 ) { |
780 ) { |
782 if (list == NULL) |
782 if (list == NULL) |
783 return NULL; |
783 return NULL; |
784 |
784 |
785 list->base.cl = &cx_linked_list_class; |
785 list->base.cl = &cx_linked_list_class; |
786 list->base.allocator = allocator; |
786 list->base.allocator = allocator; |
787 list->base.list_destructor = (cx_destructor_func) cx_ll_default_destructor; |
|
788 list->base.cmpfunc = comparator; |
787 list->base.cmpfunc = comparator; |
789 list->base.itemsize = item_size; |
788 list->base.itemsize = item_size; |
790 list->base.capacity = SIZE_MAX; |
789 list->base.capacity = SIZE_MAX; |
791 |
790 |
792 return (CxList *) list; |
791 return (CxList *) list; |
800 if (list == NULL) |
799 if (list == NULL) |
801 return NULL; |
800 return NULL; |
802 |
801 |
803 list->base.cl = &cx_pointer_linked_list_class; |
802 list->base.cl = &cx_pointer_linked_list_class; |
804 list->base.allocator = allocator; |
803 list->base.allocator = allocator; |
805 list->base.list_destructor = (cx_destructor_func) cx_ll_default_destructor; |
|
806 list->base.cmpfunc = comparator; |
804 list->base.cmpfunc = comparator; |
807 list->base.itemsize = sizeof(void *); |
805 list->base.itemsize = sizeof(void *); |
808 list->base.capacity = SIZE_MAX; |
806 list->base.capacity = SIZE_MAX; |
809 |
807 |
810 return (CxList *) list; |
808 return (CxList *) list; |
819 ) { |
817 ) { |
820 CxList *list = cxLinkedListCreate(allocator, comparator, item_size); |
818 CxList *list = cxLinkedListCreate(allocator, comparator, item_size); |
821 if (list == NULL) return NULL; |
819 if (list == NULL) return NULL; |
822 cx_for_n (i, num_items) { |
820 cx_for_n (i, num_items) { |
823 if (0 != cxListAdd(list, ((const unsigned char *) array) + i * item_size)) { |
821 if (0 != cxListAdd(list, ((const unsigned char *) array) + i * item_size)) { |
824 return cx_ll_default_destructor(list); |
822 cx_ll_destructor(list); |
|
823 cxFree(allocator, list); |
|
824 return NULL; |
825 } |
825 } |
826 } |
826 } |
827 return list; |
827 return list; |
828 } |
828 } |