54 i < index ? i++ : i--; |
54 i < index ? i++ : i--; |
55 } |
55 } |
56 return (void *) cur; |
56 return (void *) cur; |
57 } |
57 } |
58 |
58 |
59 ssize_t cx_linked_list_find( |
59 void *cx_linked_list_find( |
60 const void *start, |
60 const void *start, |
61 ptrdiff_t loc_advance, |
61 ptrdiff_t loc_advance, |
62 ptrdiff_t loc_data, |
62 ptrdiff_t loc_data, |
63 cx_compare_func cmp_func, |
63 cx_compare_func cmp_func, |
64 const void *elem |
64 const void *elem, |
65 ) { |
65 size_t *found_index |
66 void *dummy; |
66 ) { |
67 return cx_linked_list_find_node( |
|
68 &dummy, start, |
|
69 loc_advance, loc_data, |
|
70 cmp_func, elem |
|
71 ); |
|
72 } |
|
73 |
|
74 ssize_t cx_linked_list_find_node( |
|
75 void **result, |
|
76 const void *start, |
|
77 ptrdiff_t loc_advance, |
|
78 ptrdiff_t loc_data, |
|
79 cx_compare_func cmp_func, |
|
80 const void *elem |
|
81 ) { |
|
82 assert(result != NULL); |
|
83 assert(start != NULL); |
67 assert(start != NULL); |
84 assert(loc_advance >= 0); |
68 assert(loc_advance >= 0); |
85 assert(loc_data >= 0); |
69 assert(loc_data >= 0); |
86 assert(cmp_func); |
70 assert(cmp_func); |
87 |
71 |
88 const void *node = start; |
72 void *node = (void*) start; |
89 ssize_t index = 0; |
73 size_t index = 0; |
90 do { |
74 do { |
91 void *current = ll_data(node); |
75 void *current = ll_data(node); |
92 if (cmp_func(current, elem) == 0) { |
76 if (cmp_func(current, elem) == 0) { |
93 *result = (void *) node; |
77 if (found_index != NULL) { |
94 return index; |
78 *found_index = index; |
|
79 } |
|
80 return node; |
95 } |
81 } |
96 node = ll_advance(node); |
82 node = ll_advance(node); |
97 index++; |
83 index++; |
98 } while (node != NULL); |
84 } while (node != NULL); |
99 *result = NULL; |
85 return NULL; |
100 return -1; |
|
101 } |
86 } |
102 |
87 |
103 void *cx_linked_list_first( |
88 void *cx_linked_list_first( |
104 const void *node, |
89 const void *node, |
105 ptrdiff_t loc_prev |
90 ptrdiff_t loc_prev |
928 cx_linked_list *ll = (cx_linked_list *) list; |
913 cx_linked_list *ll = (cx_linked_list *) list; |
929 cx_linked_list_node *node = cx_ll_node_at(ll, index); |
914 cx_linked_list_node *node = cx_ll_node_at(ll, index); |
930 return node == NULL ? NULL : node->payload; |
915 return node == NULL ? NULL : node->payload; |
931 } |
916 } |
932 |
917 |
933 static ssize_t cx_ll_find_remove( |
918 static size_t cx_ll_find_remove( |
934 struct cx_list_s *list, |
919 struct cx_list_s *list, |
935 const void *elem, |
920 const void *elem, |
936 bool remove |
921 bool remove |
937 ) { |
922 ) { |
|
923 size_t index; |
|
924 cx_linked_list *ll = ((cx_linked_list *) list); |
|
925 cx_linked_list_node *node = cx_linked_list_find( |
|
926 ll->begin, |
|
927 CX_LL_LOC_NEXT, CX_LL_LOC_DATA, |
|
928 list->collection.cmpfunc, elem, |
|
929 &index |
|
930 ); |
|
931 if (node == NULL) { |
|
932 return list->collection.size; |
|
933 } |
938 if (remove) { |
934 if (remove) { |
939 cx_linked_list *ll = ((cx_linked_list *) list); |
935 cx_invoke_destructor(list, node->payload); |
940 cx_linked_list_node *node; |
936 cx_linked_list_remove((void **) &ll->begin, (void **) &ll->end, |
941 ssize_t index = cx_linked_list_find_node( |
937 CX_LL_LOC_PREV, CX_LL_LOC_NEXT, node); |
942 (void **) &node, |
938 list->collection.size--; |
943 ll->begin, |
939 cxFree(list->collection.allocator, node); |
944 CX_LL_LOC_NEXT, CX_LL_LOC_DATA, |
940 } |
945 list->collection.cmpfunc, elem |
941 return index; |
946 ); |
|
947 if (node != NULL) { |
|
948 cx_invoke_destructor(list, node->payload); |
|
949 cx_linked_list_remove((void **) &ll->begin, (void **) &ll->end, |
|
950 CX_LL_LOC_PREV, CX_LL_LOC_NEXT, node); |
|
951 list->collection.size--; |
|
952 cxFree(list->collection.allocator, node); |
|
953 } |
|
954 return index; |
|
955 } else { |
|
956 return cx_linked_list_find( |
|
957 ((cx_linked_list *) list)->begin, |
|
958 CX_LL_LOC_NEXT, CX_LL_LOC_DATA, |
|
959 list->collection.cmpfunc, elem |
|
960 ); |
|
961 } |
|
962 } |
942 } |
963 |
943 |
964 static void cx_ll_sort(struct cx_list_s *list) { |
944 static void cx_ll_sort(struct cx_list_s *list) { |
965 cx_linked_list *ll = (cx_linked_list *) list; |
945 cx_linked_list *ll = (cx_linked_list *) list; |
966 cx_linked_list_sort((void **) &ll->begin, (void **) &ll->end, |
946 cx_linked_list_sort((void **) &ll->begin, (void **) &ll->end, |