src/linked_list.c

changeset 664
af5bf4603a5d
parent 662
d0d95740071b
child 666
b5dd654deb3b
equal deleted inserted replaced
663:d50b5dc1e058 664:af5bf4603a5d
567 cx_linked_list_node *node = cx_ll_node_at(ll, index); 567 cx_linked_list_node *node = cx_ll_node_at(ll, index);
568 568
569 // out-of-bounds check 569 // out-of-bounds check
570 if (node == NULL) return 1; 570 if (node == NULL) return 1;
571 571
572 // element destruction
573 if (list->content_destructor_type != CX_DESTRUCTOR_NONE) {
574 cx_list_invoke_destructor(list, node->payload);
575 }
576
572 // remove 577 // remove
573 cx_linked_list_remove((void **) &ll->begin, (void **) &ll->end, 578 cx_linked_list_remove((void **) &ll->begin, (void **) &ll->end,
574 CX_LL_LOC_PREV, CX_LL_LOC_NEXT, node); 579 CX_LL_LOC_PREV, CX_LL_LOC_NEXT, node);
575 580
576 // adjust size 581 // adjust size
578 583
579 // free and return 584 // free and return
580 cxFree(list->allocator, node); 585 cxFree(list->allocator, node);
581 586
582 return 0; 587 return 0;
588 }
589
590 static void cx_ll_clear(struct cx_list_s *list) {
591 if (list->size == 0) return;
592
593 cx_linked_list *ll = (cx_linked_list *) list;
594 cx_linked_list_node *node = ll->begin;
595
596 // looks super redundant, but avoids repeatedly checking
597 // the destructor type for each element
598 switch (list->content_destructor_type) {
599 case CX_DESTRUCTOR_SIMPLE: {
600 while (node != NULL) {
601 list->simple_destructor(node->payload);
602 cx_linked_list_node *next = node->next;
603 cxFree(list->allocator, node);
604 node = next;
605 }
606 break;
607 }
608 case CX_DESTRUCTOR_ADVANCED: {
609 while (node != NULL) {
610 list->advanced_destructor.func(list->advanced_destructor.data,
611 node->payload);
612 cx_linked_list_node *next = node->next;
613 cxFree(list->allocator, node);
614 node = next;
615 }
616 break;
617 }
618 case CX_DESTRUCTOR_NONE: {
619 while (node != NULL) {
620 cx_linked_list_node *next = node->next;
621 cxFree(list->allocator, node);
622 node = next;
623 }
624 break;
625 }
626 }
627
628 ll->begin = ll->end = NULL;
629 list->size = 0;
583 } 630 }
584 631
585 #ifndef CX_LINKED_LIST_SWAP_SBO_SIZE 632 #ifndef CX_LINKED_LIST_SWAP_SBO_SIZE
586 #define CX_LINKED_LIST_SWAP_SBO_SIZE 16 633 #define CX_LINKED_LIST_SWAP_SBO_SIZE 16
587 #endif 634 #endif
751 static void cx_ll_iter_next(void *it) { 798 static void cx_ll_iter_next(void *it) {
752 struct cx_iterator_base_s *itbase = it; 799 struct cx_iterator_base_s *itbase = it;
753 if (itbase->remove) { 800 if (itbase->remove) {
754 itbase->remove = false; 801 itbase->remove = false;
755 struct cx_mut_iterator_s *iter = it; 802 struct cx_mut_iterator_s *iter = it;
803 struct cx_list_s *list = iter->src_handle;
756 cx_linked_list *ll = iter->src_handle; 804 cx_linked_list *ll = iter->src_handle;
757 cx_linked_list_node *node = iter->elem_handle; 805 cx_linked_list_node *node = iter->elem_handle;
758 iter->elem_handle = node->next; 806 iter->elem_handle = node->next;
807 if (list->content_destructor_type != CX_DESTRUCTOR_NONE) {
808 cx_list_invoke_destructor(list, node->payload);
809 }
759 cx_linked_list_remove((void **) &ll->begin, (void **) &ll->end, 810 cx_linked_list_remove((void **) &ll->begin, (void **) &ll->end,
760 CX_LL_LOC_PREV, CX_LL_LOC_NEXT, node); 811 CX_LL_LOC_PREV, CX_LL_LOC_NEXT, node);
761 ll->base.size--; 812 list->size--;
762 cxFree(ll->base.allocator, node); 813 cxFree(list->allocator, node);
763 } else { 814 } else {
764 struct cx_iterator_s *iter = it; 815 struct cx_iterator_s *iter = it;
765 iter->index++; 816 iter->index++;
766 cx_linked_list_node *node = iter->elem_handle; 817 cx_linked_list_node *node = iter->elem_handle;
767 iter->elem_handle = node->next; 818 iter->elem_handle = node->next;
771 static void cx_ll_iter_prev(void *it) { 822 static void cx_ll_iter_prev(void *it) {
772 struct cx_iterator_base_s *itbase = it; 823 struct cx_iterator_base_s *itbase = it;
773 if (itbase->remove) { 824 if (itbase->remove) {
774 itbase->remove = false; 825 itbase->remove = false;
775 struct cx_mut_iterator_s *iter = it; 826 struct cx_mut_iterator_s *iter = it;
827 struct cx_list_s *list = iter->src_handle;
776 cx_linked_list *ll = iter->src_handle; 828 cx_linked_list *ll = iter->src_handle;
777 cx_linked_list_node *node = iter->elem_handle; 829 cx_linked_list_node *node = iter->elem_handle;
778 iter->elem_handle = node->prev; 830 iter->elem_handle = node->prev;
779 iter->index--; 831 iter->index--;
832 if (list->content_destructor_type != CX_DESTRUCTOR_NONE) {
833 cx_list_invoke_destructor(list, node->payload);
834 }
780 cx_linked_list_remove((void **) &ll->begin, (void **) &ll->end, 835 cx_linked_list_remove((void **) &ll->begin, (void **) &ll->end,
781 CX_LL_LOC_PREV, CX_LL_LOC_NEXT, node); 836 CX_LL_LOC_PREV, CX_LL_LOC_NEXT, node);
782 ll->base.size--; 837 list->size--;
783 cxFree(ll->base.allocator, node); 838 cxFree(list->allocator, node);
784 } else { 839 } else {
785 struct cx_iterator_s *iter = it; 840 struct cx_iterator_s *iter = it;
786 iter->index--; 841 iter->index--;
787 cx_linked_list_node *node = iter->elem_handle; 842 cx_linked_list_node *node = iter->elem_handle;
788 iter->elem_handle = node->prev; 843 iter->elem_handle = node->prev;
859 cx_ll_destructor, 914 cx_ll_destructor,
860 cx_ll_insert_element, 915 cx_ll_insert_element,
861 cx_ll_insert_array, 916 cx_ll_insert_array,
862 cx_ll_insert_iter, 917 cx_ll_insert_iter,
863 cx_ll_remove, 918 cx_ll_remove,
919 cx_ll_clear,
864 cx_ll_swap, 920 cx_ll_swap,
865 cx_ll_at, 921 cx_ll_at,
866 cx_ll_find, 922 cx_ll_find,
867 cx_ll_sort, 923 cx_ll_sort,
868 cx_ll_compare, 924 cx_ll_compare,

mercurial