| 146 CxMapIterator src_iter = cxMapIterator(src); |
146 CxMapIterator src_iter = cxMapIterator(src); |
| 147 for (size_t i = 0; i < cxMapSize(src); i++) { |
147 for (size_t i = 0; i < cxMapSize(src); i++) { |
| 148 const CxMapEntry *entry = cxIteratorCurrent(src_iter); |
148 const CxMapEntry *entry = cxIteratorCurrent(src_iter); |
| 149 void **dst_mem = cxMapEmplace(dst, *(entry->key)); |
149 void **dst_mem = cxMapEmplace(dst, *(entry->key)); |
| 150 if (dst_mem == NULL) { |
150 if (dst_mem == NULL) { |
| 151 return 1; |
151 return 1; // LCOV_EXCL_LINE |
| 152 } |
152 } |
| 153 void *target = cxCollectionStoresPointers(dst) ? NULL : dst_mem; |
153 void *target = cxCollectionStoresPointers(dst) ? NULL : dst_mem; |
| 154 void *dst_ptr = clone_func(target, entry->value, clone_allocator, data); |
154 void *dst_ptr = clone_func(target, entry->value, clone_allocator, data); |
| 155 if (dst_ptr == NULL) { |
155 if (dst_ptr == NULL) { |
| 156 cx_map_remove_uninitialized_entry(dst, *(entry->key)); |
156 cx_map_remove_uninitialized_entry(dst, *(entry->key)); |
| 166 |
166 |
| 167 int cxMapDifference(CxMap *dst, const CxMap *minuend, const CxMap *subtrahend, |
167 int cxMapDifference(CxMap *dst, const CxMap *minuend, const CxMap *subtrahend, |
| 168 cx_clone_func clone_func, const CxAllocator *clone_allocator, void *data) { |
168 cx_clone_func clone_func, const CxAllocator *clone_allocator, void *data) { |
| 169 if (clone_allocator == NULL) clone_allocator = cxDefaultAllocator; |
169 if (clone_allocator == NULL) clone_allocator = cxDefaultAllocator; |
| 170 |
170 |
| 171 const bool map_was_not_empty = cxMapSize(dst) > 0; |
171 // if the destination map already contains something, |
| |
172 // remove what does not belong to the difference |
| |
173 CxMapIterator dst_iter = cxMapIteratorKeys(dst); |
| |
174 cx_foreach(const CxHashKey *, key, dst_iter) { |
| |
175 if (cxMapContains(subtrahend, *key)) { |
| |
176 cxIteratorFlagRemoval(dst_iter); |
| |
177 } |
| |
178 } |
| |
179 |
| 172 CxMapIterator src_iter = cxMapIterator(minuend); |
180 CxMapIterator src_iter = cxMapIterator(minuend); |
| 173 cx_foreach(const CxMapEntry *, entry, src_iter) { |
181 cx_foreach(const CxMapEntry *, entry, src_iter) { |
| 174 if (cxMapContains(subtrahend, *entry->key)) { |
182 if (cxMapContains(subtrahend, *entry->key)) { |
| 175 if (map_was_not_empty) { |
183 continue; |
| 176 cxMapRemove(dst, *entry->key); |
184 } |
| 177 } |
185 void** dst_mem = cxMapEmplace(dst, *entry->key); |
| 178 } else { |
186 if (dst_mem == NULL) { |
| 179 void** dst_mem = cxMapEmplace(dst, *entry->key); |
187 return 1; // LCOV_EXCL_LINE |
| 180 if (dst_mem == NULL) { |
188 } |
| 181 return 1; |
189 void *target = cxCollectionStoresPointers(dst) ? NULL : dst_mem; |
| 182 } |
190 void* dst_ptr = clone_func(target, entry->value, clone_allocator, data); |
| 183 void *target = cxCollectionStoresPointers(dst) ? NULL : dst_mem; |
191 if (dst_ptr == NULL) { |
| 184 void* dst_ptr = clone_func(target, entry->value, clone_allocator, data); |
192 cx_map_remove_uninitialized_entry(dst, *(entry->key)); |
| 185 if (dst_ptr == NULL) { |
193 return 1; |
| 186 cx_map_remove_uninitialized_entry(dst, *(entry->key)); |
194 } |
| 187 return 1; |
195 if (cxCollectionStoresPointers(dst)) { |
| 188 } |
196 *dst_mem = dst_ptr; |
| 189 if (cxCollectionStoresPointers(dst)) { |
|
| 190 *dst_mem = dst_ptr; |
|
| 191 } |
|
| 192 } |
197 } |
| 193 } |
198 } |
| 194 return 0; |
199 return 0; |
| 195 } |
200 } |
| 196 |
201 |
| 197 int cxMapListDifference(CxMap *dst, const CxMap *src, const CxList *keys, |
202 int cxMapListDifference(CxMap *dst, const CxMap *src, const CxList *keys, |
| 198 cx_clone_func clone_func, const CxAllocator *clone_allocator, void *data) { |
203 cx_clone_func clone_func, const CxAllocator *clone_allocator, void *data) { |
| 199 const bool map_was_not_empty = cxMapSize(dst) > 0; |
204 if (clone_allocator == NULL) clone_allocator = cxDefaultAllocator; |
| |
205 |
| |
206 // if the destination map already contains something, |
| |
207 // remove what does not belong to the difference |
| |
208 CxMapIterator dst_iter = cxMapIteratorKeys(dst); |
| |
209 cx_foreach(const CxHashKey *, key, dst_iter) { |
| |
210 if (cxListContains(keys, key)) { |
| |
211 cxIteratorFlagRemoval(dst_iter); |
| |
212 } |
| |
213 } |
| |
214 |
| 200 CxMapIterator src_iter = cxMapIterator(src); |
215 CxMapIterator src_iter = cxMapIterator(src); |
| 201 cx_foreach(const CxMapEntry *, entry, src_iter) { |
216 cx_foreach(const CxMapEntry *, entry, src_iter) { |
| 202 if (cxListContains(keys, entry->key)) { |
217 if (cxListContains(keys, entry->key)) { |
| 203 if (map_was_not_empty) { |
218 continue; |
| 204 cxMapRemove(dst, *entry->key); |
219 } |
| 205 } |
220 void** dst_mem = cxMapEmplace(dst, *entry->key); |
| 206 } else { |
221 if (dst_mem == NULL) { |
| 207 void** dst_mem = cxMapEmplace(dst, *entry->key); |
222 return 1; // LCOV_EXCL_LINE |
| 208 if (dst_mem == NULL) { |
223 } |
| 209 return 1; |
224 void *target = cxCollectionStoresPointers(dst) ? NULL : dst_mem; |
| 210 } |
225 void* dst_ptr = clone_func(target, entry->value, clone_allocator, data); |
| 211 void *target = cxCollectionStoresPointers(dst) ? NULL : dst_mem; |
226 if (dst_ptr == NULL) { |
| 212 void* dst_ptr = clone_func(target, entry->value, clone_allocator, data); |
227 cx_map_remove_uninitialized_entry(dst, *(entry->key)); |
| 213 if (dst_ptr == NULL) { |
228 return 1; |
| 214 cx_map_remove_uninitialized_entry(dst, *(entry->key)); |
229 } |
| 215 return 1; |
230 if (cxCollectionStoresPointers(dst)) { |
| 216 } |
231 *dst_mem = dst_ptr; |
| 217 if (cxCollectionStoresPointers(dst)) { |
|
| 218 *dst_mem = dst_ptr; |
|
| 219 } |
|
| 220 } |
232 } |
| 221 } |
233 } |
| 222 return 0; |
234 return 0; |
| 223 } |
235 } |