52 cx_destructor_func map_destr; |
52 cx_destructor_func map_destr; |
53 cx_destructor_func2 map_destr2; |
53 cx_destructor_func2 map_destr2; |
54 void *map_destr_data; |
54 void *map_destr_data; |
55 }; |
55 }; |
56 |
56 |
57 static void cx_kv_list_destructor_wrapper_list(void *list_ptr, void *elem) { |
57 static void cx_kv_list_destructor_wrapper(void *list_ptr, void *elem) { |
58 const cx_kv_list *kv_list = list_ptr; |
58 const cx_kv_list *kv_list = list_ptr; |
59 // list destructor is already called with proper deref of the elem |
59 // list destructor is already called with proper deref of the elem |
60 if (kv_list->list_destr) { |
60 if (kv_list->list_destr) { |
61 kv_list->list_destr(elem); |
61 kv_list->list_destr(elem); |
62 } |
62 } |
76 // an own destructor function which invokes all these |
76 // an own destructor function which invokes all these |
77 if (list->list.base.collection.simple_destructor != NULL) { |
77 if (list->list.base.collection.simple_destructor != NULL) { |
78 list->list_destr = list->list.base.collection.simple_destructor; |
78 list->list_destr = list->list.base.collection.simple_destructor; |
79 list->list.base.collection.simple_destructor = NULL; |
79 list->list.base.collection.simple_destructor = NULL; |
80 } |
80 } |
81 if (list->list.base.collection.advanced_destructor != cx_kv_list_destructor_wrapper_list) { |
81 if (list->list.base.collection.advanced_destructor != cx_kv_list_destructor_wrapper) { |
82 list->list_destr2 = list->list.base.collection.advanced_destructor; |
82 list->list_destr2 = list->list.base.collection.advanced_destructor; |
83 list->list_destr_data = list->list.base.collection.destructor_data; |
83 list->list_destr_data = list->list.base.collection.destructor_data; |
84 list->list.base.collection.advanced_destructor = cx_kv_list_destructor_wrapper_list; |
84 list->list.base.collection.advanced_destructor = cx_kv_list_destructor_wrapper; |
85 list->list.base.collection.destructor_data = list; |
85 list->list.base.collection.destructor_data = list; |
86 } |
86 } |
87 if (list->map->map_base.base.collection.simple_destructor != NULL) { |
87 if (list->map->map_base.base.collection.simple_destructor != NULL) { |
88 list->map_destr = list->map->map_base.base.collection.simple_destructor; |
88 list->map_destr = list->map->map_base.base.collection.simple_destructor; |
89 list->map->map_base.base.collection.simple_destructor = NULL; |
89 list->map->map_base.base.collection.simple_destructor = NULL; |
202 struct cx_list_s *list, |
202 struct cx_list_s *list, |
203 const void *elem, |
203 const void *elem, |
204 bool remove |
204 bool remove |
205 ) { |
205 ) { |
206 cx_kv_list *kv_list = (cx_kv_list*)list; |
206 cx_kv_list *kv_list = (cx_kv_list*)list; |
207 cx_kv_list_update_destructors(kv_list); |
207 // we do not use the original list methods, |
208 // TODO: implement removal of the key in the map |
208 // because that would need two passes for removal |
209 return kv_list->list_methods->find_remove(list, elem, remove); |
209 // (the first to find the index, the second to get a pointer) |
|
210 if (list->collection.size == 0) return 0; |
|
211 |
|
212 size_t index; |
|
213 cx_linked_list *ll = &kv_list->list; |
|
214 char *node = cx_linked_list_find( |
|
215 ll->begin, |
|
216 ll->loc_next, ll->loc_data, |
|
217 list->collection.cmpfunc, elem, |
|
218 &index |
|
219 ); |
|
220 if (node == NULL) { |
|
221 return list->collection.size; |
|
222 } |
|
223 if (remove) { |
|
224 cx_kv_list_update_destructors(kv_list); |
|
225 cx_invoke_advanced_destructor(list, node + ll->loc_data); |
|
226 cx_linked_list_remove(&ll->begin, &ll->end, |
|
227 ll->loc_prev, ll->loc_next, node); |
|
228 CxHashKey *key = cx_kv_list_loc_key(kv_list, node + ll->loc_data); |
|
229 if (key->hash != 0) { |
|
230 kv_list->map_methods->remove(&kv_list->map->map_base.base, *key, NULL); |
|
231 } |
|
232 list->collection.size--; |
|
233 cxFree(list->collection.allocator, node); |
|
234 } |
|
235 return index; |
210 } |
236 } |
211 |
237 |
212 static void cx_kvl_sort(struct cx_list_s *list) { |
238 static void cx_kvl_sort(struct cx_list_s *list) { |
213 cx_kv_list *kv_list = (cx_kv_list*)list; |
239 cx_kv_list *kv_list = (cx_kv_list*)list; |
214 kv_list->list_methods->sort(list); |
240 kv_list->list_methods->sort(list); |