src/map.c

changeset 1445
e8089a590b71
parent 1444
dd9dcbb39c2f
equal deleted inserted replaced
1444:dd9dcbb39c2f 1445:e8089a590b71
27 */ 27 */
28 28
29 #include "cx/map.h" 29 #include "cx/map.h"
30 #include <string.h> 30 #include <string.h>
31 31
32 #include "cx/list.h"
33
32 // <editor-fold desc="empty map implementation"> 34 // <editor-fold desc="empty map implementation">
33 35
34 static void cx_empty_map_noop(cx_attr_unused CxMap *map) { 36 static void cx_empty_map_noop(cx_attr_unused CxMap *map) {
35 // this is a noop, but MUST be implemented 37 // this is a noop, but MUST be implemented
36 } 38 }
170 cxIteratorNext(src_iter); 172 cxIteratorNext(src_iter);
171 } 173 }
172 } 174 }
173 return 0; 175 return 0;
174 } 176 }
177
178 int cxMapDifference(CxMap *dst, const CxMap *minuend, const CxMap *subtrahend,
179 cx_clone_func clone_func, const CxAllocator *clone_allocator, void *data) {
180 const bool map_was_not_empty = cxMapSize(dst) > 0;
181 CxMapIterator src_iter = cxMapIterator(minuend);
182 if (cxCollectionStoresPointers(dst)) {
183 cx_foreach(const CxMapEntry *, entry, src_iter) {
184 if (cxMapContains(subtrahend, *entry->key)) {
185 if (map_was_not_empty) {
186 cxMapRemove(dst, *entry->key);
187 }
188 } else {
189 void** dst_mem = cxMapEmplace(dst, *entry->key);
190 if (dst_mem == NULL) {
191 return 1;
192 }
193
194 void* dst_ptr = clone_func(NULL, entry->value, clone_allocator, data);
195 if (dst_ptr == NULL) {
196 cx_map_remove_uninitialized_entry(dst, *(entry->key));
197 return 1;
198 }
199 *dst_mem = dst_ptr;
200 }
201 }
202 } else {
203 cx_foreach(const CxMapEntry *, entry, src_iter) {
204 if (cxMapContains(subtrahend, *entry->key)) {
205 if (map_was_not_empty) {
206 cxMapRemove(dst, *entry->key);
207 }
208 } else {
209 void* dst_mem = cxMapEmplace(dst, *entry->key);
210 if (dst_mem == NULL) {
211 return 1;
212 }
213 if (NULL == clone_func(dst_mem, entry->value, clone_allocator, data)) {
214 cx_map_remove_uninitialized_entry(dst, *entry->key);
215 return 1;
216 }
217 }
218 }
219 }
220 return 0;
221 }
222
223 int cxMapListDifference(CxMap *dst, const CxMap *src, const CxList *keys,
224 cx_clone_func clone_func, const CxAllocator *clone_allocator, void *data) {
225 const bool map_was_not_empty = cxMapSize(dst) > 0;
226 CxMapIterator src_iter = cxMapIterator(src);
227 if (cxCollectionStoresPointers(dst)) {
228 cx_foreach(const CxMapEntry *, entry, src_iter) {
229 if (cxListContains(keys, entry->key)) {
230 if (map_was_not_empty) {
231 cxMapRemove(dst, *entry->key);
232 }
233 } else {
234 void** dst_mem = cxMapEmplace(dst, *entry->key);
235 if (dst_mem == NULL) {
236 return 1;
237 }
238
239 void* dst_ptr = clone_func(NULL, entry->value, clone_allocator, data);
240 if (dst_ptr == NULL) {
241 cx_map_remove_uninitialized_entry(dst, *(entry->key));
242 return 1;
243 }
244 *dst_mem = dst_ptr;
245 }
246 }
247 } else {
248 cx_foreach(const CxMapEntry *, entry, src_iter) {
249 if (cxListContains(keys, entry->key)) {
250 if (map_was_not_empty) {
251 cxMapRemove(dst, *entry->key);
252 }
253 } else {
254 void* dst_mem = cxMapEmplace(dst, *entry->key);
255 if (dst_mem == NULL) {
256 return 1;
257 }
258 if (NULL == clone_func(dst_mem, entry->value, clone_allocator, data)) {
259 cx_map_remove_uninitialized_entry(dst, *entry->key);
260 return 1;
261 }
262 }
263 }
264 }
265 return 0;
266 }

mercurial