544 node = node->next; |
544 node = node->next; |
545 } |
545 } |
546 return n; |
546 return n; |
547 } |
547 } |
548 |
548 |
549 static int cx_ll_insert( |
|
550 struct cx_list_s *list, |
|
551 size_t index, |
|
552 void const *elem |
|
553 ) { |
|
554 return cx_ll_insert_array(list, index, elem, 1) != 1; |
|
555 } |
|
556 |
|
557 static int cx_ll_add( |
|
558 struct cx_list_s *list, |
|
559 void const *elem |
|
560 ) { |
|
561 return cx_ll_insert(list, list->size, elem); |
|
562 } |
|
563 |
|
564 static size_t cx_ll_add_array( |
|
565 struct cx_list_s *list, |
|
566 void const *array, |
|
567 size_t n |
|
568 ) { |
|
569 return cx_ll_insert_array(list, list->size, array, n); |
|
570 } |
|
571 |
|
572 static int cx_ll_remove( |
549 static int cx_ll_remove( |
573 struct cx_list_s *list, |
550 struct cx_list_s *list, |
574 size_t index |
551 size_t index |
575 ) { |
552 ) { |
576 cx_linked_list *ll = (cx_linked_list *) list; |
553 cx_linked_list *ll = (cx_linked_list *) list; |
689 iter.base.mutating = false; |
666 iter.base.mutating = false; |
690 iter.base.remove = false; |
667 iter.base.remove = false; |
691 return iter; |
668 return iter; |
692 } |
669 } |
693 |
670 |
694 static CxMutIterator cx_ll_mut_iterator( |
|
695 struct cx_list_s *list, |
|
696 size_t index |
|
697 ) { |
|
698 CxIterator it = cx_ll_iterator(list, index); |
|
699 it.base.mutating = true; |
|
700 |
|
701 // we know the iterators share the same memory layout |
|
702 CxMutIterator iter; |
|
703 memcpy(&iter, &it, sizeof(CxMutIterator)); |
|
704 return iter; |
|
705 } |
|
706 |
|
707 static int cx_ll_insert_iter( |
671 static int cx_ll_insert_iter( |
708 CxMutIterator *iter, |
672 CxMutIterator *iter, |
709 void const *elem, |
673 void const *elem, |
710 int prepend |
674 int prepend |
711 ) { |
675 ) { |
716 cx_linked_list_node *choice[2] = {node, node->prev}; |
680 cx_linked_list_node *choice[2] = {node, node->prev}; |
717 int result = cx_ll_insert_at(list, choice[prepend], elem); |
681 int result = cx_ll_insert_at(list, choice[prepend], elem); |
718 iter->index += prepend * (0 == result); |
682 iter->index += prepend * (0 == result); |
719 return result; |
683 return result; |
720 } else { |
684 } else { |
721 int result = cx_ll_insert(list, list->size, elem); |
685 int result = cx_ll_insert_array(list, list->size, elem, 1) != 1; |
722 iter->index = list->size; |
686 iter->index = list->size; |
723 return result; |
687 return result; |
724 } |
688 } |
725 } |
689 } |
726 |
690 |
736 // do not free the list pointer, this is just a destructor! |
700 // do not free the list pointer, this is just a destructor! |
737 } |
701 } |
738 |
702 |
739 static cx_list_class cx_linked_list_class = { |
703 static cx_list_class cx_linked_list_class = { |
740 cx_ll_destructor, |
704 cx_ll_destructor, |
741 cx_ll_add, |
|
742 cx_ll_add_array, |
|
743 cx_ll_insert, |
|
744 cx_ll_insert_array, |
705 cx_ll_insert_array, |
745 cx_ll_insert_iter, |
706 cx_ll_insert_iter, |
746 cx_ll_remove, |
707 cx_ll_remove, |
747 cx_ll_at, |
708 cx_ll_at, |
748 cx_ll_find, |
709 cx_ll_find, |
749 cx_ll_sort, |
710 cx_ll_sort, |
750 cx_ll_compare, |
711 cx_ll_compare, |
751 cx_ll_reverse, |
712 cx_ll_reverse, |
752 cx_ll_iterator, |
713 cx_ll_iterator, |
753 cx_ll_mut_iterator, |
|
754 }; |
714 }; |
755 |
715 |
756 CxList *cxLinkedListCreate( |
716 CxList *cxLinkedListCreate( |
757 CxAllocator const *allocator, |
717 CxAllocator const *allocator, |
758 CxListComparator comparator, |
718 CxListComparator comparator, |