105 } |
105 } |
106 if (list->map->map_base.base.collection.simple_destructor != NULL) { |
106 if (list->map->map_base.base.collection.simple_destructor != NULL) { |
107 list->map_destr = list->map->map_base.base.collection.simple_destructor; |
107 list->map_destr = list->map->map_base.base.collection.simple_destructor; |
108 list->map->map_base.base.collection.simple_destructor = NULL; |
108 list->map->map_base.base.collection.simple_destructor = NULL; |
109 } |
109 } |
110 if (list->map->map_base.base.collection.advanced_destructor != cx_kv_list_destructor_wrapper_map) { |
110 if (list->map->map_base.base.collection.advanced_destructor != NULL) { |
111 list->map_destr2 = list->map->map_base.base.collection.advanced_destructor; |
111 list->map_destr2 = list->map->map_base.base.collection.advanced_destructor; |
112 list->map_destr_data = list->map->map_base.base.collection.destructor_data; |
112 list->map_destr_data = list->map->map_base.base.collection.destructor_data; |
113 list->map->map_base.base.collection.advanced_destructor = cx_kv_list_destructor_wrapper_map; |
113 list->map->map_base.base.collection.advanced_destructor = NULL; |
114 list->map->map_base.base.collection.destructor_data = list; |
114 list->map->map_base.base.collection.destructor_data = NULL; |
115 } |
115 } |
116 } |
116 } |
117 |
117 |
118 static void cx_kvl_deallocate(struct cx_list_s *list) { |
118 static void cx_kvl_deallocate(struct cx_list_s *list) { |
119 cx_kv_list *kv_list = (cx_kv_list*)list; |
119 cx_kv_list *kv_list = (cx_kv_list*)list; |
120 // patch the destructors |
120 // patch the destructors |
121 cx_kv_list_update_destructors(kv_list); |
121 cx_kv_list_update_destructors(kv_list); |
122 // free the map first, but skip the destructors of the map |
|
123 cxDefineAdvancedDestructor(&kv_list->map->map_base.base, NULL, NULL); |
|
124 kv_list->map_methods->deallocate(&kv_list->map->map_base.base); |
122 kv_list->map_methods->deallocate(&kv_list->map->map_base.base); |
125 // then free the list, now the destructors may be called |
123 // then free the list, now the destructors may be called |
126 kv_list->list_methods->deallocate(list); |
124 kv_list->list_methods->deallocate(list); |
127 } |
125 } |
128 |
126 |
183 } |
181 } |
184 |
182 |
185 static void cx_kvl_clear(struct cx_list_s *list) { |
183 static void cx_kvl_clear(struct cx_list_s *list) { |
186 cx_kv_list *kv_list = (cx_kv_list*)list; |
184 cx_kv_list *kv_list = (cx_kv_list*)list; |
187 // patch the destructors |
185 // patch the destructors |
188 // but remove the wrapper from the map to avoid calling it twice |
|
189 cx_kv_list_update_destructors(kv_list); |
186 cx_kv_list_update_destructors(kv_list); |
190 cxDefineAdvancedDestructor(&kv_list->map->map_base.base, NULL, NULL); |
|
191 // clear the list |
187 // clear the list |
192 kv_list->list_methods->clear(list); |
188 kv_list->list_methods->clear(list); |
193 // then clear the map |
189 // then clear the map |
194 kv_list->map_methods->clear(&kv_list->map->map_base.base); |
190 kv_list->map_methods->clear(&kv_list->map->map_base.base); |
195 } |
191 } |
249 } |
245 } |
250 |
246 |
251 static void cx_kvl_map_clear(struct cx_map_s *map) { |
247 static void cx_kvl_map_clear(struct cx_map_s *map) { |
252 cx_kv_list *kv_list = ((struct cx_kv_list_map_s*)map)->list; |
248 cx_kv_list *kv_list = ((struct cx_kv_list_map_s*)map)->list; |
253 cx_kv_list_update_destructors(kv_list); |
249 cx_kv_list_update_destructors(kv_list); |
254 // TODO: iterate through the map elements, unlink them from the list, and free them |
250 kv_list->list_methods->clear(&kv_list->list.base); |
255 kv_list->map_methods->clear(map); |
251 kv_list->map_methods->clear(map); |
256 } |
252 } |
257 |
253 |
258 static void *cx_kvl_map_put(CxMap *map, CxHashKey key, void *value) { |
254 static void *cx_kvl_map_put(CxMap *map, CxHashKey key, void *value) { |
259 cx_kv_list *kv_list = ((struct cx_kv_list_map_s*)map)->list; |
255 cx_kv_list *kv_list = ((struct cx_kv_list_map_s*)map)->list; |