126 void cxMapFree(CxMap *map) { |
126 void cxMapFree(CxMap *map) { |
127 if (map == NULL) return; |
127 if (map == NULL) return; |
128 map->cl->deallocate(map); |
128 map->cl->deallocate(map); |
129 } |
129 } |
130 |
130 |
|
131 static void cx_map_remove_uninitialized_entry(CxMap *map, CxHashKey key) { |
|
132 cx_destructor_func destr_bak = map->collection.simple_destructor; |
|
133 cx_destructor_func2 destr2_bak = map->collection.advanced_destructor; |
|
134 map->collection.simple_destructor = NULL; |
|
135 map->collection.advanced_destructor = NULL; |
|
136 cxMapRemove(map, key); |
|
137 map->collection.simple_destructor = destr_bak; |
|
138 map->collection.advanced_destructor = destr2_bak; |
|
139 } |
|
140 |
131 size_t cxMapClone(CxMap *dst, const CxMap *src, cx_clone_func clone_func, |
141 size_t cxMapClone(CxMap *dst, const CxMap *src, cx_clone_func clone_func, |
132 const CxAllocator *clone_allocator, void *data) { |
142 const CxAllocator *clone_allocator, void *data) { |
133 CxMapIterator src_iter = cxMapIterator(src); |
143 CxMapIterator src_iter = cxMapIterator(src); |
134 size_t i = 0; |
144 size_t i = 0; |
135 if (cxCollectionStoresPointers(dst)) { |
145 if (cxCollectionStoresPointers(dst)) { |
139 if (dst_mem == NULL) { |
149 if (dst_mem == NULL) { |
140 return i; |
150 return i; |
141 } |
151 } |
142 void *dst_ptr = clone_func(NULL, entry->value, clone_allocator, data); |
152 void *dst_ptr = clone_func(NULL, entry->value, clone_allocator, data); |
143 if (dst_ptr == NULL) { |
153 if (dst_ptr == NULL) { |
144 // TODO: remove the entry to avoid calling destructors on uninitialized memory |
154 cx_map_remove_uninitialized_entry(dst, *(entry->key)); |
145 return i; |
155 return i; |
146 } |
156 } |
147 *dst_mem = dst_ptr; |
157 *dst_mem = dst_ptr; |
148 cxIteratorNext(src_iter); |
158 cxIteratorNext(src_iter); |
149 } |
159 } |
153 void *dst_mem = cxMapEmplace(dst, *(entry->key)); |
163 void *dst_mem = cxMapEmplace(dst, *(entry->key)); |
154 if (dst_mem == NULL) { |
164 if (dst_mem == NULL) { |
155 return i; |
165 return i; |
156 } |
166 } |
157 if (clone_func(dst_mem, entry->value, clone_allocator, data) == NULL) { |
167 if (clone_func(dst_mem, entry->value, clone_allocator, data) == NULL) { |
158 // TODO: remove the entry to avoid calling destructors on uninitialized memory |
168 cx_map_remove_uninitialized_entry(dst, *(entry->key)); |
159 return i; |
169 return i; |
160 } |
170 } |
161 cxIteratorNext(src_iter); |
171 cxIteratorNext(src_iter); |
162 } |
172 } |
163 } |
173 } |