src/linked_list.c

changeset 630
ac5e7f789048
parent 629
6c81ee4f11ad
child 638
eafb45eefc51
equal deleted inserted replaced
629:6c81ee4f11ad 630:ac5e7f789048
641 return cx_linked_list_compare(left->begin, right->begin, 641 return cx_linked_list_compare(left->begin, right->begin,
642 CX_LL_LOC_NEXT, CX_LL_LOC_DATA, 642 CX_LL_LOC_NEXT, CX_LL_LOC_DATA,
643 left->follow_ptr, right->follow_ptr, list->cmpfunc); 643 left->follow_ptr, right->follow_ptr, list->cmpfunc);
644 } 644 }
645 645
646 static bool cx_ll_iter_valid(CxIterator const *iter) { 646 static bool cx_ll_iter_valid(void const *it) {
647 struct cx_iterator_s const *iter = it;
647 return iter->elem_handle != NULL; 648 return iter->elem_handle != NULL;
648 } 649 }
649 650
650 static void cx_ll_iter_next(CxIterator *iter) { 651 static void cx_ll_iter_next(void *it) {
651 if (iter->remove) { 652 struct cx_iterator_base_s *itbase = it;
652 iter->remove = false; 653 if (itbase->remove) {
654 itbase->remove = false;
655 struct cx_mut_iterator_s *iter = it;
653 cx_linked_list *ll = iter->src_handle; 656 cx_linked_list *ll = iter->src_handle;
654 cx_linked_list_node *node = iter->elem_handle; 657 cx_linked_list_node *node = iter->elem_handle;
655 iter->elem_handle = node->next; 658 iter->elem_handle = node->next;
656 cx_linked_list_remove((void **) &ll->begin, (void **) &ll->end, 659 cx_linked_list_remove((void **) &ll->begin, (void **) &ll->end,
657 CX_LL_LOC_PREV, CX_LL_LOC_NEXT, node); 660 CX_LL_LOC_PREV, CX_LL_LOC_NEXT, node);
658 ll->base.size--; 661 ll->base.size--;
659 cxFree(ll->base.allocator, node); 662 cxFree(ll->base.allocator, node);
660 } else { 663 } else {
664 struct cx_iterator_s *iter = it;
661 iter->index++; 665 iter->index++;
662 cx_linked_list_node *node = iter->elem_handle; 666 cx_linked_list_node *node = iter->elem_handle;
663 iter->elem_handle = node->next; 667 iter->elem_handle = node->next;
664 } 668 }
665 } 669 }
666 670
667 static void *cx_ll_iter_current(CxIterator const *iter) { 671 static void *cx_ll_iter_current(void const *it) {
672 struct cx_iterator_s const *iter = it;
668 cx_linked_list_node *node = iter->elem_handle; 673 cx_linked_list_node *node = iter->elem_handle;
669 return node->payload; 674 return node->payload;
670 } 675 }
671 676
672 static void *cx_pll_iter_current(CxIterator const *iter) { 677 static void *cx_pll_iter_current(void const *it) {
678 struct cx_iterator_s const *iter = it;
673 cx_linked_list_node *node = iter->elem_handle; 679 cx_linked_list_node *node = iter->elem_handle;
674 return *(void **) node->payload; 680 return *(void **) node->payload;
675 } 681 }
676 682
683 static bool cx_ll_iter_flag_rm(void *it) {
684 struct cx_iterator_base_s *iter = it;
685 if (iter->mutating) {
686 iter->remove = true;
687 return true;
688 } else {
689 return false;
690 }
691 }
692
677 static CxIterator cx_ll_iterator( 693 static CxIterator cx_ll_iterator(
678 struct cx_list_s *list, 694 struct cx_list_s const *list,
679 size_t index 695 size_t index
680 ) { 696 ) {
681 CxIterator iter; 697 CxIterator iter;
682 iter.index = index; 698 iter.index = index;
683 iter.src_handle = list; 699 iter.src_handle = list;
684 iter.elem_handle = cx_ll_node_at((cx_linked_list const *) list, index); 700 iter.elem_handle = cx_ll_node_at((cx_linked_list const *) list, index);
685 iter.valid = cx_ll_iter_valid; 701 iter.base.valid = cx_ll_iter_valid;
686 iter.current = cx_ll_iter_current; 702 iter.base.current = cx_ll_iter_current;
687 iter.next = cx_ll_iter_next; 703 iter.base.next = cx_ll_iter_next;
688 iter.remove = false; 704 iter.base.flag_removal = cx_ll_iter_flag_rm;
705 iter.base.mutating = false;
706 iter.base.remove = false;
689 return iter; 707 return iter;
690 } 708 }
691 709
692 static CxIterator cx_pll_iterator( 710 static CxIterator cx_pll_iterator(
711 struct cx_list_s const *list,
712 size_t index
713 ) {
714 CxIterator iter = cx_ll_iterator(list, index);
715 iter.base.current = cx_pll_iter_current;
716 return iter;
717 }
718
719 static CxMutIterator cx_ll_mut_iterator(
693 struct cx_list_s *list, 720 struct cx_list_s *list,
694 size_t index 721 size_t index
695 ) { 722 ) {
696 CxIterator iter = cx_ll_iterator(list, index); 723 CxIterator it = cx_ll_iterator(list, index);
697 iter.current = cx_pll_iter_current; 724 it.base.mutating = true;
725
726 // we know the iterators share the same memory layout
727 CxMutIterator iter;
728 memcpy(&iter, &it, sizeof(CxMutIterator));
698 return iter; 729 return iter;
699 } 730 }
700 731
732 static CxMutIterator cx_pll_mut_iterator(
733 struct cx_list_s *list,
734 size_t index
735 ) {
736 CxMutIterator iter = cx_ll_mut_iterator(list, index);
737 iter.base.current = cx_pll_iter_current;
738 return iter;
739 }
740
701 static int cx_ll_insert_iter( 741 static int cx_ll_insert_iter(
702 CxIterator *iter, 742 CxMutIterator *iter,
703 void const *elem, 743 void const *elem,
704 int prepend 744 int prepend
705 ) { 745 ) {
706 struct cx_list_s *list = iter->src_handle; 746 struct cx_list_s *list = iter->src_handle;
707 cx_linked_list_node *node = iter->elem_handle; 747 cx_linked_list_node *node = iter->elem_handle;
717 return result; 757 return result;
718 } 758 }
719 } 759 }
720 760
721 static int cx_pll_insert_iter( 761 static int cx_pll_insert_iter(
722 CxIterator *iter, 762 CxMutIterator *iter,
723 void const *elem, 763 void const *elem,
724 int prepend 764 int prepend
725 ) { 765 ) {
726 return cx_ll_insert_iter(iter, &elem, prepend); 766 return cx_ll_insert_iter(iter, &elem, prepend);
727 } 767 }
748 cx_ll_at, 788 cx_ll_at,
749 cx_ll_find, 789 cx_ll_find,
750 cx_ll_sort, 790 cx_ll_sort,
751 cx_ll_compare, 791 cx_ll_compare,
752 cx_ll_reverse, 792 cx_ll_reverse,
753 cx_ll_iterator 793 cx_ll_iterator,
794 cx_ll_mut_iterator,
754 }; 795 };
755 796
756 static cx_list_class cx_pointer_linked_list_class = { 797 static cx_list_class cx_pointer_linked_list_class = {
757 cx_ll_destructor, 798 cx_ll_destructor,
758 cx_pll_add, 799 cx_pll_add,
764 cx_ll_find, 805 cx_ll_find,
765 cx_ll_sort, 806 cx_ll_sort,
766 cx_ll_compare, 807 cx_ll_compare,
767 cx_ll_reverse, 808 cx_ll_reverse,
768 cx_pll_iterator, 809 cx_pll_iterator,
810 cx_pll_mut_iterator,
769 }; 811 };
770 812
771 CxList *cxLinkedListCreate( 813 CxList *cxLinkedListCreate(
772 CxAllocator const *allocator, 814 CxAllocator const *allocator,
773 CxListComparator comparator, 815 CxListComparator comparator,

mercurial