814 struct cx_iterator_s const *iter = it; |
814 struct cx_iterator_s const *iter = it; |
815 return iter->elem_handle != NULL; |
815 return iter->elem_handle != NULL; |
816 } |
816 } |
817 |
817 |
818 static void cx_ll_iter_next(void *it) { |
818 static void cx_ll_iter_next(void *it) { |
819 struct cx_iterator_base_s *itbase = it; |
819 struct cx_iterator_s *iter = it; |
820 if (itbase->remove) { |
820 if (iter->remove) { |
821 itbase->remove = false; |
821 iter->remove = false; |
822 struct cx_mut_iterator_s *iter = it; |
822 struct cx_list_s *list = iter->src_handle.m; |
823 struct cx_list_s *list = iter->src_handle; |
823 cx_linked_list *ll = iter->src_handle.m; |
824 cx_linked_list *ll = iter->src_handle; |
|
825 cx_linked_list_node *node = iter->elem_handle; |
824 cx_linked_list_node *node = iter->elem_handle; |
826 iter->elem_handle = node->next; |
825 iter->elem_handle = node->next; |
827 cx_invoke_destructor(list, node->payload); |
826 cx_invoke_destructor(list, node->payload); |
828 cx_linked_list_remove((void **) &ll->begin, (void **) &ll->end, |
827 cx_linked_list_remove((void **) &ll->begin, (void **) &ll->end, |
829 CX_LL_LOC_PREV, CX_LL_LOC_NEXT, node); |
828 CX_LL_LOC_PREV, CX_LL_LOC_NEXT, node); |
830 list->size--; |
829 list->size--; |
831 cxFree(list->allocator, node); |
830 cxFree(list->allocator, node); |
832 } else { |
831 } else { |
833 struct cx_iterator_s *iter = it; |
|
834 iter->index++; |
832 iter->index++; |
835 cx_linked_list_node *node = iter->elem_handle; |
833 cx_linked_list_node *node = iter->elem_handle; |
836 iter->elem_handle = node->next; |
834 iter->elem_handle = node->next; |
837 } |
835 } |
838 } |
836 } |
839 |
837 |
840 static void cx_ll_iter_prev(void *it) { |
838 static void cx_ll_iter_prev(void *it) { |
841 struct cx_iterator_base_s *itbase = it; |
839 struct cx_iterator_s *iter = it; |
842 if (itbase->remove) { |
840 if (iter->remove) { |
843 itbase->remove = false; |
841 iter->remove = false; |
844 struct cx_mut_iterator_s *iter = it; |
842 struct cx_list_s *list = iter->src_handle.m; |
845 struct cx_list_s *list = iter->src_handle; |
843 cx_linked_list *ll = iter->src_handle.m; |
846 cx_linked_list *ll = iter->src_handle; |
|
847 cx_linked_list_node *node = iter->elem_handle; |
844 cx_linked_list_node *node = iter->elem_handle; |
848 iter->elem_handle = node->prev; |
845 iter->elem_handle = node->prev; |
849 iter->index--; |
846 iter->index--; |
850 cx_invoke_destructor(list, node->payload); |
847 cx_invoke_destructor(list, node->payload); |
851 cx_linked_list_remove((void **) &ll->begin, (void **) &ll->end, |
848 cx_linked_list_remove((void **) &ll->begin, (void **) &ll->end, |
852 CX_LL_LOC_PREV, CX_LL_LOC_NEXT, node); |
849 CX_LL_LOC_PREV, CX_LL_LOC_NEXT, node); |
853 list->size--; |
850 list->size--; |
854 cxFree(list->allocator, node); |
851 cxFree(list->allocator, node); |
855 } else { |
852 } else { |
856 struct cx_iterator_s *iter = it; |
|
857 iter->index--; |
853 iter->index--; |
858 cx_linked_list_node *node = iter->elem_handle; |
854 cx_linked_list_node *node = iter->elem_handle; |
859 iter->elem_handle = node->prev; |
855 iter->elem_handle = node->prev; |
860 } |
856 } |
861 } |
857 } |
871 size_t index, |
867 size_t index, |
872 bool backwards |
868 bool backwards |
873 ) { |
869 ) { |
874 CxIterator iter; |
870 CxIterator iter; |
875 iter.index = index; |
871 iter.index = index; |
876 iter.src_handle = list; |
872 iter.src_handle.c = list; |
877 iter.elem_handle = cx_ll_node_at((cx_linked_list const *) list, index); |
873 iter.elem_handle = cx_ll_node_at((cx_linked_list const *) list, index); |
878 iter.elem_size = list->item_size; |
874 iter.elem_size = list->item_size; |
879 iter.elem_count = list->size; |
875 iter.elem_count = list->size; |
880 iter.base.valid = cx_ll_iter_valid; |
876 iter.valid = cx_ll_iter_valid; |
881 iter.base.current = cx_ll_iter_current; |
877 iter.current = cx_ll_iter_current; |
882 iter.base.next = backwards ? cx_ll_iter_prev : cx_ll_iter_next; |
878 iter.next = backwards ? cx_ll_iter_prev : cx_ll_iter_next; |
883 iter.base.mutating = false; |
879 iter.mutating = false; |
884 iter.base.remove = false; |
880 iter.remove = false; |
885 return iter; |
881 return iter; |
886 } |
882 } |
887 |
883 |
888 static int cx_ll_insert_iter( |
884 static int cx_ll_insert_iter( |
889 CxMutIterator *iter, |
885 CxIterator *iter, |
890 void const *elem, |
886 void const *elem, |
891 int prepend |
887 int prepend |
892 ) { |
888 ) { |
893 struct cx_list_s *list = iter->src_handle; |
889 struct cx_list_s *list = iter->src_handle.m; |
894 cx_linked_list_node *node = iter->elem_handle; |
890 cx_linked_list_node *node = iter->elem_handle; |
895 if (node != NULL) { |
891 if (node != NULL) { |
896 assert(prepend >= 0 && prepend <= 1); |
892 assert(prepend >= 0 && prepend <= 1); |
897 cx_linked_list_node *choice[2] = {node, node->prev}; |
893 cx_linked_list_node *choice[2] = {node, node->prev}; |
898 int result = cx_ll_insert_at(list, choice[prepend], elem); |
894 int result = cx_ll_insert_at(list, choice[prepend], elem); |