src/map.c

changeset 1450
09a73312d5ec
parent 1449
bbca398783ed
equal deleted inserted replaced
1449:bbca398783ed 1450:09a73312d5ec
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 }

mercurial