62 ptrdiff_t loc_advance, |
62 ptrdiff_t loc_advance, |
63 ptrdiff_t loc_data, |
63 ptrdiff_t loc_data, |
64 cx_compare_func cmp_func, |
64 cx_compare_func cmp_func, |
65 void const *elem |
65 void const *elem |
66 ) { |
66 ) { |
|
67 void *dummy; |
|
68 return cx_linked_list_find_node( |
|
69 &dummy, start, |
|
70 loc_advance, loc_data, |
|
71 cmp_func, elem |
|
72 ); |
|
73 } |
|
74 |
|
75 ssize_t cx_linked_list_find_node( |
|
76 void **result, |
|
77 void const *start, |
|
78 ptrdiff_t loc_advance, |
|
79 ptrdiff_t loc_data, |
|
80 cx_compare_func cmp_func, |
|
81 void const *elem |
|
82 ) { |
|
83 assert(result != NULL); |
67 assert(start != NULL); |
84 assert(start != NULL); |
68 assert(loc_advance >= 0); |
85 assert(loc_advance >= 0); |
69 assert(loc_data >= 0); |
86 assert(loc_data >= 0); |
70 assert(cmp_func); |
87 assert(cmp_func); |
71 |
88 |
72 void const *node = start; |
89 void const *node = start; |
73 ssize_t index = 0; |
90 ssize_t index = 0; |
74 do { |
91 do { |
75 void *current = ll_data(node); |
92 void *current = ll_data(node); |
76 if (cmp_func(current, elem) == 0) { |
93 if (cmp_func(current, elem) == 0) { |
|
94 *result = (void*) node; |
77 return index; |
95 return index; |
78 } |
96 } |
79 node = ll_advance(node); |
97 node = ll_advance(node); |
80 index++; |
98 index++; |
81 } while (node != NULL); |
99 } while (node != NULL); |
|
100 *result = NULL; |
82 return -1; |
101 return -1; |
83 } |
102 } |
84 |
103 |
85 void *cx_linked_list_first( |
104 void *cx_linked_list_first( |
86 void const *node, |
105 void const *node, |
734 cx_linked_list *ll = (cx_linked_list *) list; |
753 cx_linked_list *ll = (cx_linked_list *) list; |
735 cx_linked_list_node *node = cx_ll_node_at(ll, index); |
754 cx_linked_list_node *node = cx_ll_node_at(ll, index); |
736 return node == NULL ? NULL : node->payload; |
755 return node == NULL ? NULL : node->payload; |
737 } |
756 } |
738 |
757 |
739 static ssize_t cx_ll_find( |
758 static ssize_t cx_ll_find_remove( |
740 struct cx_list_s const *list, |
759 struct cx_list_s *list, |
741 void const *elem |
760 void const *elem, |
742 ) { |
761 bool remove |
743 return cx_linked_list_find(((cx_linked_list *) list)->begin, |
762 ) { |
744 CX_LL_LOC_NEXT, CX_LL_LOC_DATA, |
763 if (remove) { |
745 list->cmpfunc, elem); |
764 cx_linked_list *ll = ((cx_linked_list *) list); |
|
765 cx_linked_list_node *node; |
|
766 ssize_t index = cx_linked_list_find_node( |
|
767 (void **) &node, |
|
768 ll->begin, |
|
769 CX_LL_LOC_NEXT, CX_LL_LOC_DATA, |
|
770 list->cmpfunc, elem |
|
771 ); |
|
772 if (node != NULL) { |
|
773 cx_invoke_destructor(list, node->payload); |
|
774 cx_linked_list_remove((void **) &ll->begin, (void **) &ll->end, |
|
775 CX_LL_LOC_PREV, CX_LL_LOC_NEXT, node); |
|
776 list->size--; |
|
777 cxFree(list->allocator, node); |
|
778 } |
|
779 return index; |
|
780 } else { |
|
781 return cx_linked_list_find( |
|
782 ((cx_linked_list *) list)->begin, |
|
783 CX_LL_LOC_NEXT, CX_LL_LOC_DATA, |
|
784 list->cmpfunc, elem |
|
785 ); |
|
786 } |
746 } |
787 } |
747 |
788 |
748 static void cx_ll_sort(struct cx_list_s *list) { |
789 static void cx_ll_sort(struct cx_list_s *list) { |
749 cx_linked_list *ll = (cx_linked_list *) list; |
790 cx_linked_list *ll = (cx_linked_list *) list; |
750 cx_linked_list_sort((void **) &ll->begin, (void **) &ll->end, |
791 cx_linked_list_sort((void **) &ll->begin, (void **) &ll->end, |