| 108 if (map == NULL) map = cxEmptyMap; |
110 if (map == NULL) map = cxEmptyMap; |
| 109 return map->cl->iterator(map, CX_MAP_ITERATOR_PAIRS); |
111 return map->cl->iterator(map, CX_MAP_ITERATOR_PAIRS); |
| 110 } |
112 } |
| 111 |
113 |
| 112 int cx_map_put(CxMap *map, CxHashKey key, void *value) { |
114 int cx_map_put(CxMap *map, CxHashKey key, void *value) { |
| 113 return map->cl->put(map, key, value) == NULL; |
115 return map->cl->put(map, key, value).key == NULL; |
| 114 } |
116 } |
| 115 |
117 |
| 116 void *cx_map_emplace(CxMap *map, CxHashKey key) { |
118 void *cx_map_emplace(CxMap *map, CxHashKey key) { |
| 117 return map->cl->put(map, key, NULL); |
119 const CxMapEntry entry = map->cl->put(map, key, NULL); |
| |
120 if (entry.key == NULL) return NULL; |
| |
121 return entry.value; |
| 118 } |
122 } |
| 119 |
123 |
| 120 void *cx_map_get(const CxMap *map, CxHashKey key) { |
124 void *cx_map_get(const CxMap *map, CxHashKey key) { |
| 121 return map->cl->get(map, key); |
125 return map->cl->get(map, key); |
| 122 } |
126 } |
| 138 cxMapRemove(map, key); |
142 cxMapRemove(map, key); |
| 139 map->collection.simple_destructor = destr_bak; |
143 map->collection.simple_destructor = destr_bak; |
| 140 map->collection.advanced_destructor = destr2_bak; |
144 map->collection.advanced_destructor = destr2_bak; |
| 141 } |
145 } |
| 142 |
146 |
| |
147 static void* cx_map_shallow_clone_func(void *dst, const void *src, const CxAllocator *al, void *data) { |
| |
148 size_t elem_size = *(size_t*)data; |
| |
149 if (dst == NULL) dst = cxMalloc(al, elem_size); |
| |
150 if (dst != NULL) memcpy(dst, src, elem_size); |
| |
151 return dst; |
| |
152 } |
| |
153 |
| |
154 #define use_shallow_clone_func(map) cx_map_shallow_clone_func, NULL, (void*)&((map)->collection.elem_size) |
| |
155 |
| 143 int cxMapClone(CxMap *dst, const CxMap *src, cx_clone_func clone_func, |
156 int cxMapClone(CxMap *dst, const CxMap *src, cx_clone_func clone_func, |
| 144 const CxAllocator *clone_allocator, void *data) { |
157 const CxAllocator *clone_allocator, void *data) { |
| 145 if (clone_allocator == NULL) clone_allocator = cxDefaultAllocator; |
158 if (clone_allocator == NULL) clone_allocator = cxDefaultAllocator; |
| 146 CxMapIterator src_iter = cxMapIterator(src); |
159 CxMapIterator src_iter = cxMapIterator(src); |
| 147 for (size_t i = 0; i < cxMapSize(src); i++) { |
160 for (size_t i = 0; i < cxMapSize(src); i++) { |
| 291 *dst_mem = dst_ptr; |
304 *dst_mem = dst_ptr; |
| 292 } |
305 } |
| 293 } |
306 } |
| 294 return 0; |
307 return 0; |
| 295 } |
308 } |
| |
309 |
| |
310 int cxMapCloneShallow(CxMap *dst, const CxMap *src) { |
| |
311 return cxMapClone(dst, src, use_shallow_clone_func(src)); |
| |
312 } |
| |
313 |
| |
314 int cxMapDifferenceShallow(CxMap *dst, const CxMap *minuend, const CxMap *subtrahend) { |
| |
315 return cxMapDifference(dst, minuend, subtrahend, use_shallow_clone_func(minuend)); |
| |
316 } |
| |
317 |
| |
318 int cxMapListDifferenceShallow(CxMap *dst, const CxMap *src, const CxList *keys) { |
| |
319 return cxMapListDifference(dst, src, keys, use_shallow_clone_func(src)); |
| |
320 } |
| |
321 |
| |
322 int cxMapIntersectionShallow(CxMap *dst, const CxMap *src, const CxMap *other) { |
| |
323 return cxMapIntersection(dst, src, other, use_shallow_clone_func(src)); |
| |
324 } |
| |
325 |
| |
326 int cxMapListIntersectionShallow(CxMap *dst, const CxMap *src, const CxList *keys) { |
| |
327 return cxMapListIntersection(dst, src, keys, use_shallow_clone_func(src)); |
| |
328 } |
| |
329 |
| |
330 int cxMapUnionShallow(CxMap *dst, const CxMap *src) { |
| |
331 return cxMapUnion(dst, src, use_shallow_clone_func(src)); |
| |
332 } |
| |
333 |
| |
334 int cxMapCompare(const CxMap *map, const CxMap *other) { |
| |
335 // compare map sizes |
| |
336 const size_t size_left = cxMapSize(map); |
| |
337 const size_t size_right = cxMapSize(other); |
| |
338 if (size_left < size_right) { |
| |
339 return -1; |
| |
340 } else if (size_left > size_right) { |
| |
341 return 1; |
| |
342 } |
| |
343 |
| |
344 // iterate through the first map |
| |
345 CxMapIterator iter = cxMapIterator(map); |
| |
346 cx_foreach(const CxMapEntry *, entry, iter) { |
| |
347 const void *value_left = entry->value; |
| |
348 const void *value_right = cxMapGet(other, *entry->key); |
| |
349 // if the other map does not have the key, we are done |
| |
350 if (value_right == NULL) { |
| |
351 return -1; |
| |
352 } |
| |
353 // compare the values |
| |
354 const int d = cx_invoke_compare_func(map, value_left, value_right); |
| |
355 if (d != 0) { |
| |
356 return d; |
| |
357 } |
| |
358 } |
| |
359 |
| |
360 return 0; |
| |
361 } |