ucx/map.c

branch
dav-2
changeset 891
4d58cbcc9efa
parent 889
42cdbf9bbd49
equal deleted inserted replaced
890:e77ccf1c4bb3 891:4d58cbcc9efa
68 }; 68 };
69 69
70 CxMap cx_empty_map = { 70 CxMap cx_empty_map = {
71 { 71 {
72 NULL, 72 NULL,
73 NULL,
74 0, 73 0,
75 0, 74 0,
75 NULL,
76 NULL,
77 NULL,
76 NULL, 78 NULL,
77 NULL, 79 NULL,
78 NULL, 80 NULL,
79 false, 81 false,
80 true 82 true
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 }

mercurial